qontract-reconcile 0.10.2.dev310__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.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/METADATA +13 -12
- {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/RECORD +396 -391
- 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 +5 -5
- 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 +125 -84
- 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 +12 -4
- reconcile/cli.py +111 -18
- reconcile/cluster_deployment_mapper.py +2 -3
- reconcile/dashdotdb_dora.py +5 -12
- reconcile/dashdotdb_slo.py +1 -1
- reconcile/database_access_manager.py +125 -121
- reconcile/deadmanssnitch.py +1 -5
- 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 +10 -14
- 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 +3510 -1865
- 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 +450 -402
- 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_job_builder.py +1 -1
- reconcile/jenkins_worker_fleets.py +80 -11
- 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 +122 -10
- reconcile/openshift_cluster_bots.py +5 -5
- reconcile/openshift_groups.py +5 -0
- reconcile/openshift_limitranges.py +1 -1
- reconcile/openshift_namespace_labels.py +1 -1
- reconcile/openshift_namespaces.py +97 -101
- reconcile/openshift_resources_base.py +10 -5
- reconcile/openshift_rhcs_certs.py +77 -40
- 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 +8 -7
- reconcile/openshift_tekton_resources.py +1 -1
- 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/oum/providers.py +1 -1
- reconcile/prometheus_rules_tester/integration.py +4 -4
- reconcile/quay_mirror.py +1 -1
- reconcile/queries.py +131 -0
- reconcile/requests_sender.py +8 -3
- reconcile/resource_scraper.py +1 -5
- reconcile/rhidp/common.py +3 -5
- reconcile/rhidp/sso_client/base.py +19 -10
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
- reconcile/saas_auto_promotions_manager/subscriber.py +4 -3
- reconcile/sendgrid_teammates.py +20 -9
- reconcile/skupper_network/integration.py +2 -2
- reconcile/slack_usergroups.py +35 -14
- reconcile/sql_query.py +1 -0
- reconcile/status.py +2 -2
- 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 +18 -8
- reconcile/terraform_cloudflare_dns.py +3 -3
- reconcile/terraform_cloudflare_resources.py +12 -13
- reconcile/terraform_cloudflare_users.py +3 -2
- reconcile/terraform_init/integration.py +187 -23
- reconcile/terraform_repo.py +16 -12
- reconcile/terraform_resources.py +18 -10
- reconcile/terraform_tgw_attachments.py +28 -20
- reconcile/terraform_users.py +27 -22
- reconcile/terraform_vpc_peerings.py +15 -3
- reconcile/terraform_vpc_resources/integration.py +23 -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/gpg.py +5 -3
- reconcile/utils/gql.py +4 -7
- reconcile/utils/helm.py +2 -1
- reconcile/utils/helpers.py +1 -1
- reconcile/utils/imap_client.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/jenkins_api.py +24 -1
- reconcile/utils/jinja2/utils.py +6 -8
- reconcile/utils/jira_client.py +82 -63
- reconcile/utils/jjb_client.py +78 -46
- reconcile/utils/jobcontroller/controller.py +2 -2
- reconcile/utils/jobcontroller/models.py +17 -1
- reconcile/utils/json.py +74 -0
- reconcile/utils/ldap_client.py +4 -3
- reconcile/utils/lean_terraform_client.py +3 -1
- 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/__init__.py +3 -1
- reconcile/utils/mr/app_interface_reporter.py +6 -3
- reconcile/utils/mr/aws_access.py +1 -1
- reconcile/utils/mr/base.py +7 -13
- reconcile/utils/mr/clusters_updates.py +4 -2
- reconcile/utils/mr/notificator.py +3 -3
- reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +4 -1
- reconcile/utils/mr/promote_qontract.py +28 -12
- reconcile/utils/mr/update_access_report_base.py +3 -4
- reconcile/utils/mr/user_maintenance.py +7 -6
- reconcile/utils/oc.py +445 -336
- 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/ocm.py +81 -71
- 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/ocm_base_client.py +4 -4
- reconcile/utils/openshift_resource.py +83 -52
- reconcile/utils/openssl.py +2 -2
- 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 +11 -8
- reconcile/utils/repo_owners.py +21 -29
- reconcile/utils/rhcsv2_certs.py +138 -35
- reconcile/utils/rosa/session.py +16 -0
- reconcile/utils/runtime/integration.py +2 -3
- reconcile/utils/runtime/meta.py +2 -1
- 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 +60 -32
- reconcile/utils/secret_reader.py +6 -6
- reconcile/utils/sharding.py +1 -1
- reconcile/utils/slack_api.py +26 -4
- reconcile/utils/sloth.py +224 -0
- reconcile/utils/sqs_gateway.py +16 -11
- reconcile/utils/state.py +2 -1
- reconcile/utils/structs.py +1 -1
- reconcile/utils/terraform_client.py +29 -26
- reconcile/utils/terrascript_aws_client.py +200 -116
- reconcile/utils/three_way_diff_strategy.py +1 -1
- reconcile/utils/unleash/server.py +2 -8
- reconcile/utils/vault.py +44 -41
- reconcile/utils/vcs.py +8 -8
- reconcile/vault_replication.py +119 -58
- 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/gpg_encrypt.py +4 -1
- tools/cli_commands/systems_and_tools.py +5 -1
- tools/qontract_cli.py +36 -21
- tools/template_validation.py +3 -1
- reconcile/gql_definitions/ocm_oidc_idp/__init__.py +0 -0
- reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
- reconcile/jenkins/__init__.py +0 -0
- reconcile/jenkins/types.py +0 -77
- {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/entry_points.txt +0 -0
reconcile/slack_usergroups.py
CHANGED
|
@@ -3,18 +3,19 @@ import sys
|
|
|
3
3
|
from collections.abc import (
|
|
4
4
|
Callable,
|
|
5
5
|
Iterable,
|
|
6
|
+
MutableMapping,
|
|
6
7
|
Sequence,
|
|
7
8
|
)
|
|
8
9
|
from datetime import datetime
|
|
9
10
|
from typing import (
|
|
10
11
|
Any,
|
|
11
12
|
TypedDict,
|
|
13
|
+
TypeVar,
|
|
12
14
|
)
|
|
13
15
|
|
|
14
16
|
from github.GithubException import UnknownObjectException
|
|
15
17
|
from pydantic import BaseModel
|
|
16
|
-
from
|
|
17
|
-
from sretoolbox.utils import retry
|
|
18
|
+
from sretoolbox.utils import datatransformation, retry
|
|
18
19
|
|
|
19
20
|
from reconcile import (
|
|
20
21
|
openshift_users,
|
|
@@ -40,6 +41,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
|
|
|
40
41
|
)
|
|
41
42
|
from reconcile.typed_queries.pagerduty_instances import get_pagerduty_instances
|
|
42
43
|
from reconcile.utils import gql
|
|
44
|
+
from reconcile.utils.datetime_util import ensure_utc, utc_now
|
|
43
45
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
|
44
46
|
from reconcile.utils.exceptions import (
|
|
45
47
|
AppInterfaceSettingsError,
|
|
@@ -74,6 +76,26 @@ INTEGRATION_VERSION = "0.1.0"
|
|
|
74
76
|
|
|
75
77
|
error_occurred = False
|
|
76
78
|
|
|
79
|
+
KeyType = TypeVar("KeyType")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def deep_update(
|
|
83
|
+
mapping: dict[KeyType, Any],
|
|
84
|
+
*updating_mappings: MutableMapping[KeyType, Any],
|
|
85
|
+
) -> dict[KeyType, Any]:
|
|
86
|
+
updated_mapping = mapping.copy()
|
|
87
|
+
for updating_mapping in updating_mappings:
|
|
88
|
+
for k, v in updating_mapping.items():
|
|
89
|
+
if (
|
|
90
|
+
k in updated_mapping
|
|
91
|
+
and isinstance(updated_mapping[k], dict)
|
|
92
|
+
and isinstance(v, dict)
|
|
93
|
+
):
|
|
94
|
+
updated_mapping[k] = deep_update(updated_mapping[k], v)
|
|
95
|
+
else:
|
|
96
|
+
updated_mapping[k] = v
|
|
97
|
+
return updated_mapping
|
|
98
|
+
|
|
77
99
|
|
|
78
100
|
def get_git_api(url: str) -> GithubRepositoryApi | GitLabApi:
|
|
79
101
|
"""Return GitHub/GitLab API based on url."""
|
|
@@ -122,15 +144,12 @@ class State(BaseModel):
|
|
|
122
144
|
SlackState = dict[str, dict[str, State]]
|
|
123
145
|
|
|
124
146
|
|
|
125
|
-
class WorkspaceSpec(BaseModel):
|
|
147
|
+
class WorkspaceSpec(BaseModel, arbitrary_types_allowed=True):
|
|
126
148
|
"""Slack workspace spec."""
|
|
127
149
|
|
|
128
150
|
slack: SlackApi
|
|
129
151
|
managed_usergroups: list[str] = []
|
|
130
152
|
|
|
131
|
-
class Config:
|
|
132
|
-
arbitrary_types_allowed = True
|
|
133
|
-
|
|
134
153
|
|
|
135
154
|
SlackMap = dict[str, WorkspaceSpec]
|
|
136
155
|
|
|
@@ -357,11 +376,11 @@ def get_slack_usernames_from_owners(
|
|
|
357
376
|
|
|
358
377
|
def get_slack_usernames_from_schedule(schedule: Iterable[ScheduleEntryV1]) -> list[str]:
|
|
359
378
|
"""Return list of usernames from all schedules."""
|
|
360
|
-
now =
|
|
379
|
+
now = utc_now()
|
|
361
380
|
all_slack_usernames: list[str] = []
|
|
362
381
|
for entry in schedule:
|
|
363
|
-
start = datetime.strptime(entry.start, DATE_FORMAT)
|
|
364
|
-
end = datetime.strptime(entry.end, DATE_FORMAT)
|
|
382
|
+
start = ensure_utc(datetime.strptime(entry.start, DATE_FORMAT)) # noqa: DTZ007
|
|
383
|
+
end = ensure_utc(datetime.strptime(entry.end, DATE_FORMAT)) # noqa: DTZ007
|
|
365
384
|
if start <= now <= end:
|
|
366
385
|
all_slack_usernames.extend(get_slack_username(u) for u in entry.users)
|
|
367
386
|
return all_slack_usernames
|
|
@@ -819,7 +838,9 @@ def run(
|
|
|
819
838
|
desired_usergroup_name=usergroup_name,
|
|
820
839
|
)
|
|
821
840
|
# merge the two desired states recursively
|
|
822
|
-
desired_state =
|
|
841
|
+
desired_state = datatransformation.deep_merge(
|
|
842
|
+
desired_state, desired_state_cluster_usergroups
|
|
843
|
+
)
|
|
823
844
|
|
|
824
845
|
runner_params: RunnerParams = {
|
|
825
846
|
"dry_run": dry_run,
|
|
@@ -891,10 +912,10 @@ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
|
|
891
912
|
if role.tag_on_cluster_updates is not False
|
|
892
913
|
]
|
|
893
914
|
return {
|
|
894
|
-
"permissions": [p.
|
|
915
|
+
"permissions": [p.model_dump() for p in get_permissions(gqlapi.query)],
|
|
895
916
|
"pagerduty_instances": [
|
|
896
|
-
p.
|
|
917
|
+
p.model_dump() for p in get_pagerduty_instances(gqlapi.query)
|
|
897
918
|
],
|
|
898
|
-
"users": [u.
|
|
899
|
-
"clusters": [c.
|
|
919
|
+
"users": [u.model_dump() for u in users],
|
|
920
|
+
"clusters": [c.model_dump() for c in get_clusters(gqlapi.query)],
|
|
900
921
|
}
|
reconcile/sql_query.py
CHANGED
reconcile/status.py
CHANGED
|
@@ -11,7 +11,7 @@ class ExitCodes:
|
|
|
11
11
|
class _RunningState:
|
|
12
12
|
_state: dict[Any, Any] = {}
|
|
13
13
|
|
|
14
|
-
def __init__(self):
|
|
14
|
+
def __init__(self) -> None:
|
|
15
15
|
self.__dict__ = self._state
|
|
16
16
|
|
|
17
17
|
|
|
@@ -22,7 +22,7 @@ class RunningState(_RunningState):
|
|
|
22
22
|
by the callers.
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
-
def __getattr__(self, item):
|
|
25
|
+
def __getattr__(self, item: str) -> None:
|
|
26
26
|
"""
|
|
27
27
|
Default value for attributes not explicitly created is None.
|
|
28
28
|
"""
|
reconcile/status_board.py
CHANGED
|
@@ -52,7 +52,7 @@ class AbstractStatusBoard(ABC, BaseModel):
|
|
|
52
52
|
"""Abstract class for upgrade policies
|
|
53
53
|
Used to create and delete upgrade policies in OCM."""
|
|
54
54
|
|
|
55
|
-
id: str | None
|
|
55
|
+
id: str | None = None
|
|
56
56
|
name: str
|
|
57
57
|
fullname: str
|
|
58
58
|
|
|
@@ -88,7 +88,7 @@ class AbstractStatusBoard(ABC, BaseModel):
|
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
class Product(AbstractStatusBoard):
|
|
91
|
-
applications: list["Application"] | None
|
|
91
|
+
applications: list["Application"] | None = None
|
|
92
92
|
|
|
93
93
|
def create(self, ocm: OCMBaseClient) -> None:
|
|
94
94
|
spec = self.to_ocm_spec()
|
|
@@ -121,7 +121,7 @@ class Product(AbstractStatusBoard):
|
|
|
121
121
|
|
|
122
122
|
class Application(AbstractStatusBoard):
|
|
123
123
|
product: Product
|
|
124
|
-
services: list["Service"] | None
|
|
124
|
+
services: list["Service"] | None = None
|
|
125
125
|
|
|
126
126
|
def create(self, ocm: OCMBaseClient) -> None:
|
|
127
127
|
if self.product.id:
|
|
@@ -214,9 +214,9 @@ class Service(AbstractStatusBoard):
|
|
|
214
214
|
|
|
215
215
|
|
|
216
216
|
# Resolve forward references after class definitions
|
|
217
|
-
Product.
|
|
218
|
-
Application.
|
|
219
|
-
Service.
|
|
217
|
+
Product.model_rebuild()
|
|
218
|
+
Application.model_rebuild()
|
|
219
|
+
Service.model_rebuild()
|
|
220
220
|
|
|
221
221
|
|
|
222
222
|
class UpdateNotSupportedError(Exception):
|
|
@@ -29,12 +29,12 @@ class AtlassianRawComponent(BaseModel):
|
|
|
29
29
|
|
|
30
30
|
id: str
|
|
31
31
|
name: str
|
|
32
|
-
description: str | None
|
|
32
|
+
description: str | None = None
|
|
33
33
|
position: int
|
|
34
34
|
status: str
|
|
35
|
-
automation_email: str | None
|
|
36
|
-
group_id: str | None
|
|
37
|
-
group: bool | None
|
|
35
|
+
automation_email: str | None = None
|
|
36
|
+
group_id: str | None = None
|
|
37
|
+
group: bool | None = None
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class AtlassianRawMaintenanceUpdate(BaseModel):
|
|
@@ -56,9 +56,9 @@ class AtlassianRawMaintenance(BaseModel):
|
|
|
56
56
|
scheduled_until: str
|
|
57
57
|
incident_updates: list[AtlassianRawMaintenanceUpdate]
|
|
58
58
|
components: list[AtlassianRawComponent]
|
|
59
|
-
auto_transition_deliver_notifications_at_end: bool | None
|
|
60
|
-
auto_transition_deliver_notifications_at_start: bool | None
|
|
61
|
-
scheduled_remind_prior: bool | None
|
|
59
|
+
auto_transition_deliver_notifications_at_end: bool | None = None
|
|
60
|
+
auto_transition_deliver_notifications_at_start: bool | None = None
|
|
61
|
+
scheduled_remind_prior: bool | None = None
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
class AtlassianAPI:
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import sys
|
|
3
|
-
from datetime import
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
4
|
|
|
5
5
|
from reconcile.slack_base import slackapi_from_queries
|
|
6
6
|
from reconcile.statuspage.atlassian import AtlassianStatusPageProvider
|
|
7
7
|
from reconcile.statuspage.integration import get_binding_state, get_status_pages
|
|
8
8
|
from reconcile.statuspage.page import StatusMaintenance
|
|
9
9
|
from reconcile.statuspage.state import S3ComponentBindingState
|
|
10
|
+
from reconcile.utils.datetime_util import utc_now
|
|
10
11
|
from reconcile.utils.differ import diff_iterables
|
|
11
12
|
from reconcile.utils.runtime.integration import (
|
|
12
13
|
NoParams,
|
|
@@ -52,7 +53,7 @@ class StatusPageMaintenancesIntegration(QontractReconcileIntegration[NoParams]):
|
|
|
52
53
|
desired_state: list[StatusMaintenance],
|
|
53
54
|
binding_state: S3ComponentBindingState,
|
|
54
55
|
) -> None:
|
|
55
|
-
now =
|
|
56
|
+
now = utc_now()
|
|
56
57
|
slack = slackapi_from_queries(QONTRACT_INTEGRATION, init_usergroups=False)
|
|
57
58
|
for m in desired_state:
|
|
58
59
|
scheduled_start = m.schedule_start
|
|
@@ -68,7 +69,7 @@ class StatusPageMaintenancesIntegration(QontractReconcileIntegration[NoParams]):
|
|
|
68
69
|
def run(self, dry_run: bool = False) -> None:
|
|
69
70
|
binding_state = get_binding_state(self.name, self.secret_reader)
|
|
70
71
|
pages = get_status_pages()
|
|
71
|
-
now =
|
|
72
|
+
now = utc_now()
|
|
72
73
|
|
|
73
74
|
error = False
|
|
74
75
|
for p in pages:
|
reconcile/statuspage/page.py
CHANGED
|
@@ -19,19 +19,17 @@ from reconcile.statuspage.status import (
|
|
|
19
19
|
PROVIDER_NAME = "statuspage"
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class StatusComponent(BaseModel):
|
|
22
|
+
class StatusComponent(BaseModel, arbitrary_types_allowed=True):
|
|
23
23
|
"""
|
|
24
24
|
Represents a status page component from the desired state.
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
27
|
name: str
|
|
28
28
|
display_name: str
|
|
29
|
-
description: str | None
|
|
30
|
-
group_name: str | None
|
|
29
|
+
description: str | None = None
|
|
30
|
+
group_name: str | None = None
|
|
31
|
+
# Status provider configs hold different ways for a component to determine its status
|
|
31
32
|
status_provider_configs: list[StatusProvider]
|
|
32
|
-
"""
|
|
33
|
-
Status provider configs hold different ways for a component to determine its status
|
|
34
|
-
"""
|
|
35
33
|
|
|
36
34
|
def status_management_enabled(self) -> bool:
|
|
37
35
|
"""
|
|
@@ -49,9 +47,6 @@ class StatusComponent(BaseModel):
|
|
|
49
47
|
return "operational"
|
|
50
48
|
return None
|
|
51
49
|
|
|
52
|
-
class Config:
|
|
53
|
-
arbitrary_types_allowed = True
|
|
54
|
-
|
|
55
50
|
def __eq__(self, other: object) -> bool:
|
|
56
51
|
if not isinstance(other, StatusComponent):
|
|
57
52
|
raise NotImplementedError("Cannot compare to non StatusComponent objects.")
|
reconcile/statuspage/status.py
CHANGED
|
@@ -2,18 +2,15 @@ from abc import (
|
|
|
2
2
|
ABC,
|
|
3
3
|
abstractmethod,
|
|
4
4
|
)
|
|
5
|
-
from datetime import
|
|
6
|
-
UTC,
|
|
7
|
-
datetime,
|
|
8
|
-
)
|
|
5
|
+
from datetime import datetime
|
|
9
6
|
|
|
10
|
-
from dateutil.parser import isoparse
|
|
11
7
|
from pydantic import BaseModel
|
|
12
8
|
|
|
13
9
|
from reconcile.gql_definitions.statuspage.statuspages import (
|
|
14
10
|
ManualStatusProviderV1,
|
|
15
11
|
StatusProviderV1,
|
|
16
12
|
)
|
|
13
|
+
from reconcile.utils.datetime_util import from_utc_iso_format, utc_now
|
|
17
14
|
|
|
18
15
|
# This module defines the interface for status providers for components on status
|
|
19
16
|
# pages. A status provider is responsible for determining the status of a component.
|
|
@@ -70,7 +67,7 @@ class ManualStatusProvider(StatusProvider, BaseModel):
|
|
|
70
67
|
raise ValueError(
|
|
71
68
|
"manual component status time window is invalid: end before start"
|
|
72
69
|
)
|
|
73
|
-
now =
|
|
70
|
+
now = utc_now()
|
|
74
71
|
if self.start and now < self.start:
|
|
75
72
|
return False
|
|
76
73
|
return not (self.end and self.end < now)
|
|
@@ -84,8 +81,8 @@ def build_status_provider_config(
|
|
|
84
81
|
provider specific implementation that provides the status resolution logic.
|
|
85
82
|
"""
|
|
86
83
|
if isinstance(cfg, ManualStatusProviderV1):
|
|
87
|
-
start =
|
|
88
|
-
end =
|
|
84
|
+
start = from_utc_iso_format(cfg.manual.q_from) if cfg.manual.q_from else None
|
|
85
|
+
end = from_utc_iso_format(cfg.manual.until) if cfg.manual.until else None
|
|
89
86
|
return ManualStatusProvider(
|
|
90
87
|
component_status=cfg.manual.component_status,
|
|
91
88
|
start=start,
|
|
@@ -47,7 +47,7 @@ rosa create cluster -y --cluster-name={{ cluster_name }} \
|
|
|
47
47
|
--service-cidr {{ cluster.network.service }} \
|
|
48
48
|
--pod-cidr {{ cluster.network.pod }} \
|
|
49
49
|
--host-prefix 23 \
|
|
50
|
-
--replicas
|
|
50
|
+
--replicas 3 \
|
|
51
51
|
--compute-machine-type {{ cluster.machine_pools[0].instance_type }} \
|
|
52
52
|
{% if cluster.spec.disable_user_workload_monitoring -%}
|
|
53
53
|
--disable-workload-monitoring \
|
|
@@ -55,4 +55,8 @@ rosa create cluster -y --cluster-name={{ cluster_name }} \
|
|
|
55
55
|
{% if cluster.spec.provision_shard_id -%}
|
|
56
56
|
--properties provision_shard_id:{{ cluster.spec.provision_shard_id }} \
|
|
57
57
|
{% endif -%}
|
|
58
|
+
{% if cluster.spec.fips -%}
|
|
59
|
+
--fips \
|
|
60
|
+
{% endif -%}
|
|
58
61
|
--channel-group {{ cluster.spec.channel }}
|
|
62
|
+
|
|
@@ -47,7 +47,7 @@ rosa create cluster --cluster-name={{ cluster_name }} \
|
|
|
47
47
|
--service-cidr {{ cluster.network.service }} \
|
|
48
48
|
--pod-cidr {{ cluster.network.pod }} \
|
|
49
49
|
--host-prefix 23 \
|
|
50
|
-
--replicas
|
|
50
|
+
--replicas 3 \
|
|
51
51
|
--compute-machine-type {{ cluster.machine_pools[0].instance_type }} \
|
|
52
52
|
{% if cluster.spec.private -%}
|
|
53
53
|
--private \
|
|
@@ -59,4 +59,7 @@ rosa create cluster --cluster-name={{ cluster_name }} \
|
|
|
59
59
|
{% if cluster.spec.provision_shard_id -%}
|
|
60
60
|
--properties provision_shard_id:{{ cluster.spec.provision_shard_id }} \
|
|
61
61
|
{% endif -%}
|
|
62
|
+
{% if cluster.spec.fips -%}
|
|
63
|
+
--fips \
|
|
64
|
+
{% endif -%}
|
|
62
65
|
--channel-group {{ cluster.spec.channel }}
|
|
@@ -108,14 +108,14 @@ class TemplateRenderingMR(MergeRequestBase):
|
|
|
108
108
|
if content.is_new:
|
|
109
109
|
gitlab_cli.create_file(
|
|
110
110
|
branch_name=self.branch,
|
|
111
|
-
file_path=
|
|
111
|
+
file_path=content.path.lstrip("/"),
|
|
112
112
|
commit_message="termplate rendering output",
|
|
113
113
|
content=content.content,
|
|
114
114
|
)
|
|
115
115
|
else:
|
|
116
116
|
gitlab_cli.update_file(
|
|
117
117
|
branch_name=self.branch,
|
|
118
|
-
file_path=
|
|
118
|
+
file_path=content.path.lstrip("/"),
|
|
119
119
|
commit_message="termplate rendering output",
|
|
120
120
|
content=content.content,
|
|
121
121
|
)
|
|
@@ -18,7 +18,7 @@ from reconcile.utils.secret_reader import SecretReaderBase
|
|
|
18
18
|
|
|
19
19
|
class TemplateData(BaseModel):
|
|
20
20
|
variables: dict[str, Any]
|
|
21
|
-
current: dict[str, Any] | None
|
|
21
|
+
current: dict[str, Any] | None = None
|
|
22
22
|
current_with_explicit_start: bool | None = False
|
|
23
23
|
|
|
24
24
|
|
|
@@ -26,7 +26,7 @@ class TemplatePatch(Protocol):
|
|
|
26
26
|
path: str
|
|
27
27
|
identifier: str | None
|
|
28
28
|
|
|
29
|
-
def
|
|
29
|
+
def model_dump(self) -> dict[str, str]: ...
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class Template(Protocol):
|
|
@@ -36,7 +36,7 @@ class Template(Protocol):
|
|
|
36
36
|
template: str
|
|
37
37
|
overwrite: bool | None
|
|
38
38
|
|
|
39
|
-
def
|
|
39
|
+
def model_dump(self) -> dict[str, str]: ...
|
|
40
40
|
|
|
41
41
|
@property
|
|
42
42
|
def patch(self) -> TemplatePatch | None:
|
reconcile/templating/renderer.py
CHANGED
|
@@ -33,6 +33,7 @@ from reconcile.utils import gql
|
|
|
33
33
|
from reconcile.utils.git import checkout, clone
|
|
34
34
|
from reconcile.utils.gql import GqlApi
|
|
35
35
|
from reconcile.utils.jinja2.utils import TemplateRenderOptions, process_jinja2_template
|
|
36
|
+
from reconcile.utils.json import json_dumps
|
|
36
37
|
from reconcile.utils.ruamel import create_ruamel_instance
|
|
37
38
|
from reconcile.utils.runtime.integration import (
|
|
38
39
|
PydanticRunParams,
|
|
@@ -95,18 +96,16 @@ class LocalFilePersistence(FilePersistence):
|
|
|
95
96
|
This class provides a simple file persistence implementation for local files.
|
|
96
97
|
"""
|
|
97
98
|
|
|
98
|
-
def __init__(self, dry_run: bool,
|
|
99
|
+
def __init__(self, dry_run: bool, app_interface_root_path: str) -> None:
|
|
99
100
|
super().__init__(dry_run)
|
|
100
|
-
|
|
101
|
-
raise ValueError("app_interface_data_path should end with /data")
|
|
102
|
-
self.app_interface_data_path = app_interface_data_path
|
|
101
|
+
self.app_interface_root_path = app_interface_root_path
|
|
103
102
|
|
|
104
103
|
def read(self, path: str) -> str | None:
|
|
105
|
-
return self._read_local_file(join_path(self.
|
|
104
|
+
return self._read_local_file(join_path(self.app_interface_root_path, path))
|
|
106
105
|
|
|
107
106
|
def flush(self) -> None:
|
|
108
107
|
for output in self.outputs:
|
|
109
|
-
filepath = Path(join_path(self.
|
|
108
|
+
filepath = Path(join_path(self.app_interface_root_path, output.path))
|
|
110
109
|
filepath.parent.mkdir(parents=True, exist_ok=True)
|
|
111
110
|
filepath.write_text(output.content, encoding="utf-8")
|
|
112
111
|
|
|
@@ -159,7 +158,7 @@ class ClonedRepoGitlabPersistence(FilePersistence):
|
|
|
159
158
|
self, dry_run: bool, local_path: str, vcs: VCS, mr_manager: MergeRequestManager
|
|
160
159
|
):
|
|
161
160
|
super().__init__(dry_run)
|
|
162
|
-
self.local_path =
|
|
161
|
+
self.local_path = local_path
|
|
163
162
|
self.vcs = vcs
|
|
164
163
|
self.mr_manager = mr_manager
|
|
165
164
|
|
|
@@ -217,7 +216,7 @@ def unpack_static_variables(
|
|
|
217
216
|
each: dict[str, Any],
|
|
218
217
|
) -> dict:
|
|
219
218
|
return {
|
|
220
|
-
k: json.loads(process_jinja2_template(body=
|
|
219
|
+
k: json.loads(process_jinja2_template(body=json_dumps(v), vars={"each": each}))
|
|
221
220
|
for k, v in (collection_variables.static or {}).items()
|
|
222
221
|
}
|
|
223
222
|
|
|
@@ -240,8 +239,8 @@ def unpack_dynamic_variables(
|
|
|
240
239
|
|
|
241
240
|
class TemplateRendererIntegrationParams(PydanticRunParams):
|
|
242
241
|
clone_repo: bool = False
|
|
243
|
-
|
|
244
|
-
template_collection_name: str | None
|
|
242
|
+
app_interface_root_path: str | None = None
|
|
243
|
+
template_collection_name: str | None = None
|
|
245
244
|
|
|
246
245
|
|
|
247
246
|
def join_path(base: str, sub: str) -> str:
|
|
@@ -367,10 +366,10 @@ class TemplateRendererIntegration(QontractReconcileIntegration):
|
|
|
367
366
|
persistence: FilePersistence
|
|
368
367
|
ruaml_instance = create_ruamel_instance(explicit_start=True)
|
|
369
368
|
|
|
370
|
-
if not self.params.clone_repo and self.params.
|
|
369
|
+
if not self.params.clone_repo and self.params.app_interface_root_path:
|
|
371
370
|
persistence = LocalFilePersistence(
|
|
372
371
|
dry_run=dry_run,
|
|
373
|
-
|
|
372
|
+
app_interface_root_path=self.params.app_interface_root_path,
|
|
374
373
|
)
|
|
375
374
|
self.reconcile(persistence, ruaml_instance)
|
|
376
375
|
|
|
@@ -411,4 +410,4 @@ class TemplateRendererIntegration(QontractReconcileIntegration):
|
|
|
411
410
|
self.reconcile(persistence, ruaml_instance)
|
|
412
411
|
|
|
413
412
|
else:
|
|
414
|
-
raise ValueError("App-interface-
|
|
413
|
+
raise ValueError("App-interface-root-path must be set")
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import sys
|
|
3
3
|
from collections.abc import (
|
|
4
|
+
Callable,
|
|
4
5
|
Iterable,
|
|
5
6
|
Mapping,
|
|
6
7
|
)
|
|
@@ -8,6 +9,7 @@ from typing import Any
|
|
|
8
9
|
|
|
9
10
|
from reconcile import queries
|
|
10
11
|
from reconcile.status import ExitCodes
|
|
12
|
+
from reconcile.typed_queries.external_resources import get_settings
|
|
11
13
|
from reconcile.utils import dnsutils
|
|
12
14
|
from reconcile.utils.aws_api import AWSApi
|
|
13
15
|
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
|
@@ -25,8 +27,10 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
|
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
def build_desired_state(
|
|
28
|
-
zones: Iterable[Mapping
|
|
29
|
-
|
|
30
|
+
zones: Iterable[Mapping[str, Any]],
|
|
31
|
+
all_accounts: Iterable[Mapping[str, Any]],
|
|
32
|
+
settings: Mapping[str, Any],
|
|
33
|
+
) -> list[dict[str, Any]]:
|
|
30
34
|
"""
|
|
31
35
|
Build the desired state from the app-interface resources
|
|
32
36
|
|
|
@@ -36,7 +40,7 @@ def build_desired_state(
|
|
|
36
40
|
:rtype: list of dict
|
|
37
41
|
"""
|
|
38
42
|
|
|
39
|
-
desired_state = []
|
|
43
|
+
desired_state: list[dict[str, Any]] = []
|
|
40
44
|
for zone in zones:
|
|
41
45
|
account = zone["account"]
|
|
42
46
|
account_name = account["name"]
|
|
@@ -208,8 +212,8 @@ def run(
|
|
|
208
212
|
enable_deletion: bool = True,
|
|
209
213
|
thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
|
|
210
214
|
account_name: str | None = None,
|
|
211
|
-
defer=None,
|
|
212
|
-
):
|
|
215
|
+
defer: Callable | None = None,
|
|
216
|
+
) -> None:
|
|
213
217
|
settings = queries.get_app_interface_settings()
|
|
214
218
|
zones = queries.get_dns_zones(account_name=account_name)
|
|
215
219
|
|
|
@@ -224,13 +228,18 @@ def run(
|
|
|
224
228
|
f"No participating AWS accounts found, consider disabling this integration, account name: {account_name}"
|
|
225
229
|
)
|
|
226
230
|
return
|
|
227
|
-
|
|
231
|
+
try:
|
|
232
|
+
default_tags = get_settings().default_tags
|
|
233
|
+
except ValueError:
|
|
234
|
+
# no external resources settings found
|
|
235
|
+
default_tags = None
|
|
228
236
|
ts = Terrascript(
|
|
229
237
|
QONTRACT_INTEGRATION,
|
|
230
238
|
"",
|
|
231
239
|
thread_pool_size,
|
|
232
240
|
participating_accounts,
|
|
233
241
|
settings=settings,
|
|
242
|
+
default_tags=default_tags,
|
|
234
243
|
)
|
|
235
244
|
|
|
236
245
|
desired_state = build_desired_state(zones, all_accounts, settings)
|
|
@@ -255,7 +264,8 @@ def run(
|
|
|
255
264
|
if tf is None:
|
|
256
265
|
sys.exit(ExitCodes.ERROR)
|
|
257
266
|
|
|
258
|
-
defer
|
|
267
|
+
if defer:
|
|
268
|
+
defer(tf.cleanup)
|
|
259
269
|
|
|
260
270
|
_, err = tf.plan(enable_deletion)
|
|
261
271
|
if err:
|
|
@@ -269,7 +279,7 @@ def run(
|
|
|
269
279
|
sys.exit(ExitCodes.ERROR)
|
|
270
280
|
|
|
271
281
|
|
|
272
|
-
def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
|
|
282
|
+
def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
|
273
283
|
return {
|
|
274
284
|
"zones": queries.get_dns_zones(),
|
|
275
285
|
}
|
|
@@ -155,7 +155,7 @@ class TerraformCloudflareDNSIntegration(
|
|
|
155
155
|
|
|
156
156
|
accts_per_zone = []
|
|
157
157
|
for zone in query_zones.zones or []:
|
|
158
|
-
acct = zone.account.
|
|
158
|
+
acct = zone.account.model_dump(by_alias=True)
|
|
159
159
|
acct["name"] = f"{zone.account.name}-{zone.identifier}"
|
|
160
160
|
accts_per_zone.append(acct)
|
|
161
161
|
|
|
@@ -369,11 +369,11 @@ def cloudflare_dns_zone_to_external_resource(
|
|
|
369
369
|
provision_provider=DEFAULT_PROVISIONER_PROVIDER,
|
|
370
370
|
provisioner={"name": f"{zone.account.name}-{zone.identifier}"},
|
|
371
371
|
namespace=DEFAULT_NAMESPACE,
|
|
372
|
-
resource=zone.
|
|
372
|
+
resource=zone.model_dump(by_alias=True, exclude=DEFAULT_EXCLUDE_KEY),
|
|
373
373
|
)
|
|
374
374
|
external_resource_spec.resource["provider"] = DEFAULT_PROVIDER
|
|
375
375
|
external_resource_spec.resource["records"] = [
|
|
376
|
-
record.
|
|
376
|
+
record.model_dump(by_alias=True) for record in zone.records or []
|
|
377
377
|
]
|
|
378
378
|
external_resource_specs.append(external_resource_spec)
|
|
379
379
|
return external_resource_specs
|