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/ocm_machine_pools.py
CHANGED
|
@@ -7,11 +7,7 @@ from collections.abc import Iterable, Mapping
|
|
|
7
7
|
from enum import Enum
|
|
8
8
|
from typing import Any, Self
|
|
9
9
|
|
|
10
|
-
from pydantic import
|
|
11
|
-
BaseModel,
|
|
12
|
-
Field,
|
|
13
|
-
root_validator,
|
|
14
|
-
)
|
|
10
|
+
from pydantic import BaseModel, Field, SerializeAsAny, model_validator
|
|
15
11
|
|
|
16
12
|
from reconcile import queries
|
|
17
13
|
from reconcile.gql_definitions.common.clusters import (
|
|
@@ -22,6 +18,7 @@ from reconcile.gql_definitions.common.clusters import (
|
|
|
22
18
|
from reconcile.typed_queries.clusters import get_clusters
|
|
23
19
|
from reconcile.utils.differ import diff_mappings
|
|
24
20
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
|
21
|
+
from reconcile.utils.json import json_dumps
|
|
25
22
|
from reconcile.utils.ocm import (
|
|
26
23
|
DEFAULT_OCM_MACHINE_POOL_ID,
|
|
27
24
|
OCM,
|
|
@@ -61,7 +58,8 @@ class MachinePoolAutoscaling(AbstractAutoscaling):
|
|
|
61
58
|
min_replicas: int
|
|
62
59
|
max_replicas: int
|
|
63
60
|
|
|
64
|
-
@
|
|
61
|
+
@model_validator(mode="before")
|
|
62
|
+
@classmethod
|
|
65
63
|
def max_greater_min(cls, field_values: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
66
64
|
min_replicas = field_values.get("min_replicas")
|
|
67
65
|
max_replicas = field_values.get("max_replicas")
|
|
@@ -82,7 +80,8 @@ class NodePoolAutoscaling(AbstractAutoscaling):
|
|
|
82
80
|
min_replica: int
|
|
83
81
|
max_replica: int
|
|
84
82
|
|
|
85
|
-
@
|
|
83
|
+
@model_validator(mode="before")
|
|
84
|
+
@classmethod
|
|
86
85
|
def max_greater_min(cls, field_values: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
87
86
|
min_replica = field_values.get("min_replica")
|
|
88
87
|
max_replica = field_values.get("max_replica")
|
|
@@ -103,14 +102,15 @@ class AbstractPool(ABC, BaseModel):
|
|
|
103
102
|
# Abstract class for machine pools, to be implemented by OSD/HyperShift classes
|
|
104
103
|
|
|
105
104
|
id: str
|
|
106
|
-
replicas: int | None
|
|
107
|
-
taints: list[Mapping[str, str]] | None
|
|
108
|
-
labels: Mapping[str, str] | None
|
|
105
|
+
replicas: int | None = None
|
|
106
|
+
taints: list[Mapping[str, str]] | None = None
|
|
107
|
+
labels: Mapping[str, str] | None = None
|
|
109
108
|
cluster: str
|
|
110
109
|
cluster_type: ClusterType = Field(..., exclude=True)
|
|
111
|
-
autoscaling: AbstractAutoscaling | None
|
|
110
|
+
autoscaling: SerializeAsAny[AbstractAutoscaling] | None = None
|
|
112
111
|
|
|
113
|
-
@
|
|
112
|
+
@model_validator(mode="before")
|
|
113
|
+
@classmethod
|
|
114
114
|
def validate_scaling(cls, field_values: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
115
115
|
if field_values.get("autoscaling") and field_values.get("replicas"):
|
|
116
116
|
raise ValueError("autoscaling and replicas are mutually exclusive")
|
|
@@ -154,13 +154,13 @@ class MachinePool(AbstractPool):
|
|
|
154
154
|
instance_type: str
|
|
155
155
|
|
|
156
156
|
def delete(self, ocm: OCM) -> None:
|
|
157
|
-
ocm.delete_machine_pool(self.cluster, self.
|
|
157
|
+
ocm.delete_machine_pool(self.cluster, self.model_dump(by_alias=True))
|
|
158
158
|
|
|
159
159
|
def create(self, ocm: OCM) -> None:
|
|
160
|
-
ocm.create_machine_pool(self.cluster, self.
|
|
160
|
+
ocm.create_machine_pool(self.cluster, self.model_dump(by_alias=True))
|
|
161
161
|
|
|
162
162
|
def update(self, ocm: OCM) -> None:
|
|
163
|
-
update_dict = self.
|
|
163
|
+
update_dict = self.model_dump(by_alias=True)
|
|
164
164
|
# can not update instance_type
|
|
165
165
|
del update_dict["instance_type"]
|
|
166
166
|
if not update_dict["labels"]:
|
|
@@ -170,7 +170,10 @@ class MachinePool(AbstractPool):
|
|
|
170
170
|
ocm.update_machine_pool(self.cluster, update_dict)
|
|
171
171
|
|
|
172
172
|
def has_diff(self, pool: ClusterMachinePoolV1) -> bool:
|
|
173
|
-
|
|
173
|
+
pool_taints = (
|
|
174
|
+
[p.model_dump(by_alias=True) for p in pool.taints] if pool.taints else None
|
|
175
|
+
)
|
|
176
|
+
if self.taints != pool_taints or self.labels != pool.labels:
|
|
174
177
|
logging.warning(
|
|
175
178
|
f"updating labels or taints for machine pool {pool.q_id} "
|
|
176
179
|
f"will only be applied to new Nodes"
|
|
@@ -178,7 +181,7 @@ class MachinePool(AbstractPool):
|
|
|
178
181
|
|
|
179
182
|
return (
|
|
180
183
|
self.replicas != pool.replicas
|
|
181
|
-
or self.taints !=
|
|
184
|
+
or self.taints != pool_taints
|
|
182
185
|
or self.labels != pool.labels
|
|
183
186
|
or self.instance_type != pool.instance_type
|
|
184
187
|
or self._has_diff_autoscale(pool)
|
|
@@ -214,7 +217,7 @@ class MachinePool(AbstractPool):
|
|
|
214
217
|
replicas=pool.replicas,
|
|
215
218
|
autoscaling=autoscaling,
|
|
216
219
|
instance_type=pool.instance_type,
|
|
217
|
-
taints=[p.
|
|
220
|
+
taints=[p.model_dump(by_alias=True) for p in pool.taints or []],
|
|
218
221
|
labels=pool.labels,
|
|
219
222
|
cluster=cluster,
|
|
220
223
|
cluster_type=cluster_type,
|
|
@@ -232,14 +235,14 @@ class NodePool(AbstractPool):
|
|
|
232
235
|
subnet: str | None
|
|
233
236
|
|
|
234
237
|
def delete(self, ocm: OCM) -> None:
|
|
235
|
-
ocm.delete_node_pool(self.cluster, self.
|
|
238
|
+
ocm.delete_node_pool(self.cluster, self.model_dump(by_alias=True))
|
|
236
239
|
|
|
237
240
|
def create(self, ocm: OCM) -> None:
|
|
238
|
-
spec = self.
|
|
241
|
+
spec = self.model_dump(by_alias=True)
|
|
239
242
|
ocm.create_node_pool(self.cluster, spec)
|
|
240
243
|
|
|
241
244
|
def update(self, ocm: OCM) -> None:
|
|
242
|
-
update_dict = self.
|
|
245
|
+
update_dict = self.model_dump(by_alias=True)
|
|
243
246
|
# can not update instance_type
|
|
244
247
|
del update_dict["aws_node_pool"]
|
|
245
248
|
# can not update subnet
|
|
@@ -251,7 +254,10 @@ class NodePool(AbstractPool):
|
|
|
251
254
|
ocm.update_node_pool(self.cluster, update_dict)
|
|
252
255
|
|
|
253
256
|
def has_diff(self, pool: ClusterMachinePoolV1) -> bool:
|
|
254
|
-
|
|
257
|
+
pool_taints = (
|
|
258
|
+
[p.model_dump(by_alias=True) for p in pool.taints] if pool.taints else None
|
|
259
|
+
)
|
|
260
|
+
if self.taints != pool_taints or self.labels != pool.labels:
|
|
255
261
|
logging.warning(
|
|
256
262
|
f"updating labels or taints for node pool {pool.q_id} "
|
|
257
263
|
f"will only be applied to new Nodes"
|
|
@@ -259,7 +265,7 @@ class NodePool(AbstractPool):
|
|
|
259
265
|
|
|
260
266
|
return (
|
|
261
267
|
self.replicas != pool.replicas
|
|
262
|
-
or self.taints !=
|
|
268
|
+
or self.taints != pool_taints
|
|
263
269
|
or self.labels != pool.labels
|
|
264
270
|
or self.aws_node_pool.instance_type != pool.instance_type
|
|
265
271
|
or self.subnet != pool.subnet
|
|
@@ -297,7 +303,7 @@ class NodePool(AbstractPool):
|
|
|
297
303
|
aws_node_pool=AWSNodePool(
|
|
298
304
|
instance_type=pool.instance_type,
|
|
299
305
|
),
|
|
300
|
-
taints=[p.
|
|
306
|
+
taints=[p.model_dump(by_alias=True) for p in pool.taints or []],
|
|
301
307
|
labels=pool.labels,
|
|
302
308
|
subnet=pool.subnet,
|
|
303
309
|
cluster=cluster,
|
|
@@ -312,7 +318,7 @@ class PoolHandler(BaseModel):
|
|
|
312
318
|
pool: AbstractPool
|
|
313
319
|
|
|
314
320
|
def act(self, dry_run: bool, ocm: OCM) -> None:
|
|
315
|
-
logging.info(f"{self.action} {self.pool.
|
|
321
|
+
logging.info(f"{self.action} {self.pool.model_dump(by_alias=True)}")
|
|
316
322
|
if dry_run:
|
|
317
323
|
return
|
|
318
324
|
|
|
@@ -469,7 +475,7 @@ def calculate_diff(
|
|
|
469
475
|
if invalid_diff:
|
|
470
476
|
errors.append(
|
|
471
477
|
InvalidUpdateError(
|
|
472
|
-
f"can not update {invalid_diff} for existing machine pool on cluster {cluster_name}, CURRENT: {diff_pair.current
|
|
478
|
+
f"can not update {invalid_diff} for existing machine pool on cluster {cluster_name}, CURRENT: {json_dumps(diff_pair.current)}, DESIRED: {json_dumps(diff_pair.desired)}"
|
|
473
479
|
)
|
|
474
480
|
)
|
|
475
481
|
else:
|
|
@@ -531,7 +537,7 @@ def run(dry_run: bool) -> None:
|
|
|
531
537
|
|
|
532
538
|
settings = queries.get_app_interface_settings()
|
|
533
539
|
cluster_like_objects = [
|
|
534
|
-
cluster.
|
|
540
|
+
cluster.model_dump(by_alias=True) for cluster in filtered_clusters
|
|
535
541
|
]
|
|
536
542
|
ocm_map = OCMMap(
|
|
537
543
|
clusters=cluster_like_objects,
|
reconcile/openshift_base.py
CHANGED
|
@@ -29,10 +29,14 @@ from reconcile.utils import (
|
|
|
29
29
|
metrics,
|
|
30
30
|
)
|
|
31
31
|
from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
|
|
32
|
+
from reconcile.utils.differ import DiffPair
|
|
32
33
|
from reconcile.utils.oc import (
|
|
34
|
+
POD_RECYCLE_SUPPORTED_OWNER_KINDS,
|
|
35
|
+
AmbiguousResourceTypeError,
|
|
33
36
|
DeploymentFieldIsImmutableError,
|
|
34
37
|
FieldIsImmutableError,
|
|
35
38
|
InvalidValueApplyError,
|
|
39
|
+
KindNotFoundError,
|
|
36
40
|
MayNotChangeOnceSetError,
|
|
37
41
|
MetaDataAnnotationsTooLongApplyError,
|
|
38
42
|
OC_Map,
|
|
@@ -60,6 +64,10 @@ AUTH_METHOD_USER_KEY = {
|
|
|
60
64
|
"oidc": "org_username",
|
|
61
65
|
"rhidp": "org_username",
|
|
62
66
|
}
|
|
67
|
+
RECYCLE_POD_ANNOTATIONS = [
|
|
68
|
+
"kubectl.kubernetes.io/restartedAt",
|
|
69
|
+
"openshift.openshift.io/restartedAt",
|
|
70
|
+
]
|
|
63
71
|
|
|
64
72
|
|
|
65
73
|
class ValidationError(Exception):
|
|
@@ -128,6 +136,29 @@ class ClusterMap(Protocol):
|
|
|
128
136
|
) -> list[str]: ...
|
|
129
137
|
|
|
130
138
|
|
|
139
|
+
def validate_managed_resource_types(
|
|
140
|
+
oc: OCCli,
|
|
141
|
+
managed_resource_types: Iterable[str],
|
|
142
|
+
managed_resource_names: Iterable[Mapping[str, Any]],
|
|
143
|
+
cluster_scope_resource_validation: bool,
|
|
144
|
+
) -> None:
|
|
145
|
+
"""Validate the managed resource types."""
|
|
146
|
+
managed_resources = [
|
|
147
|
+
managed_resource_name["resource"]
|
|
148
|
+
for managed_resource_name in managed_resource_names
|
|
149
|
+
]
|
|
150
|
+
for managed_resource_type in managed_resource_types:
|
|
151
|
+
# The k8s kind must be supported by the cluster
|
|
152
|
+
resource = oc.get_api_resource(managed_resource_type)
|
|
153
|
+
|
|
154
|
+
if cluster_scope_resource_validation and not resource.namespaced:
|
|
155
|
+
# cluster-scoped resources must be use managedResourceNames!
|
|
156
|
+
if managed_resource_type not in managed_resources:
|
|
157
|
+
raise ValidationError(
|
|
158
|
+
f"Cluster-scoped resource {managed_resource_type} must be managed by name only. Please use 'managedResourceNames' field to specify the names of the resources to manage."
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
131
162
|
def init_specs_to_fetch(
|
|
132
163
|
ri: ResourceInventory,
|
|
133
164
|
oc_map: ClusterMap,
|
|
@@ -136,6 +167,7 @@ def init_specs_to_fetch(
|
|
|
136
167
|
override_managed_types: Iterable[str] | None = None,
|
|
137
168
|
managed_types_key: str = "managedResourceTypes",
|
|
138
169
|
cluster_admin: bool = False,
|
|
170
|
+
cluster_scope_resource_validation: bool = False,
|
|
139
171
|
) -> list[StateSpec]:
|
|
140
172
|
state_specs: list[StateSpec] = []
|
|
141
173
|
|
|
@@ -163,9 +195,27 @@ def init_specs_to_fetch(
|
|
|
163
195
|
logging.log(level=ex.log_level, msg=ex.message)
|
|
164
196
|
continue
|
|
165
197
|
|
|
198
|
+
managed_resource_names = namespace_info.get("managedResourceNames") or []
|
|
199
|
+
try:
|
|
200
|
+
validate_managed_resource_types(
|
|
201
|
+
oc,
|
|
202
|
+
managed_types,
|
|
203
|
+
managed_resource_names,
|
|
204
|
+
cluster_scope_resource_validation=cluster_scope_resource_validation,
|
|
205
|
+
)
|
|
206
|
+
except KindNotFoundError:
|
|
207
|
+
# We must allow kinds that are not supported by the cluster because:
|
|
208
|
+
# 1. We install CRD with an operator in the same MR
|
|
209
|
+
# 2. SAAS files initialize the namespace objects with managedResourceTypes from the SAAS file
|
|
210
|
+
# and we can't expect that all of those are valid for all clusters
|
|
211
|
+
pass
|
|
212
|
+
except (AmbiguousResourceTypeError, ValidationError) as e:
|
|
213
|
+
ri.register_error()
|
|
214
|
+
logging.error(f"[{cluster}/{namespace_info['name']}] {e}")
|
|
215
|
+
continue
|
|
216
|
+
|
|
166
217
|
namespace = namespace_info["name"]
|
|
167
218
|
# These may exit but have a value of None
|
|
168
|
-
managed_resource_names = namespace_info.get("managedResourceNames") or []
|
|
169
219
|
managed_resource_type_overrides = (
|
|
170
220
|
namespace_info.get("managedResourceTypeOverrides") or []
|
|
171
221
|
)
|
|
@@ -315,7 +365,6 @@ def populate_current_state(
|
|
|
315
365
|
|
|
316
366
|
if caller and openshift_resource.caller != caller:
|
|
317
367
|
continue
|
|
318
|
-
|
|
319
368
|
ri.add_current(
|
|
320
369
|
spec.cluster,
|
|
321
370
|
spec.namespace,
|
|
@@ -341,6 +390,7 @@ def fetch_current_state(
|
|
|
341
390
|
cluster_admin: bool = False,
|
|
342
391
|
caller: str | None = None,
|
|
343
392
|
init_projects: bool = False,
|
|
393
|
+
cluster_scope_resource_validation: bool = False,
|
|
344
394
|
) -> tuple[ResourceInventory, OC_Map]:
|
|
345
395
|
ri = ResourceInventory()
|
|
346
396
|
settings = queries.get_app_interface_settings()
|
|
@@ -363,6 +413,7 @@ def fetch_current_state(
|
|
|
363
413
|
clusters=clusters,
|
|
364
414
|
override_managed_types=override_managed_types,
|
|
365
415
|
cluster_admin=cluster_admin,
|
|
416
|
+
cluster_scope_resource_validation=cluster_scope_resource_validation,
|
|
366
417
|
)
|
|
367
418
|
threaded.run(
|
|
368
419
|
populate_current_state,
|
|
@@ -535,11 +586,15 @@ def apply(
|
|
|
535
586
|
# take care of the resize ourselves.
|
|
536
587
|
# ref: https://github.com/kubernetes/enhancements/pull/2842
|
|
537
588
|
if resize_required:
|
|
589
|
+
if desired_storage is None:
|
|
590
|
+
raise ValidationError(
|
|
591
|
+
"Resource body does not contain storage information."
|
|
592
|
+
) from None
|
|
538
593
|
logging.info(["resizing_pvcs", cluster, namespace, owned_pvc_names])
|
|
539
594
|
oc.resize_pvcs(namespace, owned_pvc_names, desired_storage)
|
|
540
595
|
|
|
541
596
|
if recycle_pods:
|
|
542
|
-
oc.recycle_pods(dry_run, namespace,
|
|
597
|
+
oc.recycle_pods(dry_run, namespace, resource)
|
|
543
598
|
|
|
544
599
|
|
|
545
600
|
def create(
|
|
@@ -783,10 +838,56 @@ def handle_identical_resources(
|
|
|
783
838
|
return actions
|
|
784
839
|
|
|
785
840
|
|
|
841
|
+
def patch_desired_resource_for_recycle_annotations(
|
|
842
|
+
desired: OR,
|
|
843
|
+
current: OR,
|
|
844
|
+
) -> OR:
|
|
845
|
+
"""
|
|
846
|
+
Patch desired resource with recycle annotations to pod template from current resource.
|
|
847
|
+
This is to avoid full pods recycle when changes are not affecting pod template.
|
|
848
|
+
Note desired annotations can override current annotations.
|
|
849
|
+
For example, if desired resource has kubectl.kubernetes.io/restartedAt defined,
|
|
850
|
+
it will be used instead of current resource annotation.
|
|
851
|
+
|
|
852
|
+
Args:
|
|
853
|
+
desired: desired resource
|
|
854
|
+
current: current resource
|
|
855
|
+
|
|
856
|
+
Returns:
|
|
857
|
+
patched desired resource
|
|
858
|
+
"""
|
|
859
|
+
if current.kind not in POD_RECYCLE_SUPPORTED_OWNER_KINDS:
|
|
860
|
+
return desired
|
|
861
|
+
|
|
862
|
+
current_annotations = (
|
|
863
|
+
current.body.get("spec", {})
|
|
864
|
+
.get("template", {})
|
|
865
|
+
.get("metadata", {})
|
|
866
|
+
.get("annotations")
|
|
867
|
+
or {}
|
|
868
|
+
)
|
|
869
|
+
patch_annotations = {
|
|
870
|
+
k: value
|
|
871
|
+
for k in RECYCLE_POD_ANNOTATIONS
|
|
872
|
+
if (value := current_annotations.get(k))
|
|
873
|
+
}
|
|
874
|
+
if patch_annotations:
|
|
875
|
+
desired_annotations = (
|
|
876
|
+
desired.body.setdefault("spec", {})
|
|
877
|
+
.setdefault("template", {})
|
|
878
|
+
.setdefault("metadata", {})
|
|
879
|
+
.setdefault("annotations", {})
|
|
880
|
+
)
|
|
881
|
+
desired.body["spec"]["template"]["metadata"]["annotations"] = (
|
|
882
|
+
patch_annotations | desired_annotations
|
|
883
|
+
)
|
|
884
|
+
return desired
|
|
885
|
+
|
|
886
|
+
|
|
786
887
|
def handle_modified_resources(
|
|
787
888
|
oc_map: ClusterMap,
|
|
788
889
|
ri: ResourceInventory,
|
|
789
|
-
modified_resources: Mapping[
|
|
890
|
+
modified_resources: Mapping[str, DiffPair[OR, OR]],
|
|
790
891
|
cluster: str,
|
|
791
892
|
namespace: str,
|
|
792
893
|
resource_type: str,
|
|
@@ -982,6 +1083,12 @@ def _realize_resource_data_3way_diff(
|
|
|
982
1083
|
if options.enable_deletion and options.override_enable_deletion is False:
|
|
983
1084
|
options.enable_deletion = False
|
|
984
1085
|
|
|
1086
|
+
for k in data["current"].keys() & data["desired"].keys():
|
|
1087
|
+
patch_desired_resource_for_recycle_annotations(
|
|
1088
|
+
desired=data["desired"][k],
|
|
1089
|
+
current=data["current"][k],
|
|
1090
|
+
)
|
|
1091
|
+
|
|
985
1092
|
diff_result = differ.diff_mappings(
|
|
986
1093
|
data["current"], data["desired"], equal=three_way_diff_using_hash
|
|
987
1094
|
)
|
|
@@ -1095,11 +1202,11 @@ def _validate_resources_used_exist(
|
|
|
1095
1202
|
)
|
|
1096
1203
|
for used_name, used_keys in used_resources.items():
|
|
1097
1204
|
# perhaps used resource is deployed together with the using resource?
|
|
1098
|
-
|
|
1205
|
+
desired_resource = ri.get_desired(cluster, namespace, used_kind, used_name)
|
|
1099
1206
|
# if not, perhaps it's a secret that will be created from a Service's
|
|
1100
1207
|
# serving-cert that is deployed along with the using resource?
|
|
1101
1208
|
# lets iterate through all resources and find Services that have the annotation
|
|
1102
|
-
if not
|
|
1209
|
+
if not desired_resource and used_kind == "Secret":
|
|
1103
1210
|
# consider only Service resources that are in the same cluster & namespace
|
|
1104
1211
|
service_resources = []
|
|
1105
1212
|
for cname, nname, restype, res in ri:
|
|
@@ -1123,12 +1230,12 @@ def _validate_resources_used_exist(
|
|
|
1123
1230
|
}:
|
|
1124
1231
|
# found a match. we assume the serving cert secret will
|
|
1125
1232
|
# be present at some point soon after the Service is deployed
|
|
1126
|
-
|
|
1233
|
+
desired_resource = service
|
|
1127
1234
|
break
|
|
1128
1235
|
|
|
1129
|
-
if
|
|
1236
|
+
if desired_resource:
|
|
1130
1237
|
# get the body to match with the possible result from oc.get
|
|
1131
|
-
resource =
|
|
1238
|
+
resource = desired_resource.body
|
|
1132
1239
|
else:
|
|
1133
1240
|
# no. perhaps used resource exists in the namespace?
|
|
1134
1241
|
resource = oc.get(
|
|
@@ -1360,6 +1467,11 @@ class HasOpenShiftResources(Protocol):
|
|
|
1360
1467
|
openshift_resources: list | None
|
|
1361
1468
|
|
|
1362
1469
|
|
|
1470
|
+
@runtime_checkable
|
|
1471
|
+
class HasOpenShiftResourcesRequired(Protocol):
|
|
1472
|
+
openshift_resources: list
|
|
1473
|
+
|
|
1474
|
+
|
|
1363
1475
|
@runtime_checkable
|
|
1364
1476
|
class HasOpenshiftServiceAccountTokens(Protocol):
|
|
1365
1477
|
openshift_service_account_tokens: list | None
|
|
@@ -1368,7 +1480,7 @@ class HasOpenshiftServiceAccountTokens(Protocol):
|
|
|
1368
1480
|
@runtime_checkable
|
|
1369
1481
|
class HasSharedResourcesOpenShiftResources(Protocol):
|
|
1370
1482
|
@property
|
|
1371
|
-
def shared_resources(self) -> Sequence[
|
|
1483
|
+
def shared_resources(self) -> Sequence[HasOpenShiftResourcesRequired] | None: ...
|
|
1372
1484
|
|
|
1373
1485
|
|
|
1374
1486
|
@runtime_checkable
|
|
@@ -5,7 +5,6 @@ import subprocess
|
|
|
5
5
|
import sys
|
|
6
6
|
import tempfile
|
|
7
7
|
import urllib.request
|
|
8
|
-
from typing import cast
|
|
9
8
|
from urllib.error import URLError
|
|
10
9
|
|
|
11
10
|
from pydantic import BaseModel
|
|
@@ -17,6 +16,7 @@ from reconcile.gql_definitions.openshift_cluster_bots.clusters import ClusterV1
|
|
|
17
16
|
from reconcile.status import ExitCodes
|
|
18
17
|
from reconcile.utils import gql
|
|
19
18
|
from reconcile.utils.disabled_integrations import integration_is_enabled
|
|
19
|
+
from reconcile.utils.json import json_dumps
|
|
20
20
|
from reconcile.utils.mr import clusters_updates
|
|
21
21
|
from reconcile.utils.ocm import OCM, OCMMap
|
|
22
22
|
from reconcile.utils.openshift_resource import (
|
|
@@ -24,7 +24,7 @@ from reconcile.utils.openshift_resource import (
|
|
|
24
24
|
QONTRACT_ANNOTATION_INTEGRATION_VERSION,
|
|
25
25
|
)
|
|
26
26
|
from reconcile.utils.semver_helper import make_semver
|
|
27
|
-
from reconcile.utils.vault import VaultClient
|
|
27
|
+
from reconcile.utils.vault import VaultClient
|
|
28
28
|
|
|
29
29
|
QONTRACT_INTEGRATION = "openshift-cluster-bots"
|
|
30
30
|
QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
|
|
@@ -103,7 +103,7 @@ def oc(
|
|
|
103
103
|
|
|
104
104
|
def oc_apply(kubeconfig: str, namespace: str, items: list[dict]) -> None:
|
|
105
105
|
for item in items:
|
|
106
|
-
stdin =
|
|
106
|
+
stdin = json_dumps(item).encode()
|
|
107
107
|
oc(kubeconfig, namespace, ["apply", "-f", "-"], stdin)
|
|
108
108
|
|
|
109
109
|
|
|
@@ -238,7 +238,7 @@ def create_cluster_bots(
|
|
|
238
238
|
def update_vault(
|
|
239
239
|
cluster: ClusterV1, config: Config, token: str, admin_token: str | None
|
|
240
240
|
) -> None:
|
|
241
|
-
vault =
|
|
241
|
+
vault = VaultClient.get_instance()
|
|
242
242
|
vault.write(
|
|
243
243
|
{
|
|
244
244
|
"path": vault_secret(cluster, config, cluster_admin=False)["path"],
|
|
@@ -301,7 +301,7 @@ def filter_clusters(clusters: list[ClusterV1]) -> list[ClusterV1]:
|
|
|
301
301
|
|
|
302
302
|
def get_ocm_map(clusters: list[ClusterV1]) -> OCMMap:
|
|
303
303
|
settings = queries.get_app_interface_settings()
|
|
304
|
-
clusters_info = [c.
|
|
304
|
+
clusters_info = [c.model_dump(by_alias=True) for c in clusters]
|
|
305
305
|
return OCMMap(
|
|
306
306
|
settings=settings,
|
|
307
307
|
clusters=clusters_info,
|
reconcile/openshift_groups.py
CHANGED
|
@@ -243,10 +243,15 @@ def act(diff: Mapping[str, str | None], oc_map: ClusterMap) -> None:
|
|
|
243
243
|
return None
|
|
244
244
|
|
|
245
245
|
if action == "create_group":
|
|
246
|
+
assert group # make mypy happy
|
|
246
247
|
oc.create_group(group)
|
|
247
248
|
elif action == "add_user_to_group":
|
|
249
|
+
assert group # make mypy happy
|
|
250
|
+
assert user # make mypy happy
|
|
248
251
|
oc.add_user_to_group(group, user)
|
|
249
252
|
elif action == "del_user_from_group":
|
|
253
|
+
assert group # make mypy happy
|
|
254
|
+
assert user # make mypy happy
|
|
250
255
|
oc.del_user_from_group(group, user)
|
|
251
256
|
elif action == "delete_group":
|
|
252
257
|
logging.debug("skipping group deletion")
|
|
@@ -229,7 +229,7 @@ def get_gql_namespaces_in_shard() -> list[NamespaceV1]:
|
|
|
229
229
|
return [
|
|
230
230
|
ns
|
|
231
231
|
for ns in all_namespaces
|
|
232
|
-
if not ob.is_namespace_deleted(ns.
|
|
232
|
+
if not ob.is_namespace_deleted(ns.model_dump(by_alias=True))
|
|
233
233
|
and is_in_shard(f"{ns.cluster.name}/{ns.name}")
|
|
234
234
|
]
|
|
235
235
|
|