qontract-reconcile 0.10.2.dev361__py3-none-any.whl → 0.10.2.dev474__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qontract_reconcile-0.10.2.dev361.dist-info → qontract_reconcile-0.10.2.dev474.dist-info}/METADATA +14 -13
- {qontract_reconcile-0.10.2.dev361.dist-info → qontract_reconcile-0.10.2.dev474.dist-info}/RECORD +371 -364
- {qontract_reconcile-0.10.2.dev361.dist-info → qontract_reconcile-0.10.2.dev474.dist-info}/WHEEL +1 -1
- reconcile/acs_rbac.py +2 -2
- reconcile/aus/advanced_upgrade_service.py +18 -12
- reconcile/aus/aus_sts_gate_handler.py +59 -0
- reconcile/aus/base.py +137 -34
- 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_gate_approver.py +1 -16
- reconcile/aus/version_gates/sts_version_gate_handler.py +5 -72
- reconcile/automated_actions/config/integration.py +16 -4
- reconcile/aws_account_manager/integration.py +21 -9
- reconcile/aws_account_manager/reconciler.py +3 -3
- reconcile/aws_account_manager/utils.py +1 -1
- 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 +1 -1
- reconcile/aws_iam_keys.py +1 -0
- reconcile/aws_saml_idp/integration.py +12 -4
- reconcile/aws_saml_roles/integration.py +30 -23
- reconcile/aws_version_sync/integration.py +6 -12
- reconcile/change_owners/README.md +1 -1
- reconcile/change_owners/bundle.py +3 -3
- reconcile/change_owners/change_log_tracking.py +3 -2
- reconcile/change_owners/change_owners.py +108 -42
- reconcile/change_owners/decision.py +1 -1
- reconcile/change_owners/diff.py +0 -2
- reconcile/checkpoint.py +11 -3
- reconcile/cli.py +94 -11
- 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 +8 -8
- reconcile/external_resources/factories.py +4 -6
- reconcile/external_resources/integration.py +1 -1
- reconcile/external_resources/manager.py +8 -6
- reconcile/external_resources/meta.py +0 -1
- reconcile/external_resources/metrics.py +1 -1
- reconcile/external_resources/model.py +19 -15
- reconcile/external_resources/reconciler.py +7 -4
- reconcile/external_resources/secrets_sync.py +6 -10
- reconcile/external_resources/state.py +26 -16
- reconcile/fleet_labeler/integration.py +1 -1
- reconcile/gabi_authorized_users.py +5 -2
- 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_owners.py +15 -11
- reconcile/gitlab_permissions.py +8 -12
- reconcile/glitchtip_project_alerts/integration.py +3 -1
- reconcile/gql_definitions/acs/acs_instances.py +5 -5
- reconcile/gql_definitions/acs/acs_policies.py +5 -5
- reconcile/gql_definitions/acs/acs_rbac.py +5 -5
- reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +5 -5
- reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +5 -5
- reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +5 -5
- reconcile/gql_definitions/app_sre_tekton_access_revalidation/roles.py +5 -5
- reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py +5 -5
- reconcile/gql_definitions/automated_actions/instance.py +46 -7
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +14 -5
- reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +27 -66
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_saml_roles/roles.py +5 -5
- reconcile/gql_definitions/aws_version_sync/clusters.py +5 -5
- reconcile/gql_definitions/aws_version_sync/namespaces.py +5 -5
- reconcile/gql_definitions/change_owners/queries/change_types.py +5 -5
- reconcile/gql_definitions/change_owners/queries/self_service_roles.py +5 -5
- reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +5 -5
- reconcile/gql_definitions/common/alerting_services_settings.py +5 -5
- reconcile/gql_definitions/common/app_code_component_repos.py +5 -5
- reconcile/gql_definitions/common/app_interface_custom_messages.py +5 -5
- reconcile/gql_definitions/common/app_interface_dms_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_repo_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_roles.py +5 -5
- reconcile/gql_definitions/common/app_interface_state_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_vault_settings.py +5 -5
- reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +5 -5
- reconcile/gql_definitions/common/apps.py +5 -5
- reconcile/gql_definitions/common/aws_vpc_requests.py +18 -5
- reconcile/gql_definitions/common/aws_vpcs.py +5 -5
- reconcile/gql_definitions/common/clusters.py +7 -5
- reconcile/gql_definitions/common/clusters_minimal.py +5 -5
- reconcile/gql_definitions/common/clusters_with_dms.py +5 -5
- reconcile/gql_definitions/common/clusters_with_peering.py +5 -5
- reconcile/gql_definitions/common/github_orgs.py +5 -5
- reconcile/gql_definitions/common/jira_settings.py +5 -5
- reconcile/gql_definitions/common/jiralert_settings.py +5 -5
- reconcile/gql_definitions/common/ldap_settings.py +5 -5
- reconcile/gql_definitions/common/namespaces.py +5 -5
- reconcile/gql_definitions/common/namespaces_minimal.py +7 -5
- reconcile/gql_definitions/common/ocm_env_telemeter.py +5 -5
- reconcile/gql_definitions/common/ocm_environments.py +5 -5
- reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
- reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -5
- reconcile/gql_definitions/common/pipeline_providers.py +5 -5
- reconcile/gql_definitions/common/quay_instances.py +5 -5
- reconcile/gql_definitions/common/quay_orgs.py +5 -5
- reconcile/gql_definitions/common/reserved_networks.py +5 -5
- reconcile/gql_definitions/common/rhcs_provider_settings.py +5 -5
- reconcile/gql_definitions/common/saas_files.py +5 -5
- reconcile/gql_definitions/common/saas_target_namespaces.py +5 -5
- reconcile/gql_definitions/common/saasherder_settings.py +5 -5
- reconcile/gql_definitions/common/slack_workspaces.py +5 -5
- reconcile/gql_definitions/common/smtp_client_settings.py +5 -5
- reconcile/gql_definitions/common/state_aws_account.py +5 -5
- reconcile/gql_definitions/common/users.py +5 -5
- reconcile/gql_definitions/common/users_with_paths.py +5 -5
- reconcile/gql_definitions/cost_report/app_names.py +5 -5
- reconcile/gql_definitions/cost_report/cost_namespaces.py +5 -5
- reconcile/gql_definitions/cost_report/settings.py +5 -5
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +5 -5
- reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +5 -5
- reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +5 -5
- reconcile/gql_definitions/email_sender/apps.py +5 -5
- reconcile/gql_definitions/email_sender/emails.py +5 -5
- reconcile/gql_definitions/email_sender/users.py +5 -5
- reconcile/gql_definitions/endpoints_discovery/apps.py +5 -5
- reconcile/gql_definitions/external_resources/aws_accounts.py +5 -5
- reconcile/gql_definitions/external_resources/external_resources_modules.py +5 -5
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +38 -7
- reconcile/gql_definitions/external_resources/external_resources_settings.py +5 -5
- reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +5 -5
- reconcile/gql_definitions/fleet_labeler/fleet_labels.py +5 -5
- reconcile/gql_definitions/fragments/aus_organization.py +5 -5
- reconcile/gql_definitions/fragments/aws_account_common.py +7 -5
- reconcile/gql_definitions/fragments/aws_account_managed.py +5 -5
- reconcile/gql_definitions/fragments/aws_account_sso.py +5 -5
- reconcile/gql_definitions/fragments/aws_infra_management_account.py +5 -5
- reconcile/gql_definitions/fragments/aws_organization.py +33 -0
- reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
- reconcile/gql_definitions/fragments/aws_vpc_request.py +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 +5 -5
- reconcile/gql_definitions/gcp/gcp_projects.py +5 -5
- reconcile/gql_definitions/gitlab_members/gitlab_instances.py +5 -5
- reconcile/gql_definitions/gitlab_members/permissions.py +5 -5
- reconcile/gql_definitions/glitchtip/glitchtip_instance.py +5 -5
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +5 -5
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +5 -5
- reconcile/gql_definitions/integrations/integrations.py +5 -5
- reconcile/gql_definitions/introspection.json +775 -136
- reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +5 -5
- reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +5 -5
- reconcile/gql_definitions/jira/jira_servers.py +5 -5
- reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +9 -5
- reconcile/gql_definitions/jumphosts/jumphosts.py +5 -5
- reconcile/gql_definitions/ldap_groups/roles.py +5 -5
- reconcile/gql_definitions/ldap_groups/settings.py +5 -5
- reconcile/gql_definitions/maintenance/maintenances.py +5 -5
- reconcile/gql_definitions/membershipsources/roles.py +5 -5
- reconcile/gql_definitions/ocm_labels/clusters.py +5 -5
- reconcile/gql_definitions/ocm_labels/organizations.py +5 -5
- reconcile/gql_definitions/openshift_cluster_bots/clusters.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_groups.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_roles.py +5 -5
- reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +5 -5
- reconcile/gql_definitions/quay_membership/quay_membership.py +5 -5
- reconcile/gql_definitions/rhcs/certs.py +25 -79
- reconcile/gql_definitions/rhcs/openshift_resource_rhcs_cert.py +43 -0
- reconcile/gql_definitions/rhidp/organizations.py +5 -5
- reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +5 -5
- reconcile/gql_definitions/service_dependencies/service_dependencies.py +5 -5
- reconcile/gql_definitions/sharding/aws_accounts.py +5 -5
- reconcile/gql_definitions/sharding/ocm_organization.py +5 -5
- reconcile/gql_definitions/skupper_network/site_controller_template.py +5 -5
- reconcile/gql_definitions/skupper_network/skupper_networks.py +5 -5
- reconcile/gql_definitions/slack_usergroups/clusters.py +5 -5
- reconcile/gql_definitions/slack_usergroups/permissions.py +5 -5
- reconcile/gql_definitions/slack_usergroups/users.py +5 -5
- reconcile/gql_definitions/slo_documents/slo_documents.py +5 -5
- reconcile/gql_definitions/status_board/status_board.py +5 -5
- reconcile/gql_definitions/statuspage/statuspages.py +5 -5
- reconcile/gql_definitions/templating/template_collection.py +5 -5
- reconcile/gql_definitions/templating/templates.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +5 -5
- reconcile/gql_definitions/terraform_init/aws_accounts.py +19 -5
- reconcile/gql_definitions/terraform_repo/terraform_repo.py +5 -5
- reconcile/gql_definitions/terraform_resources/database_access_manager.py +5 -5
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +37 -7
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +15 -5
- reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +5 -5
- reconcile/gql_definitions/vault_instances/vault_instances.py +5 -5
- reconcile/gql_definitions/vault_policies/vault_policies.py +5 -5
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +8 -5
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +6 -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 -57
- 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 -4
- reconcile/openshift_cluster_bots.py +1 -1
- reconcile/openshift_namespace_labels.py +1 -1
- reconcile/openshift_namespaces.py +96 -101
- reconcile/openshift_resources_base.py +6 -2
- reconcile/openshift_rhcs_certs.py +74 -37
- reconcile/openshift_rolebindings.py +7 -11
- reconcile/openshift_saas_deploy.py +4 -5
- reconcile/openshift_saas_deploy_change_tester.py +9 -7
- reconcile/openshift_saas_deploy_trigger_cleaner.py +3 -5
- reconcile/openshift_serviceaccount_tokens.py +2 -2
- reconcile/openshift_upgrade_watcher.py +4 -4
- reconcile/oum/labelset.py +5 -3
- reconcile/oum/models.py +1 -4
- reconcile/prometheus_rules_tester/integration.py +3 -3
- reconcile/quay_base.py +25 -6
- reconcile/quay_membership.py +55 -29
- reconcile/quay_mirror.py +1 -1
- reconcile/quay_mirror_org.py +6 -4
- reconcile/quay_permissions.py +81 -75
- reconcile/quay_repos.py +35 -37
- reconcile/queries.py +132 -1
- 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 +1 -1
- reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +1 -1
- reconcile/templating/lib/rendering.py +3 -3
- reconcile/templating/renderer.py +2 -2
- reconcile/templating/validator.py +4 -4
- 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 +6 -6
- 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/terraform_vpc_resources/merge_request.py +12 -2
- reconcile/terraform_vpc_resources/merge_request_manager.py +43 -19
- 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 +20 -15
- 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/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/environ.py +5 -0
- reconcile/utils/expiration.py +7 -3
- reconcile/utils/external_resource_spec.py +2 -0
- reconcile/utils/filtering.py +1 -1
- reconcile/utils/gitlab_api.py +19 -5
- reconcile/utils/glitchtip/client.py +6 -2
- reconcile/utils/glitchtip/models.py +25 -28
- reconcile/utils/gql.py +4 -7
- reconcile/utils/helpers.py +1 -1
- reconcile/utils/instrumented_wrappers.py +1 -1
- reconcile/utils/internal_groups/client.py +2 -2
- reconcile/utils/internal_groups/models.py +8 -17
- reconcile/utils/jinja2/utils.py +6 -101
- reconcile/utils/jira_client.py +82 -63
- reconcile/utils/jjb_client.py +26 -13
- reconcile/utils/jobcontroller/controller.py +2 -2
- reconcile/utils/jobcontroller/models.py +17 -1
- reconcile/utils/json.py +43 -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/app_interface_reporter.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 +252 -201
- reconcile/utils/oc_filters.py +3 -3
- reconcile/utils/ocm/addons.py +0 -1
- reconcile/utils/ocm/base.py +17 -20
- reconcile/utils/ocm/cluster_groups.py +1 -1
- reconcile/utils/ocm/identity_providers.py +2 -2
- reconcile/utils/ocm/labels.py +1 -1
- reconcile/utils/ocm/products.py +8 -8
- 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 +8 -3
- reconcile/utils/pagerduty_api.py +10 -7
- reconcile/utils/promotion_state.py +6 -11
- reconcile/utils/quay_api.py +74 -87
- reconcile/utils/raw_github_api.py +1 -1
- reconcile/utils/rhcsv2_certs.py +86 -23
- 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 +23 -20
- reconcile/utils/saasherder/saasherder.py +50 -27
- reconcile/utils/slack_api.py +2 -2
- reconcile/utils/sloth.py +171 -2
- reconcile/utils/structs.py +1 -1
- reconcile/utils/terraform_client.py +5 -4
- reconcile/utils/terrascript_aws_client.py +274 -124
- 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
- reconcile/vpc_peerings_validator.py +13 -0
- 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/qontract_cli.py +28 -17
- tools/template_validation.py +3 -1
- {qontract_reconcile-0.10.2.dev361.dist-info → qontract_reconcile-0.10.2.dev474.dist-info}/entry_points.txt +0 -0
reconcile/queries.py
CHANGED
|
@@ -477,6 +477,12 @@ AWS_ACCOUNTS_QUERY = """
|
|
|
477
477
|
integrations
|
|
478
478
|
}
|
|
479
479
|
deleteKeys
|
|
480
|
+
organization {
|
|
481
|
+
payerAccount {
|
|
482
|
+
organizationAccountTags
|
|
483
|
+
}
|
|
484
|
+
tags
|
|
485
|
+
}
|
|
480
486
|
{% if reset_passwords %}
|
|
481
487
|
resetPasswords {
|
|
482
488
|
user {
|
|
@@ -499,6 +505,12 @@ AWS_ACCOUNTS_QUERY = """
|
|
|
499
505
|
name
|
|
500
506
|
uid
|
|
501
507
|
supportedDeploymentRegions
|
|
508
|
+
organization {
|
|
509
|
+
payerAccount {
|
|
510
|
+
organizationAccountTags
|
|
511
|
+
}
|
|
512
|
+
tags
|
|
513
|
+
}
|
|
502
514
|
}
|
|
503
515
|
... on AWSAccountSharingOptionAMI_v1 {
|
|
504
516
|
regex
|
|
@@ -606,6 +618,12 @@ awsInfrastructureManagementAccounts {
|
|
|
606
618
|
version
|
|
607
619
|
format
|
|
608
620
|
}
|
|
621
|
+
organization {
|
|
622
|
+
payerAccount {
|
|
623
|
+
organizationAccountTags
|
|
624
|
+
}
|
|
625
|
+
tags
|
|
626
|
+
}
|
|
609
627
|
}
|
|
610
628
|
accessLevel
|
|
611
629
|
default
|
|
@@ -636,6 +654,12 @@ awsInfrastructureAccess {
|
|
|
636
654
|
version
|
|
637
655
|
format
|
|
638
656
|
}
|
|
657
|
+
organization {
|
|
658
|
+
payerAccount {
|
|
659
|
+
organizationAccountTags
|
|
660
|
+
}
|
|
661
|
+
tags
|
|
662
|
+
}
|
|
639
663
|
}
|
|
640
664
|
roles {
|
|
641
665
|
users {
|
|
@@ -745,6 +769,12 @@ CLUSTERS_QUERY = """
|
|
|
745
769
|
version
|
|
746
770
|
format
|
|
747
771
|
}
|
|
772
|
+
organization {
|
|
773
|
+
payerAccount {
|
|
774
|
+
organizationAccountTags
|
|
775
|
+
}
|
|
776
|
+
tags
|
|
777
|
+
}
|
|
748
778
|
rosa {
|
|
749
779
|
ocm_environments {
|
|
750
780
|
ocm {
|
|
@@ -773,6 +803,7 @@ CLUSTERS_QUERY = """
|
|
|
773
803
|
private
|
|
774
804
|
provision_shard_id
|
|
775
805
|
disable_user_workload_monitoring
|
|
806
|
+
fips
|
|
776
807
|
}
|
|
777
808
|
externalConfiguration {
|
|
778
809
|
labels
|
|
@@ -829,6 +860,12 @@ CLUSTERS_QUERY = """
|
|
|
829
860
|
version
|
|
830
861
|
format
|
|
831
862
|
}
|
|
863
|
+
organization {
|
|
864
|
+
payerAccount {
|
|
865
|
+
organizationAccountTags
|
|
866
|
+
}
|
|
867
|
+
tags
|
|
868
|
+
}
|
|
832
869
|
}
|
|
833
870
|
vpc_id
|
|
834
871
|
cidr_block
|
|
@@ -847,6 +884,12 @@ CLUSTERS_QUERY = """
|
|
|
847
884
|
version
|
|
848
885
|
format
|
|
849
886
|
}
|
|
887
|
+
organization {
|
|
888
|
+
payerAccount {
|
|
889
|
+
organizationAccountTags
|
|
890
|
+
}
|
|
891
|
+
tags
|
|
892
|
+
}
|
|
850
893
|
}
|
|
851
894
|
tags
|
|
852
895
|
}
|
|
@@ -861,6 +904,12 @@ CLUSTERS_QUERY = """
|
|
|
861
904
|
version
|
|
862
905
|
format
|
|
863
906
|
}
|
|
907
|
+
organization {
|
|
908
|
+
payerAccount {
|
|
909
|
+
organizationAccountTags
|
|
910
|
+
}
|
|
911
|
+
tags
|
|
912
|
+
}
|
|
864
913
|
}
|
|
865
914
|
tags
|
|
866
915
|
cidrBlock
|
|
@@ -889,6 +938,12 @@ CLUSTERS_QUERY = """
|
|
|
889
938
|
version
|
|
890
939
|
format
|
|
891
940
|
}
|
|
941
|
+
organization {
|
|
942
|
+
payerAccount {
|
|
943
|
+
organizationAccountTags
|
|
944
|
+
}
|
|
945
|
+
tags
|
|
946
|
+
}
|
|
892
947
|
}
|
|
893
948
|
}
|
|
894
949
|
accessLevel
|
|
@@ -914,6 +969,12 @@ CLUSTERS_QUERY = """
|
|
|
914
969
|
version
|
|
915
970
|
format
|
|
916
971
|
}
|
|
972
|
+
organization {
|
|
973
|
+
payerAccount {
|
|
974
|
+
organizationAccountTags
|
|
975
|
+
}
|
|
976
|
+
tags
|
|
977
|
+
}
|
|
917
978
|
}
|
|
918
979
|
}
|
|
919
980
|
}
|
|
@@ -1067,6 +1128,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1067
1128
|
version
|
|
1068
1129
|
format
|
|
1069
1130
|
}
|
|
1131
|
+
organization {
|
|
1132
|
+
payerAccount {
|
|
1133
|
+
organizationAccountTags
|
|
1134
|
+
}
|
|
1135
|
+
tags
|
|
1136
|
+
}
|
|
1070
1137
|
}
|
|
1071
1138
|
accessLevel
|
|
1072
1139
|
default
|
|
@@ -1088,6 +1155,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1088
1155
|
version
|
|
1089
1156
|
format
|
|
1090
1157
|
}
|
|
1158
|
+
organization {
|
|
1159
|
+
payerAccount {
|
|
1160
|
+
organizationAccountTags
|
|
1161
|
+
}
|
|
1162
|
+
tags
|
|
1163
|
+
}
|
|
1091
1164
|
}
|
|
1092
1165
|
}
|
|
1093
1166
|
}
|
|
@@ -1112,6 +1185,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1112
1185
|
version
|
|
1113
1186
|
format
|
|
1114
1187
|
}
|
|
1188
|
+
organization {
|
|
1189
|
+
payerAccount {
|
|
1190
|
+
organizationAccountTags
|
|
1191
|
+
}
|
|
1192
|
+
tags
|
|
1193
|
+
}
|
|
1115
1194
|
}
|
|
1116
1195
|
vpc_id
|
|
1117
1196
|
cidr_block
|
|
@@ -1131,6 +1210,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1131
1210
|
version
|
|
1132
1211
|
format
|
|
1133
1212
|
}
|
|
1213
|
+
organization {
|
|
1214
|
+
payerAccount {
|
|
1215
|
+
organizationAccountTags
|
|
1216
|
+
}
|
|
1217
|
+
tags
|
|
1218
|
+
}
|
|
1134
1219
|
}
|
|
1135
1220
|
tags
|
|
1136
1221
|
assumeRole
|
|
@@ -1146,6 +1231,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1146
1231
|
version
|
|
1147
1232
|
format
|
|
1148
1233
|
}
|
|
1234
|
+
organization {
|
|
1235
|
+
payerAccount {
|
|
1236
|
+
organizationAccountTags
|
|
1237
|
+
}
|
|
1238
|
+
tags
|
|
1239
|
+
}
|
|
1149
1240
|
}
|
|
1150
1241
|
tags
|
|
1151
1242
|
cidrBlock
|
|
@@ -1175,6 +1266,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1175
1266
|
version
|
|
1176
1267
|
format
|
|
1177
1268
|
}
|
|
1269
|
+
organization {
|
|
1270
|
+
payerAccount {
|
|
1271
|
+
organizationAccountTags
|
|
1272
|
+
}
|
|
1273
|
+
tags
|
|
1274
|
+
}
|
|
1178
1275
|
}
|
|
1179
1276
|
}
|
|
1180
1277
|
}
|
|
@@ -1190,6 +1287,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1190
1287
|
version
|
|
1191
1288
|
format
|
|
1192
1289
|
}
|
|
1290
|
+
organization {
|
|
1291
|
+
payerAccount {
|
|
1292
|
+
organizationAccountTags
|
|
1293
|
+
}
|
|
1294
|
+
tags
|
|
1295
|
+
}
|
|
1193
1296
|
}
|
|
1194
1297
|
accessLevel
|
|
1195
1298
|
default
|
|
@@ -1216,6 +1319,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1216
1319
|
version
|
|
1217
1320
|
format
|
|
1218
1321
|
}
|
|
1322
|
+
organization {
|
|
1323
|
+
payerAccount {
|
|
1324
|
+
organizationAccountTags
|
|
1325
|
+
}
|
|
1326
|
+
tags
|
|
1327
|
+
}
|
|
1219
1328
|
}
|
|
1220
1329
|
}
|
|
1221
1330
|
}
|
|
@@ -1231,6 +1340,12 @@ CLUSTER_PEERING_QUERY = """
|
|
|
1231
1340
|
version
|
|
1232
1341
|
format
|
|
1233
1342
|
}
|
|
1343
|
+
organization {
|
|
1344
|
+
payerAccount {
|
|
1345
|
+
organizationAccountTags
|
|
1346
|
+
}
|
|
1347
|
+
tags
|
|
1348
|
+
}
|
|
1234
1349
|
}
|
|
1235
1350
|
}
|
|
1236
1351
|
}
|
|
@@ -1700,7 +1815,7 @@ def get_review_repos() -> list[dict[str, str]]:
|
|
|
1700
1815
|
return [
|
|
1701
1816
|
{"url": c["url"], "name": c["name"]}
|
|
1702
1817
|
for c in code_components
|
|
1703
|
-
if c
|
|
1818
|
+
if c.get("showInReviewQueue", False)
|
|
1704
1819
|
]
|
|
1705
1820
|
|
|
1706
1821
|
|
|
@@ -2230,6 +2345,12 @@ JIRA_BOARDS_QUICK_QUERY = """
|
|
|
2230
2345
|
version
|
|
2231
2346
|
format
|
|
2232
2347
|
}
|
|
2348
|
+
email {
|
|
2349
|
+
path
|
|
2350
|
+
field
|
|
2351
|
+
version
|
|
2352
|
+
format
|
|
2353
|
+
}
|
|
2233
2354
|
}
|
|
2234
2355
|
}
|
|
2235
2356
|
}
|
|
@@ -2336,6 +2457,12 @@ DNS_ZONES_QUERY = """
|
|
|
2336
2457
|
version
|
|
2337
2458
|
format
|
|
2338
2459
|
}
|
|
2460
|
+
organization {
|
|
2461
|
+
payerAccount {
|
|
2462
|
+
organizationAccountTags
|
|
2463
|
+
}
|
|
2464
|
+
tags
|
|
2465
|
+
}
|
|
2339
2466
|
}
|
|
2340
2467
|
vpc {
|
|
2341
2468
|
vpc_id
|
|
@@ -2697,6 +2824,10 @@ APP_METADATA = """
|
|
|
2697
2824
|
path
|
|
2698
2825
|
field
|
|
2699
2826
|
}
|
|
2827
|
+
email {
|
|
2828
|
+
path
|
|
2829
|
+
field
|
|
2830
|
+
}
|
|
2700
2831
|
}
|
|
2701
2832
|
}
|
|
2702
2833
|
slackUserGroup {
|
reconcile/rhidp/common.py
CHANGED
|
@@ -7,10 +7,7 @@ from enum import StrEnum
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
from urllib.parse import urlparse
|
|
9
9
|
|
|
10
|
-
from pydantic import
|
|
11
|
-
BaseModel,
|
|
12
|
-
root_validator,
|
|
13
|
-
)
|
|
10
|
+
from pydantic import BaseModel, model_validator
|
|
14
11
|
|
|
15
12
|
from reconcile.gql_definitions.common.ocm_environments import (
|
|
16
13
|
query as ocm_environment_query,
|
|
@@ -63,7 +60,8 @@ class ClusterAuth(BaseModel):
|
|
|
63
60
|
issuer: str
|
|
64
61
|
status: str
|
|
65
62
|
|
|
66
|
-
@
|
|
63
|
+
@model_validator(mode="before")
|
|
64
|
+
@classmethod
|
|
67
65
|
def name_no_spaces(
|
|
68
66
|
cls, values: MutableMapping[str, Any]
|
|
69
67
|
) -> MutableMapping[str, Any]:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import http
|
|
1
2
|
import logging
|
|
2
3
|
from collections.abc import (
|
|
3
4
|
Iterable,
|
|
@@ -10,6 +11,7 @@ from urllib.parse import (
|
|
|
10
11
|
)
|
|
11
12
|
|
|
12
13
|
import jwt
|
|
14
|
+
from requests import HTTPError
|
|
13
15
|
|
|
14
16
|
from reconcile.rhidp.common import (
|
|
15
17
|
Cluster,
|
|
@@ -237,7 +239,7 @@ def create_sso_client(
|
|
|
237
239
|
secret_reader.vault_client.write(
|
|
238
240
|
secret={
|
|
239
241
|
"path": secret.path,
|
|
240
|
-
"data": sso_client.
|
|
242
|
+
"data": sso_client.model_dump(),
|
|
241
243
|
},
|
|
242
244
|
decode_base64=False,
|
|
243
245
|
)
|
|
@@ -256,9 +258,18 @@ def delete_sso_client(
|
|
|
256
258
|
)
|
|
257
259
|
sso_client = SSOClient(**secret_reader.read_all_secret(secret=secret))
|
|
258
260
|
keycloak_api = keycloak_map.get(sso_client.issuer)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
try:
|
|
262
|
+
keycloak_api.delete_client(
|
|
263
|
+
registration_client_uri=sso_client.registration_client_uri,
|
|
264
|
+
registration_access_token=sso_client.registration_access_token,
|
|
265
|
+
)
|
|
266
|
+
except HTTPError as e:
|
|
267
|
+
if e.response.status_code != http.HTTPStatus.UNAUTHORIZED:
|
|
268
|
+
logging.error(f"Failed to delete SSO client {sso_client_id}: {e}")
|
|
269
|
+
raise
|
|
270
|
+
# something went wrong with the registration token, maybe it expired
|
|
271
|
+
logging.error(
|
|
272
|
+
f"Failed to delete SSO client {sso_client_id} due to unauthorized error: {e}. Continuing to delete the vault secret."
|
|
273
|
+
)
|
|
263
274
|
|
|
264
275
|
secret_reader.vault_client.delete(path=secret.path)
|
|
@@ -177,7 +177,7 @@ def is_namespace_addressed_by_selector(
|
|
|
177
177
|
# json representation of namespace to filter on
|
|
178
178
|
# remove all the None values to simplify the jsonpath expressions
|
|
179
179
|
namespace_as_dict = {
|
|
180
|
-
"namespace": [namespace.
|
|
180
|
+
"namespace": [namespace.model_dump(by_alias=True, exclude_none=True)]
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
do_include = any(
|
|
@@ -2,7 +2,7 @@ import hashlib
|
|
|
2
2
|
import logging
|
|
3
3
|
from collections.abc import Iterable
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from datetime import
|
|
5
|
+
from datetime import timedelta
|
|
6
6
|
|
|
7
7
|
from croniter import croniter
|
|
8
8
|
|
|
@@ -13,6 +13,7 @@ from reconcile.saas_auto_promotions_manager.publisher import (
|
|
|
13
13
|
DeploymentInfo,
|
|
14
14
|
Publisher,
|
|
15
15
|
)
|
|
16
|
+
from reconcile.utils.datetime_util import utc_now
|
|
16
17
|
from reconcile.utils.slo_document_manager import SLODocumentManager
|
|
17
18
|
|
|
18
19
|
CONTENT_HASH_LENGTH = 32
|
|
@@ -113,7 +114,7 @@ class Subscriber:
|
|
|
113
114
|
We accumulate the time a ref is running on all publishers for this subscriber.
|
|
114
115
|
We compare that accumulated time with the soak_days setting of the subscriber.
|
|
115
116
|
"""
|
|
116
|
-
now =
|
|
117
|
+
now = utc_now()
|
|
117
118
|
delta = timedelta(days=0)
|
|
118
119
|
for channel in self.channels:
|
|
119
120
|
for publisher in channel.publishers:
|
|
@@ -136,7 +137,7 @@ class Subscriber:
|
|
|
136
137
|
self.schedule,
|
|
137
138
|
)
|
|
138
139
|
return False
|
|
139
|
-
return croniter.match(self.schedule,
|
|
140
|
+
return croniter.match(self.schedule, utc_now(), day_or=False)
|
|
140
141
|
|
|
141
142
|
def _compute_desired_ref(self) -> None:
|
|
142
143
|
"""
|
|
@@ -85,7 +85,7 @@ def compile_skupper_sites(
|
|
|
85
85
|
or skupper_network.site_controller_templates
|
|
86
86
|
):
|
|
87
87
|
tmpl_vars = tmpl.variables or {}
|
|
88
|
-
tmpl_vars["resource"] = {"namespace": ns.
|
|
88
|
+
tmpl_vars["resource"] = {"namespace": ns.model_dump(by_alias=True)}
|
|
89
89
|
|
|
90
90
|
site_controller_objects.append(
|
|
91
91
|
load_site_controller_template(tmpl.path, tmpl_vars)
|
|
@@ -304,6 +304,6 @@ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
|
|
304
304
|
skupper_networks = get_skupper_networks(gqlapi.query)
|
|
305
305
|
return {
|
|
306
306
|
"skupper_sites": [
|
|
307
|
-
site.
|
|
307
|
+
site.model_dump() for site in compile_skupper_sites(skupper_networks)
|
|
308
308
|
],
|
|
309
309
|
}
|
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_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.")
|