qontract-reconcile 0.10.2.dev349__py3-none-any.whl → 0.10.2.dev414__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.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/METADATA +12 -11
- {qontract_reconcile-0.10.2.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/RECORD +356 -350
- reconcile/acs_rbac.py +2 -2
- reconcile/aus/advanced_upgrade_service.py +15 -12
- reconcile/aus/base.py +26 -27
- reconcile/aus/cluster_version_data.py +15 -5
- reconcile/aus/models.py +1 -1
- reconcile/automated_actions/config/integration.py +15 -3
- reconcile/aws_account_manager/integration.py +8 -8
- reconcile/aws_account_manager/reconciler.py +3 -3
- reconcile/aws_ami_cleanup/integration.py +8 -12
- reconcile/aws_ami_share.py +69 -62
- reconcile/aws_cloudwatch_log_retention/integration.py +155 -126
- reconcile/aws_ecr_image_pull_secrets.py +2 -2
- reconcile/aws_iam_keys.py +7 -41
- reconcile/aws_saml_idp/integration.py +12 -4
- reconcile/aws_saml_roles/integration.py +32 -25
- reconcile/aws_version_sync/integration.py +6 -12
- reconcile/change_owners/bundle.py +3 -3
- reconcile/change_owners/change_log_tracking.py +3 -2
- reconcile/change_owners/change_owners.py +1 -1
- reconcile/change_owners/diff.py +2 -4
- reconcile/checkpoint.py +11 -3
- reconcile/cli.py +33 -8
- reconcile/dashdotdb_dora.py +5 -12
- reconcile/dashdotdb_slo.py +1 -1
- reconcile/database_access_manager.py +123 -117
- reconcile/dynatrace_token_provider/integration.py +1 -1
- reconcile/endpoints_discovery/integration.py +4 -1
- reconcile/endpoints_discovery/merge_request.py +1 -1
- reconcile/endpoints_discovery/merge_request_manager.py +9 -11
- reconcile/external_resources/factories.py +5 -12
- reconcile/external_resources/integration.py +1 -1
- reconcile/external_resources/manager.py +24 -10
- reconcile/external_resources/meta.py +0 -1
- reconcile/external_resources/metrics.py +1 -1
- reconcile/external_resources/model.py +13 -13
- reconcile/external_resources/reconciler.py +7 -4
- reconcile/external_resources/secrets_sync.py +6 -8
- reconcile/external_resources/state.py +60 -17
- reconcile/fleet_labeler/integration.py +1 -1
- reconcile/gabi_authorized_users.py +8 -5
- reconcile/gcp_image_mirror.py +2 -2
- reconcile/github_org.py +1 -1
- reconcile/github_owners.py +4 -0
- reconcile/gitlab_housekeeping.py +13 -15
- reconcile/gitlab_members.py +6 -12
- reconcile/gitlab_mr_sqs_consumer.py +2 -2
- reconcile/gitlab_owners.py +15 -11
- reconcile/gitlab_permissions.py +8 -12
- reconcile/glitchtip_project_alerts/integration.py +3 -1
- reconcile/gql_definitions/acs/acs_instances.py +5 -5
- reconcile/gql_definitions/acs/acs_policies.py +5 -5
- reconcile/gql_definitions/acs/acs_rbac.py +5 -5
- reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +5 -5
- reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +5 -5
- reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +5 -5
- reconcile/gql_definitions/app_sre_tekton_access_revalidation/roles.py +5 -5
- reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py +5 -5
- reconcile/gql_definitions/automated_actions/instance.py +46 -7
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +5 -5
- reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +27 -66
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_saml_roles/roles.py +5 -5
- reconcile/gql_definitions/aws_version_sync/clusters.py +5 -5
- reconcile/gql_definitions/aws_version_sync/namespaces.py +5 -5
- reconcile/gql_definitions/change_owners/queries/change_types.py +5 -5
- reconcile/gql_definitions/change_owners/queries/self_service_roles.py +5 -5
- reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +5 -5
- reconcile/gql_definitions/common/alerting_services_settings.py +5 -5
- reconcile/gql_definitions/common/app_code_component_repos.py +5 -5
- reconcile/gql_definitions/common/app_interface_custom_messages.py +5 -5
- reconcile/gql_definitions/common/app_interface_dms_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_repo_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_roles.py +5 -5
- reconcile/gql_definitions/common/app_interface_state_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_vault_settings.py +5 -5
- reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +5 -5
- reconcile/gql_definitions/common/apps.py +5 -5
- reconcile/gql_definitions/common/aws_vpc_requests.py +15 -5
- reconcile/gql_definitions/common/aws_vpcs.py +5 -5
- reconcile/gql_definitions/common/clusters.py +7 -5
- reconcile/gql_definitions/common/clusters_minimal.py +5 -5
- reconcile/gql_definitions/common/clusters_with_dms.py +5 -5
- reconcile/gql_definitions/common/clusters_with_peering.py +5 -5
- reconcile/gql_definitions/common/github_orgs.py +5 -5
- reconcile/gql_definitions/common/jira_settings.py +5 -5
- reconcile/gql_definitions/common/jiralert_settings.py +5 -5
- reconcile/gql_definitions/common/ldap_settings.py +5 -5
- reconcile/gql_definitions/common/namespaces.py +5 -5
- reconcile/gql_definitions/common/namespaces_minimal.py +7 -5
- reconcile/gql_definitions/common/ocm_env_telemeter.py +5 -5
- reconcile/gql_definitions/common/ocm_environments.py +5 -5
- reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
- reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -5
- reconcile/gql_definitions/common/pipeline_providers.py +5 -5
- reconcile/gql_definitions/common/quay_instances.py +5 -5
- reconcile/gql_definitions/common/quay_orgs.py +5 -5
- reconcile/gql_definitions/common/reserved_networks.py +5 -5
- reconcile/gql_definitions/common/rhcs_provider_settings.py +5 -5
- reconcile/gql_definitions/common/saas_files.py +5 -5
- reconcile/gql_definitions/common/saas_target_namespaces.py +5 -5
- reconcile/gql_definitions/common/saasherder_settings.py +5 -5
- reconcile/gql_definitions/common/slack_workspaces.py +5 -5
- reconcile/gql_definitions/common/smtp_client_settings.py +5 -5
- reconcile/gql_definitions/common/state_aws_account.py +5 -5
- reconcile/gql_definitions/common/users.py +5 -5
- reconcile/gql_definitions/common/users_with_paths.py +5 -5
- reconcile/gql_definitions/cost_report/app_names.py +5 -5
- reconcile/gql_definitions/cost_report/cost_namespaces.py +5 -5
- reconcile/gql_definitions/cost_report/settings.py +5 -5
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +5 -5
- reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +5 -5
- reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +5 -5
- reconcile/gql_definitions/email_sender/apps.py +5 -5
- reconcile/gql_definitions/email_sender/emails.py +5 -5
- reconcile/gql_definitions/email_sender/users.py +5 -5
- reconcile/gql_definitions/endpoints_discovery/apps.py +5 -5
- reconcile/gql_definitions/external_resources/aws_accounts.py +5 -5
- reconcile/gql_definitions/external_resources/external_resources_modules.py +5 -5
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +89 -6
- reconcile/gql_definitions/external_resources/external_resources_settings.py +7 -5
- reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +5 -5
- reconcile/gql_definitions/fleet_labeler/fleet_labels.py +5 -5
- reconcile/gql_definitions/fragments/aus_organization.py +5 -5
- reconcile/gql_definitions/fragments/aws_account_common.py +7 -5
- reconcile/gql_definitions/fragments/aws_account_managed.py +5 -5
- reconcile/gql_definitions/fragments/aws_account_sso.py +5 -5
- reconcile/gql_definitions/fragments/aws_infra_management_account.py +5 -5
- reconcile/gql_definitions/fragments/aws_organization.py +33 -0
- reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
- reconcile/gql_definitions/fragments/aws_vpc_request.py +7 -5
- reconcile/gql_definitions/fragments/container_image_mirror.py +5 -5
- reconcile/gql_definitions/fragments/deploy_resources.py +5 -5
- reconcile/gql_definitions/fragments/disable.py +5 -5
- reconcile/gql_definitions/fragments/email_service.py +5 -5
- reconcile/gql_definitions/fragments/email_user.py +5 -5
- reconcile/gql_definitions/fragments/jumphost_common_fields.py +5 -5
- reconcile/gql_definitions/fragments/membership_source.py +5 -5
- reconcile/gql_definitions/fragments/minimal_ocm_organization.py +5 -5
- reconcile/gql_definitions/fragments/oc_connection_cluster.py +5 -5
- reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
- reconcile/gql_definitions/fragments/pipeline_provider_retention.py +5 -5
- reconcile/gql_definitions/fragments/prometheus_instance.py +5 -5
- reconcile/gql_definitions/fragments/resource_limits_requirements.py +5 -5
- reconcile/gql_definitions/fragments/resource_requests_requirements.py +5 -5
- reconcile/gql_definitions/fragments/resource_values.py +5 -5
- reconcile/gql_definitions/fragments/saas_slo_document.py +5 -5
- reconcile/gql_definitions/fragments/saas_target_namespace.py +5 -5
- reconcile/gql_definitions/fragments/serviceaccount_token.py +5 -5
- reconcile/gql_definitions/fragments/terraform_state.py +5 -5
- reconcile/gql_definitions/fragments/upgrade_policy.py +5 -5
- reconcile/gql_definitions/fragments/user.py +5 -5
- reconcile/gql_definitions/fragments/vault_secret.py +5 -5
- reconcile/gql_definitions/gcp/gcp_docker_repos.py +5 -5
- reconcile/gql_definitions/gcp/gcp_projects.py +5 -5
- reconcile/gql_definitions/gitlab_members/gitlab_instances.py +5 -5
- reconcile/gql_definitions/gitlab_members/permissions.py +5 -5
- reconcile/gql_definitions/glitchtip/glitchtip_instance.py +5 -5
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +5 -5
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +5 -5
- reconcile/gql_definitions/integrations/integrations.py +5 -5
- reconcile/gql_definitions/introspection.json +2137 -1053
- reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +5 -5
- reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +5 -5
- reconcile/gql_definitions/jira/jira_servers.py +5 -5
- reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +9 -5
- reconcile/gql_definitions/jumphosts/jumphosts.py +5 -5
- reconcile/gql_definitions/ldap_groups/roles.py +5 -5
- reconcile/gql_definitions/ldap_groups/settings.py +5 -5
- reconcile/gql_definitions/maintenance/maintenances.py +5 -5
- reconcile/gql_definitions/membershipsources/roles.py +5 -5
- reconcile/gql_definitions/ocm_labels/clusters.py +5 -5
- reconcile/gql_definitions/ocm_labels/organizations.py +5 -5
- reconcile/gql_definitions/openshift_cluster_bots/clusters.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_groups.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_roles.py +5 -5
- reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +5 -5
- reconcile/gql_definitions/quay_membership/quay_membership.py +5 -5
- reconcile/gql_definitions/rhcs/certs.py +5 -5
- reconcile/gql_definitions/rhidp/organizations.py +5 -5
- reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +5 -5
- reconcile/gql_definitions/service_dependencies/service_dependencies.py +5 -5
- reconcile/gql_definitions/sharding/aws_accounts.py +5 -5
- reconcile/gql_definitions/sharding/ocm_organization.py +5 -5
- reconcile/gql_definitions/skupper_network/site_controller_template.py +5 -5
- reconcile/gql_definitions/skupper_network/skupper_networks.py +5 -5
- reconcile/gql_definitions/slack_usergroups/clusters.py +5 -5
- reconcile/gql_definitions/slack_usergroups/permissions.py +5 -5
- reconcile/gql_definitions/slack_usergroups/users.py +5 -5
- reconcile/gql_definitions/slo_documents/slo_documents.py +5 -5
- reconcile/gql_definitions/status_board/status_board.py +5 -5
- reconcile/gql_definitions/statuspage/statuspages.py +5 -5
- reconcile/gql_definitions/templating/template_collection.py +5 -5
- reconcile/gql_definitions/templating/templates.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +5 -5
- reconcile/gql_definitions/terraform_init/aws_accounts.py +19 -5
- reconcile/gql_definitions/terraform_repo/terraform_repo.py +5 -5
- reconcile/gql_definitions/terraform_resources/database_access_manager.py +5 -5
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +38 -6
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +15 -5
- reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +5 -5
- reconcile/gql_definitions/vault_instances/vault_instances.py +5 -5
- reconcile/gql_definitions/vault_policies/vault_policies.py +5 -5
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +5 -5
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +5 -5
- reconcile/integrations_manager.py +3 -3
- reconcile/jenkins_worker_fleets.py +10 -8
- reconcile/jira_permissions_validator.py +237 -122
- reconcile/ldap_groups/integration.py +1 -1
- reconcile/ocm/types.py +35 -56
- reconcile/ocm_aws_infrastructure_access.py +1 -1
- reconcile/ocm_clusters.py +4 -4
- reconcile/ocm_labels/integration.py +3 -2
- reconcile/ocm_machine_pools.py +23 -23
- reconcile/openshift_base.py +53 -2
- reconcile/openshift_cluster_bots.py +3 -2
- reconcile/openshift_namespace_labels.py +1 -1
- reconcile/openshift_namespaces.py +97 -101
- reconcile/openshift_resources_base.py +6 -2
- reconcile/openshift_rhcs_certs.py +5 -5
- reconcile/openshift_rolebindings.py +7 -11
- reconcile/openshift_saas_deploy.py +6 -7
- reconcile/openshift_saas_deploy_change_tester.py +9 -7
- reconcile/openshift_saas_deploy_trigger_cleaner.py +3 -5
- reconcile/openshift_serviceaccount_tokens.py +2 -2
- reconcile/openshift_upgrade_watcher.py +4 -4
- reconcile/oum/labelset.py +5 -3
- reconcile/oum/models.py +1 -4
- reconcile/prometheus_rules_tester/integration.py +3 -3
- reconcile/quay_mirror.py +1 -1
- reconcile/queries.py +131 -1
- reconcile/rhidp/common.py +3 -5
- reconcile/rhidp/sso_client/base.py +1 -1
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
- reconcile/saas_auto_promotions_manager/subscriber.py +4 -3
- reconcile/skupper_network/integration.py +2 -2
- reconcile/slack_usergroups.py +35 -14
- reconcile/sql_query.py +1 -0
- reconcile/status_board.py +6 -6
- reconcile/statuspage/atlassian.py +7 -7
- reconcile/statuspage/integrations/maintenances.py +4 -3
- reconcile/statuspage/page.py +4 -9
- reconcile/statuspage/status.py +5 -8
- reconcile/templates/rosa-classic-cluster-creation.sh.j2 +4 -0
- reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +3 -0
- reconcile/templating/lib/rendering.py +3 -3
- reconcile/templating/renderer.py +4 -3
- reconcile/terraform_aws_route53.py +7 -1
- reconcile/terraform_cloudflare_dns.py +3 -3
- reconcile/terraform_cloudflare_resources.py +5 -5
- reconcile/terraform_cloudflare_users.py +3 -2
- reconcile/terraform_init/integration.py +187 -23
- reconcile/terraform_repo.py +16 -12
- reconcile/terraform_resources.py +17 -7
- reconcile/terraform_tgw_attachments.py +27 -19
- reconcile/terraform_users.py +7 -0
- reconcile/terraform_vpc_peerings.py +14 -3
- reconcile/terraform_vpc_resources/integration.py +10 -1
- reconcile/typed_queries/aws_account_tags.py +41 -0
- reconcile/typed_queries/cost_report/app_names.py +1 -1
- reconcile/typed_queries/cost_report/cost_namespaces.py +2 -2
- reconcile/typed_queries/saas_files.py +13 -13
- reconcile/typed_queries/status_board.py +2 -2
- reconcile/unleash_feature_toggles/integration.py +4 -2
- reconcile/utils/acs/base.py +6 -3
- reconcile/utils/acs/policies.py +2 -2
- reconcile/utils/aggregated_list.py +4 -3
- reconcile/utils/aws_api.py +51 -54
- reconcile/utils/aws_api_typed/api.py +38 -9
- reconcile/utils/aws_api_typed/cloudformation.py +149 -0
- reconcile/utils/aws_api_typed/logs.py +73 -0
- reconcile/utils/aws_api_typed/organization.py +4 -2
- reconcile/utils/datetime_util.py +67 -0
- reconcile/utils/deadmanssnitch_api.py +1 -1
- reconcile/utils/differ.py +2 -3
- reconcile/utils/early_exit_cache.py +11 -12
- reconcile/utils/expiration.py +7 -3
- reconcile/utils/external_resource_spec.py +24 -1
- reconcile/utils/filtering.py +1 -1
- reconcile/utils/gitlab_api.py +7 -5
- reconcile/utils/glitchtip/client.py +6 -2
- reconcile/utils/glitchtip/models.py +25 -28
- reconcile/utils/gql.py +4 -7
- reconcile/utils/helm.py +2 -1
- reconcile/utils/helpers.py +1 -1
- reconcile/utils/instrumented_wrappers.py +1 -1
- reconcile/utils/internal_groups/client.py +2 -2
- reconcile/utils/internal_groups/models.py +8 -17
- reconcile/utils/jinja2/utils.py +6 -101
- reconcile/utils/jira_client.py +82 -63
- reconcile/utils/jjb_client.py +9 -12
- reconcile/utils/jobcontroller/controller.py +1 -1
- reconcile/utils/jobcontroller/models.py +17 -1
- reconcile/utils/json.py +70 -0
- reconcile/utils/membershipsources/app_interface_resolver.py +4 -2
- reconcile/utils/membershipsources/models.py +16 -23
- reconcile/utils/membershipsources/resolver.py +4 -2
- reconcile/utils/merge_request_manager/merge_request_manager.py +4 -4
- reconcile/utils/merge_request_manager/parser.py +6 -6
- reconcile/utils/metrics.py +5 -5
- reconcile/utils/models.py +304 -82
- reconcile/utils/mr/app_interface_reporter.py +2 -2
- reconcile/utils/mr/base.py +2 -2
- reconcile/utils/mr/notificator.py +3 -3
- reconcile/utils/mr/update_access_report_base.py +3 -4
- reconcile/utils/mr/user_maintenance.py +3 -2
- reconcile/utils/oc.py +118 -97
- reconcile/utils/oc_filters.py +3 -3
- reconcile/utils/ocm/addons.py +0 -1
- reconcile/utils/ocm/base.py +17 -20
- reconcile/utils/ocm/cluster_groups.py +1 -1
- reconcile/utils/ocm/identity_providers.py +2 -2
- reconcile/utils/ocm/labels.py +1 -1
- reconcile/utils/ocm/products.py +9 -3
- reconcile/utils/ocm/search_filters.py +3 -6
- reconcile/utils/ocm/service_log.py +4 -6
- reconcile/utils/ocm/sre_capability_labels.py +20 -13
- reconcile/utils/openshift_resource.py +10 -5
- reconcile/utils/output.py +3 -2
- reconcile/utils/pagerduty_api.py +10 -7
- reconcile/utils/promotion_state.py +6 -11
- reconcile/utils/raw_github_api.py +1 -1
- reconcile/utils/rhcsv2_certs.py +1 -4
- reconcile/utils/runtime/integration.py +2 -3
- reconcile/utils/runtime/runner.py +2 -2
- reconcile/utils/saasherder/interfaces.py +13 -20
- reconcile/utils/saasherder/models.py +25 -21
- reconcile/utils/saasherder/saasherder.py +35 -24
- reconcile/utils/slack_api.py +26 -4
- reconcile/utils/sloth.py +171 -2
- reconcile/utils/sqs_gateway.py +2 -1
- reconcile/utils/state.py +2 -1
- reconcile/utils/structs.py +1 -1
- reconcile/utils/terraform_client.py +5 -4
- reconcile/utils/terrascript_aws_client.py +171 -114
- reconcile/utils/unleash/server.py +2 -8
- reconcile/utils/vault.py +5 -12
- reconcile/utils/vcs.py +8 -8
- reconcile/vault_replication.py +107 -42
- tools/app_interface_reporter.py +4 -4
- tools/cli_commands/cost_report/cost_management_api.py +3 -3
- tools/cli_commands/cost_report/view.py +7 -6
- tools/cli_commands/erv2.py +3 -1
- tools/cli_commands/systems_and_tools.py +5 -1
- tools/qontract_cli.py +31 -18
- tools/template_validation.py +3 -1
- {qontract_reconcile-0.10.2.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/entry_points.txt +0 -0
|
@@ -20,6 +20,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
|
20
20
|
get_app_interface_vault_settings,
|
|
21
21
|
)
|
|
22
22
|
from reconcile.typed_queries.aws_vpc_requests import get_aws_vpc_requests
|
|
23
|
+
from reconcile.typed_queries.external_resources import get_settings
|
|
23
24
|
from reconcile.typed_queries.github_orgs import get_github_orgs
|
|
24
25
|
from reconcile.typed_queries.gitlab_instances import get_gitlab_instances
|
|
25
26
|
from reconcile.utils import gql
|
|
@@ -161,13 +162,21 @@ class TerraformVpcResources(QontractReconcileIntegration[TerraformVpcResourcesPa
|
|
|
161
162
|
logging.debug("No VPC requests found, nothing to do.")
|
|
162
163
|
sys.exit(ExitCodes.SUCCESS)
|
|
163
164
|
|
|
164
|
-
accounts_untyped: list[dict] = [
|
|
165
|
+
accounts_untyped: list[dict] = [
|
|
166
|
+
acc.model_dump(by_alias=True) for acc in accounts
|
|
167
|
+
]
|
|
168
|
+
try:
|
|
169
|
+
default_tags = get_settings().default_tags
|
|
170
|
+
except ValueError:
|
|
171
|
+
# no external resources settings found
|
|
172
|
+
default_tags = None
|
|
165
173
|
with TerrascriptClient(
|
|
166
174
|
integration=QONTRACT_INTEGRATION,
|
|
167
175
|
integration_prefix=QONTRACT_TF_PREFIX,
|
|
168
176
|
thread_pool_size=thread_pool_size,
|
|
169
177
|
accounts=accounts_untyped,
|
|
170
178
|
secret_reader=secret_reader,
|
|
179
|
+
default_tags=default_tags,
|
|
171
180
|
) as ts_client:
|
|
172
181
|
ts_client.populate_vpc_requests(data, AWS_PROVIDER_VERSION)
|
|
173
182
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from collections.abc import Mapping
|
|
3
|
+
|
|
4
|
+
from reconcile.gql_definitions.fragments.aws_organization import (
|
|
5
|
+
AWSOrganization,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_aws_account_tags(
|
|
10
|
+
organization: AWSOrganization | Mapping | None,
|
|
11
|
+
) -> dict[str, str]:
|
|
12
|
+
"""
|
|
13
|
+
Get AWS account tags by merging payer account tags
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
organization: AWSOrganization | Mapping | None - The organization object from which to extract tags.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
dict[str, str]: A dictionary containing the merged tags from the payer account and the account itself.
|
|
20
|
+
"""
|
|
21
|
+
if organization is None:
|
|
22
|
+
return {}
|
|
23
|
+
|
|
24
|
+
match organization:
|
|
25
|
+
case AWSOrganization():
|
|
26
|
+
payer_account_tags = (
|
|
27
|
+
organization.payer_account.organization_account_tags or {}
|
|
28
|
+
)
|
|
29
|
+
account_tags = organization.tags or {}
|
|
30
|
+
case Mapping():
|
|
31
|
+
payer_account_tags = organization.get("payerAccount", {}).get(
|
|
32
|
+
"organizationAccountTags", {}
|
|
33
|
+
)
|
|
34
|
+
if isinstance(payer_account_tags, str):
|
|
35
|
+
payer_account_tags = json.loads(payer_account_tags)
|
|
36
|
+
|
|
37
|
+
account_tags = organization.get("tags", {})
|
|
38
|
+
if isinstance(account_tags, str):
|
|
39
|
+
account_tags = json.loads(account_tags)
|
|
40
|
+
|
|
41
|
+
return payer_account_tags | account_tags
|
|
@@ -13,7 +13,7 @@ class CostNamespace(BaseModel, frozen=True):
|
|
|
13
13
|
labels: CostNamespaceLabels
|
|
14
14
|
app_name: str
|
|
15
15
|
cluster_name: str
|
|
16
|
-
cluster_external_id: str | None
|
|
16
|
+
cluster_external_id: str | None = None
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def get_cost_namespaces(
|
|
@@ -32,7 +32,7 @@ def get_cost_namespaces(
|
|
|
32
32
|
return [
|
|
33
33
|
CostNamespace(
|
|
34
34
|
name=namespace.name,
|
|
35
|
-
labels=CostNamespaceLabels.
|
|
35
|
+
labels=CostNamespaceLabels.model_validate(namespace.labels or {}),
|
|
36
36
|
app_name=namespace.app.name,
|
|
37
37
|
cluster_name=namespace.cluster.name,
|
|
38
38
|
cluster_external_id=namespace.cluster.spec.external_id
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import hashlib
|
|
2
|
-
import json
|
|
3
2
|
from collections.abc import Callable
|
|
4
3
|
from threading import Lock
|
|
5
4
|
from typing import Any
|
|
@@ -7,7 +6,6 @@ from typing import Any
|
|
|
7
6
|
from jsonpath_ng.exceptions import JsonPathParserError
|
|
8
7
|
from pydantic import (
|
|
9
8
|
BaseModel,
|
|
10
|
-
Extra,
|
|
11
9
|
Field,
|
|
12
10
|
Json,
|
|
13
11
|
)
|
|
@@ -48,10 +46,16 @@ from reconcile.utils.exceptions import (
|
|
|
48
46
|
AppInterfaceSettingsError,
|
|
49
47
|
ParameterError,
|
|
50
48
|
)
|
|
49
|
+
from reconcile.utils.json import json_dumps
|
|
51
50
|
from reconcile.utils.jsonpath import parse_jsonpath
|
|
52
51
|
|
|
53
52
|
|
|
54
|
-
class SaasResourceTemplateTarget(
|
|
53
|
+
class SaasResourceTemplateTarget(
|
|
54
|
+
ConfiguredBaseModel,
|
|
55
|
+
validate_by_alias=True,
|
|
56
|
+
# ignore `namespaceSelector` and 'provider' fields from the GQL schema
|
|
57
|
+
extra="ignore",
|
|
58
|
+
):
|
|
55
59
|
path: str | None = Field(..., alias="path")
|
|
56
60
|
name: str | None = Field(..., alias="name")
|
|
57
61
|
# the namespace must be required to fulfill the saas file schema (utils.saasherder.interface.SaasFile)
|
|
@@ -79,12 +83,8 @@ class SaasResourceTemplateTarget(ConfiguredBaseModel):
|
|
|
79
83
|
digest_size=20,
|
|
80
84
|
).hexdigest()
|
|
81
85
|
|
|
82
|
-
class Config:
|
|
83
|
-
# ignore `namespaceSelector` and 'provider' fields from the GQL schema
|
|
84
|
-
extra = Extra.ignore
|
|
85
|
-
|
|
86
86
|
|
|
87
|
-
class SaasResourceTemplate(ConfiguredBaseModel):
|
|
87
|
+
class SaasResourceTemplate(ConfiguredBaseModel, validate_by_alias=True):
|
|
88
88
|
name: str = Field(..., alias="name")
|
|
89
89
|
url: str = Field(..., alias="url")
|
|
90
90
|
path: str = Field(..., alias="path")
|
|
@@ -97,7 +97,7 @@ class SaasResourceTemplate(ConfiguredBaseModel):
|
|
|
97
97
|
targets: list[SaasResourceTemplateTarget] = Field(..., alias="targets")
|
|
98
98
|
|
|
99
99
|
|
|
100
|
-
class SaasFile(ConfiguredBaseModel):
|
|
100
|
+
class SaasFile(ConfiguredBaseModel, validate_by_alias=True):
|
|
101
101
|
path: str = Field(..., alias="path")
|
|
102
102
|
name: str = Field(..., alias="name")
|
|
103
103
|
labels: Json | None = Field(..., alias="labels")
|
|
@@ -221,7 +221,7 @@ class SaasFileList:
|
|
|
221
221
|
with self._namespaces_as_dict_lock:
|
|
222
222
|
self._namespaces_as_dict_cache = {
|
|
223
223
|
"namespace": [
|
|
224
|
-
ns.
|
|
224
|
+
ns.model_dump(by_alias=True, exclude_none=True)
|
|
225
225
|
for ns in self.namespaces
|
|
226
226
|
]
|
|
227
227
|
}
|
|
@@ -283,7 +283,7 @@ class SaasFileList:
|
|
|
283
283
|
if app_name and saas_file.app.name != app_name:
|
|
284
284
|
continue
|
|
285
285
|
|
|
286
|
-
sf = saas_file.
|
|
286
|
+
sf = saas_file.model_copy(deep=True)
|
|
287
287
|
if env_name:
|
|
288
288
|
for rt in sf.resource_templates[:]:
|
|
289
289
|
for target in rt.targets[:]:
|
|
@@ -302,7 +302,7 @@ def convert_parameters_to_json_string(root: dict[str, Any]) -> dict[str, Any]:
|
|
|
302
302
|
"""Find all parameter occurrences and convert them to a json string."""
|
|
303
303
|
for key, value in root.items():
|
|
304
304
|
if key in {"parameters", "labels"}:
|
|
305
|
-
root[key] =
|
|
305
|
+
root[key] = json_dumps(value) if value is not None else None
|
|
306
306
|
elif isinstance(value, dict):
|
|
307
307
|
root[key] = convert_parameters_to_json_string(value)
|
|
308
308
|
elif isinstance(value, list):
|
|
@@ -314,7 +314,7 @@ def convert_parameters_to_json_string(root: dict[str, Any]) -> dict[str, Any]:
|
|
|
314
314
|
|
|
315
315
|
|
|
316
316
|
def export_model(model: BaseModel) -> dict[str, Any]:
|
|
317
|
-
return convert_parameters_to_json_string(model.
|
|
317
|
+
return convert_parameters_to_json_string(model.model_dump(by_alias=True))
|
|
318
318
|
|
|
319
319
|
|
|
320
320
|
def get_saas_files(
|
|
@@ -32,7 +32,7 @@ def get_selected_app_names(
|
|
|
32
32
|
prefix = f"{namespace.app.parent_app.name}-"
|
|
33
33
|
name = f"{prefix}{namespace.app.name}"
|
|
34
34
|
selected_app_names.add(name)
|
|
35
|
-
app = namespace.app.
|
|
35
|
+
app = namespace.app.model_dump(by_alias=True)
|
|
36
36
|
app["name"] = name
|
|
37
37
|
apps["apps"].append(app)
|
|
38
38
|
|
|
@@ -40,7 +40,7 @@ def get_selected_app_names(
|
|
|
40
40
|
name = f"{namespace.app.name}-{child.name}"
|
|
41
41
|
if name not in selected_app_names:
|
|
42
42
|
selected_app_names.add(f"{namespace.app.name}-{child.name}")
|
|
43
|
-
child_dict = child.
|
|
43
|
+
child_dict = child.model_dump(by_alias=True)
|
|
44
44
|
child_dict["name"] = name
|
|
45
45
|
apps["apps"].append(child_dict)
|
|
46
46
|
|
|
@@ -31,7 +31,7 @@ QONTRACT_INTEGRATION_VERSION = make_semver(1, 0, 0)
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class UnleashTogglesIntegrationParams(PydanticRunParams):
|
|
34
|
-
instance: str | None
|
|
34
|
+
instance: str | None = None
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def feature_toggle_equal(c: FeatureToggle, d: FeatureToggleUnleashV1) -> bool:
|
|
@@ -68,7 +68,9 @@ class UnleashTogglesIntegration(
|
|
|
68
68
|
if not query_func:
|
|
69
69
|
query_func = gql.get_api().query
|
|
70
70
|
return {
|
|
71
|
-
"toggles": [
|
|
71
|
+
"toggles": [
|
|
72
|
+
ft.model_dump() for ft in self.get_unleash_instances(query_func)
|
|
73
|
+
],
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
def get_unleash_instances(
|
reconcile/utils/acs/base.py
CHANGED
|
@@ -6,7 +6,7 @@ from typing import (
|
|
|
6
6
|
)
|
|
7
7
|
|
|
8
8
|
import requests
|
|
9
|
-
from pydantic import BaseModel
|
|
9
|
+
from pydantic import BaseModel, ConfigDict
|
|
10
10
|
|
|
11
11
|
from reconcile.gql_definitions.acs.acs_instances import AcsInstanceV1
|
|
12
12
|
from reconcile.gql_definitions.acs.acs_instances import query as acs_instances_query
|
|
@@ -19,8 +19,11 @@ class AcsBaseApi(BaseModel):
|
|
|
19
19
|
timeout: int = 30
|
|
20
20
|
session: requests.Session = requests.Session()
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
model_config = ConfigDict(
|
|
23
|
+
validate_by_name=True,
|
|
24
|
+
validate_by_alias=True,
|
|
25
|
+
arbitrary_types_allowed=True,
|
|
26
|
+
)
|
|
24
27
|
|
|
25
28
|
def __enter__(self) -> Self:
|
|
26
29
|
return self
|
reconcile/utils/acs/policies.py
CHANGED
|
@@ -11,7 +11,7 @@ class Scope(BaseModel):
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
cluster: str
|
|
14
|
-
namespace: str | None
|
|
14
|
+
namespace: str | None = None
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class PolicyCondition(BaseModel):
|
|
@@ -23,7 +23,7 @@ class PolicyCondition(BaseModel):
|
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
25
|
field_name: str
|
|
26
|
-
negate: bool | None
|
|
26
|
+
negate: bool | None = None
|
|
27
27
|
values: list[str]
|
|
28
28
|
|
|
29
29
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import logging
|
|
3
2
|
from collections.abc import Callable, KeysView
|
|
4
3
|
from typing import Any, TypedDict
|
|
5
4
|
|
|
5
|
+
from reconcile.utils.json import json_dumps
|
|
6
|
+
|
|
6
7
|
Action = Callable[[Any, list[Any]], bool]
|
|
7
8
|
Cond = Callable[[Any], bool]
|
|
8
9
|
|
|
@@ -89,11 +90,11 @@ class AggregatedList:
|
|
|
89
90
|
return list(self._dict.values())
|
|
90
91
|
|
|
91
92
|
def to_json(self) -> str:
|
|
92
|
-
return
|
|
93
|
+
return json_dumps(self.dump(), indent=4)
|
|
93
94
|
|
|
94
95
|
@staticmethod
|
|
95
96
|
def hash_params(params: Any) -> int:
|
|
96
|
-
return hash(
|
|
97
|
+
return hash(json_dumps(params))
|
|
97
98
|
|
|
98
99
|
|
|
99
100
|
class AggregatedDiffRunner:
|
reconcile/utils/aws_api.py
CHANGED
|
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
|
3
3
|
import logging
|
|
4
4
|
import operator
|
|
5
5
|
import os
|
|
6
|
-
import re
|
|
7
6
|
from functools import lru_cache
|
|
8
7
|
from threading import Lock
|
|
9
8
|
from typing import (
|
|
@@ -25,6 +24,7 @@ import reconcile.utils.lean_terraform_client as terraform
|
|
|
25
24
|
from reconcile.utils.secret_reader import SecretReader, SecretReaderBase
|
|
26
25
|
|
|
27
26
|
if TYPE_CHECKING:
|
|
27
|
+
import re
|
|
28
28
|
from collections.abc import (
|
|
29
29
|
Iterable,
|
|
30
30
|
Iterator,
|
|
@@ -583,40 +583,6 @@ class AWSApi:
|
|
|
583
583
|
|
|
584
584
|
return error, service_account_recycle_complete
|
|
585
585
|
|
|
586
|
-
def disable_keys(
|
|
587
|
-
self,
|
|
588
|
-
dry_run: bool,
|
|
589
|
-
keys_to_disable: Mapping,
|
|
590
|
-
) -> bool:
|
|
591
|
-
error = False
|
|
592
|
-
users_keys = self.get_users_keys()
|
|
593
|
-
for account, s in self.sessions.items():
|
|
594
|
-
iam = self.get_session_client(s, "iam")
|
|
595
|
-
keys = keys_to_disable.get(account, [])
|
|
596
|
-
for key in keys:
|
|
597
|
-
user_and_user_keys = [
|
|
598
|
-
(user, user_keys)
|
|
599
|
-
for user, user_keys in users_keys[account].items()
|
|
600
|
-
if key in user_keys
|
|
601
|
-
]
|
|
602
|
-
if not user_and_user_keys:
|
|
603
|
-
continue
|
|
604
|
-
if len(user_and_user_keys) > 1:
|
|
605
|
-
raise RuntimeError(
|
|
606
|
-
f"key {key} returned multiple users: {user_and_user_keys}"
|
|
607
|
-
)
|
|
608
|
-
user = user_and_user_keys[0][0]
|
|
609
|
-
key_status = self.get_user_key_status(iam, user, key)
|
|
610
|
-
if key_status == "Active":
|
|
611
|
-
logging.info(["disable_key", account, user, key])
|
|
612
|
-
if not dry_run:
|
|
613
|
-
iam.update_access_key(
|
|
614
|
-
UserName=user, AccessKeyId=key, Status="Inactive"
|
|
615
|
-
)
|
|
616
|
-
else:
|
|
617
|
-
logging.info(["key_already_disabled", account, user, key])
|
|
618
|
-
return error
|
|
619
|
-
|
|
620
586
|
def get_users_keys(self) -> dict:
|
|
621
587
|
users_keys = {}
|
|
622
588
|
for account, s in self.sessions.items():
|
|
@@ -1108,28 +1074,40 @@ class AWSApi:
|
|
|
1108
1074
|
return [rt["RouteTableId"] for rt in vpc_route_tables]
|
|
1109
1075
|
|
|
1110
1076
|
@staticmethod
|
|
1111
|
-
def
|
|
1112
|
-
|
|
1113
|
-
) -> list[dict[str, Any]]:
|
|
1114
|
-
results = []
|
|
1115
|
-
pattern = re.compile(regex)
|
|
1116
|
-
for i in images:
|
|
1117
|
-
if not re.search(pattern, i["Name"]):
|
|
1118
|
-
continue
|
|
1119
|
-
if i["State"] != "available":
|
|
1120
|
-
continue
|
|
1121
|
-
item = {"image_id": i["ImageId"], "tags": i.get("Tags", [])}
|
|
1122
|
-
results.append(item)
|
|
1077
|
+
def normalize_tags(tags: Iterable[TagTypeDef]) -> dict[str, str]:
|
|
1078
|
+
return {tag["Key"]: tag["Value"] for tag in tags}
|
|
1123
1079
|
|
|
1124
|
-
|
|
1080
|
+
@staticmethod
|
|
1081
|
+
def _filter_amis(
|
|
1082
|
+
images: Iterable[ImageTypeDef],
|
|
1083
|
+
regex: re.Pattern,
|
|
1084
|
+
) -> dict[str, dict[str, str]]:
|
|
1085
|
+
return {
|
|
1086
|
+
image["ImageId"]: AWSApi.normalize_tags(image.get("Tags", []))
|
|
1087
|
+
for image in images
|
|
1088
|
+
if regex.search(image["Name"]) and image["State"] == "available"
|
|
1089
|
+
}
|
|
1125
1090
|
|
|
1126
1091
|
def get_amis_details(
|
|
1127
1092
|
self,
|
|
1128
1093
|
account: Mapping[str, Any],
|
|
1129
1094
|
owner_account: Mapping[str, Any],
|
|
1130
|
-
regex:
|
|
1095
|
+
regex: re.Pattern,
|
|
1131
1096
|
region: str | None = None,
|
|
1132
|
-
) ->
|
|
1097
|
+
) -> dict[str, dict[str, str]]:
|
|
1098
|
+
"""
|
|
1099
|
+
Get AMI details for an account, find AMI name matches regex and state is available.
|
|
1100
|
+
Return ImageId and normalized tags.
|
|
1101
|
+
|
|
1102
|
+
Args:
|
|
1103
|
+
account: AWS account
|
|
1104
|
+
owner_account: AMI owner AWS account uid
|
|
1105
|
+
regex: regex to filter AMI name
|
|
1106
|
+
region: AWS account region
|
|
1107
|
+
|
|
1108
|
+
Returns:
|
|
1109
|
+
dict[str, dict[str, str]]: Key is AMI ImageId, value is AMI normalized tags.
|
|
1110
|
+
"""
|
|
1133
1111
|
ec2 = self._account_ec2_client(account["name"], region_name=region)
|
|
1134
1112
|
images = self.get_account_amis(ec2, owner=owner_account["uid"])
|
|
1135
1113
|
return self._filter_amis(images, regex)
|
|
@@ -1209,12 +1187,31 @@ class AWSApi:
|
|
|
1209
1187
|
client = self._account_cloudwatch_client(account_name, region_name=region_name)
|
|
1210
1188
|
client.delete_log_group(logGroupName=group_name)
|
|
1211
1189
|
|
|
1212
|
-
def
|
|
1213
|
-
self,
|
|
1190
|
+
def create_tags(
|
|
1191
|
+
self,
|
|
1192
|
+
account: Mapping[str, Any],
|
|
1193
|
+
resource_id: str,
|
|
1194
|
+
tags: Mapping[str, str],
|
|
1214
1195
|
) -> None:
|
|
1196
|
+
"""
|
|
1197
|
+
Create tags on EC2 resources (AMI)
|
|
1198
|
+
|
|
1199
|
+
Args:
|
|
1200
|
+
account: AWS account
|
|
1201
|
+
resource_id: AWS resource id
|
|
1202
|
+
tags: tags to update
|
|
1203
|
+
|
|
1204
|
+
Returns:
|
|
1205
|
+
None
|
|
1206
|
+
"""
|
|
1215
1207
|
ec2 = self._account_ec2_client(account["name"])
|
|
1216
|
-
|
|
1217
|
-
|
|
1208
|
+
formatted_tags: list[TagTypeDef] = [
|
|
1209
|
+
{"Key": k, "Value": v} for k, v in tags.items()
|
|
1210
|
+
]
|
|
1211
|
+
ec2.create_tags(
|
|
1212
|
+
Resources=[resource_id],
|
|
1213
|
+
Tags=formatted_tags,
|
|
1214
|
+
)
|
|
1218
1215
|
|
|
1219
1216
|
def get_alb_network_interface_ips(
|
|
1220
1217
|
self, account: awsh.Account, service_name: str
|
|
@@ -6,9 +6,11 @@ from functools import cached_property
|
|
|
6
6
|
from typing import TYPE_CHECKING, Any, TypeVar
|
|
7
7
|
|
|
8
8
|
from boto3 import Session
|
|
9
|
+
from botocore.config import Config
|
|
9
10
|
from pydantic import BaseModel
|
|
10
11
|
|
|
11
12
|
import reconcile.utils.aws_api_typed.account
|
|
13
|
+
import reconcile.utils.aws_api_typed.cloudformation
|
|
12
14
|
import reconcile.utils.aws_api_typed.dynamodb
|
|
13
15
|
import reconcile.utils.aws_api_typed.iam
|
|
14
16
|
import reconcile.utils.aws_api_typed.organization
|
|
@@ -17,8 +19,10 @@ import reconcile.utils.aws_api_typed.service_quotas
|
|
|
17
19
|
import reconcile.utils.aws_api_typed.sts
|
|
18
20
|
import reconcile.utils.aws_api_typed.support
|
|
19
21
|
from reconcile.utils.aws_api_typed.account import AWSApiAccount
|
|
22
|
+
from reconcile.utils.aws_api_typed.cloudformation import AWSApiCloudFormation
|
|
20
23
|
from reconcile.utils.aws_api_typed.dynamodb import AWSApiDynamoDB
|
|
21
24
|
from reconcile.utils.aws_api_typed.iam import AWSApiIam
|
|
25
|
+
from reconcile.utils.aws_api_typed.logs import AWSApiLogs
|
|
22
26
|
from reconcile.utils.aws_api_typed.organization import AWSApiOrganizations
|
|
23
27
|
from reconcile.utils.aws_api_typed.s3 import AWSApiS3
|
|
24
28
|
from reconcile.utils.aws_api_typed.service_quotas import AWSApiServiceQuotas
|
|
@@ -31,7 +35,9 @@ if TYPE_CHECKING:
|
|
|
31
35
|
SubApi = TypeVar(
|
|
32
36
|
"SubApi",
|
|
33
37
|
AWSApiAccount,
|
|
38
|
+
AWSApiCloudFormation,
|
|
34
39
|
AWSApiDynamoDB,
|
|
40
|
+
AWSApiLogs,
|
|
35
41
|
AWSApiIam,
|
|
36
42
|
AWSApiOrganizations,
|
|
37
43
|
AWSApiS3,
|
|
@@ -40,6 +46,13 @@ SubApi = TypeVar(
|
|
|
40
46
|
AWSApiSupport,
|
|
41
47
|
)
|
|
42
48
|
|
|
49
|
+
DEFAULT_CONFIG = Config(
|
|
50
|
+
retries={
|
|
51
|
+
"mode": "standard",
|
|
52
|
+
"total_max_attempts": 10,
|
|
53
|
+
},
|
|
54
|
+
)
|
|
55
|
+
|
|
43
56
|
|
|
44
57
|
class AWSCredentials(ABC):
|
|
45
58
|
@abstractmethod
|
|
@@ -174,28 +187,34 @@ class AWSApi:
|
|
|
174
187
|
"""Return a new or cached sub api client."""
|
|
175
188
|
match api_cls:
|
|
176
189
|
case reconcile.utils.aws_api_typed.account.AWSApiAccount:
|
|
177
|
-
client = self.session.client("account")
|
|
190
|
+
client = self.session.client("account", config=DEFAULT_CONFIG)
|
|
191
|
+
api = api_cls(client)
|
|
192
|
+
case reconcile.utils.aws_api_typed.cloudformation.AWSApiCloudFormation:
|
|
193
|
+
client = self.session.client("cloudformation", config=DEFAULT_CONFIG)
|
|
178
194
|
api = api_cls(client)
|
|
179
195
|
case reconcile.utils.aws_api_typed.dynamodb.AWSApiDynamoDB:
|
|
180
|
-
client = self.session.client("dynamodb")
|
|
196
|
+
client = self.session.client("dynamodb", config=DEFAULT_CONFIG)
|
|
181
197
|
api = api_cls(client)
|
|
182
198
|
case reconcile.utils.aws_api_typed.iam.AWSApiIam:
|
|
183
|
-
client = self.session.client("iam")
|
|
199
|
+
client = self.session.client("iam", config=DEFAULT_CONFIG)
|
|
200
|
+
api = api_cls(client)
|
|
201
|
+
case reconcile.utils.aws_api_typed.logs.AWSApiLogs:
|
|
202
|
+
client = self.session.client("logs", config=DEFAULT_CONFIG)
|
|
184
203
|
api = api_cls(client)
|
|
185
204
|
case reconcile.utils.aws_api_typed.organization.AWSApiOrganizations:
|
|
186
|
-
client = self.session.client("organizations")
|
|
205
|
+
client = self.session.client("organizations", config=DEFAULT_CONFIG)
|
|
187
206
|
api = api_cls(client)
|
|
188
207
|
case reconcile.utils.aws_api_typed.s3.AWSApiS3:
|
|
189
|
-
client = self.session.client("s3")
|
|
208
|
+
client = self.session.client("s3", config=DEFAULT_CONFIG)
|
|
190
209
|
api = api_cls(client)
|
|
191
210
|
case reconcile.utils.aws_api_typed.service_quotas.AWSApiServiceQuotas:
|
|
192
|
-
client = self.session.client("service-quotas")
|
|
211
|
+
client = self.session.client("service-quotas", config=DEFAULT_CONFIG)
|
|
193
212
|
api = api_cls(client)
|
|
194
213
|
case reconcile.utils.aws_api_typed.sts.AWSApiSts:
|
|
195
|
-
client = self.session.client("sts")
|
|
214
|
+
client = self.session.client("sts", config=DEFAULT_CONFIG)
|
|
196
215
|
api = api_cls(client)
|
|
197
216
|
case reconcile.utils.aws_api_typed.support.AWSApiSupport:
|
|
198
|
-
client = self.session.client("support")
|
|
217
|
+
client = self.session.client("support", config=DEFAULT_CONFIG)
|
|
199
218
|
api = api_cls(client)
|
|
200
219
|
case _:
|
|
201
220
|
raise ValueError(f"Unknown API class: {api_cls}")
|
|
@@ -205,9 +224,14 @@ class AWSApi:
|
|
|
205
224
|
|
|
206
225
|
@cached_property
|
|
207
226
|
def account(self) -> AWSApiAccount:
|
|
208
|
-
"""Return an AWS
|
|
227
|
+
"""Return an AWS Account Api client"""
|
|
209
228
|
return self._init_sub_api(AWSApiAccount)
|
|
210
229
|
|
|
230
|
+
@cached_property
|
|
231
|
+
def cloudformation(self) -> AWSApiCloudFormation:
|
|
232
|
+
"""Return an AWS CloudFormation Api client"""
|
|
233
|
+
return self._init_sub_api(AWSApiCloudFormation)
|
|
234
|
+
|
|
211
235
|
@cached_property
|
|
212
236
|
def dynamodb(self) -> AWSApiDynamoDB:
|
|
213
237
|
"""Return an AWS DynamoDB Api client"""
|
|
@@ -218,6 +242,11 @@ class AWSApi:
|
|
|
218
242
|
"""Return an AWS IAM Api client."""
|
|
219
243
|
return self._init_sub_api(AWSApiIam)
|
|
220
244
|
|
|
245
|
+
@cached_property
|
|
246
|
+
def logs(self) -> AWSApiLogs:
|
|
247
|
+
"""Return an AWS Logs Api client."""
|
|
248
|
+
return self._init_sub_api(AWSApiLogs)
|
|
249
|
+
|
|
221
250
|
@cached_property
|
|
222
251
|
def organizations(self) -> AWSApiOrganizations:
|
|
223
252
|
"""Return an AWS Organizations Api client."""
|