qontract-reconcile 0.10.2.dev334__py3-none-any.whl → 0.10.2.dev439__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.
Potentially problematic release.
This version of qontract-reconcile might be problematic. Click here for more details.
- {qontract_reconcile-0.10.2.dev334.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/METADATA +13 -12
- {qontract_reconcile-0.10.2.dev334.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/RECORD +366 -361
- reconcile/acs_rbac.py +2 -2
- reconcile/aus/advanced_upgrade_service.py +18 -12
- reconcile/aus/base.py +134 -32
- reconcile/aus/cluster_version_data.py +15 -5
- reconcile/aus/models.py +3 -1
- reconcile/aus/ocm_addons_upgrade_scheduler_org.py +1 -0
- reconcile/aus/ocm_upgrade_scheduler.py +8 -1
- reconcile/aus/ocm_upgrade_scheduler_org.py +20 -5
- reconcile/aus/version_gates/sts_version_gate_handler.py +54 -1
- reconcile/automated_actions/config/integration.py +16 -4
- 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 +3 -3
- reconcile/aws_iam_keys.py +1 -0
- 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 +111 -18
- 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 +8 -5
- reconcile/external_resources/meta.py +0 -1
- reconcile/external_resources/metrics.py +1 -1
- reconcile/external_resources/model.py +20 -20
- reconcile/external_resources/reconciler.py +7 -4
- reconcile/external_resources/secrets_sync.py +8 -11
- reconcile/external_resources/state.py +26 -16
- 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 +10 -10
- reconcile/gql_definitions/acs/acs_policies.py +5 -5
- reconcile/gql_definitions/acs/acs_rbac.py +6 -6
- reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +32 -32
- reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +26 -26
- reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +6 -7
- 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 +51 -12
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +11 -11
- reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +20 -10
- reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +28 -68
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +20 -10
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +20 -10
- reconcile/gql_definitions/aws_saml_roles/roles.py +5 -5
- reconcile/gql_definitions/aws_version_sync/clusters.py +10 -10
- 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 +9 -9
- reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +18 -18
- reconcile/gql_definitions/common/alerting_services_settings.py +9 -9
- 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 +120 -0
- reconcile/gql_definitions/common/app_interface_state_settings.py +10 -10
- 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 +22 -9
- reconcile/gql_definitions/common/aws_vpcs.py +11 -11
- reconcile/gql_definitions/common/clusters.py +37 -35
- reconcile/gql_definitions/common/clusters_minimal.py +14 -14
- reconcile/gql_definitions/common/clusters_with_dms.py +6 -6
- reconcile/gql_definitions/common/clusters_with_peering.py +29 -30
- reconcile/gql_definitions/common/github_orgs.py +10 -10
- reconcile/gql_definitions/common/jira_settings.py +10 -10
- reconcile/gql_definitions/common/jiralert_settings.py +5 -5
- reconcile/gql_definitions/common/ldap_settings.py +5 -5
- reconcile/gql_definitions/common/namespaces.py +42 -44
- reconcile/gql_definitions/common/namespaces_minimal.py +15 -13
- reconcile/gql_definitions/common/ocm_env_telemeter.py +12 -12
- reconcile/gql_definitions/common/ocm_environments.py +19 -19
- reconcile/gql_definitions/common/pagerduty_instances.py +9 -9
- reconcile/gql_definitions/common/pgp_reencryption_settings.py +6 -6
- reconcile/gql_definitions/common/pipeline_providers.py +29 -29
- 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 +44 -44
- reconcile/gql_definitions/common/saas_target_namespaces.py +10 -10
- 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 +19 -19
- reconcile/gql_definitions/common/state_aws_account.py +7 -8
- 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 +9 -9
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +43 -43
- reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +10 -10
- 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 +8 -8
- reconcile/gql_definitions/email_sender/users.py +6 -6
- reconcile/gql_definitions/endpoints_discovery/apps.py +10 -10
- reconcile/gql_definitions/external_resources/aws_accounts.py +9 -9
- reconcile/gql_definitions/external_resources/external_resources_modules.py +23 -23
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +494 -410
- reconcile/gql_definitions/external_resources/external_resources_settings.py +28 -26
- reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +5 -5
- reconcile/gql_definitions/fleet_labeler/fleet_labels.py +40 -40
- 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_vpc_request_subnet.py → aws_organization.py} +12 -8
- reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
- reconcile/gql_definitions/fragments/aws_vpc_request.py +12 -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 +9 -9
- reconcile/gql_definitions/gcp/gcp_projects.py +9 -9
- reconcile/gql_definitions/gitlab_members/gitlab_instances.py +9 -9
- reconcile/gql_definitions/gitlab_members/permissions.py +9 -9
- reconcile/gql_definitions/glitchtip/glitchtip_instance.py +9 -9
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +11 -11
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +9 -9
- reconcile/gql_definitions/integrations/integrations.py +48 -51
- reconcile/gql_definitions/introspection.json +3207 -1683
- reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +11 -11
- reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +10 -10
- reconcile/gql_definitions/jira/jira_servers.py +5 -5
- reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +14 -10
- reconcile/gql_definitions/jumphosts/jumphosts.py +13 -13
- reconcile/gql_definitions/ldap_groups/roles.py +5 -5
- reconcile/gql_definitions/ldap_groups/settings.py +9 -9
- reconcile/gql_definitions/maintenance/maintenances.py +5 -5
- reconcile/gql_definitions/membershipsources/roles.py +5 -5
- reconcile/gql_definitions/ocm_labels/clusters.py +18 -19
- reconcile/gql_definitions/ocm_labels/organizations.py +5 -5
- reconcile/gql_definitions/openshift_cluster_bots/clusters.py +22 -22
- reconcile/gql_definitions/openshift_groups/managed_groups.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_roles.py +6 -6
- reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +10 -10
- reconcile/gql_definitions/quay_membership/quay_membership.py +6 -6
- reconcile/gql_definitions/rhcs/certs.py +33 -87
- reconcile/gql_definitions/rhcs/openshift_resource_rhcs_cert.py +43 -0
- reconcile/gql_definitions/rhidp/organizations.py +18 -18
- reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +5 -5
- reconcile/gql_definitions/service_dependencies/service_dependencies.py +8 -8
- reconcile/gql_definitions/sharding/aws_accounts.py +10 -10
- reconcile/gql_definitions/sharding/ocm_organization.py +8 -8
- reconcile/gql_definitions/skupper_network/site_controller_template.py +5 -5
- reconcile/gql_definitions/skupper_network/skupper_networks.py +10 -10
- reconcile/gql_definitions/slack_usergroups/clusters.py +5 -5
- reconcile/gql_definitions/slack_usergroups/permissions.py +9 -9
- 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 +6 -7
- reconcile/gql_definitions/statuspage/statuspages.py +9 -9
- 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 +6 -6
- reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +11 -11
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +11 -11
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +20 -25
- reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +6 -6
- reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +12 -12
- reconcile/gql_definitions/terraform_init/aws_accounts.py +23 -9
- reconcile/gql_definitions/terraform_repo/terraform_repo.py +9 -9
- reconcile/gql_definitions/terraform_resources/database_access_manager.py +5 -5
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +440 -407
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +23 -17
- reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +9 -9
- reconcile/gql_definitions/vault_instances/vault_instances.py +61 -61
- reconcile/gql_definitions/vault_policies/vault_policies.py +11 -11
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +8 -8
- 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 +33 -27
- reconcile/openshift_base.py +113 -5
- 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 +74 -37
- reconcile/openshift_rolebindings.py +230 -130
- 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/openshift_users.py +5 -3
- 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 -0
- reconcile/rhidp/common.py +3 -5
- reconcile/rhidp/sso_client/base.py +16 -5
- 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 +5 -1
- reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +4 -1
- reconcile/templating/lib/merge_request_manager.py +2 -2
- reconcile/templating/lib/rendering.py +3 -3
- reconcile/templating/renderer.py +12 -13
- 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 +20 -8
- reconcile/typed_queries/app_interface_roles.py +10 -0
- 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 -20
- 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/binary.py +7 -12
- 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 -8
- reconcile/utils/jira_client.py +82 -63
- reconcile/utils/jjb_client.py +28 -15
- reconcile/utils/jobcontroller/controller.py +2 -2
- reconcile/utils/jobcontroller/models.py +17 -1
- reconcile/utils/json.py +74 -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 +249 -203
- reconcile/utils/oc_filters.py +3 -3
- reconcile/utils/ocm/addons.py +0 -1
- reconcile/utils/ocm/base.py +18 -21
- 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 +138 -35
- reconcile/utils/rosa/session.py +16 -0
- 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 +55 -31
- reconcile/utils/slack_api.py +26 -4
- reconcile/utils/sloth.py +224 -0
- 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 +192 -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 +1 -1
- tools/cli_commands/systems_and_tools.py +5 -1
- tools/qontract_cli.py +31 -18
- tools/template_validation.py +3 -1
- reconcile/gql_definitions/cna/__init__.py +0 -0
- reconcile/gql_definitions/cna/queries/__init__.py +0 -0
- reconcile/gql_definitions/ocm_oidc_idp/__init__.py +0 -0
- reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
- {qontract_reconcile-0.10.2.dev334.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev334.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/entry_points.txt +0 -0
reconcile/terraform_repo.py
CHANGED
|
@@ -41,10 +41,10 @@ class RepoOutput(BaseModel):
|
|
|
41
41
|
project_path: str
|
|
42
42
|
delete: bool
|
|
43
43
|
aws_creds: VaultSecret
|
|
44
|
-
variables: TerraformRepoVariablesV1 | None
|
|
45
|
-
bucket: str | None
|
|
46
|
-
region: str | None
|
|
47
|
-
bucket_path: str | None
|
|
44
|
+
variables: TerraformRepoVariablesV1 | None = None
|
|
45
|
+
bucket: str | None = None
|
|
46
|
+
region: str | None = None
|
|
47
|
+
bucket_path: str | None = None
|
|
48
48
|
require_fips: bool
|
|
49
49
|
tf_version: str
|
|
50
50
|
|
|
@@ -62,8 +62,8 @@ class OutputFile(BaseModel):
|
|
|
62
62
|
class TerraformRepoIntegrationParams(PydanticRunParams):
|
|
63
63
|
output_file: str | None
|
|
64
64
|
validate_git: bool
|
|
65
|
-
gitlab_project_id: str | None
|
|
66
|
-
gitlab_merge_request_id: int | None
|
|
65
|
+
gitlab_project_id: str | None = None
|
|
66
|
+
gitlab_merge_request_id: int | None = None
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
class TerraformRepoIntegration(
|
|
@@ -168,7 +168,7 @@ class TerraformRepoIntegration(
|
|
|
168
168
|
self.params.output_file, "w", encoding="locale"
|
|
169
169
|
) as output_file:
|
|
170
170
|
yaml.safe_dump(
|
|
171
|
-
data=output.
|
|
171
|
+
data=output.model_dump(),
|
|
172
172
|
stream=output_file,
|
|
173
173
|
explicit_start=True,
|
|
174
174
|
)
|
|
@@ -177,7 +177,7 @@ class TerraformRepoIntegration(
|
|
|
177
177
|
f"Unable to write to '{self.params.output_file}'"
|
|
178
178
|
) from None
|
|
179
179
|
else:
|
|
180
|
-
print(yaml.safe_dump(data=output.
|
|
180
|
+
print(yaml.safe_dump(data=output.model_dump(), explicit_start=True))
|
|
181
181
|
|
|
182
182
|
return output
|
|
183
183
|
|
|
@@ -206,7 +206,7 @@ class TerraformRepoIntegration(
|
|
|
206
206
|
keys = state.ls()
|
|
207
207
|
for key in keys:
|
|
208
208
|
if value := state.get(key.lstrip("/"), None):
|
|
209
|
-
repo = TerraformRepoV1.
|
|
209
|
+
repo = TerraformRepoV1.model_validate(value)
|
|
210
210
|
repo_list.append(repo)
|
|
211
211
|
|
|
212
212
|
return repo_list
|
|
@@ -283,7 +283,7 @@ class TerraformRepoIntegration(
|
|
|
283
283
|
for add_key, add_val in diff_result.add.items():
|
|
284
284
|
# state.add already performs a json.dumps(key) so we export the
|
|
285
285
|
# pydantic model as a dict to avoid a double json dump with extra quotes
|
|
286
|
-
state.add(add_key, add_val.
|
|
286
|
+
state.add(add_key, add_val.model_dump(by_alias=True), force=True)
|
|
287
287
|
for delete_key in diff_result.delete:
|
|
288
288
|
state.rm(delete_key)
|
|
289
289
|
for change_key, change_val in diff_result.change.items():
|
|
@@ -291,7 +291,9 @@ class TerraformRepoIntegration(
|
|
|
291
291
|
state.rm(change_key)
|
|
292
292
|
else:
|
|
293
293
|
state.add(
|
|
294
|
-
change_key,
|
|
294
|
+
change_key,
|
|
295
|
+
change_val.desired.model_dump(by_alias=True),
|
|
296
|
+
force=True,
|
|
295
297
|
)
|
|
296
298
|
except KeyError:
|
|
297
299
|
pass
|
|
@@ -394,5 +396,7 @@ class TerraformRepoIntegration(
|
|
|
394
396
|
def early_exit_desired_state(self, *args: Any, **kwargs: Any) -> dict[str, Any]:
|
|
395
397
|
gqlapi = gql.get_api()
|
|
396
398
|
return {
|
|
397
|
-
"repos": [
|
|
399
|
+
"repos": [
|
|
400
|
+
repo.model_dump() for repo in self.get_repos(query_func=gqlapi.query)
|
|
401
|
+
]
|
|
398
402
|
}
|
reconcile/terraform_resources.py
CHANGED
|
@@ -27,6 +27,7 @@ from reconcile.gql_definitions.terraform_resources.terraform_resources_namespace
|
|
|
27
27
|
from reconcile.typed_queries.app_interface_vault_settings import (
|
|
28
28
|
get_app_interface_vault_settings,
|
|
29
29
|
)
|
|
30
|
+
from reconcile.typed_queries.external_resources import get_settings
|
|
30
31
|
from reconcile.typed_queries.terraform_namespaces import get_namespaces
|
|
31
32
|
from reconcile.utils import gql
|
|
32
33
|
from reconcile.utils.aws_api import AWSApi
|
|
@@ -136,7 +137,7 @@ def fetch_current_state(
|
|
|
136
137
|
use_jump_host=use_jump_host,
|
|
137
138
|
thread_pool_size=thread_pool_size,
|
|
138
139
|
)
|
|
139
|
-
namespaces_dicts = [ns.
|
|
140
|
+
namespaces_dicts = [ns.model_dump(by_alias=True) for ns in namespaces]
|
|
140
141
|
state_specs = ob.init_specs_to_fetch(
|
|
141
142
|
ri, oc_map, namespaces=namespaces_dicts, override_managed_types=["Secret"]
|
|
142
143
|
)
|
|
@@ -158,6 +159,7 @@ def init_working_dirs(
|
|
|
158
159
|
accounts: list[dict[str, Any]],
|
|
159
160
|
thread_pool_size: int,
|
|
160
161
|
settings: Mapping[str, Any] | None = None,
|
|
162
|
+
default_tags: Mapping[str, str] | None = None,
|
|
161
163
|
) -> tuple[Terrascript, dict[str, str]]:
|
|
162
164
|
ts = Terrascript(
|
|
163
165
|
QONTRACT_INTEGRATION,
|
|
@@ -165,6 +167,7 @@ def init_working_dirs(
|
|
|
165
167
|
thread_pool_size,
|
|
166
168
|
accounts,
|
|
167
169
|
settings=settings,
|
|
170
|
+
default_tags=default_tags,
|
|
168
171
|
)
|
|
169
172
|
working_dirs = ts.dump()
|
|
170
173
|
return ts, working_dirs
|
|
@@ -241,8 +244,15 @@ def setup(
|
|
|
241
244
|
secret_reader = create_secret_reader(use_vault=vault_settings.vault)
|
|
242
245
|
|
|
243
246
|
settings = queries.get_app_interface_settings() or {}
|
|
247
|
+
try:
|
|
248
|
+
default_tags = get_settings().default_tags
|
|
249
|
+
except ValueError:
|
|
250
|
+
# no external resources settings found
|
|
251
|
+
default_tags = None
|
|
244
252
|
# initialize terrascript (scripting engine to generate terraform manifests)
|
|
245
|
-
ts, working_dirs = init_working_dirs(
|
|
253
|
+
ts, working_dirs = init_working_dirs(
|
|
254
|
+
accounts, thread_pool_size, settings=settings, default_tags=default_tags
|
|
255
|
+
)
|
|
246
256
|
|
|
247
257
|
# initialize terraform client
|
|
248
258
|
# it is used to plan and apply according to the output of terrascript
|
|
@@ -263,7 +273,7 @@ def setup(
|
|
|
263
273
|
)
|
|
264
274
|
else:
|
|
265
275
|
ocm_map = None
|
|
266
|
-
tf_namespaces_dicts = [ns.
|
|
276
|
+
tf_namespaces_dicts = [ns.model_dump(by_alias=True) for ns in tf_namespaces]
|
|
267
277
|
|
|
268
278
|
provider_exclusions = settings.get("terraformResourcesProviderExclusions") or []
|
|
269
279
|
ts.init_populate_specs(
|
|
@@ -285,16 +295,16 @@ def filter_tf_namespaces(
|
|
|
285
295
|
) -> list[NamespaceV1]:
|
|
286
296
|
tf_namespaces = []
|
|
287
297
|
for namespace_info in namespaces:
|
|
288
|
-
if ob.is_namespace_deleted(namespace_info.
|
|
298
|
+
if ob.is_namespace_deleted(namespace_info.model_dump(by_alias=True)):
|
|
289
299
|
continue
|
|
290
|
-
if not managed_external_resources(namespace_info.
|
|
300
|
+
if not managed_external_resources(namespace_info.model_dump(by_alias=True)):
|
|
291
301
|
continue
|
|
292
302
|
|
|
293
303
|
if not account_names:
|
|
294
304
|
tf_namespaces.append(namespace_info)
|
|
295
305
|
continue
|
|
296
306
|
|
|
297
|
-
specs = get_external_resource_specs(namespace_info.
|
|
307
|
+
specs = get_external_resource_specs(namespace_info.model_dump(by_alias=True))
|
|
298
308
|
if not specs:
|
|
299
309
|
tf_namespaces.append(namespace_info)
|
|
300
310
|
continue
|
|
@@ -557,7 +567,7 @@ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
|
|
557
567
|
}
|
|
558
568
|
for ns_info in get_tf_namespaces():
|
|
559
569
|
for spec in get_external_resource_specs(
|
|
560
|
-
ns_info.
|
|
570
|
+
ns_info.model_dump(by_alias=True), provision_provider=PROVIDER_AWS
|
|
561
571
|
):
|
|
562
572
|
resource_paths = [
|
|
563
573
|
spec.resource.get("defaults"),
|
|
@@ -32,6 +32,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
|
32
32
|
get_app_interface_vault_settings,
|
|
33
33
|
)
|
|
34
34
|
from reconcile.typed_queries.clusters_with_peering import get_clusters_with_peering
|
|
35
|
+
from reconcile.typed_queries.external_resources import get_settings
|
|
35
36
|
from reconcile.typed_queries.terraform_tgw_attachments.aws_accounts import (
|
|
36
37
|
get_aws_accounts,
|
|
37
38
|
)
|
|
@@ -68,7 +69,7 @@ class ValidationError(Exception):
|
|
|
68
69
|
class TGWAccountProviderInfo(BaseModel):
|
|
69
70
|
name: str
|
|
70
71
|
uid: str
|
|
71
|
-
assume_role: str | None
|
|
72
|
+
assume_role: str | None = None
|
|
72
73
|
assume_region: str
|
|
73
74
|
|
|
74
75
|
|
|
@@ -80,10 +81,10 @@ class Requester(BaseModel):
|
|
|
80
81
|
tgw_id: str
|
|
81
82
|
tgw_arn: str
|
|
82
83
|
region: str
|
|
83
|
-
routes: list[dict] | None
|
|
84
|
-
rules: list[dict] | None
|
|
85
|
-
hostedzones: list[str] | None
|
|
86
|
-
cidr_block: str | None
|
|
84
|
+
routes: list[dict] | None = None
|
|
85
|
+
rules: list[dict] | None = None
|
|
86
|
+
hostedzones: list[str] | None = None
|
|
87
|
+
cidr_block: str | None = None
|
|
87
88
|
cidr_blocks: list[str]
|
|
88
89
|
account: TGWAccountProviderInfo
|
|
89
90
|
|
|
@@ -91,11 +92,11 @@ class Requester(BaseModel):
|
|
|
91
92
|
class Accepter(BaseModel):
|
|
92
93
|
cidr_block: str
|
|
93
94
|
region: str
|
|
94
|
-
vpc_id: str | None
|
|
95
|
-
route_table_ids: list[str] | None
|
|
96
|
-
subnets_id_az: list[dict[str, str]] | None
|
|
95
|
+
vpc_id: str | None = None
|
|
96
|
+
route_table_ids: list[str] | None = None
|
|
97
|
+
subnets_id_az: list[dict[str, str]] | None = None
|
|
97
98
|
account: ClusterAccountProviderInfo
|
|
98
|
-
api_security_group_id: str | None
|
|
99
|
+
api_security_group_id: str | None = None
|
|
99
100
|
|
|
100
101
|
|
|
101
102
|
class DesiredStateItem(BaseModel):
|
|
@@ -192,7 +193,7 @@ def _build_desired_state_tgw_connection(
|
|
|
192
193
|
yield None
|
|
193
194
|
|
|
194
195
|
account_tgws = awsapi.get_tgws_details(
|
|
195
|
-
peer_connection.account.
|
|
196
|
+
peer_connection.account.model_dump(by_alias=True),
|
|
196
197
|
cluster_region,
|
|
197
198
|
cluster_cidr_block,
|
|
198
199
|
tags=peer_connection.tags or {},
|
|
@@ -274,7 +275,7 @@ def _build_accepter(
|
|
|
274
275
|
)
|
|
275
276
|
(vpc_id, route_table_ids, subnets_id_az, api_security_group_id) = (
|
|
276
277
|
awsapi.get_cluster_vpc_details(
|
|
277
|
-
account.
|
|
278
|
+
account.model_dump(by_alias=True),
|
|
278
279
|
route_tables=bool(peer_connection.manage_routes),
|
|
279
280
|
subnets=True,
|
|
280
281
|
hcp_vpc_endpoint_sg=allow_hcp_private_api_access,
|
|
@@ -317,12 +318,12 @@ def _build_ocm_map(
|
|
|
317
318
|
clusters: Iterable[ClusterV1],
|
|
318
319
|
vault_settings: AppInterfaceSettingsV1,
|
|
319
320
|
) -> OCMMap | None:
|
|
320
|
-
ocm_clusters = [c.
|
|
321
|
+
ocm_clusters = [c.model_dump(by_alias=True) for c in clusters if c.ocm]
|
|
321
322
|
return (
|
|
322
323
|
OCMMap(
|
|
323
324
|
clusters=ocm_clusters,
|
|
324
325
|
integration=QONTRACT_INTEGRATION,
|
|
325
|
-
settings=vault_settings.
|
|
326
|
+
settings=vault_settings.model_dump(by_alias=True),
|
|
326
327
|
)
|
|
327
328
|
if ocm_clusters
|
|
328
329
|
# this is a case for an OCP cluster which is not provisioned
|
|
@@ -346,7 +347,7 @@ def _populate_tgw_attachments_working_dirs(
|
|
|
346
347
|
accounts_by_infra_account_name: dict[str, list[dict[str, Any]]] = {}
|
|
347
348
|
for item in desired_state:
|
|
348
349
|
accounts_by_infra_account_name.setdefault(item.infra_acount_name, []).append(
|
|
349
|
-
item.accepter.account.
|
|
350
|
+
item.accepter.account.model_dump(by_alias=True)
|
|
350
351
|
)
|
|
351
352
|
for infra_account_name, accounts in accounts_by_infra_account_name.items():
|
|
352
353
|
ts.populate_additional_providers(infra_account_name, accounts)
|
|
@@ -428,7 +429,9 @@ def setup(
|
|
|
428
429
|
print_to_file: str | None = None,
|
|
429
430
|
) -> tuple[SecretReaderBase, AWSApi, Terraform, Terrascript]:
|
|
430
431
|
tgw_clusters = desired_state_data_source.clusters
|
|
431
|
-
all_accounts = [
|
|
432
|
+
all_accounts = [
|
|
433
|
+
a.model_dump(by_alias=True) for a in desired_state_data_source.accounts
|
|
434
|
+
]
|
|
432
435
|
account_by_name = {a["name"]: a for a in all_accounts}
|
|
433
436
|
vault_settings = get_app_interface_vault_settings()
|
|
434
437
|
secret_reader = create_secret_reader(vault_settings.vault)
|
|
@@ -444,13 +447,18 @@ def setup(
|
|
|
444
447
|
raise RuntimeError("Could not find VPC ID for cluster")
|
|
445
448
|
|
|
446
449
|
_validate_tgw_connection_names(desired_state)
|
|
447
|
-
|
|
450
|
+
try:
|
|
451
|
+
default_tags = get_settings().default_tags
|
|
452
|
+
except ValueError:
|
|
453
|
+
# no external resources settings found
|
|
454
|
+
default_tags = None
|
|
448
455
|
ts = Terrascript(
|
|
449
456
|
QONTRACT_INTEGRATION,
|
|
450
457
|
"",
|
|
451
458
|
thread_pool_size,
|
|
452
459
|
tgw_accounts,
|
|
453
|
-
settings=vault_settings.
|
|
460
|
+
settings=vault_settings.model_dump(by_alias=True),
|
|
461
|
+
default_tags=default_tags,
|
|
454
462
|
)
|
|
455
463
|
tgw_rosa_cluster_accounts = [
|
|
456
464
|
account_by_name[c.spec.account.name]
|
|
@@ -510,7 +518,7 @@ def run(
|
|
|
510
518
|
) -> None:
|
|
511
519
|
desired_state_data_source = _fetch_desired_state_data_source(account_name)
|
|
512
520
|
tgw_accounts = [
|
|
513
|
-
a.
|
|
521
|
+
a.model_dump(by_alias=True)
|
|
514
522
|
for a in _filter_tgw_accounts(
|
|
515
523
|
desired_state_data_source.accounts, desired_state_data_source.clusters
|
|
516
524
|
)
|
|
@@ -567,7 +575,7 @@ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
|
|
567
575
|
desired_state = _fetch_desired_state_data_source()
|
|
568
576
|
for a in desired_state.accounts:
|
|
569
577
|
a.deletion_approvals = []
|
|
570
|
-
return desired_state.
|
|
578
|
+
return desired_state.model_dump(by_alias=True)
|
|
571
579
|
|
|
572
580
|
|
|
573
581
|
def desired_state_shard_config() -> DesiredStateShardConfig:
|
reconcile/terraform_users.py
CHANGED
|
@@ -11,6 +11,7 @@ from reconcile import (
|
|
|
11
11
|
)
|
|
12
12
|
from reconcile.change_owners.diff import IDENTIFIER_FIELD_NAME
|
|
13
13
|
from reconcile.gql_definitions.common.pgp_reencryption_settings import query
|
|
14
|
+
from reconcile.typed_queries.external_resources import get_settings
|
|
14
15
|
from reconcile.utils import (
|
|
15
16
|
expiration,
|
|
16
17
|
gql,
|
|
@@ -126,12 +127,18 @@ def setup(
|
|
|
126
127
|
participating_aws_accounts = _filter_participating_aws_accounts(accounts, roles)
|
|
127
128
|
|
|
128
129
|
settings = queries.get_app_interface_settings()
|
|
130
|
+
try:
|
|
131
|
+
default_tags = get_settings().default_tags
|
|
132
|
+
except ValueError:
|
|
133
|
+
# no external resources settings found
|
|
134
|
+
default_tags = None
|
|
129
135
|
ts = Terrascript(
|
|
130
136
|
QONTRACT_INTEGRATION,
|
|
131
137
|
QONTRACT_TF_PREFIX,
|
|
132
138
|
thread_pool_size,
|
|
133
139
|
participating_aws_accounts,
|
|
134
140
|
settings=settings,
|
|
141
|
+
default_tags=default_tags,
|
|
135
142
|
)
|
|
136
143
|
err = ts.populate_users(
|
|
137
144
|
roles,
|
|
@@ -7,6 +7,7 @@ from typing import Any, TypedDict
|
|
|
7
7
|
import reconcile.utils.terraform_client as terraform
|
|
8
8
|
import reconcile.utils.terrascript_aws_client as terrascript
|
|
9
9
|
from reconcile import queries
|
|
10
|
+
from reconcile.typed_queries import external_resources
|
|
10
11
|
from reconcile.utils import (
|
|
11
12
|
aws_api,
|
|
12
13
|
ocm,
|
|
@@ -654,8 +655,18 @@ def run(
|
|
|
654
655
|
])
|
|
655
656
|
|
|
656
657
|
account_by_name = {a["name"]: a for a in accounts}
|
|
658
|
+
try:
|
|
659
|
+
default_tags = external_resources.get_settings().default_tags
|
|
660
|
+
except ValueError:
|
|
661
|
+
# no external resources settings found
|
|
662
|
+
default_tags = None
|
|
657
663
|
with terrascript.TerrascriptClient(
|
|
658
|
-
QONTRACT_INTEGRATION,
|
|
664
|
+
QONTRACT_INTEGRATION,
|
|
665
|
+
"",
|
|
666
|
+
thread_pool_size,
|
|
667
|
+
infra_accounts,
|
|
668
|
+
settings=settings,
|
|
669
|
+
default_tags=default_tags,
|
|
659
670
|
) as ts:
|
|
660
671
|
rosa_cluster_accounts = [
|
|
661
672
|
account_by_name[c["spec"]["account"]["name"]]
|
|
@@ -664,8 +675,8 @@ def run(
|
|
|
664
675
|
]
|
|
665
676
|
ts.populate_configs(rosa_cluster_accounts)
|
|
666
677
|
|
|
667
|
-
for infra_account_name,
|
|
668
|
-
ts.populate_additional_providers(infra_account_name,
|
|
678
|
+
for infra_account_name, accounts in participating_accounts.items():
|
|
679
|
+
ts.populate_additional_providers(infra_account_name, accounts)
|
|
669
680
|
ts.populate_vpc_peerings(desired_state)
|
|
670
681
|
working_dirs = ts.dump(print_to_file=print_to_file)
|
|
671
682
|
terraform_configurations = ts.terraform_configurations()
|
|
@@ -20,9 +20,11 @@ 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
|
|
27
|
+
from reconcile.utils.disabled_integrations import integration_is_enabled
|
|
26
28
|
from reconcile.utils.runtime.integration import (
|
|
27
29
|
DesiredStateShardConfig,
|
|
28
30
|
PydanticRunParams,
|
|
@@ -61,12 +63,14 @@ class TerraformVpcResources(QontractReconcileIntegration[TerraformVpcResourcesPa
|
|
|
61
63
|
) -> list[AWSAccountV1]:
|
|
62
64
|
"""Return a list of accounts extracted from the provided VPCRequests.
|
|
63
65
|
If account_name is given returns the account object with that name."""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
return [
|
|
67
|
+
vpc.account
|
|
68
|
+
for vpc in data
|
|
69
|
+
if (
|
|
70
|
+
integration_is_enabled(self.name, vpc.account)
|
|
71
|
+
and (not account_name or vpc.account.name == account_name)
|
|
72
|
+
)
|
|
73
|
+
]
|
|
70
74
|
|
|
71
75
|
def _handle_outputs(
|
|
72
76
|
self, requests: Iterable[VPCRequest], outputs: Mapping[str, Any]
|
|
@@ -154,20 +158,28 @@ class TerraformVpcResources(QontractReconcileIntegration[TerraformVpcResourcesPa
|
|
|
154
158
|
if data:
|
|
155
159
|
accounts = self._filter_accounts(data, account_name)
|
|
156
160
|
if account_name and not accounts:
|
|
157
|
-
msg = f"The account {account_name} doesn't have any managed
|
|
161
|
+
msg = f"The account {account_name} doesn't have any managed vpcs or the {QONTRACT_INTEGRATION} integration is disabled for this account. Verify your input"
|
|
158
162
|
logging.debug(msg)
|
|
159
163
|
sys.exit(ExitCodes.SUCCESS)
|
|
160
164
|
else:
|
|
161
165
|
logging.debug("No VPC requests found, nothing to do.")
|
|
162
166
|
sys.exit(ExitCodes.SUCCESS)
|
|
163
167
|
|
|
164
|
-
accounts_untyped: list[dict] = [
|
|
168
|
+
accounts_untyped: list[dict] = [
|
|
169
|
+
acc.model_dump(by_alias=True) for acc in accounts
|
|
170
|
+
]
|
|
171
|
+
try:
|
|
172
|
+
default_tags = get_settings().default_tags
|
|
173
|
+
except ValueError:
|
|
174
|
+
# no external resources settings found
|
|
175
|
+
default_tags = None
|
|
165
176
|
with TerrascriptClient(
|
|
166
177
|
integration=QONTRACT_INTEGRATION,
|
|
167
178
|
integration_prefix=QONTRACT_TF_PREFIX,
|
|
168
179
|
thread_pool_size=thread_pool_size,
|
|
169
180
|
accounts=accounts_untyped,
|
|
170
181
|
secret_reader=secret_reader,
|
|
182
|
+
default_tags=default_tags,
|
|
171
183
|
) as ts_client:
|
|
172
184
|
ts_client.populate_vpc_requests(data, AWS_PROVIDER_VERSION)
|
|
173
185
|
|
|
@@ -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
|