qontract-reconcile 0.9.1rc298__py3-none-any.whl → 0.10.1.dev1203__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.1.dev1203.dist-info/METADATA +500 -0
- qontract_reconcile-0.10.1.dev1203.dist-info/RECORD +771 -0
- {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
- {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/entry_points.txt +4 -2
- reconcile/acs_notifiers.py +126 -0
- reconcile/acs_policies.py +243 -0
- reconcile/acs_rbac.py +596 -0
- reconcile/aus/advanced_upgrade_service.py +621 -8
- reconcile/aus/aus_label_source.py +115 -0
- reconcile/aus/base.py +1053 -353
- reconcile/{utils → aus}/cluster_version_data.py +27 -12
- reconcile/aus/healthchecks.py +77 -0
- reconcile/aus/metrics.py +158 -0
- reconcile/aus/models.py +245 -5
- reconcile/aus/node_pool_spec.py +35 -0
- reconcile/aus/ocm_addons_upgrade_scheduler_org.py +225 -110
- reconcile/aus/ocm_upgrade_scheduler.py +76 -71
- reconcile/aus/ocm_upgrade_scheduler_org.py +81 -23
- reconcile/aus/version_gate_approver.py +204 -0
- reconcile/aus/version_gates/__init__.py +12 -0
- reconcile/aus/version_gates/handler.py +33 -0
- reconcile/aus/version_gates/ingress_gate_handler.py +32 -0
- reconcile/aus/version_gates/ocp_gate_handler.py +26 -0
- reconcile/aus/version_gates/sts_version_gate_handler.py +100 -0
- reconcile/aws_account_manager/README.md +5 -0
- reconcile/aws_account_manager/integration.py +373 -0
- reconcile/aws_account_manager/merge_request_manager.py +114 -0
- reconcile/aws_account_manager/metrics.py +39 -0
- reconcile/aws_account_manager/reconciler.py +403 -0
- reconcile/aws_account_manager/utils.py +41 -0
- reconcile/aws_ami_cleanup/integration.py +273 -0
- reconcile/aws_ami_share.py +18 -14
- reconcile/aws_cloudwatch_log_retention/integration.py +253 -0
- reconcile/aws_iam_keys.py +1 -1
- reconcile/aws_iam_password_reset.py +56 -20
- reconcile/aws_saml_idp/integration.py +204 -0
- reconcile/aws_saml_roles/integration.py +322 -0
- reconcile/aws_support_cases_sos.py +2 -2
- reconcile/aws_version_sync/integration.py +430 -0
- reconcile/aws_version_sync/merge_request_manager/merge_request.py +156 -0
- reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py +160 -0
- reconcile/aws_version_sync/utils.py +64 -0
- reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
- reconcile/change_owners/README.md +34 -0
- reconcile/change_owners/approver.py +7 -9
- reconcile/change_owners/bundle.py +134 -9
- reconcile/change_owners/change_log_tracking.py +236 -0
- reconcile/change_owners/change_owners.py +204 -194
- reconcile/change_owners/change_types.py +183 -265
- reconcile/change_owners/changes.py +488 -0
- reconcile/change_owners/decision.py +120 -41
- reconcile/change_owners/diff.py +63 -92
- reconcile/change_owners/implicit_ownership.py +19 -16
- reconcile/change_owners/self_service_roles.py +158 -35
- reconcile/change_owners/tester.py +20 -18
- reconcile/checkpoint.py +4 -6
- reconcile/cli.py +1523 -242
- reconcile/closedbox_endpoint_monitoring_base.py +10 -17
- reconcile/cluster_auth_rhidp/integration.py +257 -0
- reconcile/cluster_deployment_mapper.py +2 -5
- reconcile/cna/assets/asset.py +4 -7
- reconcile/cna/assets/null.py +2 -5
- reconcile/cna/integration.py +2 -3
- reconcile/cna/state.py +6 -9
- reconcile/dashdotdb_base.py +31 -10
- reconcile/dashdotdb_cso.py +3 -6
- reconcile/dashdotdb_dora.py +530 -0
- reconcile/dashdotdb_dvo.py +10 -13
- reconcile/dashdotdb_slo.py +75 -19
- reconcile/database_access_manager.py +753 -0
- reconcile/deadmanssnitch.py +207 -0
- reconcile/dynatrace_token_provider/dependencies.py +69 -0
- reconcile/dynatrace_token_provider/integration.py +656 -0
- reconcile/dynatrace_token_provider/metrics.py +62 -0
- reconcile/dynatrace_token_provider/model.py +14 -0
- reconcile/dynatrace_token_provider/ocm.py +140 -0
- reconcile/dynatrace_token_provider/validate.py +48 -0
- reconcile/endpoints_discovery/integration.py +348 -0
- reconcile/endpoints_discovery/merge_request.py +96 -0
- reconcile/endpoints_discovery/merge_request_manager.py +178 -0
- reconcile/external_resources/aws.py +204 -0
- reconcile/external_resources/factories.py +163 -0
- reconcile/external_resources/integration.py +194 -0
- reconcile/external_resources/integration_secrets_sync.py +47 -0
- reconcile/external_resources/manager.py +405 -0
- reconcile/external_resources/meta.py +17 -0
- reconcile/external_resources/metrics.py +95 -0
- reconcile/external_resources/model.py +350 -0
- reconcile/external_resources/reconciler.py +265 -0
- reconcile/external_resources/secrets_sync.py +465 -0
- reconcile/external_resources/state.py +258 -0
- reconcile/gabi_authorized_users.py +19 -11
- reconcile/gcr_mirror.py +43 -34
- reconcile/github_org.py +4 -6
- reconcile/github_owners.py +1 -1
- reconcile/github_repo_invites.py +2 -5
- reconcile/gitlab_fork_compliance.py +14 -13
- reconcile/gitlab_housekeeping.py +185 -91
- reconcile/gitlab_labeler.py +15 -14
- reconcile/gitlab_members.py +126 -120
- reconcile/gitlab_owners.py +53 -66
- reconcile/gitlab_permissions.py +167 -6
- reconcile/glitchtip/README.md +150 -0
- reconcile/glitchtip/integration.py +99 -51
- reconcile/glitchtip/reconciler.py +99 -70
- reconcile/glitchtip_project_alerts/__init__.py +0 -0
- reconcile/glitchtip_project_alerts/integration.py +333 -0
- reconcile/glitchtip_project_dsn/integration.py +43 -43
- reconcile/gql_definitions/acs/__init__.py +0 -0
- reconcile/gql_definitions/acs/acs_instances.py +83 -0
- reconcile/gql_definitions/acs/acs_policies.py +239 -0
- reconcile/gql_definitions/acs/acs_rbac.py +111 -0
- reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +46 -8
- reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +38 -8
- reconcile/gql_definitions/app_interface_metrics_exporter/__init__.py +0 -0
- reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +61 -0
- reconcile/gql_definitions/aws_account_manager/__init__.py +0 -0
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +177 -0
- reconcile/gql_definitions/aws_ami_cleanup/__init__.py +0 -0
- reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +161 -0
- reconcile/gql_definitions/aws_saml_idp/__init__.py +0 -0
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +117 -0
- reconcile/gql_definitions/aws_saml_roles/__init__.py +0 -0
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +117 -0
- reconcile/gql_definitions/aws_saml_roles/roles.py +97 -0
- reconcile/gql_definitions/aws_version_sync/__init__.py +0 -0
- reconcile/gql_definitions/aws_version_sync/clusters.py +83 -0
- reconcile/gql_definitions/aws_version_sync/namespaces.py +143 -0
- reconcile/gql_definitions/change_owners/queries/change_types.py +16 -29
- reconcile/gql_definitions/change_owners/queries/self_service_roles.py +45 -11
- reconcile/gql_definitions/cluster_auth_rhidp/__init__.py +0 -0
- reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +128 -0
- reconcile/gql_definitions/cna/queries/cna_provisioners.py +6 -8
- reconcile/gql_definitions/cna/queries/cna_resources.py +3 -5
- reconcile/gql_definitions/common/alerting_services_settings.py +2 -2
- reconcile/gql_definitions/common/app_code_component_repos.py +9 -5
- reconcile/gql_definitions/{glitchtip/glitchtip_settings.py → common/app_interface_custom_messages.py} +14 -16
- reconcile/gql_definitions/common/app_interface_dms_settings.py +86 -0
- reconcile/gql_definitions/common/app_interface_repo_settings.py +2 -2
- reconcile/gql_definitions/common/app_interface_state_settings.py +3 -5
- reconcile/gql_definitions/common/app_interface_vault_settings.py +3 -5
- reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +120 -0
- reconcile/gql_definitions/common/apps.py +72 -0
- reconcile/gql_definitions/common/aws_vpc_requests.py +109 -0
- reconcile/gql_definitions/common/aws_vpcs.py +84 -0
- reconcile/gql_definitions/common/clusters.py +120 -254
- reconcile/gql_definitions/common/clusters_minimal.py +11 -35
- reconcile/gql_definitions/common/clusters_with_dms.py +72 -0
- reconcile/gql_definitions/common/clusters_with_peering.py +70 -98
- reconcile/gql_definitions/common/github_orgs.py +2 -2
- reconcile/gql_definitions/common/jira_settings.py +68 -0
- reconcile/gql_definitions/common/jiralert_settings.py +68 -0
- reconcile/gql_definitions/common/namespaces.py +74 -32
- reconcile/gql_definitions/common/namespaces_minimal.py +4 -10
- reconcile/gql_definitions/common/ocm_env_telemeter.py +95 -0
- reconcile/gql_definitions/common/ocm_environments.py +4 -2
- reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
- reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -11
- reconcile/gql_definitions/common/pipeline_providers.py +45 -90
- reconcile/gql_definitions/common/quay_instances.py +64 -0
- reconcile/gql_definitions/common/quay_orgs.py +68 -0
- reconcile/gql_definitions/common/reserved_networks.py +94 -0
- reconcile/gql_definitions/common/saas_files.py +133 -95
- reconcile/gql_definitions/common/saas_target_namespaces.py +41 -26
- reconcile/gql_definitions/common/saasherder_settings.py +2 -2
- reconcile/gql_definitions/common/slack_workspaces.py +62 -0
- reconcile/gql_definitions/common/smtp_client_settings.py +2 -2
- reconcile/gql_definitions/common/state_aws_account.py +77 -0
- reconcile/gql_definitions/common/users.py +3 -2
- reconcile/gql_definitions/cost_report/__init__.py +0 -0
- reconcile/gql_definitions/cost_report/app_names.py +68 -0
- reconcile/gql_definitions/cost_report/cost_namespaces.py +86 -0
- reconcile/gql_definitions/cost_report/settings.py +77 -0
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +42 -12
- reconcile/gql_definitions/dynatrace_token_provider/__init__.py +0 -0
- reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +79 -0
- reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +84 -0
- reconcile/gql_definitions/endpoints_discovery/__init__.py +0 -0
- reconcile/gql_definitions/endpoints_discovery/namespaces.py +127 -0
- reconcile/gql_definitions/external_resources/__init__.py +0 -0
- reconcile/gql_definitions/external_resources/aws_accounts.py +73 -0
- reconcile/gql_definitions/external_resources/external_resources_modules.py +78 -0
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +1111 -0
- reconcile/gql_definitions/external_resources/external_resources_settings.py +98 -0
- reconcile/gql_definitions/fragments/aus_organization.py +34 -39
- reconcile/gql_definitions/fragments/aws_account_common.py +62 -0
- reconcile/gql_definitions/fragments/aws_account_managed.py +57 -0
- reconcile/gql_definitions/fragments/aws_account_sso.py +35 -0
- reconcile/gql_definitions/fragments/aws_infra_management_account.py +2 -2
- reconcile/gql_definitions/fragments/aws_vpc.py +47 -0
- reconcile/gql_definitions/fragments/aws_vpc_request.py +65 -0
- reconcile/gql_definitions/fragments/aws_vpc_request_subnet.py +29 -0
- reconcile/gql_definitions/fragments/deplopy_resources.py +7 -7
- reconcile/gql_definitions/fragments/disable.py +28 -0
- reconcile/gql_definitions/fragments/jumphost_common_fields.py +2 -2
- reconcile/gql_definitions/fragments/membership_source.py +47 -0
- reconcile/gql_definitions/fragments/minimal_ocm_organization.py +29 -0
- reconcile/gql_definitions/fragments/oc_connection_cluster.py +4 -9
- reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
- reconcile/gql_definitions/fragments/pipeline_provider_retention.py +30 -0
- reconcile/gql_definitions/fragments/prometheus_instance.py +48 -0
- reconcile/gql_definitions/fragments/resource_limits_requirements.py +29 -0
- reconcile/gql_definitions/fragments/{resource_requirements.py → resource_requests_requirements.py} +3 -3
- reconcile/gql_definitions/fragments/resource_values.py +2 -2
- reconcile/gql_definitions/fragments/saas_target_namespace.py +55 -12
- reconcile/gql_definitions/fragments/serviceaccount_token.py +38 -0
- reconcile/gql_definitions/fragments/terraform_state.py +36 -0
- reconcile/gql_definitions/fragments/upgrade_policy.py +5 -3
- reconcile/gql_definitions/fragments/user.py +3 -2
- reconcile/gql_definitions/fragments/vault_secret.py +2 -2
- reconcile/gql_definitions/gitlab_members/gitlab_instances.py +6 -2
- reconcile/gql_definitions/gitlab_members/permissions.py +3 -5
- reconcile/gql_definitions/glitchtip/glitchtip_instance.py +16 -2
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +22 -23
- reconcile/gql_definitions/glitchtip_project_alerts/__init__.py +0 -0
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +173 -0
- reconcile/gql_definitions/integrations/integrations.py +62 -45
- reconcile/gql_definitions/introspection.json +51176 -0
- reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +13 -5
- reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +79 -0
- reconcile/gql_definitions/jira/__init__.py +0 -0
- reconcile/gql_definitions/jira/jira_servers.py +80 -0
- reconcile/gql_definitions/jira_permissions_validator/__init__.py +0 -0
- reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +131 -0
- reconcile/gql_definitions/jumphosts/jumphosts.py +3 -5
- reconcile/gql_definitions/ldap_groups/__init__.py +0 -0
- reconcile/gql_definitions/ldap_groups/roles.py +111 -0
- reconcile/gql_definitions/ldap_groups/settings.py +79 -0
- reconcile/gql_definitions/maintenance/__init__.py +0 -0
- reconcile/gql_definitions/maintenance/maintenances.py +101 -0
- reconcile/gql_definitions/membershipsources/__init__.py +0 -0
- reconcile/gql_definitions/membershipsources/roles.py +112 -0
- reconcile/gql_definitions/ocm_labels/__init__.py +0 -0
- reconcile/gql_definitions/ocm_labels/clusters.py +112 -0
- reconcile/gql_definitions/ocm_labels/organizations.py +78 -0
- reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
- reconcile/gql_definitions/openshift_cluster_bots/__init__.py +0 -0
- reconcile/gql_definitions/openshift_cluster_bots/clusters.py +126 -0
- reconcile/gql_definitions/openshift_groups/managed_groups.py +2 -2
- reconcile/gql_definitions/openshift_groups/managed_roles.py +3 -2
- reconcile/gql_definitions/openshift_serviceaccount_tokens/__init__.py +0 -0
- reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +132 -0
- reconcile/gql_definitions/quay_membership/quay_membership.py +3 -5
- reconcile/gql_definitions/rhidp/__init__.py +0 -0
- reconcile/gql_definitions/rhidp/organizations.py +96 -0
- reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +2 -2
- reconcile/gql_definitions/service_dependencies/service_dependencies.py +9 -31
- reconcile/gql_definitions/sharding/aws_accounts.py +2 -2
- reconcile/gql_definitions/sharding/ocm_organization.py +63 -0
- reconcile/gql_definitions/skupper_network/site_controller_template.py +2 -2
- reconcile/gql_definitions/skupper_network/skupper_networks.py +12 -38
- reconcile/gql_definitions/slack_usergroups/clusters.py +2 -2
- reconcile/gql_definitions/slack_usergroups/permissions.py +8 -15
- reconcile/gql_definitions/slack_usergroups/users.py +3 -2
- reconcile/gql_definitions/slo_documents/__init__.py +0 -0
- reconcile/gql_definitions/slo_documents/slo_documents.py +142 -0
- reconcile/gql_definitions/status_board/__init__.py +0 -0
- reconcile/gql_definitions/status_board/status_board.py +163 -0
- reconcile/gql_definitions/statuspage/statuspages.py +56 -7
- reconcile/gql_definitions/templating/__init__.py +0 -0
- reconcile/gql_definitions/templating/template_collection.py +130 -0
- reconcile/gql_definitions/templating/templates.py +108 -0
- reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +4 -8
- reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +8 -8
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +6 -8
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +45 -56
- reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +4 -8
- reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +4 -8
- reconcile/gql_definitions/terraform_init/__init__.py +0 -0
- reconcile/gql_definitions/terraform_init/aws_accounts.py +93 -0
- reconcile/gql_definitions/terraform_repo/__init__.py +0 -0
- reconcile/gql_definitions/terraform_repo/terraform_repo.py +141 -0
- reconcile/gql_definitions/terraform_resources/database_access_manager.py +158 -0
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +153 -162
- reconcile/gql_definitions/terraform_tgw_attachments/__init__.py +0 -0
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +119 -0
- reconcile/gql_definitions/unleash_feature_toggles/__init__.py +0 -0
- reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +113 -0
- reconcile/gql_definitions/vault_instances/vault_instances.py +17 -50
- reconcile/gql_definitions/vault_policies/vault_policies.py +2 -2
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +49 -12
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +7 -2
- reconcile/integrations_manager.py +25 -13
- reconcile/jenkins/types.py +5 -1
- reconcile/jenkins_base.py +36 -0
- reconcile/jenkins_job_builder.py +10 -48
- reconcile/jenkins_job_builds_cleaner.py +40 -25
- reconcile/jenkins_job_cleaner.py +1 -3
- reconcile/jenkins_roles.py +22 -26
- reconcile/jenkins_webhooks.py +9 -6
- reconcile/jenkins_worker_fleets.py +11 -6
- reconcile/jira_permissions_validator.py +340 -0
- reconcile/jira_watcher.py +3 -5
- reconcile/ldap_groups/__init__.py +0 -0
- reconcile/ldap_groups/integration.py +279 -0
- reconcile/ldap_users.py +3 -0
- reconcile/ocm/types.py +39 -59
- reconcile/ocm_additional_routers.py +0 -1
- reconcile/ocm_addons_upgrade_tests_trigger.py +10 -15
- reconcile/ocm_aws_infrastructure_access.py +30 -32
- reconcile/ocm_clusters.py +217 -130
- reconcile/ocm_external_configuration_labels.py +15 -0
- reconcile/ocm_github_idp.py +1 -1
- reconcile/ocm_groups.py +25 -5
- reconcile/ocm_internal_notifications/__init__.py +0 -0
- reconcile/ocm_internal_notifications/integration.py +119 -0
- reconcile/ocm_labels/__init__.py +0 -0
- reconcile/ocm_labels/integration.py +409 -0
- reconcile/ocm_machine_pools.py +517 -108
- reconcile/ocm_upgrade_scheduler_org_updater.py +15 -11
- reconcile/openshift_base.py +609 -207
- reconcile/openshift_cluster_bots.py +344 -0
- reconcile/openshift_clusterrolebindings.py +15 -15
- reconcile/openshift_groups.py +42 -45
- reconcile/openshift_limitranges.py +1 -0
- reconcile/openshift_namespace_labels.py +22 -28
- reconcile/openshift_namespaces.py +22 -22
- reconcile/openshift_network_policies.py +4 -8
- reconcile/openshift_prometheus_rules.py +43 -0
- reconcile/openshift_resourcequotas.py +2 -16
- reconcile/openshift_resources.py +12 -10
- reconcile/openshift_resources_base.py +304 -328
- reconcile/openshift_rolebindings.py +18 -20
- reconcile/openshift_saas_deploy.py +105 -21
- reconcile/openshift_saas_deploy_change_tester.py +30 -35
- reconcile/openshift_saas_deploy_trigger_base.py +39 -36
- reconcile/openshift_saas_deploy_trigger_cleaner.py +41 -27
- reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
- reconcile/openshift_saas_deploy_trigger_images.py +1 -2
- reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
- reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
- reconcile/openshift_serviceaccount_tokens.py +138 -74
- reconcile/openshift_tekton_resources.py +89 -24
- reconcile/openshift_upgrade_watcher.py +110 -62
- reconcile/openshift_users.py +16 -15
- reconcile/openshift_vault_secrets.py +11 -6
- reconcile/oum/__init__.py +0 -0
- reconcile/oum/base.py +387 -0
- reconcile/oum/labelset.py +55 -0
- reconcile/oum/metrics.py +71 -0
- reconcile/oum/models.py +69 -0
- reconcile/oum/providers.py +59 -0
- reconcile/oum/standalone.py +196 -0
- reconcile/prometheus_rules_tester/integration.py +31 -23
- reconcile/quay_base.py +4 -1
- reconcile/quay_membership.py +1 -2
- reconcile/quay_mirror.py +111 -61
- reconcile/quay_mirror_org.py +34 -21
- reconcile/quay_permissions.py +7 -3
- reconcile/quay_repos.py +24 -32
- reconcile/queries.py +263 -198
- reconcile/query_validator.py +3 -5
- reconcile/resource_scraper.py +3 -4
- reconcile/{template_tester.py → resource_template_tester.py} +3 -3
- reconcile/rhidp/__init__.py +0 -0
- reconcile/rhidp/common.py +214 -0
- reconcile/rhidp/metrics.py +20 -0
- reconcile/rhidp/ocm_oidc_idp/__init__.py +0 -0
- reconcile/rhidp/ocm_oidc_idp/base.py +221 -0
- reconcile/rhidp/ocm_oidc_idp/integration.py +56 -0
- reconcile/rhidp/ocm_oidc_idp/metrics.py +22 -0
- reconcile/rhidp/sso_client/__init__.py +0 -0
- reconcile/rhidp/sso_client/base.py +266 -0
- reconcile/rhidp/sso_client/integration.py +60 -0
- reconcile/rhidp/sso_client/metrics.py +39 -0
- reconcile/run_integration.py +293 -0
- reconcile/saas_auto_promotions_manager/integration.py +69 -24
- reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +208 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py +28 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py +3 -4
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +172 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py +42 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +226 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py +23 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +108 -32
- reconcile/saas_auto_promotions_manager/meta.py +4 -0
- reconcile/saas_auto_promotions_manager/publisher.py +32 -4
- reconcile/saas_auto_promotions_manager/s3_exporter.py +77 -0
- reconcile/saas_auto_promotions_manager/subscriber.py +110 -23
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +48 -41
- reconcile/saas_file_validator.py +16 -6
- reconcile/sendgrid_teammates.py +27 -12
- reconcile/service_dependencies.py +0 -3
- reconcile/signalfx_endpoint_monitoring.py +2 -5
- reconcile/skupper_network/integration.py +10 -11
- reconcile/skupper_network/models.py +3 -5
- reconcile/skupper_network/reconciler.py +28 -35
- reconcile/skupper_network/site_controller.py +8 -8
- reconcile/slack_base.py +4 -7
- reconcile/slack_usergroups.py +249 -171
- reconcile/sql_query.py +324 -171
- reconcile/status.py +0 -1
- reconcile/status_board.py +275 -0
- reconcile/statuspage/__init__.py +0 -5
- reconcile/statuspage/atlassian.py +219 -80
- reconcile/statuspage/integration.py +9 -97
- reconcile/statuspage/integrations/__init__.py +0 -0
- reconcile/statuspage/integrations/components.py +77 -0
- reconcile/statuspage/integrations/maintenances.py +111 -0
- reconcile/statuspage/page.py +107 -72
- reconcile/statuspage/state.py +6 -11
- reconcile/statuspage/status.py +8 -12
- reconcile/templates/rosa-classic-cluster-creation.sh.j2 +60 -0
- reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +61 -0
- reconcile/templating/__init__.py +0 -0
- reconcile/templating/lib/__init__.py +0 -0
- reconcile/templating/lib/merge_request_manager.py +180 -0
- reconcile/templating/lib/model.py +20 -0
- reconcile/templating/lib/rendering.py +191 -0
- reconcile/templating/renderer.py +410 -0
- reconcile/templating/validator.py +153 -0
- reconcile/terraform_aws_route53.py +13 -10
- reconcile/terraform_cloudflare_dns.py +92 -122
- reconcile/terraform_cloudflare_resources.py +15 -13
- reconcile/terraform_cloudflare_users.py +27 -27
- reconcile/terraform_init/__init__.py +0 -0
- reconcile/terraform_init/integration.py +165 -0
- reconcile/terraform_init/merge_request.py +57 -0
- reconcile/terraform_init/merge_request_manager.py +102 -0
- reconcile/terraform_repo.py +403 -0
- reconcile/terraform_resources.py +266 -168
- reconcile/terraform_tgw_attachments.py +417 -167
- reconcile/terraform_users.py +40 -17
- reconcile/terraform_vpc_peerings.py +310 -142
- reconcile/terraform_vpc_resources/__init__.py +0 -0
- reconcile/terraform_vpc_resources/integration.py +220 -0
- reconcile/terraform_vpc_resources/merge_request.py +57 -0
- reconcile/terraform_vpc_resources/merge_request_manager.py +107 -0
- reconcile/typed_queries/alerting_services_settings.py +1 -2
- reconcile/typed_queries/app_interface_custom_messages.py +24 -0
- reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +17 -0
- reconcile/typed_queries/app_interface_metrics_exporter/__init__.py +0 -0
- reconcile/typed_queries/app_interface_metrics_exporter/onboarding_status.py +13 -0
- reconcile/typed_queries/app_interface_repo_url.py +1 -2
- reconcile/typed_queries/app_interface_state_settings.py +1 -3
- reconcile/typed_queries/app_interface_vault_settings.py +1 -2
- reconcile/typed_queries/app_quay_repos_escalation_policies.py +14 -0
- reconcile/typed_queries/apps.py +11 -0
- reconcile/typed_queries/aws_vpc_requests.py +9 -0
- reconcile/typed_queries/aws_vpcs.py +12 -0
- reconcile/typed_queries/cloudflare.py +10 -0
- reconcile/typed_queries/clusters.py +7 -5
- reconcile/typed_queries/clusters_minimal.py +6 -5
- reconcile/typed_queries/clusters_with_dms.py +16 -0
- reconcile/typed_queries/cost_report/__init__.py +0 -0
- reconcile/typed_queries/cost_report/app_names.py +22 -0
- reconcile/typed_queries/cost_report/cost_namespaces.py +43 -0
- reconcile/typed_queries/cost_report/settings.py +15 -0
- reconcile/typed_queries/dynatrace.py +10 -0
- reconcile/typed_queries/dynatrace_environments.py +14 -0
- reconcile/typed_queries/dynatrace_token_provider_token_specs.py +14 -0
- reconcile/typed_queries/external_resources.py +46 -0
- reconcile/typed_queries/get_state_aws_account.py +20 -0
- reconcile/typed_queries/glitchtip.py +10 -0
- reconcile/typed_queries/jenkins.py +25 -0
- reconcile/typed_queries/jira.py +7 -0
- reconcile/typed_queries/jira_settings.py +16 -0
- reconcile/typed_queries/jiralert_settings.py +22 -0
- reconcile/typed_queries/ocm.py +8 -0
- reconcile/typed_queries/pagerduty_instances.py +2 -7
- reconcile/typed_queries/quay.py +23 -0
- reconcile/typed_queries/repos.py +20 -8
- reconcile/typed_queries/reserved_networks.py +12 -0
- reconcile/typed_queries/saas_files.py +221 -167
- reconcile/typed_queries/slack.py +7 -0
- reconcile/typed_queries/slo_documents.py +12 -0
- reconcile/typed_queries/status_board.py +58 -0
- reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
- reconcile/typed_queries/terraform_namespaces.py +1 -2
- reconcile/typed_queries/terraform_tgw_attachments/__init__.py +0 -0
- reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +16 -0
- reconcile/typed_queries/unleash.py +10 -0
- reconcile/typed_queries/users.py +11 -0
- reconcile/typed_queries/vault.py +10 -0
- reconcile/unleash_feature_toggles/__init__.py +0 -0
- reconcile/unleash_feature_toggles/integration.py +287 -0
- reconcile/utils/acs/__init__.py +0 -0
- reconcile/utils/acs/base.py +81 -0
- reconcile/utils/acs/notifiers.py +143 -0
- reconcile/utils/acs/policies.py +163 -0
- reconcile/utils/acs/rbac.py +277 -0
- reconcile/utils/aggregated_list.py +11 -9
- reconcile/utils/amtool.py +6 -4
- reconcile/utils/aws_api.py +279 -66
- reconcile/utils/aws_api_typed/__init__.py +0 -0
- reconcile/utils/aws_api_typed/account.py +23 -0
- reconcile/utils/aws_api_typed/api.py +273 -0
- reconcile/utils/aws_api_typed/dynamodb.py +16 -0
- reconcile/utils/aws_api_typed/iam.py +67 -0
- reconcile/utils/aws_api_typed/organization.py +152 -0
- reconcile/utils/aws_api_typed/s3.py +26 -0
- reconcile/utils/aws_api_typed/service_quotas.py +79 -0
- reconcile/utils/aws_api_typed/sts.py +36 -0
- reconcile/utils/aws_api_typed/support.py +79 -0
- reconcile/utils/aws_helper.py +42 -3
- reconcile/utils/batches.py +11 -0
- reconcile/utils/binary.py +7 -9
- reconcile/utils/cloud_resource_best_practice/__init__.py +0 -0
- reconcile/utils/cloud_resource_best_practice/aws_rds.py +66 -0
- reconcile/utils/clusterhealth/__init__.py +0 -0
- reconcile/utils/clusterhealth/providerbase.py +39 -0
- reconcile/utils/clusterhealth/telemeter.py +39 -0
- reconcile/utils/config.py +3 -4
- reconcile/utils/deadmanssnitch_api.py +86 -0
- reconcile/utils/differ.py +205 -0
- reconcile/utils/disabled_integrations.py +4 -6
- reconcile/utils/dynatrace/__init__.py +0 -0
- reconcile/utils/dynatrace/client.py +93 -0
- reconcile/utils/early_exit_cache.py +289 -0
- reconcile/utils/elasticsearch_exceptions.py +5 -0
- reconcile/utils/environ.py +2 -2
- reconcile/utils/exceptions.py +4 -0
- reconcile/utils/expiration.py +4 -8
- reconcile/utils/extended_early_exit.py +210 -0
- reconcile/utils/external_resource_spec.py +34 -12
- reconcile/utils/external_resources.py +48 -20
- reconcile/utils/filtering.py +16 -0
- reconcile/utils/git.py +49 -16
- reconcile/utils/github_api.py +10 -9
- reconcile/utils/gitlab_api.py +333 -190
- reconcile/utils/glitchtip/client.py +97 -100
- reconcile/utils/glitchtip/models.py +89 -11
- reconcile/utils/gql.py +157 -58
- reconcile/utils/grouping.py +17 -0
- reconcile/utils/helm.py +89 -18
- reconcile/utils/helpers.py +51 -0
- reconcile/utils/imap_client.py +5 -6
- reconcile/utils/internal_groups/__init__.py +0 -0
- reconcile/utils/internal_groups/client.py +160 -0
- reconcile/utils/internal_groups/models.py +71 -0
- reconcile/utils/jenkins_api.py +10 -34
- reconcile/utils/jinja2/__init__.py +0 -0
- reconcile/utils/{jinja2_ext.py → jinja2/extensions.py} +6 -4
- reconcile/utils/jinja2/filters.py +142 -0
- reconcile/utils/jinja2/utils.py +278 -0
- reconcile/utils/jira_client.py +165 -8
- reconcile/utils/jjb_client.py +47 -35
- reconcile/utils/jobcontroller/__init__.py +0 -0
- reconcile/utils/jobcontroller/controller.py +413 -0
- reconcile/utils/jobcontroller/models.py +195 -0
- reconcile/utils/jsonpath.py +4 -5
- reconcile/utils/jump_host.py +13 -12
- reconcile/utils/keycloak.py +106 -0
- reconcile/utils/ldap_client.py +35 -6
- reconcile/utils/lean_terraform_client.py +115 -6
- reconcile/utils/membershipsources/__init__.py +0 -0
- reconcile/utils/membershipsources/app_interface_resolver.py +60 -0
- reconcile/utils/membershipsources/models.py +91 -0
- reconcile/utils/membershipsources/resolver.py +110 -0
- reconcile/utils/merge_request_manager/__init__.py +0 -0
- reconcile/utils/merge_request_manager/merge_request_manager.py +99 -0
- reconcile/utils/merge_request_manager/parser.py +67 -0
- reconcile/utils/metrics.py +511 -1
- reconcile/utils/models.py +123 -0
- reconcile/utils/mr/README.md +198 -0
- reconcile/utils/mr/__init__.py +14 -10
- reconcile/utils/mr/app_interface_reporter.py +2 -2
- reconcile/utils/mr/aws_access.py +4 -4
- reconcile/utils/mr/base.py +51 -31
- reconcile/utils/mr/clusters_updates.py +10 -7
- reconcile/utils/mr/glitchtip_access_reporter.py +2 -4
- reconcile/utils/mr/labels.py +14 -1
- reconcile/utils/mr/notificator.py +1 -3
- reconcile/utils/mr/ocm_update_recommended_version.py +1 -2
- reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +7 -3
- reconcile/utils/mr/promote_qontract.py +203 -0
- reconcile/utils/mr/user_maintenance.py +24 -4
- reconcile/utils/oauth2_backend_application_session.py +132 -0
- reconcile/utils/oc.py +194 -170
- reconcile/utils/oc_connection_parameters.py +40 -51
- reconcile/utils/oc_filters.py +11 -13
- reconcile/utils/oc_map.py +14 -35
- reconcile/utils/ocm/__init__.py +30 -1
- reconcile/utils/ocm/addons.py +228 -0
- reconcile/utils/ocm/base.py +618 -5
- reconcile/utils/ocm/cluster_groups.py +5 -56
- reconcile/utils/ocm/clusters.py +111 -99
- reconcile/utils/ocm/identity_providers.py +66 -0
- reconcile/utils/ocm/label_sources.py +75 -0
- reconcile/utils/ocm/labels.py +139 -54
- reconcile/utils/ocm/manifests.py +39 -0
- reconcile/utils/ocm/ocm.py +182 -928
- reconcile/utils/ocm/products.py +758 -0
- reconcile/utils/ocm/search_filters.py +20 -28
- reconcile/utils/ocm/service_log.py +32 -79
- reconcile/utils/ocm/sre_capability_labels.py +51 -0
- reconcile/utils/ocm/status_board.py +66 -0
- reconcile/utils/ocm/subscriptions.py +49 -59
- reconcile/utils/ocm/syncsets.py +39 -0
- reconcile/utils/ocm/upgrades.py +181 -0
- reconcile/utils/ocm_base_client.py +71 -36
- reconcile/utils/openshift_resource.py +113 -67
- reconcile/utils/output.py +18 -11
- reconcile/utils/pagerduty_api.py +16 -10
- reconcile/utils/parse_dhms_duration.py +13 -1
- reconcile/utils/prometheus.py +123 -0
- reconcile/utils/promotion_state.py +56 -19
- reconcile/utils/promtool.py +5 -8
- reconcile/utils/quay_api.py +13 -25
- reconcile/utils/raw_github_api.py +3 -5
- reconcile/utils/repo_owners.py +2 -8
- reconcile/utils/rest_api_base.py +126 -0
- reconcile/utils/rosa/__init__.py +0 -0
- reconcile/utils/rosa/rosa_cli.py +310 -0
- reconcile/utils/rosa/session.py +201 -0
- reconcile/utils/ruamel.py +16 -0
- reconcile/utils/runtime/__init__.py +0 -1
- reconcile/utils/runtime/desired_state_diff.py +9 -20
- reconcile/utils/runtime/environment.py +33 -8
- reconcile/utils/runtime/integration.py +28 -12
- reconcile/utils/runtime/meta.py +1 -3
- reconcile/utils/runtime/runner.py +8 -11
- reconcile/utils/runtime/sharding.py +93 -36
- reconcile/utils/saasherder/__init__.py +1 -1
- reconcile/utils/saasherder/interfaces.py +143 -138
- reconcile/utils/saasherder/models.py +201 -43
- reconcile/utils/saasherder/saasherder.py +508 -378
- reconcile/utils/secret_reader.py +22 -27
- reconcile/utils/semver_helper.py +15 -1
- reconcile/utils/slack_api.py +124 -36
- reconcile/utils/smtp_client.py +1 -2
- reconcile/utils/sqs_gateway.py +10 -6
- reconcile/utils/state.py +276 -127
- reconcile/utils/terraform/config_client.py +6 -7
- reconcile/utils/terraform_client.py +284 -125
- reconcile/utils/terrascript/cloudflare_client.py +38 -17
- reconcile/utils/terrascript/cloudflare_resources.py +67 -18
- reconcile/utils/terrascript/models.py +2 -3
- reconcile/utils/terrascript/resources.py +1 -2
- reconcile/utils/terrascript_aws_client.py +1292 -540
- reconcile/utils/three_way_diff_strategy.py +157 -0
- reconcile/utils/unleash/__init__.py +11 -0
- reconcile/utils/{unleash.py → unleash/client.py} +35 -29
- reconcile/utils/unleash/server.py +145 -0
- reconcile/utils/vault.py +42 -32
- reconcile/utils/vaultsecretref.py +2 -4
- reconcile/utils/vcs.py +250 -0
- reconcile/vault_replication.py +38 -31
- reconcile/vpc_peerings_validator.py +82 -13
- tools/app_interface_metrics_exporter.py +70 -0
- tools/app_interface_reporter.py +44 -157
- tools/cli_commands/container_images_report.py +154 -0
- tools/cli_commands/cost_report/__init__.py +0 -0
- tools/cli_commands/cost_report/aws.py +137 -0
- tools/cli_commands/cost_report/cost_management_api.py +155 -0
- tools/cli_commands/cost_report/model.py +49 -0
- tools/cli_commands/cost_report/openshift.py +166 -0
- tools/cli_commands/cost_report/openshift_cost_optimization.py +187 -0
- tools/cli_commands/cost_report/response.py +124 -0
- tools/cli_commands/cost_report/util.py +72 -0
- tools/cli_commands/cost_report/view.py +524 -0
- tools/cli_commands/erv2.py +620 -0
- tools/cli_commands/gpg_encrypt.py +5 -8
- tools/cli_commands/systems_and_tools.py +489 -0
- tools/glitchtip_access_revalidation.py +1 -1
- tools/qontract_cli.py +2301 -673
- tools/saas_metrics_exporter/__init__.py +0 -0
- tools/saas_metrics_exporter/commit_distance/__init__.py +0 -0
- tools/saas_metrics_exporter/commit_distance/channel.py +63 -0
- tools/saas_metrics_exporter/commit_distance/commit_distance.py +103 -0
- tools/saas_metrics_exporter/commit_distance/metrics.py +19 -0
- tools/saas_metrics_exporter/main.py +99 -0
- tools/saas_promotion_state/__init__.py +0 -0
- tools/saas_promotion_state/saas_promotion_state.py +105 -0
- tools/sd_app_sre_alert_report.py +145 -0
- tools/template_validation.py +107 -0
- e2e_tests/cli.py +0 -83
- e2e_tests/create_namespace.py +0 -43
- e2e_tests/dedicated_admin_rolebindings.py +0 -44
- e2e_tests/dedicated_admin_test_base.py +0 -39
- e2e_tests/default_network_policies.py +0 -47
- e2e_tests/default_project_labels.py +0 -52
- e2e_tests/network_policy_test_base.py +0 -17
- e2e_tests/test_base.py +0 -56
- qontract_reconcile-0.9.1rc298.dist-info/METADATA +0 -63
- qontract_reconcile-0.9.1rc298.dist-info/RECORD +0 -585
- qontract_reconcile-0.9.1rc298.dist-info/top_level.txt +0 -4
- reconcile/ecr_mirror.py +0 -152
- reconcile/github_scanner.py +0 -74
- reconcile/gitlab_integrations.py +0 -63
- reconcile/gql_definitions/ocm_oidc_idp/clusters.py +0 -195
- reconcile/gql_definitions/ocp_release_mirror/ocp_release_mirror.py +0 -287
- reconcile/integrations_validator.py +0 -18
- reconcile/jenkins_plugins.py +0 -129
- reconcile/kafka_clusters.py +0 -208
- reconcile/ocm_cluster_admin.py +0 -42
- reconcile/ocm_oidc_idp.py +0 -198
- reconcile/ocp_release_mirror.py +0 -373
- reconcile/prometheus_rules_tester_old.py +0 -436
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -279
- reconcile/saas_auto_promotions_manager/utils/vcs.py +0 -141
- reconcile/sentry_config.py +0 -613
- reconcile/sentry_helper.py +0 -69
- reconcile/test/conftest.py +0 -187
- reconcile/test/fixtures.py +0 -24
- reconcile/test/saas_auto_promotions_manager/conftest.py +0 -69
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -110
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -10
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_housekeeping.py +0 -200
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -151
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -63
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -46
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -94
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -44
- reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -74
- reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
- reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -155
- reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -173
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -226
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -224
- reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -350
- reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -129
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -70
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -63
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -74
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -65
- reconcile/test/test_aggregated_list.py +0 -237
- reconcile/test/test_amtool.py +0 -37
- reconcile/test/test_auto_promoter.py +0 -295
- reconcile/test/test_aws_ami_share.py +0 -68
- reconcile/test/test_aws_iam_keys.py +0 -70
- reconcile/test/test_aws_iam_password_reset.py +0 -35
- reconcile/test/test_aws_support_cases_sos.py +0 -23
- reconcile/test/test_checkpoint.py +0 -178
- reconcile/test/test_cli.py +0 -41
- reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
- reconcile/test/test_gabi_authorized_users.py +0 -72
- reconcile/test/test_github_org.py +0 -154
- reconcile/test/test_github_repo_invites.py +0 -123
- reconcile/test/test_gitlab_housekeeping.py +0 -88
- reconcile/test/test_gitlab_labeler.py +0 -129
- reconcile/test/test_gitlab_members.py +0 -283
- reconcile/test/test_instrumented_wrappers.py +0 -18
- reconcile/test/test_integrations_manager.py +0 -995
- reconcile/test/test_jenkins_worker_fleets.py +0 -55
- reconcile/test/test_jump_host.py +0 -117
- reconcile/test/test_ldap_users.py +0 -123
- reconcile/test/test_make.py +0 -28
- reconcile/test/test_ocm_additional_routers.py +0 -134
- reconcile/test/test_ocm_addons_upgrade_scheduler_org.py +0 -149
- reconcile/test/test_ocm_clusters.py +0 -598
- reconcile/test/test_ocm_clusters_manifest_updates.py +0 -89
- reconcile/test/test_ocm_oidc_idp.py +0 -315
- reconcile/test/test_ocm_update_recommended_version.py +0 -145
- reconcile/test/test_ocm_upgrade_scheduler.py +0 -614
- reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -129
- reconcile/test/test_openshift_base.py +0 -730
- reconcile/test/test_openshift_namespace_labels.py +0 -345
- reconcile/test/test_openshift_namespaces.py +0 -256
- reconcile/test/test_openshift_resource.py +0 -415
- reconcile/test/test_openshift_resources_base.py +0 -440
- reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -310
- reconcile/test/test_openshift_tekton_resources.py +0 -253
- reconcile/test/test_openshift_upgrade_watcher.py +0 -146
- reconcile/test/test_prometheus_rules_tester.py +0 -151
- reconcile/test/test_prometheus_rules_tester_old.py +0 -77
- reconcile/test/test_quay_membership.py +0 -86
- reconcile/test/test_quay_mirror.py +0 -109
- reconcile/test/test_quay_mirror_org.py +0 -70
- reconcile/test/test_quay_repos.py +0 -59
- reconcile/test/test_queries.py +0 -53
- reconcile/test/test_repo_owners.py +0 -47
- reconcile/test/test_requests_sender.py +0 -139
- reconcile/test/test_saasherder.py +0 -1074
- reconcile/test/test_saasherder_allowed_secret_paths.py +0 -127
- reconcile/test/test_secret_reader.py +0 -153
- reconcile/test/test_slack_base.py +0 -185
- reconcile/test/test_slack_usergroups.py +0 -744
- reconcile/test/test_sql_query.py +0 -19
- reconcile/test/test_terraform_cloudflare_dns.py +0 -117
- reconcile/test/test_terraform_cloudflare_resources.py +0 -106
- reconcile/test/test_terraform_cloudflare_users.py +0 -749
- reconcile/test/test_terraform_resources.py +0 -257
- reconcile/test/test_terraform_tgw_attachments.py +0 -631
- reconcile/test/test_terraform_users.py +0 -57
- reconcile/test/test_terraform_vpc_peerings.py +0 -499
- reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1061
- reconcile/test/test_unleash.py +0 -138
- reconcile/test/test_utils_aws_api.py +0 -240
- reconcile/test/test_utils_aws_helper.py +0 -80
- reconcile/test/test_utils_cluster_version_data.py +0 -177
- reconcile/test/test_utils_data_structures.py +0 -13
- reconcile/test/test_utils_disabled_integrations.py +0 -86
- reconcile/test/test_utils_expiration.py +0 -109
- reconcile/test/test_utils_external_resource_spec.py +0 -383
- reconcile/test/test_utils_external_resources.py +0 -247
- reconcile/test/test_utils_github_api.py +0 -73
- reconcile/test/test_utils_gitlab_api.py +0 -20
- reconcile/test/test_utils_gpg.py +0 -69
- reconcile/test/test_utils_gql.py +0 -81
- reconcile/test/test_utils_helm.py +0 -306
- reconcile/test/test_utils_helpers.py +0 -55
- reconcile/test/test_utils_imap_client.py +0 -65
- reconcile/test/test_utils_jjb_client.py +0 -52
- reconcile/test/test_utils_jsonpath.py +0 -286
- reconcile/test/test_utils_ldap_client.py +0 -51
- reconcile/test/test_utils_mr.py +0 -226
- reconcile/test/test_utils_mr_clusters_updates.py +0 -77
- reconcile/test/test_utils_oc.py +0 -984
- reconcile/test/test_utils_ocm.py +0 -110
- reconcile/test/test_utils_pagerduty_api.py +0 -251
- reconcile/test/test_utils_parse_dhms_duration.py +0 -34
- reconcile/test/test_utils_password_validator.py +0 -155
- reconcile/test/test_utils_quay_api.py +0 -86
- reconcile/test/test_utils_semver_helper.py +0 -19
- reconcile/test/test_utils_sharding.py +0 -56
- reconcile/test/test_utils_slack_api.py +0 -439
- reconcile/test/test_utils_smtp_client.py +0 -73
- reconcile/test/test_utils_state.py +0 -256
- reconcile/test/test_utils_terraform.py +0 -13
- reconcile/test/test_utils_terraform_client.py +0 -585
- reconcile/test/test_utils_terraform_config_client.py +0 -219
- reconcile/test/test_utils_terrascript_aws_client.py +0 -277
- reconcile/test/test_utils_terrascript_cloudflare_client.py +0 -597
- reconcile/test/test_utils_terrascript_cloudflare_resources.py +0 -26
- reconcile/test/test_vault_replication.py +0 -515
- reconcile/test/test_vault_utils.py +0 -47
- reconcile/test/test_version_bump.py +0 -18
- reconcile/test/test_vpc_peerings_validator.py +0 -103
- reconcile/test/test_wrong_region.py +0 -78
- reconcile/typed_queries/glitchtip_settings.py +0 -18
- reconcile/typed_queries/ocp_release_mirror.py +0 -11
- reconcile/unleash_watcher.py +0 -120
- reconcile/utils/git_secrets.py +0 -63
- reconcile/utils/mr/auto_promoter.py +0 -218
- reconcile/utils/sentry_client.py +0 -383
- release/test_version.py +0 -50
- release/version.py +0 -100
- tools/test/test_qontract_cli.py +0 -60
- tools/test/test_sre_checkpoints.py +0 -79
- /e2e_tests/__init__.py → /reconcile/aus/upgrades.py +0 -0
- /reconcile/{gql_definitions/ocp_release_mirror → aws_account_manager}/__init__.py +0 -0
- /reconcile/{test → aws_ami_cleanup}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager → aws_cloudwatch_log_retention}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/merge_request_manager → aws_saml_idp}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager → aws_saml_roles}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/renderer → aws_version_sync}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/subscriber → aws_version_sync/merge_request_manager}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/utils → cluster_auth_rhidp}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/utils/saas_files_inventory → dynatrace_token_provider}/__init__.py +0 -0
- {release → reconcile/endpoints_discovery}/__init__.py +0 -0
- {tools/test → reconcile/external_resources}/__init__.py +0 -0
reconcile/utils/oc.py
CHANGED
@@ -2,9 +2,9 @@ import copy
|
|
2
2
|
import json
|
3
3
|
import logging
|
4
4
|
import os
|
5
|
+
import pathlib
|
5
6
|
import re
|
6
7
|
import subprocess
|
7
|
-
import tempfile
|
8
8
|
import threading
|
9
9
|
import time
|
10
10
|
from collections.abc import (
|
@@ -17,14 +17,10 @@ from datetime import datetime
|
|
17
17
|
from functools import wraps
|
18
18
|
from subprocess import Popen
|
19
19
|
from threading import Lock
|
20
|
-
from typing import
|
21
|
-
Any,
|
22
|
-
Optional,
|
23
|
-
Union,
|
24
|
-
)
|
20
|
+
from typing import Any
|
25
21
|
|
26
22
|
import urllib3
|
27
|
-
from kubernetes.client import (
|
23
|
+
from kubernetes.client import ( # type: ignore[attr-defined]
|
28
24
|
ApiClient,
|
29
25
|
Configuration,
|
30
26
|
)
|
@@ -55,6 +51,7 @@ from reconcile.utils.jump_host import (
|
|
55
51
|
)
|
56
52
|
from reconcile.utils.metrics import reconcile_time
|
57
53
|
from reconcile.utils.oc_connection_parameters import OCConnectionParameters
|
54
|
+
from reconcile.utils.openshift_resource import OpenshiftResource as OR
|
58
55
|
from reconcile.utils.secret_reader import (
|
59
56
|
SecretNotFound,
|
60
57
|
SecretReader,
|
@@ -66,6 +63,13 @@ urllib3.disable_warnings()
|
|
66
63
|
GET_REPLICASET_MAX_ATTEMPTS = 20
|
67
64
|
|
68
65
|
|
66
|
+
oc_run_execution_counter = Counter(
|
67
|
+
name="oc_run_execution_counter",
|
68
|
+
documentation="Counts _run method executions per integration",
|
69
|
+
labelnames=["integration"],
|
70
|
+
)
|
71
|
+
|
72
|
+
|
69
73
|
class StatusCodeError(Exception):
|
70
74
|
pass
|
71
75
|
|
@@ -130,6 +134,10 @@ class JobNotRunningError(Exception):
|
|
130
134
|
pass
|
131
135
|
|
132
136
|
|
137
|
+
class RequestEntityTooLargeError(Exception):
|
138
|
+
pass
|
139
|
+
|
140
|
+
|
133
141
|
class OCDecorators:
|
134
142
|
@classmethod
|
135
143
|
def process_reconcile_time(cls, function):
|
@@ -156,7 +164,7 @@ class OCDecorators:
|
|
156
164
|
@wraps(function)
|
157
165
|
def wrapper(*args, **kwargs):
|
158
166
|
result = function(*args, **kwargs)
|
159
|
-
msg = result[:-1] if isinstance(result,
|
167
|
+
msg = result[:-1] if isinstance(result, list | tuple) else result
|
160
168
|
|
161
169
|
if not isinstance(msg, OCProcessReconcileTimeDecoratorMsg):
|
162
170
|
return result
|
@@ -166,10 +174,10 @@ class OCDecorators:
|
|
166
174
|
time_spent = time.time() - commit_time
|
167
175
|
|
168
176
|
try:
|
169
|
-
resource_kind = msg.resource
|
170
|
-
resource_name = msg.resource
|
171
|
-
annotations = msg.resource
|
172
|
-
except
|
177
|
+
resource_kind = msg.resource.kind
|
178
|
+
resource_name = msg.resource.name
|
179
|
+
annotations = msg.resource.annotations
|
180
|
+
except Exception as e:
|
173
181
|
logging.warning(f"Error processing metric: {e}")
|
174
182
|
return result
|
175
183
|
|
@@ -208,11 +216,11 @@ class OCDecorators:
|
|
208
216
|
class OCProcessReconcileTimeDecoratorMsg:
|
209
217
|
def __init__(
|
210
218
|
self,
|
211
|
-
namespace,
|
212
|
-
resource,
|
213
|
-
server,
|
214
|
-
slow_oc_reconcile_threshold,
|
215
|
-
is_log_slow_oc_reconcile,
|
219
|
+
namespace: str,
|
220
|
+
resource: OR,
|
221
|
+
server: str | None,
|
222
|
+
slow_oc_reconcile_threshold: float,
|
223
|
+
is_log_slow_oc_reconcile: bool,
|
216
224
|
):
|
217
225
|
self.namespace = namespace
|
218
226
|
self.resource = resource
|
@@ -230,21 +238,17 @@ def equal_spec_template(t1: dict, t2: dict) -> bool:
|
|
230
238
|
"""Compare two spec.templates."""
|
231
239
|
t1_copy = copy.deepcopy(t1)
|
232
240
|
t2_copy = copy.deepcopy(t2)
|
233
|
-
|
241
|
+
with suppress(KeyError):
|
234
242
|
del t1_copy["metadata"]["labels"]["pod-template-hash"]
|
235
|
-
|
236
|
-
pass
|
237
|
-
try:
|
243
|
+
with suppress(KeyError):
|
238
244
|
del t2_copy["metadata"]["labels"]["pod-template-hash"]
|
239
|
-
except KeyError:
|
240
|
-
pass
|
241
245
|
return t1_copy == t2_copy
|
242
246
|
|
243
247
|
|
244
248
|
@dataclass
|
245
|
-
class
|
249
|
+
class OCCliApiResource:
|
246
250
|
"""This class mimics kubernetes.dynamic.resource.Resource and it's used
|
247
|
-
To get Api Resources with the
|
251
|
+
To get Api Resources with the OCCli client"""
|
248
252
|
|
249
253
|
kind: str
|
250
254
|
group: str
|
@@ -254,23 +258,23 @@ class OCDeprecatedApiResource:
|
|
254
258
|
@property
|
255
259
|
def group_version(self):
|
256
260
|
if self.group:
|
257
|
-
return "{}/{
|
261
|
+
return f"{self.group}/{self.api_version}"
|
258
262
|
return self.api_version
|
259
263
|
|
260
264
|
|
261
|
-
class
|
265
|
+
class OCCli: # pylint: disable=too-many-public-methods
|
262
266
|
def __init__(
|
263
267
|
self,
|
264
|
-
cluster_name:
|
265
|
-
server:
|
266
|
-
token:
|
267
|
-
jh:
|
268
|
-
settings:
|
268
|
+
cluster_name: str | None,
|
269
|
+
server: str | None,
|
270
|
+
token: str | None,
|
271
|
+
jh: Mapping[Any, Any] | None = None,
|
272
|
+
settings: Mapping[Any, Any] | None = None,
|
269
273
|
init_projects: bool = False,
|
270
274
|
init_api_resources: bool = False,
|
271
275
|
local: bool = False,
|
272
276
|
insecure_skip_tls_verify: bool = False,
|
273
|
-
connection_parameters:
|
277
|
+
connection_parameters: OCConnectionParameters | None = None,
|
274
278
|
):
|
275
279
|
"""
|
276
280
|
As of now we have to conform with 2 ways to initialize this client:
|
@@ -309,10 +313,10 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
309
313
|
def _init_old_without_types(
|
310
314
|
self,
|
311
315
|
cluster_name: str,
|
312
|
-
server:
|
313
|
-
token:
|
314
|
-
jh:
|
315
|
-
settings:
|
316
|
+
server: str | None,
|
317
|
+
token: str | None,
|
318
|
+
jh: Mapping[Any, Any] | None = None,
|
319
|
+
settings: Mapping[Any, Any] | None = None,
|
316
320
|
init_projects: bool = False,
|
317
321
|
init_api_resources: bool = False,
|
318
322
|
local: bool = False,
|
@@ -366,6 +370,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
366
370
|
self.api_resources_lock = threading.RLock()
|
367
371
|
self.init_api_resources = init_api_resources
|
368
372
|
self.api_resources = {}
|
373
|
+
self.projects = set()
|
369
374
|
if self.init_api_resources:
|
370
375
|
self.api_resources = self.get_api_resources()
|
371
376
|
|
@@ -375,7 +380,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
375
380
|
kind = "Project.project.openshift.io"
|
376
381
|
else:
|
377
382
|
kind = "Namespace"
|
378
|
-
self.projects =
|
383
|
+
self.projects = {p["metadata"]["name"] for p in self.get_all(kind)["items"]}
|
379
384
|
|
380
385
|
self.slow_oc_reconcile_threshold = float(
|
381
386
|
os.environ.get("SLOW_OC_RECONCILE_THRESHOLD", 600)
|
@@ -383,7 +388,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
383
388
|
|
384
389
|
self.is_log_slow_oc_reconcile = os.environ.get(
|
385
390
|
"LOG_SLOW_OC_RECONCILE", ""
|
386
|
-
).lower() in
|
391
|
+
).lower() in {"true", "yes"}
|
387
392
|
|
388
393
|
def _init(
|
389
394
|
self,
|
@@ -438,6 +443,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
438
443
|
self.api_resources_lock = threading.RLock()
|
439
444
|
self.init_api_resources = init_api_resources
|
440
445
|
self.api_resources = {}
|
446
|
+
self.projects = set()
|
441
447
|
if self.init_api_resources:
|
442
448
|
self.api_resources = self.get_api_resources()
|
443
449
|
|
@@ -447,7 +453,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
447
453
|
kind = "Project.project.openshift.io"
|
448
454
|
else:
|
449
455
|
kind = "Namespace"
|
450
|
-
self.projects =
|
456
|
+
self.projects = {p["metadata"]["name"] for p in self.get_all(kind)["items"]}
|
451
457
|
|
452
458
|
self.slow_oc_reconcile_threshold = float(
|
453
459
|
os.environ.get("SLOW_OC_RECONCILE_THRESHOLD", 600)
|
@@ -455,7 +461,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
455
461
|
|
456
462
|
self.is_log_slow_oc_reconcile = os.environ.get(
|
457
463
|
"LOG_SLOW_OC_RECONCILE", ""
|
458
|
-
).lower() in
|
464
|
+
).lower() in {"true", "yes"}
|
459
465
|
|
460
466
|
def whoami(self):
|
461
467
|
return self._run(["whoami"])
|
@@ -477,9 +483,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
477
483
|
cmd.extend(["-n", namespace])
|
478
484
|
|
479
485
|
if "labels" in kwargs:
|
480
|
-
labels_list = [
|
481
|
-
"{}={}".format(k, v) for k, v in kwargs.get("labels").items()
|
482
|
-
]
|
486
|
+
labels_list = [f"{k}={v}" for k, v in kwargs.get("labels").items()]
|
483
487
|
|
484
488
|
cmd.append("-l")
|
485
489
|
cmd.append(",".join(labels_list))
|
@@ -527,7 +531,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
527
531
|
]
|
528
532
|
self._run(cmd)
|
529
533
|
|
530
|
-
def _msg_to_process_reconcile_time(self, namespace, resource):
|
534
|
+
def _msg_to_process_reconcile_time(self, namespace: str, resource: OR):
|
531
535
|
return OCProcessReconcileTimeDecoratorMsg(
|
532
536
|
namespace=namespace,
|
533
537
|
resource=resource,
|
@@ -550,53 +554,29 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
550
554
|
result = self._run(cmd, stdin=json.dumps(template, sort_keys=True))
|
551
555
|
return json.loads(result)["items"]
|
552
556
|
|
553
|
-
def release_mirror(self, from_release, to, to_release, dockerconfig):
|
554
|
-
with tempfile.NamedTemporaryFile() as fp:
|
555
|
-
content = json.dumps(dockerconfig)
|
556
|
-
fp.write(content.encode())
|
557
|
-
fp.seek(0)
|
558
|
-
|
559
|
-
cmd = [
|
560
|
-
"adm",
|
561
|
-
"--registry-config",
|
562
|
-
fp.name,
|
563
|
-
"release",
|
564
|
-
"mirror",
|
565
|
-
"--from",
|
566
|
-
from_release,
|
567
|
-
"--to",
|
568
|
-
to,
|
569
|
-
"--to-release-image",
|
570
|
-
to_release,
|
571
|
-
"--max-per-registry",
|
572
|
-
"1",
|
573
|
-
]
|
574
|
-
|
575
|
-
self._run(cmd)
|
576
|
-
|
577
557
|
@OCDecorators.process_reconcile_time
|
578
558
|
def apply(self, namespace, resource):
|
579
559
|
cmd = ["apply", "-n", namespace, "-f", "-"]
|
580
560
|
self._run(cmd, stdin=resource.toJSON(), apply=True)
|
581
|
-
return self._msg_to_process_reconcile_time(namespace, resource
|
561
|
+
return self._msg_to_process_reconcile_time(namespace, resource)
|
582
562
|
|
583
563
|
@OCDecorators.process_reconcile_time
|
584
564
|
def create(self, namespace, resource):
|
585
565
|
cmd = ["create", "-n", namespace, "-f", "-"]
|
586
566
|
self._run(cmd, stdin=resource.toJSON(), apply=True)
|
587
|
-
return self._msg_to_process_reconcile_time(namespace, resource
|
567
|
+
return self._msg_to_process_reconcile_time(namespace, resource)
|
588
568
|
|
589
569
|
@OCDecorators.process_reconcile_time
|
590
570
|
def replace(self, namespace, resource):
|
591
571
|
cmd = ["replace", "-n", namespace, "-f", "-"]
|
592
572
|
self._run(cmd, stdin=resource.toJSON(), apply=True)
|
593
|
-
return self._msg_to_process_reconcile_time(namespace, resource
|
573
|
+
return self._msg_to_process_reconcile_time(namespace, resource)
|
594
574
|
|
595
575
|
@OCDecorators.process_reconcile_time
|
596
576
|
def patch(self, namespace, kind, name, patch):
|
597
577
|
cmd = ["patch", "-n", namespace, kind, name, "-p", json.dumps(patch)]
|
598
578
|
self._run(cmd)
|
599
|
-
resource = {"kind": kind, "metadata": {"name": name}}
|
579
|
+
resource = OR({"kind": kind, "metadata": {"name": name}}, "", "")
|
600
580
|
return self._msg_to_process_reconcile_time(namespace, resource)
|
601
581
|
|
602
582
|
@OCDecorators.process_reconcile_time
|
@@ -611,7 +591,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
611
591
|
if not cascade:
|
612
592
|
cmd.append("--cascade=orphan")
|
613
593
|
self._run(cmd)
|
614
|
-
resource = {"kind": kind, "metadata": {"name": name}}
|
594
|
+
resource = OR({"kind": kind, "metadata": {"name": name}}, "", "")
|
615
595
|
return self._msg_to_process_reconcile_time(namespace, resource)
|
616
596
|
|
617
597
|
@OCDecorators.process_reconcile_time
|
@@ -623,13 +603,12 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
623
603
|
cmd = ["label"] + ns + [kind, name, overwrite_param]
|
624
604
|
cmd.extend(added + removed)
|
625
605
|
self._run(cmd)
|
626
|
-
resource = {"kind": kind, "metadata": {"name": name}}
|
606
|
+
resource = OR({"kind": kind, "metadata": {"name": name}}, "", "")
|
627
607
|
return self._msg_to_process_reconcile_time(namespace, resource)
|
628
608
|
|
629
609
|
def project_exists(self, name):
|
630
|
-
if self.
|
631
|
-
return
|
632
|
-
|
610
|
+
if name in self.projects:
|
611
|
+
return True
|
633
612
|
try:
|
634
613
|
if self.is_kind_supported("Project"):
|
635
614
|
self.get(None, "Project.project.openshift.io", name)
|
@@ -654,7 +633,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
654
633
|
raise e
|
655
634
|
|
656
635
|
# This return will be removed by the last decorator
|
657
|
-
resource = {"kind": "Namespace", "metadata": {"name": namespace}}
|
636
|
+
resource = OR({"kind": "Namespace", "metadata": {"name": namespace}}, "", "")
|
658
637
|
return self._msg_to_process_reconcile_time(namespace, resource)
|
659
638
|
|
660
639
|
@OCDecorators.process_reconcile_time
|
@@ -666,7 +645,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
666
645
|
self._run(cmd)
|
667
646
|
|
668
647
|
# This return will be removed by the last decorator
|
669
|
-
resource = {"kind": "Namespace", "metadata": {"name": namespace}}
|
648
|
+
resource = OR({"kind": "Namespace", "metadata": {"name": namespace}}, "", "")
|
670
649
|
return self._msg_to_process_reconcile_time(namespace, resource)
|
671
650
|
|
672
651
|
def get_group_if_exists(self, name):
|
@@ -725,7 +704,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
725
704
|
group_version = r[-3].split("/", 1)
|
726
705
|
group = "" if len(group_version) == 1 else group_version[0]
|
727
706
|
api_version = group_version[-1]
|
728
|
-
obj =
|
707
|
+
obj = OCCliApiResource(kind, group, api_version, namespaced)
|
729
708
|
d = self.api_resources.setdefault(kind, [])
|
730
709
|
d.append(obj)
|
731
710
|
|
@@ -744,27 +723,72 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
744
723
|
ready_pods = [
|
745
724
|
pod
|
746
725
|
for pod in pods
|
747
|
-
if pod["status"].get("phase") in
|
726
|
+
if pod["status"].get("phase") in {"Running", "Succeeded"}
|
748
727
|
]
|
749
728
|
|
750
729
|
if not ready_pods:
|
751
730
|
raise JobNotRunningError(name)
|
752
731
|
|
753
|
-
def job_logs(
|
754
|
-
self
|
732
|
+
def job_logs(
|
733
|
+
self,
|
734
|
+
namespace,
|
735
|
+
name,
|
736
|
+
follow,
|
737
|
+
output,
|
738
|
+
wait_for_job_running=True,
|
739
|
+
wait_for_logs_process=False,
|
740
|
+
):
|
741
|
+
if wait_for_job_running:
|
742
|
+
self.wait_for_job_running(namespace, name)
|
743
|
+
|
755
744
|
cmd = ["logs", "--all-containers=true", "-n", namespace, f"job/{name}"]
|
756
745
|
if follow:
|
757
746
|
cmd.append("-f")
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
747
|
+
|
748
|
+
if isinstance(output, str | pathlib.Path):
|
749
|
+
output_file = open(os.path.join(output, name), "w", encoding="locale") # noqa: SIM115
|
750
|
+
else:
|
751
|
+
# assume it's a file-like object, e.g. sys.stdout, TextIO, ...
|
752
|
+
output_file = output
|
753
|
+
|
754
|
+
if wait_for_logs_process:
|
755
|
+
subprocess.run(self.oc_base_cmd + cmd, stdout=output_file, check=False)
|
756
|
+
else:
|
757
|
+
# collect logs to file async
|
758
|
+
Popen(self.oc_base_cmd + cmd, stdout=output_file)
|
759
|
+
|
760
|
+
def job_logs_latest_pod(self, namespace: str, name: str, output: str) -> str:
|
761
|
+
pods = self.get_items("Pod", namespace=namespace, labels={"job-name": name})
|
762
|
+
|
763
|
+
finished_pods = [
|
764
|
+
pod for pod in pods if pod["status"].get("phase") in {"Failed", "Succeeded"}
|
765
|
+
]
|
766
|
+
if not finished_pods:
|
767
|
+
raise JobNotRunningError(name)
|
768
|
+
|
769
|
+
latest_pod = sorted(
|
770
|
+
finished_pods, key=lambda pod: pod["metadata"]["creationTimestamp"]
|
771
|
+
)[-1]
|
772
|
+
cmd = [
|
773
|
+
"logs",
|
774
|
+
"--all-containers=true",
|
775
|
+
"-n",
|
776
|
+
namespace,
|
777
|
+
f"pod/{latest_pod['metadata']['name']}",
|
778
|
+
]
|
779
|
+
output_file_name = os.path.join(output, name)
|
780
|
+
with open(output_file_name, "w", encoding="locale") as f:
|
781
|
+
# collect logs to file async
|
782
|
+
p = Popen(self.oc_base_cmd + cmd, stdout=f)
|
783
|
+
# wait here for the log collection to finish
|
784
|
+
p.wait()
|
785
|
+
return output_file_name
|
762
786
|
|
763
787
|
@staticmethod
|
764
788
|
def get_service_account_username(user):
|
765
789
|
namespace = user.split("/")[0]
|
766
790
|
name = user.split("/")[1]
|
767
|
-
return "system:serviceaccount:{}:{}"
|
791
|
+
return f"system:serviceaccount:{namespace}:{name}"
|
768
792
|
|
769
793
|
def get_owned_pods(self, namespace, resource):
|
770
794
|
pods = self.get(namespace, "Pod")["items"]
|
@@ -850,9 +874,12 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
850
874
|
|
851
875
|
@retry(max_attempts=20)
|
852
876
|
def validate_pod_ready(self, namespace, name):
|
853
|
-
logging.info(
|
854
|
-
|
855
|
-
|
877
|
+
logging.info([
|
878
|
+
self.validate_pod_ready.__name__,
|
879
|
+
self.cluster_name,
|
880
|
+
namespace,
|
881
|
+
name,
|
882
|
+
])
|
856
883
|
pod = self.get(namespace, "Pod", name)
|
857
884
|
for status in pod["status"]["containerStatuses"]:
|
858
885
|
if not status["ready"]:
|
@@ -868,29 +895,27 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
868
895
|
|
869
896
|
supported_kinds = ["Secret", "ConfigMap"]
|
870
897
|
if dep_kind not in supported_kinds:
|
871
|
-
logging.debug(
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
]
|
878
|
-
)
|
898
|
+
logging.debug([
|
899
|
+
"skipping_pod_recycle_unsupported",
|
900
|
+
self.cluster_name,
|
901
|
+
namespace,
|
902
|
+
dep_kind,
|
903
|
+
])
|
879
904
|
return
|
880
905
|
|
881
906
|
dep_annotations = dep_resource.body["metadata"].get("annotations", {})
|
907
|
+
# Note, that annotations might have been set to None explicitly
|
908
|
+
dep_annotations = dep_resource.body["metadata"].get("annotations") or {}
|
882
909
|
qontract_recycle = dep_annotations.get("qontract.recycle")
|
883
910
|
if qontract_recycle is True:
|
884
911
|
raise RecyclePodsInvalidAnnotationValue('should be "true"')
|
885
912
|
if qontract_recycle != "true":
|
886
|
-
logging.debug(
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
]
|
893
|
-
)
|
913
|
+
logging.debug([
|
914
|
+
"skipping_pod_recycle_no_annotation",
|
915
|
+
self.cluster_name,
|
916
|
+
namespace,
|
917
|
+
dep_kind,
|
918
|
+
])
|
894
919
|
return
|
895
920
|
|
896
921
|
dep_name = dep_resource.name
|
@@ -1009,7 +1034,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
1009
1034
|
kind: str,
|
1010
1035
|
include_optional: bool = True,
|
1011
1036
|
) -> dict[str, set[str]]:
|
1012
|
-
if kind not in
|
1037
|
+
if kind not in {"Secret", "ConfigMap"}:
|
1013
1038
|
raise KeyError(f"unsupported resource kind: {kind}")
|
1014
1039
|
optional = "optional"
|
1015
1040
|
if kind == "Secret":
|
@@ -1065,6 +1090,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
1065
1090
|
|
1066
1091
|
@retry(exceptions=(StatusCodeError, NoOutputError), max_attempts=10)
|
1067
1092
|
def _run(self, cmd, **kwargs) -> bytes:
|
1093
|
+
oc_run_execution_counter.labels(integration=RunningState().integration).inc()
|
1068
1094
|
stdin = kwargs.get("stdin")
|
1069
1095
|
stdin_text = stdin.encode() if stdin else None
|
1070
1096
|
result = subprocess.run(
|
@@ -1102,6 +1128,8 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
1102
1128
|
raise StatefulSetUpdateForbidden(f"[{self.server}]: {err}")
|
1103
1129
|
if "the object has been modified" in err:
|
1104
1130
|
raise ObjectHasBeenModifiedError(f"[{self.server}]: {err}")
|
1131
|
+
if "Request entity too large" in err:
|
1132
|
+
raise RequestEntityTooLargeError(f"[{self.server}]: {err}")
|
1105
1133
|
if not (allow_not_found and "NotFound" in err):
|
1106
1134
|
raise StatusCodeError(f"[{self.server}]: {err}")
|
1107
1135
|
|
@@ -1118,7 +1146,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
1118
1146
|
try:
|
1119
1147
|
out_json = json.loads(out)
|
1120
1148
|
except ValueError as e:
|
1121
|
-
raise JSONParsingError(out + "\n" + str(e))
|
1149
|
+
raise JSONParsingError(out + "\n" + str(e)) from e
|
1122
1150
|
|
1123
1151
|
return out_json
|
1124
1152
|
|
@@ -1143,7 +1171,7 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
1143
1171
|
find = False
|
1144
1172
|
for gv in self.api_resources[kind]:
|
1145
1173
|
if apigroup_override == gv.group:
|
1146
|
-
if gv.group
|
1174
|
+
if not gv.group:
|
1147
1175
|
group_version = gv.api_version
|
1148
1176
|
else:
|
1149
1177
|
group_version = f"{gv.group}/{gv.api_version}"
|
@@ -1194,18 +1222,21 @@ class OCDeprecated: # pylint: disable=too-many-public-methods
|
|
1194
1222
|
return kind_resources[0].namespaced
|
1195
1223
|
|
1196
1224
|
|
1197
|
-
|
1225
|
+
REQUEST_TIMEOUT = 60
|
1226
|
+
|
1227
|
+
|
1228
|
+
class OCNative(OCCli):
|
1198
1229
|
def __init__(
|
1199
1230
|
self,
|
1200
|
-
cluster_name:
|
1201
|
-
server:
|
1202
|
-
token:
|
1203
|
-
jh:
|
1204
|
-
settings:
|
1231
|
+
cluster_name: str | None,
|
1232
|
+
server: str | None,
|
1233
|
+
token: str | None,
|
1234
|
+
jh: Mapping[Any, Any] | None = None,
|
1235
|
+
settings: Mapping[Any, Any] | None = None,
|
1205
1236
|
init_projects: bool = False,
|
1206
1237
|
local: bool = False,
|
1207
1238
|
insecure_skip_tls_verify: bool = False,
|
1208
|
-
connection_parameters:
|
1239
|
+
connection_parameters: OCConnectionParameters | None = None,
|
1209
1240
|
):
|
1210
1241
|
super().__init__(
|
1211
1242
|
cluster_name,
|
@@ -1235,14 +1266,14 @@ class OCNative(OCDeprecated):
|
|
1235
1266
|
raise Exception("A method relies on client/api_kind_version to be set")
|
1236
1267
|
|
1237
1268
|
self.object_clients: dict[Any, Any] = {}
|
1238
|
-
|
1269
|
+
self.projects = set()
|
1239
1270
|
self.init_projects = init_projects
|
1240
1271
|
if self.init_projects:
|
1241
1272
|
if self.is_kind_supported("Project"):
|
1242
1273
|
kind = "Project.project.openshift.io"
|
1243
1274
|
else:
|
1244
1275
|
kind = "Namespace"
|
1245
|
-
self.projects =
|
1276
|
+
self.projects = {p["metadata"]["name"] for p in self.get_all(kind)["items"]}
|
1246
1277
|
|
1247
1278
|
def __enter__(self):
|
1248
1279
|
return self
|
@@ -1257,13 +1288,13 @@ class OCNative(OCDeprecated):
|
|
1257
1288
|
|
1258
1289
|
@retry(exceptions=(ServerTimeoutError, InternalServerError, ForbiddenError))
|
1259
1290
|
def _get_client(self, server, token):
|
1260
|
-
opts =
|
1261
|
-
api_key
|
1262
|
-
host
|
1263
|
-
verify_ssl
|
1291
|
+
opts = {
|
1292
|
+
"api_key": {"authorization": f"Bearer {token}"},
|
1293
|
+
"host": server,
|
1294
|
+
"verify_ssl": False,
|
1264
1295
|
# default timeout seems to be 1+ minutes
|
1265
|
-
retries
|
1266
|
-
|
1296
|
+
"retries": 5,
|
1297
|
+
}
|
1267
1298
|
if self.jump_host:
|
1268
1299
|
# the ports could be parameterized, but at this point
|
1269
1300
|
# we only have need of 1 tunnel for 1 service
|
@@ -1284,7 +1315,7 @@ class OCNative(OCDeprecated):
|
|
1284
1315
|
try:
|
1285
1316
|
return DynamicClient(k8s_client, discoverer=OpenshiftLazyDiscoverer)
|
1286
1317
|
except urllib3.exceptions.MaxRetryError as e:
|
1287
|
-
raise StatusCodeError(f"[{self.server}]: {e}")
|
1318
|
+
raise StatusCodeError(f"[{self.server}]: {e}") from None
|
1288
1319
|
|
1289
1320
|
def _get_obj_client(self, kind, group_version):
|
1290
1321
|
key = f"{kind}.{group_version}"
|
@@ -1310,9 +1341,7 @@ class OCNative(OCDeprecated):
|
|
1310
1341
|
|
1311
1342
|
labels = ""
|
1312
1343
|
if "labels" in kwargs:
|
1313
|
-
labels_list = [
|
1314
|
-
"{}={}".format(k, v) for k, v in kwargs.get("labels").items()
|
1315
|
-
]
|
1344
|
+
labels_list = [f"{k}={v}" for k, v in kwargs.get("labels").items()]
|
1316
1345
|
|
1317
1346
|
labels = ",".join(labels_list)
|
1318
1347
|
|
@@ -1322,7 +1351,10 @@ class OCNative(OCDeprecated):
|
|
1322
1351
|
for resource_name in resource_names:
|
1323
1352
|
try:
|
1324
1353
|
item = obj_client.get(
|
1325
|
-
name=resource_name,
|
1354
|
+
name=resource_name,
|
1355
|
+
namespace=namespace,
|
1356
|
+
label_selector=labels,
|
1357
|
+
_request_timeout=REQUEST_TIMEOUT,
|
1326
1358
|
)
|
1327
1359
|
if item:
|
1328
1360
|
items.append(item.to_dict())
|
@@ -1331,13 +1363,14 @@ class OCNative(OCDeprecated):
|
|
1331
1363
|
items_list = {"items": items}
|
1332
1364
|
else:
|
1333
1365
|
items_list = obj_client.get(
|
1334
|
-
namespace=namespace,
|
1366
|
+
namespace=namespace,
|
1367
|
+
label_selector=labels,
|
1368
|
+
_request_timeout=REQUEST_TIMEOUT,
|
1335
1369
|
).to_dict()
|
1336
1370
|
|
1337
1371
|
items = items_list.get("items")
|
1338
1372
|
if items is None:
|
1339
1373
|
raise Exception("Expecting items")
|
1340
|
-
|
1341
1374
|
return items
|
1342
1375
|
|
1343
1376
|
@retry(max_attempts=5, exceptions=(ServerTimeoutError, ForbiddenError))
|
@@ -1345,26 +1378,30 @@ class OCNative(OCDeprecated):
|
|
1345
1378
|
k, group_version = self._parse_kind(kind)
|
1346
1379
|
obj_client = self._get_obj_client(group_version=group_version, kind=k)
|
1347
1380
|
try:
|
1348
|
-
obj = obj_client.get(
|
1381
|
+
obj = obj_client.get(
|
1382
|
+
name=name,
|
1383
|
+
namespace=namespace,
|
1384
|
+
_request_timeout=REQUEST_TIMEOUT,
|
1385
|
+
)
|
1349
1386
|
return obj.to_dict()
|
1350
1387
|
except NotFoundError as e:
|
1351
1388
|
if allow_not_found:
|
1352
1389
|
return {}
|
1353
|
-
raise StatusCodeError(f"[{self.server}]: {e}")
|
1390
|
+
raise StatusCodeError(f"[{self.server}]: {e}") from None
|
1354
1391
|
|
1355
1392
|
def get_all(self, kind, all_namespaces=False):
|
1356
1393
|
k, group_version = self._parse_kind(kind)
|
1357
1394
|
obj_client = self._get_obj_client(group_version=group_version, kind=k)
|
1358
1395
|
try:
|
1359
|
-
return obj_client.get().to_dict()
|
1396
|
+
return obj_client.get(_request_timeout=REQUEST_TIMEOUT).to_dict()
|
1360
1397
|
except NotFoundError as e:
|
1361
|
-
raise StatusCodeError(f"[{self.server}]: {e}")
|
1398
|
+
raise StatusCodeError(f"[{self.server}]: {e}") from None
|
1362
1399
|
|
1363
1400
|
|
1364
|
-
OCClient =
|
1401
|
+
OCClient = OCNative | OCCli
|
1365
1402
|
|
1366
1403
|
|
1367
|
-
class OCLocal(
|
1404
|
+
class OCLocal(OCCli):
|
1368
1405
|
def __init__(
|
1369
1406
|
self,
|
1370
1407
|
cluster_name,
|
@@ -1389,21 +1426,21 @@ class OC:
|
|
1389
1426
|
|
1390
1427
|
def __new__(
|
1391
1428
|
cls,
|
1392
|
-
cluster_name:
|
1393
|
-
server:
|
1394
|
-
token:
|
1395
|
-
jh:
|
1396
|
-
settings:
|
1429
|
+
cluster_name: str | None = None,
|
1430
|
+
server: str | None = None,
|
1431
|
+
token: str | None = None,
|
1432
|
+
jh: Mapping[Any, Any] | None = None,
|
1433
|
+
settings: Mapping[Any, Any] | None = None,
|
1397
1434
|
init_projects: bool = False,
|
1398
1435
|
init_api_resources: bool = False,
|
1399
1436
|
local: bool = False,
|
1400
1437
|
insecure_skip_tls_verify: bool = False,
|
1401
|
-
connection_parameters:
|
1438
|
+
connection_parameters: OCConnectionParameters | None = None,
|
1402
1439
|
):
|
1403
1440
|
use_native_env = os.environ.get("USE_NATIVE_CLIENT", "")
|
1404
1441
|
use_native = True
|
1405
1442
|
if len(use_native_env) > 0:
|
1406
|
-
use_native = use_native_env.lower() in
|
1443
|
+
use_native = use_native_env.lower() in {"true", "yes"}
|
1407
1444
|
else:
|
1408
1445
|
enable_toggle = "openshift-resources-native-client"
|
1409
1446
|
use_native = get_feature_toggle_state(
|
@@ -1428,7 +1465,7 @@ class OC:
|
|
1428
1465
|
)
|
1429
1466
|
|
1430
1467
|
OC.client_status.labels(cluster_name=cluster_name, native_client=False).inc()
|
1431
|
-
return
|
1468
|
+
return OCCli(
|
1432
1469
|
cluster_name=cluster_name,
|
1433
1470
|
server=server,
|
1434
1471
|
token=token,
|
@@ -1460,7 +1497,6 @@ class OC_Map:
|
|
1460
1497
|
clusters=None,
|
1461
1498
|
namespaces=None,
|
1462
1499
|
integration="",
|
1463
|
-
e2e_test="",
|
1464
1500
|
settings=None,
|
1465
1501
|
internal=None,
|
1466
1502
|
use_jump_host=True,
|
@@ -1472,7 +1508,6 @@ class OC_Map:
|
|
1472
1508
|
self.oc_map = {}
|
1473
1509
|
self.privileged_oc_map = {}
|
1474
1510
|
self.calling_integration = integration
|
1475
|
-
self.calling_e2e_test = e2e_test
|
1476
1511
|
self.settings = settings
|
1477
1512
|
self.internal = internal
|
1478
1513
|
self.use_jump_host = use_jump_host
|
@@ -1612,10 +1647,7 @@ class OC_Map:
|
|
1612
1647
|
)
|
1613
1648
|
return
|
1614
1649
|
|
1615
|
-
if self.use_jump_host
|
1616
|
-
jump_host = cluster_info.get("jumpHost")
|
1617
|
-
else:
|
1618
|
-
jump_host = None
|
1650
|
+
jump_host = cluster_info.get("jumpHost") if self.use_jump_host else None
|
1619
1651
|
if jump_host:
|
1620
1652
|
self.set_jh_ports(jump_host)
|
1621
1653
|
try:
|
@@ -1654,12 +1686,6 @@ class OC_Map:
|
|
1654
1686
|
return True
|
1655
1687
|
except (KeyError, TypeError):
|
1656
1688
|
pass
|
1657
|
-
try:
|
1658
|
-
tests = cluster_info["disable"]["e2eTests"]
|
1659
|
-
if self.calling_e2e_test.replace("_", "-") in tests:
|
1660
|
-
return True
|
1661
|
-
except (KeyError, TypeError):
|
1662
|
-
pass
|
1663
1689
|
|
1664
1690
|
return False
|
1665
1691
|
|
@@ -1717,6 +1743,9 @@ class OCLogMsg(Exception):
|
|
1717
1743
|
"""
|
1718
1744
|
return False
|
1719
1745
|
|
1746
|
+
def __str__(self) -> str:
|
1747
|
+
return super().__str__() + self.message
|
1748
|
+
|
1720
1749
|
|
1721
1750
|
LABEL_MAX_VALUE_LENGTH = 63
|
1722
1751
|
LABEL_MAX_KEY_NAME_LENGTH = 63
|
@@ -1778,7 +1807,7 @@ def validate_labels(labels: dict[str, str]) -> Iterable[str]:
|
|
1778
1807
|
f"Label key prefix is invalid, it needs to match "
|
1779
1808
|
f"'{k_prefix_pattern}'': {prefix}"
|
1780
1809
|
)
|
1781
|
-
if prefix in
|
1810
|
+
if prefix in {"kubernetes.io", "k8s.io"}:
|
1782
1811
|
err.append(f"Label key prefix is reserved: {prefix}")
|
1783
1812
|
|
1784
1813
|
return err
|
@@ -1824,22 +1853,17 @@ class OpenshiftLazyDiscoverer(LazyDiscoverer):
|
|
1824
1853
|
]
|
1825
1854
|
# If there are multiple matches, prefer non-List kinds
|
1826
1855
|
if len(results) > 1 and not all( # pylint: disable=R1729
|
1827
|
-
|
1856
|
+
isinstance(x, ResourceList) for x in results
|
1828
1857
|
):
|
1829
1858
|
results = [
|
1830
1859
|
result for result in results if not isinstance(result, ResourceList)
|
1831
1860
|
]
|
1832
1861
|
# if multiple resources are found that share a GVK, prefer the one with the most supported verbs
|
1833
|
-
if (
|
1834
|
-
len(results)
|
1835
|
-
and len(set((x.group_version, x.kind) for x in results)) == 1
|
1836
|
-
):
|
1837
|
-
if len(set(len(x.verbs) for x in results)) != 1:
|
1862
|
+
if len(results) > 1 and len({(x.group_version, x.kind) for x in results}) == 1:
|
1863
|
+
if len({len(x.verbs) for x in results}) != 1:
|
1838
1864
|
results = [max(results, key=lambda x: len(x.verbs))]
|
1839
1865
|
if len(results) == 1:
|
1840
1866
|
return results[0]
|
1841
1867
|
if not results:
|
1842
|
-
raise ResourceNotFoundError("No matches found for {}"
|
1843
|
-
raise ResourceNotUniqueError(
|
1844
|
-
"Multiple matches found for {}: {}".format(kwargs, results)
|
1845
|
-
)
|
1868
|
+
raise ResourceNotFoundError(f"No matches found for {kwargs}")
|
1869
|
+
raise ResourceNotUniqueError(f"Multiple matches found for {kwargs}: {results}")
|