qontract-reconcile 0.10.1rc879__py3-none-any.whl → 0.10.1rc894__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.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/RECORD +291 -284
- 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 +9 -14
- reconcile/aws_account_manager/reconciler.py +51 -1
- reconcile/aws_account_manager/utils.py +3 -0
- 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 +26 -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 +3 -6
- reconcile/dynatrace_token_provider/integration_v2.py +20 -0
- reconcile/dynatrace_token_provider/meta.py +1 -0
- 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 +5 -8
- reconcile/glitchtip_project_alerts/integration.py +57 -33
- reconcile/glitchtip_project_dsn/integration.py +8 -11
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +6 -0
- reconcile/gql_definitions/fragments/aws_account_managed.py +8 -0
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +4 -4
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +27 -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 +29 -30
- 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 +36 -15
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +8 -0
- 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 +6 -6
- reconcile/test/conftest.py +7 -10
- reconcile/test/fixtures.py +1 -1
- reconcile/test/saas_auto_promotions_manager/conftest.py +3 -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/dynatrace_environments.py +14 -0
- 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/aws_api_typed/account.py +23 -0
- reconcile/utils/aws_api_typed/api.py +20 -9
- 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 +38 -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 +39 -54
- 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 +12 -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 +50 -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 +105 -17
- tools/saas_promotion_state/__init__.py +0 -0
- tools/saas_promotion_state/saas_promotion_state.py +105 -0
- tools/template_validation.py +1 -1
- tools/test/conftest.py +45 -6
- tools/test/test_saas_promotion_state.py +187 -0
- {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@ import random
|
|
7
7
|
import re
|
8
8
|
import string
|
9
9
|
import tempfile
|
10
|
+
from collections import Counter
|
10
11
|
from collections.abc import (
|
11
12
|
Iterable,
|
12
13
|
Mapping,
|
@@ -21,7 +22,6 @@ from json import JSONDecodeError
|
|
21
22
|
from threading import Lock
|
22
23
|
from typing import (
|
23
24
|
Any,
|
24
|
-
Optional,
|
25
25
|
cast,
|
26
26
|
)
|
27
27
|
|
@@ -273,6 +273,18 @@ DEFAULT_TAGS = {
|
|
273
273
|
}
|
274
274
|
|
275
275
|
|
276
|
+
class OutputResourceNameNotUniqueException(Exception):
|
277
|
+
def __init__(self, namespace, duplicates):
|
278
|
+
self.namespace, self.duplicates = namespace, duplicates
|
279
|
+
super().__init__(
|
280
|
+
str.format(
|
281
|
+
"Found duplicate values {} for 'output_resource_name' in namespace {}. Please ensure 'output_resource_name' is unique in a given namespace.",
|
282
|
+
self.duplicates,
|
283
|
+
self.namespace,
|
284
|
+
)
|
285
|
+
)
|
286
|
+
|
287
|
+
|
276
288
|
class StateInaccessibleException(Exception):
|
277
289
|
pass
|
278
290
|
|
@@ -379,9 +391,9 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
379
391
|
integration_prefix: str,
|
380
392
|
thread_pool_size: int,
|
381
393
|
accounts: Iterable[dict[str, Any]],
|
382
|
-
settings:
|
383
|
-
prefetch_resources_by_schemas:
|
384
|
-
secret_reader:
|
394
|
+
settings: Mapping[str, Any] | None = None,
|
395
|
+
prefetch_resources_by_schemas: list[str] | None = None,
|
396
|
+
secret_reader: SecretReaderBase | None = None,
|
385
397
|
) -> None:
|
386
398
|
self.integration = integration
|
387
399
|
self.integration_prefix = integration_prefix
|
@@ -478,9 +490,9 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
478
490
|
self.rosa_authenticator_pre_signup_zip_lock = Lock()
|
479
491
|
self.lambda_zip: dict[str, str] = {}
|
480
492
|
self.lambda_lock = Lock()
|
481
|
-
self.github:
|
493
|
+
self.github: Github | None = None
|
482
494
|
self.github_lock = Lock()
|
483
|
-
self.gitlab:
|
495
|
+
self.gitlab: GitLabApi | None = None
|
484
496
|
self.gitlab_lock = Lock()
|
485
497
|
self.jenkins_map: dict[str, JenkinsApi] = {}
|
486
498
|
self.jenkins_lock = Lock()
|
@@ -509,7 +521,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
509
521
|
|
510
522
|
# defaults from account
|
511
523
|
bucket_backend_value = config.get("bucket")
|
512
|
-
key_backend_value = config.get("{}_key"
|
524
|
+
key_backend_value = config.get(f"{integration}_key")
|
513
525
|
region_backend_value = config.get("region")
|
514
526
|
terraform_state = config["terraformState"]
|
515
527
|
if terraform_state:
|
@@ -757,7 +769,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
757
769
|
self,
|
758
770
|
roles,
|
759
771
|
skip_reencrypt_accounts: list[str],
|
760
|
-
appsre_pgp_key:
|
772
|
+
appsre_pgp_key: str | None,
|
761
773
|
):
|
762
774
|
error = False
|
763
775
|
for role in roles:
|
@@ -785,9 +797,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
785
797
|
|
786
798
|
# we want to include the console url in the outputs
|
787
799
|
# to be used later to generate the email invitations
|
788
|
-
output_name = "{}_console-urls__{}"
|
789
|
-
self.integration_prefix, account_name
|
790
|
-
)
|
800
|
+
output_name = f"{self.integration_prefix}_console-urls__{account_name}"
|
791
801
|
output_value = account_console_url
|
792
802
|
tf_output = Output(output_name, value=output_value)
|
793
803
|
self.add_resource(account_name, tf_output)
|
@@ -846,8 +856,8 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
846
856
|
# we want the outputs to be formed into a mail invitation
|
847
857
|
# for each new user. we form an output of the form
|
848
858
|
# 'qrtf.enc-passwords[user_name] = <encrypted password>
|
849
|
-
output_name =
|
850
|
-
self.integration_prefix
|
859
|
+
output_name = (
|
860
|
+
f"{self.integration_prefix}_enc-passwords__{user_name}"
|
851
861
|
)
|
852
862
|
output_value = (
|
853
863
|
"${" + tf_iam_user_login_profile.encrypted_password + "}"
|
@@ -891,7 +901,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
891
901
|
self,
|
892
902
|
roles,
|
893
903
|
skip_reencrypt_accounts: list[str],
|
894
|
-
appsre_pgp_key:
|
904
|
+
appsre_pgp_key: str | None = None,
|
895
905
|
):
|
896
906
|
self.populate_iam_groups(roles)
|
897
907
|
err = self.populate_iam_users(
|
@@ -912,7 +922,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
912
922
|
@staticmethod
|
913
923
|
def get_resource_lifecycle(
|
914
924
|
common_values: dict[str, Any],
|
915
|
-
) ->
|
925
|
+
) -> dict[str, Any] | None:
|
916
926
|
if lifecycle := common_values.get("lifecycle"):
|
917
927
|
lifecycle = NamespaceTerraformResourceLifecycleV1(**lifecycle)
|
918
928
|
if lifecycle.create_before_destroy is None:
|
@@ -1013,7 +1023,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
1013
1023
|
record["health_check_id"] = f"${{{healthcheck_resource.id}}}"
|
1014
1024
|
|
1015
1025
|
# Get value from Vault if _records_from_vault was set
|
1016
|
-
records_from_vault:
|
1026
|
+
records_from_vault: Iterable[dict[str, str]] | None = record.pop(
|
1017
1027
|
"records_from_vault", None
|
1018
1028
|
)
|
1019
1029
|
if records_from_vault:
|
@@ -1467,7 +1477,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
1467
1477
|
|
1468
1478
|
return results
|
1469
1479
|
|
1470
|
-
def populate_resources(self, ocm_map:
|
1480
|
+
def populate_resources(self, ocm_map: OCMMap | None = None) -> None:
|
1471
1481
|
"""
|
1472
1482
|
Populates the terraform configuration from resource specs.
|
1473
1483
|
:param ocm_map:
|
@@ -1479,7 +1489,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
1479
1489
|
def init_populate_specs(
|
1480
1490
|
self,
|
1481
1491
|
namespaces: Iterable[Mapping[str, Any]],
|
1482
|
-
account_names:
|
1492
|
+
account_names: Iterable[str] | None,
|
1483
1493
|
) -> None:
|
1484
1494
|
"""
|
1485
1495
|
Initiates resource specs from the definitions in app-interface
|
@@ -1494,12 +1504,19 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
1494
1504
|
specs = get_external_resource_specs(
|
1495
1505
|
namespace_info, provision_provider=PROVIDER_AWS
|
1496
1506
|
)
|
1507
|
+
name_counter = Counter(spec.output_resource_name for spec in specs)
|
1508
|
+
duplicates = [name for name, count in name_counter.items() if count > 1]
|
1509
|
+
if duplicates:
|
1510
|
+
raise OutputResourceNameNotUniqueException(
|
1511
|
+
namespace_info.get("name"), duplicates
|
1512
|
+
)
|
1497
1513
|
for spec in specs:
|
1498
1514
|
if account_names and spec.provisioner_name not in account_names:
|
1499
1515
|
continue
|
1500
1516
|
self.account_resource_specs.setdefault(
|
1501
1517
|
spec.provisioner_name, []
|
1502
1518
|
).append(spec)
|
1519
|
+
|
1503
1520
|
self.resource_spec_inventory[spec.id_object()] = spec
|
1504
1521
|
|
1505
1522
|
def populate_tf_resources(self, spec, ocm_map=None):
|
@@ -1908,7 +1925,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
1908
1925
|
|
1909
1926
|
def _find_resource_spec(
|
1910
1927
|
self, account: str, source: str, provider: str
|
1911
|
-
) ->
|
1928
|
+
) -> ExternalResourceSpec | None:
|
1912
1929
|
if account not in self.account_resource_specs:
|
1913
1930
|
return None
|
1914
1931
|
|
@@ -2168,7 +2185,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
2168
2185
|
tf_resources.append(Output(output_name, value=output_value))
|
2169
2186
|
output_name = output_prefix + "__aws_region"
|
2170
2187
|
tf_resources.append(Output(output_name, value=region))
|
2171
|
-
endpoint = "s3.{}.amazonaws.com"
|
2188
|
+
endpoint = f"s3.{region}.amazonaws.com"
|
2172
2189
|
output_name = output_prefix + "__endpoint"
|
2173
2190
|
tf_resources.append(Output(output_name, value=endpoint))
|
2174
2191
|
|
@@ -2480,7 +2497,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
2480
2497
|
for k, v in data.items():
|
2481
2498
|
to_replace = "${" + k + "}"
|
2482
2499
|
user_policy = user_policy.replace(to_replace, v)
|
2483
|
-
output_name = output_prefix + "__{}"
|
2500
|
+
output_name = output_prefix + f"__{k}"
|
2484
2501
|
tf_resources.append(Output(output_name, value=v))
|
2485
2502
|
|
2486
2503
|
tf_aws_iam_policy = aws_iam_policy(
|
@@ -2769,10 +2786,8 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
2769
2786
|
tf_resources.append(queue_tf_resource)
|
2770
2787
|
output_name = output_prefix + "__aws_region"
|
2771
2788
|
tf_resources.append(Output(output_name, value=region))
|
2772
|
-
output_name = "{}__{}"
|
2773
|
-
output_value = "https://sqs.{}.amazonaws.com/{}/{}"
|
2774
|
-
region, uid, queue_name
|
2775
|
-
)
|
2789
|
+
output_name = f"{output_prefix}__{queue_key}"
|
2790
|
+
output_value = f"https://sqs.{region}.amazonaws.com/{uid}/{queue_name}"
|
2776
2791
|
tf_resources.append(Output(output_name, value=output_value))
|
2777
2792
|
all_queues_per_spec.append(all_queues)
|
2778
2793
|
|
@@ -2925,7 +2940,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
2925
2940
|
values["provider"] = "aws." + region
|
2926
2941
|
table_tf_resource = aws_dynamodb_table(table, **values)
|
2927
2942
|
tf_resources.append(table_tf_resource)
|
2928
|
-
output_name = "{}__{}"
|
2943
|
+
output_name = f"{output_prefix}__{table_key}"
|
2929
2944
|
tf_resources.append(Output(output_name, value=table))
|
2930
2945
|
|
2931
2946
|
output_name = output_prefix + "__aws_region"
|
@@ -2960,8 +2975,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
2960
2975
|
"Effect": "Allow",
|
2961
2976
|
"Action": ["dynamodb:*"],
|
2962
2977
|
"Resource": [
|
2963
|
-
"arn:aws:dynamodb:{}:{}:table/{}"
|
2964
|
-
for t in all_tables
|
2978
|
+
f"arn:aws:dynamodb:{region}:{uid}:table/{t}" for t in all_tables
|
2965
2979
|
],
|
2966
2980
|
}
|
2967
2981
|
],
|
@@ -3420,10 +3434,8 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
3420
3434
|
tf_resources.append(user_policy_attachment_tf_resource)
|
3421
3435
|
|
3422
3436
|
# outputs
|
3423
|
-
output_name = "{}__{}"
|
3424
|
-
output_value = "https://sqs.{}.amazonaws.com/{}/{}"
|
3425
|
-
region, uid, sqs_identifier
|
3426
|
-
)
|
3437
|
+
output_name = f"{output_prefix}__{sqs_identifier}"
|
3438
|
+
output_value = f"https://sqs.{region}.amazonaws.com/{uid}/{sqs_identifier}"
|
3427
3439
|
tf_resources.append(Output(output_name, value=output_value))
|
3428
3440
|
|
3429
3441
|
self.add_resources(account, tf_resources)
|
@@ -4042,8 +4054,8 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
4042
4054
|
def add_resource(self, account, tf_resource):
|
4043
4055
|
if account not in self.locks:
|
4044
4056
|
logging.debug(
|
4045
|
-
"integration {} is disabled for account {}. "
|
4046
|
-
"can not add resource"
|
4057
|
+
f"integration {self.integration} is disabled for account {account}. "
|
4058
|
+
"can not add resource"
|
4047
4059
|
)
|
4048
4060
|
return
|
4049
4061
|
with self.locks[account]:
|
@@ -4051,8 +4063,8 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
4051
4063
|
|
4052
4064
|
def dump(
|
4053
4065
|
self,
|
4054
|
-
print_to_file:
|
4055
|
-
existing_dirs:
|
4066
|
+
print_to_file: str | None = None,
|
4067
|
+
existing_dirs: dict[str, str] | None = None,
|
4056
4068
|
) -> dict[str, str]:
|
4057
4069
|
"""
|
4058
4070
|
Dump the Terraform configurations (in JSON format) to the working directories.
|
@@ -4311,7 +4323,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
4311
4323
|
|
4312
4324
|
def _get_elasticsearch_account_wide_resource_policy(
|
4313
4325
|
self, account: str
|
4314
|
-
) ->
|
4326
|
+
) -> aws_cloudwatch_log_resource_policy | None:
|
4315
4327
|
"""
|
4316
4328
|
https://docs.aws.amazon.com/opensearch-service/latest/developerguide/createdomain-configure-slow-logs.html
|
4317
4329
|
CloudWatch Logs supports 10 resource policies per Region.
|
@@ -5386,7 +5398,7 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
5386
5398
|
|
5387
5399
|
def get_asg_image_id(
|
5388
5400
|
self, filters: Iterable[Mapping[str, Any]], account: str, region: str
|
5389
|
-
) ->
|
5401
|
+
) -> str | None:
|
5390
5402
|
"""
|
5391
5403
|
AMI ID comes form AWS Api filter result.
|
5392
5404
|
AMI needs to be shared by integration aws-ami-share.
|
@@ -2,10 +2,7 @@ import logging
|
|
2
2
|
import os
|
3
3
|
import threading
|
4
4
|
from collections.abc import Mapping
|
5
|
-
from typing import
|
6
|
-
Any,
|
7
|
-
Optional,
|
8
|
-
)
|
5
|
+
from typing import Any
|
9
6
|
|
10
7
|
from UnleashClient import (
|
11
8
|
BaseCache,
|
@@ -13,7 +10,7 @@ from UnleashClient import (
|
|
13
10
|
)
|
14
11
|
from UnleashClient.strategies import Strategy
|
15
12
|
|
16
|
-
client:
|
13
|
+
client: UnleashClient | None = None
|
17
14
|
client_lock = threading.Lock()
|
18
15
|
|
19
16
|
|
@@ -43,7 +40,7 @@ class ClusterStrategy(Strategy):
|
|
43
40
|
|
44
41
|
|
45
42
|
class DisableClusterStrategy(ClusterStrategy):
|
46
|
-
def apply(self, context:
|
43
|
+
def apply(self, context: dict | None = None) -> bool:
|
47
44
|
enable = True
|
48
45
|
|
49
46
|
if context and "cluster_name" in context.keys():
|
@@ -54,7 +51,7 @@ class DisableClusterStrategy(ClusterStrategy):
|
|
54
51
|
|
55
52
|
|
56
53
|
class EnableClusterStrategy(ClusterStrategy):
|
57
|
-
def apply(self, context:
|
54
|
+
def apply(self, context: dict | None = None) -> bool:
|
58
55
|
enable = False
|
59
56
|
|
60
57
|
if context and "cluster_name" in context.keys():
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from enum import
|
1
|
+
from enum import StrEnum
|
2
2
|
|
3
3
|
import requests
|
4
4
|
from pydantic import BaseModel, Field
|
@@ -6,7 +6,7 @@ from pydantic import BaseModel, Field
|
|
6
6
|
from reconcile.utils.rest_api_base import ApiBase, BearerTokenAuth
|
7
7
|
|
8
8
|
|
9
|
-
class FeatureToggleType(
|
9
|
+
class FeatureToggleType(StrEnum):
|
10
10
|
experiment = "experiment"
|
11
11
|
kill_switch = "kill-switch"
|
12
12
|
release = "release"
|
reconcile/utils/vault.py
CHANGED
@@ -5,7 +5,6 @@ import threading
|
|
5
5
|
import time
|
6
6
|
from collections.abc import Mapping
|
7
7
|
from functools import lru_cache
|
8
|
-
from typing import Optional
|
9
8
|
|
10
9
|
import hvac
|
11
10
|
import requests
|
@@ -60,11 +59,11 @@ class _VaultClient:
|
|
60
59
|
|
61
60
|
def __init__(
|
62
61
|
self,
|
63
|
-
server:
|
64
|
-
role_id:
|
65
|
-
secret_id:
|
66
|
-
kube_auth_role:
|
67
|
-
kube_auth_mount:
|
62
|
+
server: str | None = None,
|
63
|
+
role_id: str | None = None,
|
64
|
+
secret_id: str | None = None,
|
65
|
+
kube_auth_role: str | None = None,
|
66
|
+
kube_auth_mount: str | None = None,
|
68
67
|
auto_refresh: bool = True,
|
69
68
|
):
|
70
69
|
config = get_config()
|
@@ -164,7 +163,7 @@ class _VaultClient:
|
|
164
163
|
self._client.auth_approle(self.role_id, self.secret_id)
|
165
164
|
|
166
165
|
@retry()
|
167
|
-
def read_all_with_version(self, secret: Mapping) -> tuple[Mapping,
|
166
|
+
def read_all_with_version(self, secret: Mapping) -> tuple[Mapping, str | None]:
|
168
167
|
"""Returns a dictionary of keys and values in a Vault secret and the
|
169
168
|
version of the secret, for V1 secrets, version will be None.
|
170
169
|
|
@@ -215,9 +214,7 @@ class _VaultClient:
|
|
215
214
|
|
216
215
|
return version
|
217
216
|
|
218
|
-
def __read_all_v2(
|
219
|
-
self, path: str, version: Optional[str]
|
220
|
-
) -> tuple[dict, Optional[str]]:
|
217
|
+
def __read_all_v2(self, path: str, version: str | None) -> tuple[dict, str | None]:
|
221
218
|
path_split = path.split("/")
|
222
219
|
mount_point = path_split[0]
|
223
220
|
read_path = "/".join(path_split[1:])
|
@@ -306,7 +303,7 @@ class _VaultClient:
|
|
306
303
|
try:
|
307
304
|
secret_field = data[field]
|
308
305
|
except KeyError:
|
309
|
-
raise SecretFieldNotFound("{}/{}"
|
306
|
+
raise SecretFieldNotFound(f"{path}/{field}")
|
310
307
|
return secret_field
|
311
308
|
|
312
309
|
@retry()
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from typing import (
|
3
|
-
Optional,
|
4
3
|
cast,
|
5
4
|
)
|
6
5
|
|
@@ -16,8 +15,8 @@ class VaultSecretRef:
|
|
16
15
|
|
17
16
|
path: str
|
18
17
|
field: str
|
19
|
-
format:
|
20
|
-
version:
|
18
|
+
format: str | None = None
|
19
|
+
version: int | None = None
|
21
20
|
|
22
21
|
def get(self, field=None, default=None):
|
23
22
|
secret_content = self._resolve_secret()
|
reconcile/utils/vcs.py
CHANGED
@@ -6,7 +6,6 @@ from collections.abc import Iterable
|
|
6
6
|
from dataclasses import dataclass
|
7
7
|
from datetime import datetime
|
8
8
|
from enum import Enum
|
9
|
-
from typing import Optional
|
10
9
|
|
11
10
|
from gitlab.v4.objects import ProjectMergeRequest
|
12
11
|
|
@@ -57,10 +56,10 @@ class VCS:
|
|
57
56
|
dry_run: bool,
|
58
57
|
allow_deleting_mrs: bool = False,
|
59
58
|
allow_opening_mrs: bool = False,
|
60
|
-
gitlab_instance:
|
61
|
-
default_gh_token:
|
62
|
-
app_interface_api:
|
63
|
-
github_api_per_repo_url:
|
59
|
+
gitlab_instance: GitLabApi | None = None,
|
60
|
+
default_gh_token: str | None = None,
|
61
|
+
app_interface_api: GitLabApi | None = None,
|
62
|
+
github_api_per_repo_url: dict[str, GithubRepositoryApi] | None = None,
|
64
63
|
):
|
65
64
|
self._dry_run = dry_run
|
66
65
|
self._allow_deleting_mrs = allow_deleting_mrs
|
@@ -106,7 +105,7 @@ class VCS:
|
|
106
105
|
return defaults[0]
|
107
106
|
|
108
107
|
def _init_github(
|
109
|
-
self, repo_url: str, auth_code:
|
108
|
+
self, repo_url: str, auth_code: HasSecret | None
|
110
109
|
) -> GithubRepositoryApi:
|
111
110
|
if repo_url not in self._gh_per_repo_url:
|
112
111
|
if auth_code:
|
@@ -159,7 +158,7 @@ class VCS:
|
|
159
158
|
return MRCheckStatus.NONE
|
160
159
|
|
161
160
|
def get_commit_sha(
|
162
|
-
self, repo_url: str, ref: str, auth_code:
|
161
|
+
self, repo_url: str, ref: str, auth_code: HasSecret | None
|
163
162
|
) -> str:
|
164
163
|
if bool(self._is_commit_sha_regex.search(ref)):
|
165
164
|
return ref
|
@@ -174,7 +173,7 @@ class VCS:
|
|
174
173
|
repo_url: str,
|
175
174
|
commit_from: str,
|
176
175
|
commit_to: str,
|
177
|
-
auth_code:
|
176
|
+
auth_code: HasSecret | None,
|
178
177
|
) -> list[Commit]:
|
179
178
|
"""
|
180
179
|
Return a list of commits between two commits.
|
reconcile/vault_replication.py
CHANGED
@@ -2,8 +2,6 @@ import logging
|
|
2
2
|
import re
|
3
3
|
from collections.abc import Iterable
|
4
4
|
from typing import (
|
5
|
-
Optional,
|
6
|
-
Union,
|
7
5
|
cast,
|
8
6
|
)
|
9
7
|
|
@@ -179,7 +177,7 @@ def copy_vault_secret(
|
|
179
177
|
|
180
178
|
def check_invalid_paths(
|
181
179
|
path_list: Iterable[str],
|
182
|
-
policy_paths:
|
180
|
+
policy_paths: Iterable[str] | None,
|
183
181
|
) -> None:
|
184
182
|
"""Checks if the paths to be replicated are present in the policy used to limit the secrets
|
185
183
|
that are going to be replicated."""
|
@@ -283,12 +281,10 @@ def get_jenkins_secret_list(
|
|
283
281
|
|
284
282
|
|
285
283
|
def get_vault_credentials(
|
286
|
-
vault_auth:
|
287
|
-
|
288
|
-
VaultInstanceV1_VaultReplicationConfigV1_VaultInstanceAuthV1,
|
289
|
-
],
|
284
|
+
vault_auth: VaultReplicationConfigV1_VaultInstanceAuthV1
|
285
|
+
| VaultInstanceV1_VaultReplicationConfigV1_VaultInstanceAuthV1,
|
290
286
|
vault_address: str,
|
291
|
-
) -> dict[str,
|
287
|
+
) -> dict[str, str | None]:
|
292
288
|
"""Returns a dictionary with the credentials used to authenticate with Vault,
|
293
289
|
retrieved from the values present on AppInterface and comming from Vault itself."""
|
294
290
|
vault_creds = {}
|
@@ -2,7 +2,6 @@ import ipaddress
|
|
2
2
|
import logging
|
3
3
|
import sys
|
4
4
|
from typing import (
|
5
|
-
Union,
|
6
5
|
cast,
|
7
6
|
)
|
8
7
|
|
@@ -107,10 +106,8 @@ def validate_no_internal_to_public_peerings(
|
|
107
106
|
}:
|
108
107
|
continue
|
109
108
|
connection = cast(
|
110
|
-
|
111
|
-
|
112
|
-
ClusterPeeringConnectionClusterRequesterV1,
|
113
|
-
],
|
109
|
+
ClusterPeeringConnectionClusterAccepterV1
|
110
|
+
| ClusterPeeringConnectionClusterRequesterV1,
|
114
111
|
connection,
|
115
112
|
)
|
116
113
|
peer = connection.cluster
|
@@ -150,10 +147,8 @@ def validate_no_public_to_public_peerings(
|
|
150
147
|
}:
|
151
148
|
continue
|
152
149
|
connection = cast(
|
153
|
-
|
154
|
-
|
155
|
-
ClusterPeeringConnectionClusterRequesterV1,
|
156
|
-
],
|
150
|
+
ClusterPeeringConnectionClusterAccepterV1
|
151
|
+
| ClusterPeeringConnectionClusterRequesterV1,
|
157
152
|
connection,
|
158
153
|
)
|
159
154
|
peer = connection.cluster
|
release/version.py
CHANGED
@@ -5,7 +5,6 @@ import os
|
|
5
5
|
import re
|
6
6
|
import subprocess
|
7
7
|
import sys
|
8
|
-
from subprocess import PIPE
|
9
8
|
from typing import Optional
|
10
9
|
|
11
10
|
GIT_VERSION_FILE = "GIT_VERSION"
|
@@ -21,7 +20,7 @@ def git() -> str:
|
|
21
20
|
"""
|
22
21
|
cmd = "git describe --tags --match=[0-9]*.[0-9]*.[0-9]*"
|
23
22
|
try:
|
24
|
-
p = subprocess.run(cmd.split(" "),
|
23
|
+
p = subprocess.run(cmd.split(" "), capture_output=True, check=True)
|
25
24
|
v = p.stdout.decode("utf-8").strip()
|
26
25
|
# tox is running setup.py sdist from the git repo, and then runs again outside
|
27
26
|
# of the git repo. At this second step, we cannot run git commands.
|
@@ -35,7 +34,7 @@ def git() -> str:
|
|
35
34
|
# if we're not in a git repo, try reading out from the GIT_VERSION file
|
36
35
|
if os.path.exists(GIT_VERSION_FILE):
|
37
36
|
with open(
|
38
|
-
GIT_VERSION_FILE,
|
37
|
+
GIT_VERSION_FILE, encoding=locale.getpreferredencoding(False)
|
39
38
|
) as f:
|
40
39
|
return f.read()
|
41
40
|
print(e.stderr)
|
@@ -45,11 +44,11 @@ def git() -> str:
|
|
45
44
|
def commit(length: int = 7) -> str:
|
46
45
|
"""get the current git commitid"""
|
47
46
|
cmd = f"git rev-parse --short={length} HEAD"
|
48
|
-
p = subprocess.run(cmd.split(" "),
|
47
|
+
p = subprocess.run(cmd.split(" "), capture_output=True, check=True)
|
49
48
|
return p.stdout.decode("utf-8").strip()
|
50
49
|
|
51
50
|
|
52
|
-
def semver(git_version: Optional[str] = None) -> str:
|
51
|
+
def semver(git_version: Optional[str] = None) -> str: # noqa: UP007 - RHEL8 has python 3.8
|
53
52
|
"""get a semantic version out of the input git version (see git())
|
54
53
|
- if a X.Y.Z tag is set on the current HEAD, we'll use this
|
55
54
|
- else we'll use X.Y.<Z+1>-<count>+<commitid> to respect semver and version
|
@@ -72,7 +71,7 @@ def semver(git_version: Optional[str] = None) -> str:
|
|
72
71
|
return str(v)
|
73
72
|
|
74
73
|
|
75
|
-
def pip(git_version: Optional[str] = None) -> str:
|
74
|
+
def pip(git_version: Optional[str] = None) -> str: # noqa: UP007 - RHEL8 has python 3.8
|
76
75
|
"""get a pip version out of the input git version (see git()),
|
77
76
|
according to https://peps.python.org/pep-0440/
|
78
77
|
- if a X.Y.Z tag is set on the current HEAD, we'll use this
|
@@ -88,7 +87,7 @@ def pip(git_version: Optional[str] = None) -> str:
|
|
88
87
|
# return str(v)
|
89
88
|
|
90
89
|
|
91
|
-
def docker(git_version: Optional[str] = None) -> str:
|
90
|
+
def docker(git_version: Optional[str] = None) -> str: # noqa: UP007 - RHEL8 has python 3.8
|
92
91
|
# docker tags don't like '+' characters, let's remove the buildinfo/commitid
|
93
92
|
return pip(git_version)
|
94
93
|
|
tools/app_interface_reporter.py
CHANGED
@@ -2,8 +2,8 @@ import logging
|
|
2
2
|
import os
|
3
3
|
import textwrap
|
4
4
|
from datetime import (
|
5
|
+
UTC,
|
5
6
|
datetime,
|
6
|
-
timezone,
|
7
7
|
)
|
8
8
|
|
9
9
|
import click
|
@@ -221,7 +221,7 @@ def get_apps_data(date, month_delta=1, thread_pool_size=10):
|
|
221
221
|
jjb: JJB = init_jjb(secret_reader)
|
222
222
|
jenkins_map = jenkins_base.get_jenkins_map()
|
223
223
|
time_limit = date - relativedelta(months=month_delta)
|
224
|
-
timestamp_limit = int(time_limit.replace(tzinfo=
|
224
|
+
timestamp_limit = int(time_limit.replace(tzinfo=UTC).timestamp())
|
225
225
|
|
226
226
|
secret_content = secret_reader.read_all({"path": DASHDOTDB_SECRET})
|
227
227
|
dashdotdb_url = secret_content["url"]
|
@@ -1,11 +1,8 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import json
|
4
|
+
from collections.abc import Mapping
|
4
5
|
from dataclasses import dataclass
|
5
|
-
from typing import (
|
6
|
-
Mapping,
|
7
|
-
Optional,
|
8
|
-
)
|
9
6
|
|
10
7
|
from reconcile import queries
|
11
8
|
from reconcile.utils import (
|
@@ -114,7 +111,7 @@ class GPGEncryptCommand:
|
|
114
111
|
f"No argument given which defines how to fetch the secret {self._command_data}"
|
115
112
|
)
|
116
113
|
|
117
|
-
def _get_gpg_key(self) ->
|
114
|
+
def _get_gpg_key(self) -> str | None:
|
118
115
|
target_user = self._command_data.target_user
|
119
116
|
users = queries.get_users_by(
|
120
117
|
refs=False,
|
@@ -156,7 +153,7 @@ class GPGEncryptCommand:
|
|
156
153
|
def create(
|
157
154
|
cls,
|
158
155
|
command_data: GPGEncryptCommandData,
|
159
|
-
secret_reader:
|
156
|
+
secret_reader: SecretReader | None = None,
|
160
157
|
) -> GPGEncryptCommand:
|
161
158
|
cls_secret_reader = (
|
162
159
|
secret_reader
|
@@ -3,7 +3,6 @@
|
|
3
3
|
|
4
4
|
from typing import (
|
5
5
|
Any,
|
6
|
-
Optional,
|
7
6
|
Self,
|
8
7
|
)
|
9
8
|
|
@@ -145,7 +144,7 @@ class SystemTool(BaseModel):
|
|
145
144
|
|
146
145
|
@classmethod
|
147
146
|
def init_from_model(
|
148
|
-
cls, model: Any, enumeration: Any, parent:
|
147
|
+
cls, model: Any, enumeration: Any, parent: str | None = None
|
149
148
|
) -> Self:
|
150
149
|
match model:
|
151
150
|
case GitlabInstanceV1():
|
@@ -284,7 +283,7 @@ class SystemTool(BaseModel):
|
|
284
283
|
cls,
|
285
284
|
c: OpenShiftClusterManagerUpgradePolicyClusterV1,
|
286
285
|
enumeration: Any,
|
287
|
-
parent:
|
286
|
+
parent: str | None = None,
|
288
287
|
) -> Self:
|
289
288
|
return cls(
|
290
289
|
system_type="openshift",
|
@@ -394,15 +393,13 @@ class SystemToolInventory:
|
|
394
393
|
def __init__(self) -> None:
|
395
394
|
self.systems_and_tools: list[SystemTool] = []
|
396
395
|
|
397
|
-
def append(
|
398
|
-
self, model: Any, enumeration: Any, parent: Optional[str] = None
|
399
|
-
) -> None:
|
396
|
+
def append(self, model: Any, enumeration: Any, parent: str | None = None) -> None:
|
400
397
|
self.systems_and_tools.append(
|
401
398
|
SystemTool.init_from_model(model, enumeration, parent=parent)
|
402
399
|
)
|
403
400
|
|
404
401
|
def update(
|
405
|
-
self, models: list[Any], enumeration: Any, parent:
|
402
|
+
self, models: list[Any], enumeration: Any, parent: str | None = None
|
406
403
|
) -> None:
|
407
404
|
for m in models:
|
408
405
|
self.append(m, enumeration, parent=parent)
|