qontract-reconcile 0.10.1rc884__py3-none-any.whl → 0.10.1rc886__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.1rc884.dist-info → qontract_reconcile-0.10.1rc886.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc884.dist-info → qontract_reconcile-0.10.1rc886.dist-info}/RECORD +279 -276
- reconcile/acs_rbac.py +1 -2
- reconcile/aus/advanced_upgrade_service.py +14 -14
- reconcile/aus/aus_label_source.py +1 -2
- reconcile/aus/base.py +23 -26
- reconcile/aus/cluster_version_data.py +4 -4
- reconcile/aus/models.py +2 -3
- reconcile/aus/version_gate_approver.py +2 -6
- reconcile/aus/version_gates/__init__.py +1 -3
- reconcile/aus/version_gates/sts_version_gate_handler.py +2 -3
- reconcile/aws_account_manager/integration.py +2 -2
- reconcile/aws_ami_cleanup/integration.py +3 -4
- reconcile/aws_iam_password_reset.py +2 -5
- reconcile/aws_version_sync/integration.py +2 -2
- reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
- reconcile/change_owners/approver.py +4 -5
- reconcile/change_owners/bundle.py +20 -22
- reconcile/change_owners/change_types.py +23 -24
- reconcile/change_owners/changes.py +13 -16
- reconcile/change_owners/decision.py +2 -5
- reconcile/change_owners/diff.py +11 -15
- reconcile/change_owners/self_service_roles.py +1 -2
- reconcile/change_owners/tester.py +7 -10
- reconcile/checkpoint.py +2 -5
- reconcile/cli.py +9 -12
- reconcile/closedbox_endpoint_monitoring_base.py +8 -11
- reconcile/cluster_deployment_mapper.py +2 -5
- reconcile/cna/assets/asset.py +4 -7
- reconcile/cna/assets/null.py +2 -5
- reconcile/cna/integration.py +2 -3
- reconcile/cna/state.py +2 -5
- reconcile/dashdotdb_base.py +8 -11
- reconcile/dashdotdb_cso.py +3 -6
- reconcile/dashdotdb_dora.py +10 -14
- reconcile/dashdotdb_dvo.py +10 -13
- reconcile/dashdotdb_slo.py +5 -8
- reconcile/database_access_manager.py +5 -6
- reconcile/dynatrace_token_provider/integration.py +2 -5
- reconcile/external_resources/integration.py +1 -1
- reconcile/external_resources/manager.py +4 -4
- reconcile/external_resources/model.py +3 -3
- reconcile/external_resources/secrets_sync.py +5 -5
- reconcile/external_resources/state.py +5 -5
- reconcile/gabi_authorized_users.py +3 -6
- reconcile/gcr_mirror.py +1 -1
- reconcile/github_org.py +1 -3
- reconcile/github_repo_invites.py +2 -5
- reconcile/gitlab_housekeeping.py +7 -11
- reconcile/gitlab_labeler.py +1 -2
- reconcile/gitlab_members.py +2 -5
- reconcile/gitlab_permissions.py +1 -3
- reconcile/glitchtip/integration.py +2 -5
- reconcile/glitchtip_project_alerts/integration.py +3 -6
- reconcile/glitchtip_project_dsn/integration.py +4 -7
- reconcile/integrations_manager.py +5 -8
- reconcile/jenkins/types.py +5 -6
- reconcile/jenkins_job_builder.py +9 -12
- reconcile/jenkins_roles.py +1 -1
- reconcile/jira_watcher.py +2 -2
- reconcile/ldap_groups/integration.py +2 -5
- reconcile/ocm/types.py +21 -26
- reconcile/ocm_addons_upgrade_tests_trigger.py +3 -6
- reconcile/ocm_clusters.py +8 -8
- reconcile/ocm_internal_notifications/integration.py +1 -2
- reconcile/ocm_labels/integration.py +2 -5
- reconcile/ocm_machine_pools.py +11 -15
- reconcile/ocm_upgrade_scheduler_org_updater.py +2 -5
- reconcile/openshift_base.py +27 -29
- reconcile/openshift_groups.py +15 -20
- reconcile/openshift_namespace_labels.py +8 -14
- reconcile/openshift_namespaces.py +5 -8
- reconcile/openshift_network_policies.py +2 -4
- reconcile/openshift_resources_base.py +19 -29
- reconcile/openshift_saas_deploy.py +9 -10
- reconcile/openshift_saas_deploy_change_tester.py +7 -10
- reconcile/openshift_saas_deploy_trigger_base.py +4 -7
- reconcile/openshift_saas_deploy_trigger_cleaner.py +5 -8
- reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
- reconcile/openshift_saas_deploy_trigger_images.py +1 -2
- reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
- reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
- reconcile/openshift_tekton_resources.py +7 -11
- reconcile/openshift_upgrade_watcher.py +10 -13
- reconcile/openshift_users.py +8 -11
- reconcile/oum/base.py +3 -4
- reconcile/oum/labelset.py +1 -2
- reconcile/oum/metrics.py +2 -2
- reconcile/oum/models.py +1 -2
- reconcile/oum/standalone.py +2 -3
- reconcile/prometheus_rules_tester/integration.py +6 -9
- reconcile/quay_membership.py +1 -2
- reconcile/quay_mirror.py +12 -13
- reconcile/quay_mirror_org.py +10 -10
- reconcile/queries.py +4 -7
- reconcile/resource_scraper.py +3 -4
- reconcile/rhidp/common.py +2 -2
- reconcile/saas_auto_promotions_manager/integration.py +5 -6
- reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +1 -2
- reconcile/saas_auto_promotions_manager/publisher.py +5 -6
- reconcile/saas_auto_promotions_manager/subscriber.py +3 -4
- reconcile/saas_file_validator.py +2 -5
- reconcile/signalfx_endpoint_monitoring.py +2 -5
- reconcile/skupper_network/integration.py +3 -6
- reconcile/skupper_network/models.py +3 -5
- reconcile/slack_base.py +4 -7
- reconcile/slack_usergroups.py +15 -17
- reconcile/sql_query.py +5 -9
- reconcile/status_board.py +4 -5
- reconcile/statuspage/atlassian.py +14 -15
- reconcile/statuspage/integrations/maintenances.py +3 -3
- reconcile/statuspage/page.py +8 -8
- reconcile/statuspage/state.py +4 -5
- reconcile/statuspage/status.py +7 -8
- reconcile/templating/lib/rendering.py +8 -8
- reconcile/templating/renderer.py +10 -11
- reconcile/templating/validator.py +4 -4
- reconcile/terraform_aws_route53.py +3 -6
- reconcile/terraform_cloudflare_dns.py +9 -12
- reconcile/terraform_cloudflare_resources.py +9 -11
- reconcile/terraform_cloudflare_users.py +8 -11
- reconcile/terraform_init/integration.py +2 -2
- reconcile/terraform_repo.py +11 -14
- reconcile/terraform_resources.py +20 -21
- reconcile/terraform_tgw_attachments.py +32 -36
- reconcile/terraform_users.py +6 -7
- reconcile/terraform_vpc_resources/integration.py +5 -5
- reconcile/test/conftest.py +7 -10
- reconcile/test/fixtures.py +1 -1
- reconcile/test/saas_auto_promotions_manager/conftest.py +2 -2
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +2 -2
- reconcile/test/test_database_access_manager.py +3 -6
- reconcile/test/test_gitlab_labeler.py +2 -5
- reconcile/test/test_jump_host.py +5 -8
- reconcile/test/test_ocm_machine_pools.py +1 -4
- reconcile/test/test_openshift_base.py +3 -6
- reconcile/test/test_openshift_cluster_bots.py +5 -5
- reconcile/test/test_openshift_namespace_labels.py +2 -3
- reconcile/test/test_openshift_saas_deploy_trigger_cleaner.py +2 -2
- reconcile/test/test_saasherder.py +9 -12
- reconcile/test/test_slack_base.py +4 -6
- reconcile/test/test_status_board.py +4 -7
- reconcile/test/test_terraform_tgw_attachments.py +14 -20
- reconcile/typed_queries/alerting_services_settings.py +1 -2
- reconcile/typed_queries/app_interface_custom_messages.py +2 -3
- reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +1 -3
- reconcile/typed_queries/app_interface_repo_url.py +1 -2
- reconcile/typed_queries/app_interface_state_settings.py +1 -3
- reconcile/typed_queries/app_interface_vault_settings.py +1 -2
- reconcile/typed_queries/aws_vpc_requests.py +1 -3
- reconcile/typed_queries/aws_vpcs.py +1 -3
- reconcile/typed_queries/clusters.py +2 -4
- reconcile/typed_queries/clusters_minimal.py +1 -3
- reconcile/typed_queries/clusters_with_dms.py +1 -3
- reconcile/typed_queries/external_resources.py +3 -4
- reconcile/typed_queries/pagerduty_instances.py +1 -2
- reconcile/typed_queries/repos.py +2 -3
- reconcile/typed_queries/reserved_networks.py +1 -3
- reconcile/typed_queries/saas_files.py +49 -59
- reconcile/typed_queries/slo_documents.py +1 -3
- reconcile/typed_queries/status_board.py +3 -7
- reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
- reconcile/typed_queries/terraform_namespaces.py +1 -2
- reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +1 -3
- reconcile/utils/acs/base.py +2 -3
- reconcile/utils/acs/notifiers.py +3 -3
- reconcile/utils/acs/policies.py +3 -3
- reconcile/utils/aggregated_list.py +1 -1
- reconcile/utils/amtool.py +1 -2
- reconcile/utils/aws_api.py +28 -31
- reconcile/utils/binary.py +1 -3
- reconcile/utils/clusterhealth/providerbase.py +1 -2
- reconcile/utils/clusterhealth/telemeter.py +2 -2
- reconcile/utils/deadmanssnitch_api.py +1 -2
- reconcile/utils/disabled_integrations.py +4 -6
- reconcile/utils/environ.py +1 -1
- reconcile/utils/expiration.py +3 -7
- reconcile/utils/external_resource_spec.py +3 -4
- reconcile/utils/external_resources.py +4 -7
- reconcile/utils/filtering.py +1 -2
- reconcile/utils/git.py +3 -9
- reconcile/utils/git_secrets.py +5 -5
- reconcile/utils/github_api.py +5 -9
- reconcile/utils/gitlab_api.py +2 -3
- reconcile/utils/glitchtip/client.py +2 -4
- reconcile/utils/glitchtip/models.py +8 -11
- reconcile/utils/gql.py +26 -35
- reconcile/utils/grouping.py +1 -3
- reconcile/utils/imap_client.py +2 -5
- reconcile/utils/internal_groups/client.py +1 -2
- reconcile/utils/internal_groups/models.py +8 -9
- reconcile/utils/jenkins_api.py +4 -4
- reconcile/utils/jinja2/extensions.py +1 -1
- reconcile/utils/jinja2/filters.py +4 -4
- reconcile/utils/jinja2/utils.py +16 -16
- reconcile/utils/jira_client.py +10 -11
- reconcile/utils/jjb_client.py +14 -17
- reconcile/utils/jobcontroller/controller.py +5 -5
- reconcile/utils/jobcontroller/models.py +2 -2
- reconcile/utils/jsonpath.py +4 -5
- reconcile/utils/jump_host.py +7 -8
- reconcile/utils/keycloak.py +3 -7
- reconcile/utils/ldap_client.py +2 -3
- reconcile/utils/lean_terraform_client.py +13 -17
- reconcile/utils/membershipsources/app_interface_resolver.py +1 -1
- reconcile/utils/membershipsources/models.py +19 -22
- reconcile/utils/metrics.py +13 -15
- reconcile/utils/mr/base.py +7 -11
- reconcile/utils/mr/glitchtip_access_reporter.py +2 -2
- reconcile/utils/mr/notificator.py +1 -2
- reconcile/utils/oc.py +32 -38
- reconcile/utils/oc_connection_parameters.py +24 -25
- reconcile/utils/oc_filters.py +2 -3
- reconcile/utils/oc_map.py +9 -15
- reconcile/utils/ocm/addons.py +7 -10
- reconcile/utils/ocm/base.py +38 -39
- reconcile/utils/ocm/clusters.py +6 -9
- reconcile/utils/ocm/label_sources.py +1 -2
- reconcile/utils/ocm/labels.py +3 -6
- reconcile/utils/ocm/ocm.py +11 -14
- reconcile/utils/ocm/products.py +1 -3
- reconcile/utils/ocm/search_filters.py +16 -17
- reconcile/utils/ocm/service_log.py +2 -3
- reconcile/utils/ocm/sre_capability_labels.py +4 -8
- reconcile/utils/ocm/subscriptions.py +1 -3
- reconcile/utils/ocm/syncsets.py +2 -4
- reconcile/utils/ocm/upgrades.py +5 -9
- reconcile/utils/ocm_base_client.py +13 -16
- reconcile/utils/openshift_resource.py +5 -11
- reconcile/utils/output.py +2 -3
- reconcile/utils/pagerduty_api.py +4 -5
- reconcile/utils/prometheus.py +2 -2
- reconcile/utils/promotion_state.py +4 -5
- reconcile/utils/promtool.py +2 -8
- reconcile/utils/quay_api.py +12 -22
- reconcile/utils/raw_github_api.py +3 -5
- reconcile/utils/rosa/rosa_cli.py +6 -6
- reconcile/utils/rosa/session.py +6 -7
- reconcile/utils/runtime/desired_state_diff.py +3 -8
- reconcile/utils/runtime/environment.py +4 -7
- reconcile/utils/runtime/integration.py +4 -4
- reconcile/utils/runtime/meta.py +1 -2
- reconcile/utils/runtime/runner.py +7 -10
- reconcile/utils/runtime/sharding.py +22 -27
- reconcile/utils/saasherder/interfaces.py +63 -69
- reconcile/utils/saasherder/models.py +30 -35
- reconcile/utils/saasherder/saasherder.py +37 -53
- reconcile/utils/secret_reader.py +17 -19
- reconcile/utils/slack_api.py +15 -17
- reconcile/utils/smtp_client.py +1 -2
- reconcile/utils/sqs_gateway.py +1 -3
- reconcile/utils/state.py +1 -2
- reconcile/utils/terraform/config_client.py +4 -5
- reconcile/utils/terraform_client.py +3 -8
- reconcile/utils/terrascript/cloudflare_client.py +4 -10
- reconcile/utils/terrascript/cloudflare_resources.py +10 -13
- reconcile/utils/terrascript/models.py +2 -3
- reconcile/utils/terrascript/resources.py +1 -2
- reconcile/utils/terrascript_aws_client.py +30 -38
- reconcile/utils/unleash/client.py +4 -7
- reconcile/utils/unleash/server.py +2 -2
- reconcile/utils/vault.py +8 -11
- reconcile/utils/vaultsecretref.py +2 -3
- reconcile/utils/vcs.py +7 -8
- reconcile/vault_replication.py +4 -8
- reconcile/vpc_peerings_validator.py +4 -9
- release/version.py +6 -7
- tools/app_interface_reporter.py +2 -2
- tools/cli_commands/gpg_encrypt.py +3 -6
- tools/cli_commands/systems_and_tools.py +4 -7
- tools/qontract_cli.py +31 -17
- tools/saas_promotion_state/__init__.py +0 -0
- tools/saas_promotion_state/saas_promotion_state.py +72 -0
- tools/template_validation.py +1 -1
- tools/test/conftest.py +45 -6
- tools/test/test_saas_promotion_state.py +86 -0
- {qontract_reconcile-0.10.1rc884.dist-info → qontract_reconcile-0.10.1rc886.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc884.dist-info → qontract_reconcile-0.10.1rc886.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc884.dist-info → qontract_reconcile-0.10.1rc886.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
from abc import ABC, abstractmethod
|
3
3
|
from io import StringIO
|
4
|
-
from typing import Any,
|
4
|
+
from typing import Any, Protocol
|
5
5
|
|
6
6
|
from pydantic import BaseModel
|
7
7
|
|
@@ -13,27 +13,27 @@ from reconcile.utils.secret_reader import SecretReaderBase
|
|
13
13
|
|
14
14
|
class TemplateData(BaseModel):
|
15
15
|
variables: dict[str, Any]
|
16
|
-
current:
|
17
|
-
current_with_explicit_start:
|
16
|
+
current: dict[str, Any] | None
|
17
|
+
current_with_explicit_start: bool | None = False
|
18
18
|
|
19
19
|
|
20
20
|
class TemplatePatch(Protocol):
|
21
21
|
path: str
|
22
|
-
identifier:
|
22
|
+
identifier: str | None
|
23
23
|
|
24
24
|
def dict(self) -> dict[str, str]: ...
|
25
25
|
|
26
26
|
|
27
27
|
class Template(Protocol):
|
28
28
|
name: str
|
29
|
-
condition:
|
29
|
+
condition: str | None
|
30
30
|
target_path: str
|
31
31
|
template: str
|
32
32
|
|
33
33
|
def dict(self) -> dict[str, str]: ...
|
34
34
|
|
35
35
|
@property
|
36
|
-
def patch(self) ->
|
36
|
+
def patch(self) -> TemplatePatch | None:
|
37
37
|
pass
|
38
38
|
|
39
39
|
|
@@ -42,7 +42,7 @@ class Renderer(ABC):
|
|
42
42
|
self,
|
43
43
|
template: Template,
|
44
44
|
data: TemplateData,
|
45
|
-
secret_reader:
|
45
|
+
secret_reader: SecretReaderBase | None = None,
|
46
46
|
):
|
47
47
|
self.template = template
|
48
48
|
self.data = data
|
@@ -149,7 +149,7 @@ class PatchRenderer(Renderer):
|
|
149
149
|
def create_renderer(
|
150
150
|
template: Template,
|
151
151
|
data: TemplateData,
|
152
|
-
secret_reader:
|
152
|
+
secret_reader: SecretReaderBase | None = None,
|
153
153
|
) -> Renderer:
|
154
154
|
if template.patch:
|
155
155
|
return PatchRenderer(template=template, data=data, secret_reader=secret_reader)
|
reconcile/templating/renderer.py
CHANGED
@@ -5,7 +5,7 @@ import tempfile
|
|
5
5
|
from abc import ABC, abstractmethod
|
6
6
|
from collections.abc import Callable
|
7
7
|
from pathlib import Path
|
8
|
-
from typing import Any,
|
8
|
+
from typing import Any, Self
|
9
9
|
|
10
10
|
from deepdiff import DeepHash
|
11
11
|
from ruamel import yaml
|
@@ -46,7 +46,7 @@ APP_INTERFACE_PATH_SEPERATOR = "/"
|
|
46
46
|
|
47
47
|
|
48
48
|
def get_template_collections(
|
49
|
-
query_func:
|
49
|
+
query_func: Callable | None = None,
|
50
50
|
) -> list[TemplateCollectionV1]:
|
51
51
|
if not query_func:
|
52
52
|
query_func = gql.get_api().query
|
@@ -59,15 +59,14 @@ class FilePersistence(ABC):
|
|
59
59
|
pass
|
60
60
|
|
61
61
|
@abstractmethod
|
62
|
-
def read(self, path: str) ->
|
62
|
+
def read(self, path: str) -> str | None:
|
63
63
|
pass
|
64
64
|
|
65
65
|
@staticmethod
|
66
|
-
def _read_local_file(path: str) ->
|
66
|
+
def _read_local_file(path: str) -> str | None:
|
67
67
|
try:
|
68
68
|
with open(
|
69
69
|
path,
|
70
|
-
"r",
|
71
70
|
encoding="utf-8",
|
72
71
|
) as f:
|
73
72
|
return f.read()
|
@@ -92,7 +91,7 @@ class LocalFilePersistence(FilePersistence):
|
|
92
91
|
filepath.parent.mkdir(parents=True, exist_ok=True)
|
93
92
|
filepath.write_text(output.content, encoding="utf-8")
|
94
93
|
|
95
|
-
def read(self, path: str) ->
|
94
|
+
def read(self, path: str) -> str | None:
|
96
95
|
return self._read_local_file(join_path(self.app_interface_data_path, path))
|
97
96
|
|
98
97
|
|
@@ -106,7 +105,7 @@ class PersistenceTransaction(FilePersistence):
|
|
106
105
|
def __init__(self, persistence: FilePersistence, dry_run: bool) -> None:
|
107
106
|
self.persistence = persistence
|
108
107
|
self.dry_run = dry_run
|
109
|
-
self.content_cache: dict[str,
|
108
|
+
self.content_cache: dict[str, str | None] = {}
|
110
109
|
self.output_cache: dict[str, TemplateOutput] = {}
|
111
110
|
|
112
111
|
def write(self, outputs: list[TemplateOutput]) -> None:
|
@@ -114,7 +113,7 @@ class PersistenceTransaction(FilePersistence):
|
|
114
113
|
self.content_cache[output.path] = output.content
|
115
114
|
self.output_cache[output.path] = output
|
116
115
|
|
117
|
-
def read(self, path: str) ->
|
116
|
+
def read(self, path: str) -> str | None:
|
118
117
|
if path not in self.content_cache:
|
119
118
|
self.content_cache[path] = self.persistence.read(path)
|
120
119
|
return self.content_cache[path]
|
@@ -153,7 +152,7 @@ class ClonedRepoGitlabPersistence(FilePersistence):
|
|
153
152
|
|
154
153
|
self.mr_manager.create_merge_request(MrData(data=outputs, auto_approved=False))
|
155
154
|
|
156
|
-
def read(self, path: str) ->
|
155
|
+
def read(self, path: str) -> str | None:
|
157
156
|
return self._read_local_file(join_path(self.local_path, path))
|
158
157
|
|
159
158
|
|
@@ -193,7 +192,7 @@ def calc_template_hash(c: TemplateCollectionV1, variables: dict[str, Any]) -> st
|
|
193
192
|
|
194
193
|
class TemplateRendererIntegrationParams(PydanticRunParams):
|
195
194
|
clone_repo: bool = False
|
196
|
-
app_interface_data_path:
|
195
|
+
app_interface_data_path: str | None
|
197
196
|
|
198
197
|
|
199
198
|
def join_path(base: str, sub: str) -> str:
|
@@ -211,7 +210,7 @@ class TemplateRendererIntegration(QontractReconcileIntegration):
|
|
211
210
|
persistence: FilePersistence,
|
212
211
|
ruaml_instance: yaml.YAML,
|
213
212
|
template_input: TemplateInput,
|
214
|
-
) ->
|
213
|
+
) -> TemplateOutput | None:
|
215
214
|
r = create_renderer(
|
216
215
|
template,
|
217
216
|
TemplateData(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import logging
|
2
|
+
from collections.abc import Callable
|
2
3
|
from difflib import context_diff
|
3
|
-
from typing import Callable, Optional
|
4
4
|
|
5
5
|
from pydantic import BaseModel
|
6
6
|
from ruamel import yaml
|
@@ -22,7 +22,7 @@ QONTRACT_INTEGRATION = "template-validator"
|
|
22
22
|
|
23
23
|
|
24
24
|
def get_templates(
|
25
|
-
query_func:
|
25
|
+
query_func: Callable | None = None,
|
26
26
|
) -> list[TemplateV1]:
|
27
27
|
if not query_func:
|
28
28
|
query_func = gql.get_api().query
|
@@ -41,7 +41,7 @@ class TemplateValidatorIntegration(QontractReconcileIntegration):
|
|
41
41
|
template: TemplateV1,
|
42
42
|
template_test: TemplateTestV1,
|
43
43
|
ruaml_instance: yaml.YAML,
|
44
|
-
secret_reader:
|
44
|
+
secret_reader: SecretReaderBase | None = None,
|
45
45
|
) -> Renderer:
|
46
46
|
return create_renderer(
|
47
47
|
template,
|
@@ -57,7 +57,7 @@ class TemplateValidatorIntegration(QontractReconcileIntegration):
|
|
57
57
|
template: TemplateV1,
|
58
58
|
template_test: TemplateTestV1,
|
59
59
|
ruaml_instance: yaml.YAML,
|
60
|
-
secret_reader:
|
60
|
+
secret_reader: SecretReaderBase | None = None,
|
61
61
|
) -> list[TemplateDiff]:
|
62
62
|
diffs: list[TemplateDiff] = []
|
63
63
|
|
@@ -4,10 +4,7 @@ from collections.abc import (
|
|
4
4
|
Iterable,
|
5
5
|
Mapping,
|
6
6
|
)
|
7
|
-
from typing import
|
8
|
-
Any,
|
9
|
-
Optional,
|
10
|
-
)
|
7
|
+
from typing import Any
|
11
8
|
|
12
9
|
from reconcile import queries
|
13
10
|
from reconcile.status import ExitCodes
|
@@ -206,10 +203,10 @@ def build_desired_state(
|
|
206
203
|
@defer
|
207
204
|
def run(
|
208
205
|
dry_run: bool = False,
|
209
|
-
print_to_file:
|
206
|
+
print_to_file: str | None = None,
|
210
207
|
enable_deletion: bool = True,
|
211
208
|
thread_pool_size: int = 10,
|
212
|
-
account_name:
|
209
|
+
account_name: str | None = None,
|
213
210
|
defer=None,
|
214
211
|
):
|
215
212
|
settings = queries.get_app_interface_settings()
|
@@ -3,12 +3,9 @@ import sys
|
|
3
3
|
from collections.abc import (
|
4
4
|
Callable,
|
5
5
|
Mapping,
|
6
|
-
)
|
7
|
-
from typing import (
|
8
|
-
Any,
|
9
|
-
Optional,
|
10
6
|
Sequence,
|
11
7
|
)
|
8
|
+
from typing import Any
|
12
9
|
|
13
10
|
from deepdiff import DeepHash
|
14
11
|
|
@@ -74,9 +71,9 @@ DEFAULT_CLOUDFLARE_ZONE_RECORDS_MAX = 500
|
|
74
71
|
class TerraformCloudflareDNSIntegrationParams(PydanticRunParams):
|
75
72
|
enable_deletion: bool
|
76
73
|
thread_pool_size: int
|
77
|
-
selected_account:
|
78
|
-
selected_zone:
|
79
|
-
print_to_file:
|
74
|
+
selected_account: str | None = None
|
75
|
+
selected_zone: str | None = None
|
76
|
+
print_to_file: str | None
|
80
77
|
|
81
78
|
|
82
79
|
class TerraformCloudflareDNSIntegration(
|
@@ -93,7 +90,7 @@ class TerraformCloudflareDNSIntegration(
|
|
93
90
|
return self.qontract_integration.replace("_", "-")
|
94
91
|
|
95
92
|
@defer
|
96
|
-
def run(self, dry_run: bool, defer:
|
93
|
+
def run(self, dry_run: bool, defer: Callable | None = None) -> None:
|
97
94
|
settings = self._get_app_interface_settings()
|
98
95
|
|
99
96
|
if not settings.settings:
|
@@ -258,7 +255,7 @@ def ensure_record_number_not_exceed_max(
|
|
258
255
|
|
259
256
|
|
260
257
|
def get_cloudflare_provider_rps(
|
261
|
-
records:
|
258
|
+
records: Sequence[CloudflareDnsRecordV1] | None,
|
262
259
|
) -> int:
|
263
260
|
"""
|
264
261
|
Setting Cloudlare Terraform provider's RPS based on the size of the zone to improve performance of MR checks.
|
@@ -277,8 +274,8 @@ def build_cloudflare_terraform_config_collection(
|
|
277
274
|
secret_reader: SecretReaderBase,
|
278
275
|
query_zones: CloudflareDnsZoneQueryData,
|
279
276
|
qontract_integration: str,
|
280
|
-
selected_account:
|
281
|
-
selected_zone:
|
277
|
+
selected_account: str | None,
|
278
|
+
selected_zone: str | None,
|
282
279
|
) -> TerraformConfigClientCollection:
|
283
280
|
cf_clients = TerraformConfigClientCollection()
|
284
281
|
cf_accounts: dict[str, CloudflareAccount] = {}
|
@@ -356,7 +353,7 @@ def build_cloudflare_terraform_config_collection(
|
|
356
353
|
|
357
354
|
|
358
355
|
def cloudflare_dns_zone_to_external_resource(
|
359
|
-
zones:
|
356
|
+
zones: list[CloudflareDnsZoneV1] | None,
|
360
357
|
) -> list[ExternalResourceSpec]:
|
361
358
|
"""
|
362
359
|
This is a method that massage a list of CloudflareDnsZoneV1 into ExternalResourceSpec
|
@@ -1,10 +1,8 @@
|
|
1
1
|
import logging
|
2
2
|
import sys
|
3
|
+
from collections.abc import Iterable
|
3
4
|
from typing import (
|
4
5
|
Any,
|
5
|
-
Iterable,
|
6
|
-
Optional,
|
7
|
-
Tuple,
|
8
6
|
cast,
|
9
7
|
)
|
10
8
|
|
@@ -120,7 +118,7 @@ def create_backend_config(
|
|
120
118
|
def build_clients(
|
121
119
|
secret_reader: SecretReaderBase,
|
122
120
|
query_accounts: TerraformCloudflareAccountsQueryData,
|
123
|
-
selected_account:
|
121
|
+
selected_account: str | None = None,
|
124
122
|
) -> list[tuple[str, TerrascriptCloudflareClient]]:
|
125
123
|
clients = []
|
126
124
|
for cf_acct in query_accounts.accounts or []:
|
@@ -158,8 +156,8 @@ def _build_oc_resources(
|
|
158
156
|
secret_reader: SecretReaderBase,
|
159
157
|
use_jump_host: bool,
|
160
158
|
thread_pool_size: int,
|
161
|
-
internal:
|
162
|
-
account_names:
|
159
|
+
internal: bool | None = None,
|
160
|
+
account_names: Iterable[str] | None = None,
|
163
161
|
) -> tuple[ResourceInventory, OCMap]:
|
164
162
|
ri = ResourceInventory()
|
165
163
|
|
@@ -194,7 +192,7 @@ def _build_oc_resources(
|
|
194
192
|
def _populate_oc_resources(
|
195
193
|
spec: CurrentStateSpec,
|
196
194
|
ri: ResourceInventory,
|
197
|
-
account_names:
|
195
|
+
account_names: Iterable[str] | None,
|
198
196
|
):
|
199
197
|
"""
|
200
198
|
This was taken from terraform_resources and might be a later candidate for DRY.
|
@@ -310,12 +308,12 @@ def _filter_cloudflare_namespaces(
|
|
310
308
|
@defer
|
311
309
|
def run(
|
312
310
|
dry_run: bool,
|
313
|
-
print_to_file:
|
311
|
+
print_to_file: str | None,
|
314
312
|
enable_deletion: bool,
|
315
313
|
thread_pool_size: int,
|
316
|
-
selected_account:
|
314
|
+
selected_account: str | None = None,
|
317
315
|
vault_output_path: str = "",
|
318
|
-
internal:
|
316
|
+
internal: bool | None = None,
|
319
317
|
use_jump_host: bool = True,
|
320
318
|
defer=None,
|
321
319
|
) -> None:
|
@@ -431,7 +429,7 @@ def run(
|
|
431
429
|
|
432
430
|
|
433
431
|
def _get_cloudflare_desired_state() -> (
|
434
|
-
|
432
|
+
tuple[
|
435
433
|
TerraformCloudflareAccountsQueryData,
|
436
434
|
TerraformCloudflareResourcesQueryData,
|
437
435
|
]
|
@@ -4,10 +4,7 @@ from collections.abc import (
|
|
4
4
|
MutableMapping,
|
5
5
|
)
|
6
6
|
from dataclasses import dataclass
|
7
|
-
from typing import
|
8
|
-
Any,
|
9
|
-
Optional,
|
10
|
-
)
|
7
|
+
from typing import Any
|
11
8
|
|
12
9
|
from reconcile.gql_definitions.terraform_cloudflare_users import (
|
13
10
|
app_interface_setting_cloudflare_and_vault,
|
@@ -69,8 +66,8 @@ class CloudflareUser:
|
|
69
66
|
|
70
67
|
|
71
68
|
class TerraformCloudflareUsersParams(PydanticRunParams):
|
72
|
-
print_to_file:
|
73
|
-
account_name:
|
69
|
+
print_to_file: str | None
|
70
|
+
account_name: str | None
|
74
71
|
thread_pool_size: int
|
75
72
|
enable_deletion: bool
|
76
73
|
|
@@ -84,7 +81,7 @@ class TerraformCloudflareUsers(
|
|
84
81
|
|
85
82
|
def get_early_exit_desired_state(
|
86
83
|
self, *args: Any, **kwargs: Any
|
87
|
-
) ->
|
84
|
+
) -> dict[str, Any] | None:
|
88
85
|
cloudflare_roles, settings = self._get_desired_state()
|
89
86
|
|
90
87
|
if not settings.settings:
|
@@ -211,7 +208,7 @@ class TerraformCloudflareUsers(
|
|
211
208
|
self,
|
212
209
|
query_data: CloudflareAccountRoleQueryData,
|
213
210
|
secret_reader: SecretReaderBase,
|
214
|
-
account_name:
|
211
|
+
account_name: str | None,
|
215
212
|
) -> TerraformConfigClientCollection:
|
216
213
|
cf_clients = TerraformConfigClientCollection()
|
217
214
|
for role in query_data.cloudflare_account_roles or []:
|
@@ -276,9 +273,9 @@ class TerraformCloudflareUsers(
|
|
276
273
|
|
277
274
|
|
278
275
|
def get_cloudflare_users(
|
279
|
-
cloudflare_roles:
|
280
|
-
account_name:
|
281
|
-
email_domain_allow_list:
|
276
|
+
cloudflare_roles: Iterable[CloudflareAccountRoleV1] | None,
|
277
|
+
account_name: str | None,
|
278
|
+
email_domain_allow_list: Iterable[str] | None,
|
282
279
|
) -> dict[str, dict[str, CloudflareUser]]:
|
283
280
|
"""
|
284
281
|
Returns a two-level dictionary of users with 1st level keys mapping to Cloudflare account names
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
from collections.abc import Callable
|
3
|
-
from datetime import
|
3
|
+
from datetime import UTC, datetime
|
4
4
|
from typing import Any
|
5
5
|
|
6
6
|
import jinja2
|
@@ -83,7 +83,7 @@ class TerraformInitIntegration(
|
|
83
83
|
"account_name": account.name,
|
84
84
|
"bucket_name": bucket_name,
|
85
85
|
"region": account.resources_default_region,
|
86
|
-
"timestamp": int(datetime.now(tz=
|
86
|
+
"timestamp": int(datetime.now(tz=UTC).timestamp()),
|
87
87
|
})
|
88
88
|
|
89
89
|
def reconcile_account(
|
reconcile/terraform_repo.py
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
from collections.abc import Callable
|
3
|
-
from typing import
|
4
|
-
Any,
|
5
|
-
Optional,
|
6
|
-
)
|
3
|
+
from typing import Any
|
7
4
|
|
8
5
|
import yaml
|
9
6
|
from pydantic import (
|
@@ -44,10 +41,10 @@ class RepoOutput(BaseModel):
|
|
44
41
|
project_path: str
|
45
42
|
delete: bool
|
46
43
|
aws_creds: VaultSecret
|
47
|
-
variables:
|
48
|
-
bucket:
|
49
|
-
region:
|
50
|
-
bucket_path:
|
44
|
+
variables: TerraformRepoVariablesV1 | None
|
45
|
+
bucket: str | None
|
46
|
+
region: str | None
|
47
|
+
bucket_path: str | None
|
51
48
|
require_fips: bool
|
52
49
|
tf_version: str
|
53
50
|
|
@@ -63,10 +60,10 @@ class OutputFile(BaseModel):
|
|
63
60
|
|
64
61
|
|
65
62
|
class TerraformRepoIntegrationParams(PydanticRunParams):
|
66
|
-
output_file:
|
63
|
+
output_file: str | None
|
67
64
|
validate_git: bool
|
68
|
-
gitlab_project_id:
|
69
|
-
gitlab_merge_request_id:
|
65
|
+
gitlab_project_id: str | None
|
66
|
+
gitlab_merge_request_id: int | None
|
70
67
|
|
71
68
|
|
72
69
|
class TerraformRepoIntegration(
|
@@ -86,7 +83,7 @@ class TerraformRepoIntegration(
|
|
86
83
|
def run(
|
87
84
|
self,
|
88
85
|
dry_run: bool,
|
89
|
-
defer:
|
86
|
+
defer: Callable | None = None,
|
90
87
|
) -> None:
|
91
88
|
gqlapi = gql.get_api()
|
92
89
|
|
@@ -304,9 +301,9 @@ class TerraformRepoIntegration(
|
|
304
301
|
existing_state: list[TerraformRepoV1],
|
305
302
|
desired_state: list[TerraformRepoV1],
|
306
303
|
dry_run: bool,
|
307
|
-
state:
|
304
|
+
state: State | None,
|
308
305
|
recreate_state: bool,
|
309
|
-
) ->
|
306
|
+
) -> list[TerraformRepoV1] | None:
|
310
307
|
"""Calculated the difference between existing and desired state
|
311
308
|
to determine what actions the executor will need to take
|
312
309
|
|
reconcile/terraform_resources.py
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
import logging
|
2
2
|
from collections.abc import (
|
3
3
|
Callable,
|
4
|
+
Collection,
|
4
5
|
Iterable,
|
5
6
|
Mapping,
|
7
|
+
Sequence,
|
6
8
|
)
|
7
9
|
from dataclasses import asdict
|
8
10
|
from typing import (
|
9
11
|
Any,
|
10
|
-
Collection,
|
11
|
-
Optional,
|
12
|
-
Sequence,
|
13
12
|
TypedDict,
|
14
13
|
cast,
|
15
14
|
)
|
@@ -72,7 +71,7 @@ QONTRACT_TF_PREFIX = "qrtf"
|
|
72
71
|
|
73
72
|
|
74
73
|
def get_tf_namespaces(
|
75
|
-
account_names:
|
74
|
+
account_names: Iterable[str] | None = None,
|
76
75
|
) -> list[NamespaceV1]:
|
77
76
|
namespaces = get_namespaces()
|
78
77
|
return filter_tf_namespaces(namespaces, account_names)
|
@@ -81,7 +80,7 @@ def get_tf_namespaces(
|
|
81
80
|
def populate_oc_resources(
|
82
81
|
spec: ob.CurrentStateSpec,
|
83
82
|
ri: ResourceInventory,
|
84
|
-
account_names:
|
83
|
+
account_names: Iterable[str] | None,
|
85
84
|
) -> None:
|
86
85
|
if spec.oc is None:
|
87
86
|
return
|
@@ -124,9 +123,9 @@ def populate_oc_resources(
|
|
124
123
|
def fetch_current_state(
|
125
124
|
namespaces: Iterable[NamespaceV1],
|
126
125
|
thread_pool_size: int,
|
127
|
-
internal:
|
126
|
+
internal: bool | None,
|
128
127
|
use_jump_host: bool,
|
129
|
-
account_names:
|
128
|
+
account_names: Iterable[str] | None,
|
130
129
|
secret_reader: SecretReaderBase,
|
131
130
|
) -> tuple[ResourceInventory, OCMap]:
|
132
131
|
ri = ResourceInventory()
|
@@ -159,7 +158,7 @@ def fetch_current_state(
|
|
159
158
|
def init_working_dirs(
|
160
159
|
accounts: list[dict[str, Any]],
|
161
160
|
thread_pool_size: int,
|
162
|
-
settings:
|
161
|
+
settings: Mapping[str, Any] | None = None,
|
163
162
|
) -> tuple[Terrascript, dict[str, str]]:
|
164
163
|
ts = Terrascript(
|
165
164
|
QONTRACT_INTEGRATION,
|
@@ -195,8 +194,8 @@ def validate_account_names(
|
|
195
194
|
|
196
195
|
def get_aws_accounts(
|
197
196
|
dry_run: bool,
|
198
|
-
include_accounts:
|
199
|
-
exclude_accounts:
|
197
|
+
include_accounts: Collection[str] | None,
|
198
|
+
exclude_accounts: Collection[str] | None,
|
200
199
|
) -> list[dict[str, Any]]:
|
201
200
|
if exclude_accounts and not dry_run:
|
202
201
|
message = "--exclude-accounts is only supported in dry-run mode"
|
@@ -236,7 +235,7 @@ def setup(
|
|
236
235
|
accounts: list[dict[str, Any]],
|
237
236
|
account_names: set[str],
|
238
237
|
tf_namespaces: list[NamespaceV1],
|
239
|
-
print_to_file:
|
238
|
+
print_to_file: str | None,
|
240
239
|
thread_pool_size: int,
|
241
240
|
) -> tuple[Terraform, TerrascriptClient, SecretReaderBase]:
|
242
241
|
vault_settings = get_app_interface_vault_settings()
|
@@ -277,7 +276,7 @@ def setup(
|
|
277
276
|
|
278
277
|
|
279
278
|
def filter_tf_namespaces(
|
280
|
-
namespaces: Iterable[NamespaceV1], account_names:
|
279
|
+
namespaces: Iterable[NamespaceV1], account_names: Iterable[str] | None
|
281
280
|
) -> list[NamespaceV1]:
|
282
281
|
tf_namespaces = []
|
283
282
|
for namespace_info in namespaces:
|
@@ -360,19 +359,19 @@ class CacheSource(TypedDict):
|
|
360
359
|
@defer
|
361
360
|
def run(
|
362
361
|
dry_run: bool,
|
363
|
-
print_to_file:
|
362
|
+
print_to_file: str | None = None,
|
364
363
|
enable_deletion: bool = False,
|
365
364
|
thread_pool_size: int = 10,
|
366
|
-
internal:
|
365
|
+
internal: bool | None = None,
|
367
366
|
use_jump_host: bool = True,
|
368
367
|
light: bool = False,
|
369
368
|
vault_output_path: str = "",
|
370
|
-
account_name:
|
371
|
-
exclude_accounts:
|
369
|
+
account_name: Sequence[str] | None = None,
|
370
|
+
exclude_accounts: Sequence[str] | None = None,
|
372
371
|
enable_extended_early_exit: bool = False,
|
373
372
|
extended_early_exit_cache_ttl_seconds: int = 3600,
|
374
373
|
log_cached_log_output: bool = False,
|
375
|
-
defer:
|
374
|
+
defer: Callable | None = None,
|
376
375
|
) -> None:
|
377
376
|
# account_name is a tuple of account names for more detail go to
|
378
377
|
# https://click.palletsprojects.com/en/8.1.x/options/#multiple-options
|
@@ -452,11 +451,11 @@ class RunnerParams(TypedDict):
|
|
452
451
|
dry_run: bool
|
453
452
|
enable_deletion: bool
|
454
453
|
thread_pool_size: int
|
455
|
-
internal:
|
454
|
+
internal: bool | None
|
456
455
|
use_jump_host: bool
|
457
456
|
light: bool
|
458
457
|
vault_output_path: str
|
459
|
-
defer:
|
458
|
+
defer: Callable | None
|
460
459
|
|
461
460
|
|
462
461
|
def runner(
|
@@ -469,11 +468,11 @@ def runner(
|
|
469
468
|
dry_run: bool,
|
470
469
|
enable_deletion: bool = False,
|
471
470
|
thread_pool_size: int = 10,
|
472
|
-
internal:
|
471
|
+
internal: bool | None = None,
|
473
472
|
use_jump_host: bool = True,
|
474
473
|
light: bool = False,
|
475
474
|
vault_output_path: str = "",
|
476
|
-
defer:
|
475
|
+
defer: Callable | None = None,
|
477
476
|
) -> ExtendedEarlyExitRunnerResult:
|
478
477
|
if not light:
|
479
478
|
disabled_deletions_detected, err = tf.plan(enable_deletion)
|