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.
Files changed (843) hide show
  1. qontract_reconcile-0.10.1.dev1203.dist-info/METADATA +500 -0
  2. qontract_reconcile-0.10.1.dev1203.dist-info/RECORD +771 -0
  3. {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
  4. {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/entry_points.txt +4 -2
  5. reconcile/acs_notifiers.py +126 -0
  6. reconcile/acs_policies.py +243 -0
  7. reconcile/acs_rbac.py +596 -0
  8. reconcile/aus/advanced_upgrade_service.py +621 -8
  9. reconcile/aus/aus_label_source.py +115 -0
  10. reconcile/aus/base.py +1053 -353
  11. reconcile/{utils → aus}/cluster_version_data.py +27 -12
  12. reconcile/aus/healthchecks.py +77 -0
  13. reconcile/aus/metrics.py +158 -0
  14. reconcile/aus/models.py +245 -5
  15. reconcile/aus/node_pool_spec.py +35 -0
  16. reconcile/aus/ocm_addons_upgrade_scheduler_org.py +225 -110
  17. reconcile/aus/ocm_upgrade_scheduler.py +76 -71
  18. reconcile/aus/ocm_upgrade_scheduler_org.py +81 -23
  19. reconcile/aus/version_gate_approver.py +204 -0
  20. reconcile/aus/version_gates/__init__.py +12 -0
  21. reconcile/aus/version_gates/handler.py +33 -0
  22. reconcile/aus/version_gates/ingress_gate_handler.py +32 -0
  23. reconcile/aus/version_gates/ocp_gate_handler.py +26 -0
  24. reconcile/aus/version_gates/sts_version_gate_handler.py +100 -0
  25. reconcile/aws_account_manager/README.md +5 -0
  26. reconcile/aws_account_manager/integration.py +373 -0
  27. reconcile/aws_account_manager/merge_request_manager.py +114 -0
  28. reconcile/aws_account_manager/metrics.py +39 -0
  29. reconcile/aws_account_manager/reconciler.py +403 -0
  30. reconcile/aws_account_manager/utils.py +41 -0
  31. reconcile/aws_ami_cleanup/integration.py +273 -0
  32. reconcile/aws_ami_share.py +18 -14
  33. reconcile/aws_cloudwatch_log_retention/integration.py +253 -0
  34. reconcile/aws_iam_keys.py +1 -1
  35. reconcile/aws_iam_password_reset.py +56 -20
  36. reconcile/aws_saml_idp/integration.py +204 -0
  37. reconcile/aws_saml_roles/integration.py +322 -0
  38. reconcile/aws_support_cases_sos.py +2 -2
  39. reconcile/aws_version_sync/integration.py +430 -0
  40. reconcile/aws_version_sync/merge_request_manager/merge_request.py +156 -0
  41. reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py +160 -0
  42. reconcile/aws_version_sync/utils.py +64 -0
  43. reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
  44. reconcile/change_owners/README.md +34 -0
  45. reconcile/change_owners/approver.py +7 -9
  46. reconcile/change_owners/bundle.py +134 -9
  47. reconcile/change_owners/change_log_tracking.py +236 -0
  48. reconcile/change_owners/change_owners.py +204 -194
  49. reconcile/change_owners/change_types.py +183 -265
  50. reconcile/change_owners/changes.py +488 -0
  51. reconcile/change_owners/decision.py +120 -41
  52. reconcile/change_owners/diff.py +63 -92
  53. reconcile/change_owners/implicit_ownership.py +19 -16
  54. reconcile/change_owners/self_service_roles.py +158 -35
  55. reconcile/change_owners/tester.py +20 -18
  56. reconcile/checkpoint.py +4 -6
  57. reconcile/cli.py +1523 -242
  58. reconcile/closedbox_endpoint_monitoring_base.py +10 -17
  59. reconcile/cluster_auth_rhidp/integration.py +257 -0
  60. reconcile/cluster_deployment_mapper.py +2 -5
  61. reconcile/cna/assets/asset.py +4 -7
  62. reconcile/cna/assets/null.py +2 -5
  63. reconcile/cna/integration.py +2 -3
  64. reconcile/cna/state.py +6 -9
  65. reconcile/dashdotdb_base.py +31 -10
  66. reconcile/dashdotdb_cso.py +3 -6
  67. reconcile/dashdotdb_dora.py +530 -0
  68. reconcile/dashdotdb_dvo.py +10 -13
  69. reconcile/dashdotdb_slo.py +75 -19
  70. reconcile/database_access_manager.py +753 -0
  71. reconcile/deadmanssnitch.py +207 -0
  72. reconcile/dynatrace_token_provider/dependencies.py +69 -0
  73. reconcile/dynatrace_token_provider/integration.py +656 -0
  74. reconcile/dynatrace_token_provider/metrics.py +62 -0
  75. reconcile/dynatrace_token_provider/model.py +14 -0
  76. reconcile/dynatrace_token_provider/ocm.py +140 -0
  77. reconcile/dynatrace_token_provider/validate.py +48 -0
  78. reconcile/endpoints_discovery/integration.py +348 -0
  79. reconcile/endpoints_discovery/merge_request.py +96 -0
  80. reconcile/endpoints_discovery/merge_request_manager.py +178 -0
  81. reconcile/external_resources/aws.py +204 -0
  82. reconcile/external_resources/factories.py +163 -0
  83. reconcile/external_resources/integration.py +194 -0
  84. reconcile/external_resources/integration_secrets_sync.py +47 -0
  85. reconcile/external_resources/manager.py +405 -0
  86. reconcile/external_resources/meta.py +17 -0
  87. reconcile/external_resources/metrics.py +95 -0
  88. reconcile/external_resources/model.py +350 -0
  89. reconcile/external_resources/reconciler.py +265 -0
  90. reconcile/external_resources/secrets_sync.py +465 -0
  91. reconcile/external_resources/state.py +258 -0
  92. reconcile/gabi_authorized_users.py +19 -11
  93. reconcile/gcr_mirror.py +43 -34
  94. reconcile/github_org.py +4 -6
  95. reconcile/github_owners.py +1 -1
  96. reconcile/github_repo_invites.py +2 -5
  97. reconcile/gitlab_fork_compliance.py +14 -13
  98. reconcile/gitlab_housekeeping.py +185 -91
  99. reconcile/gitlab_labeler.py +15 -14
  100. reconcile/gitlab_members.py +126 -120
  101. reconcile/gitlab_owners.py +53 -66
  102. reconcile/gitlab_permissions.py +167 -6
  103. reconcile/glitchtip/README.md +150 -0
  104. reconcile/glitchtip/integration.py +99 -51
  105. reconcile/glitchtip/reconciler.py +99 -70
  106. reconcile/glitchtip_project_alerts/__init__.py +0 -0
  107. reconcile/glitchtip_project_alerts/integration.py +333 -0
  108. reconcile/glitchtip_project_dsn/integration.py +43 -43
  109. reconcile/gql_definitions/acs/__init__.py +0 -0
  110. reconcile/gql_definitions/acs/acs_instances.py +83 -0
  111. reconcile/gql_definitions/acs/acs_policies.py +239 -0
  112. reconcile/gql_definitions/acs/acs_rbac.py +111 -0
  113. reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +46 -8
  114. reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +38 -8
  115. reconcile/gql_definitions/app_interface_metrics_exporter/__init__.py +0 -0
  116. reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +61 -0
  117. reconcile/gql_definitions/aws_account_manager/__init__.py +0 -0
  118. reconcile/gql_definitions/aws_account_manager/aws_accounts.py +177 -0
  119. reconcile/gql_definitions/aws_ami_cleanup/__init__.py +0 -0
  120. reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +161 -0
  121. reconcile/gql_definitions/aws_saml_idp/__init__.py +0 -0
  122. reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +117 -0
  123. reconcile/gql_definitions/aws_saml_roles/__init__.py +0 -0
  124. reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +117 -0
  125. reconcile/gql_definitions/aws_saml_roles/roles.py +97 -0
  126. reconcile/gql_definitions/aws_version_sync/__init__.py +0 -0
  127. reconcile/gql_definitions/aws_version_sync/clusters.py +83 -0
  128. reconcile/gql_definitions/aws_version_sync/namespaces.py +143 -0
  129. reconcile/gql_definitions/change_owners/queries/change_types.py +16 -29
  130. reconcile/gql_definitions/change_owners/queries/self_service_roles.py +45 -11
  131. reconcile/gql_definitions/cluster_auth_rhidp/__init__.py +0 -0
  132. reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +128 -0
  133. reconcile/gql_definitions/cna/queries/cna_provisioners.py +6 -8
  134. reconcile/gql_definitions/cna/queries/cna_resources.py +3 -5
  135. reconcile/gql_definitions/common/alerting_services_settings.py +2 -2
  136. reconcile/gql_definitions/common/app_code_component_repos.py +9 -5
  137. reconcile/gql_definitions/{glitchtip/glitchtip_settings.py → common/app_interface_custom_messages.py} +14 -16
  138. reconcile/gql_definitions/common/app_interface_dms_settings.py +86 -0
  139. reconcile/gql_definitions/common/app_interface_repo_settings.py +2 -2
  140. reconcile/gql_definitions/common/app_interface_state_settings.py +3 -5
  141. reconcile/gql_definitions/common/app_interface_vault_settings.py +3 -5
  142. reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +120 -0
  143. reconcile/gql_definitions/common/apps.py +72 -0
  144. reconcile/gql_definitions/common/aws_vpc_requests.py +109 -0
  145. reconcile/gql_definitions/common/aws_vpcs.py +84 -0
  146. reconcile/gql_definitions/common/clusters.py +120 -254
  147. reconcile/gql_definitions/common/clusters_minimal.py +11 -35
  148. reconcile/gql_definitions/common/clusters_with_dms.py +72 -0
  149. reconcile/gql_definitions/common/clusters_with_peering.py +70 -98
  150. reconcile/gql_definitions/common/github_orgs.py +2 -2
  151. reconcile/gql_definitions/common/jira_settings.py +68 -0
  152. reconcile/gql_definitions/common/jiralert_settings.py +68 -0
  153. reconcile/gql_definitions/common/namespaces.py +74 -32
  154. reconcile/gql_definitions/common/namespaces_minimal.py +4 -10
  155. reconcile/gql_definitions/common/ocm_env_telemeter.py +95 -0
  156. reconcile/gql_definitions/common/ocm_environments.py +4 -2
  157. reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
  158. reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -11
  159. reconcile/gql_definitions/common/pipeline_providers.py +45 -90
  160. reconcile/gql_definitions/common/quay_instances.py +64 -0
  161. reconcile/gql_definitions/common/quay_orgs.py +68 -0
  162. reconcile/gql_definitions/common/reserved_networks.py +94 -0
  163. reconcile/gql_definitions/common/saas_files.py +133 -95
  164. reconcile/gql_definitions/common/saas_target_namespaces.py +41 -26
  165. reconcile/gql_definitions/common/saasherder_settings.py +2 -2
  166. reconcile/gql_definitions/common/slack_workspaces.py +62 -0
  167. reconcile/gql_definitions/common/smtp_client_settings.py +2 -2
  168. reconcile/gql_definitions/common/state_aws_account.py +77 -0
  169. reconcile/gql_definitions/common/users.py +3 -2
  170. reconcile/gql_definitions/cost_report/__init__.py +0 -0
  171. reconcile/gql_definitions/cost_report/app_names.py +68 -0
  172. reconcile/gql_definitions/cost_report/cost_namespaces.py +86 -0
  173. reconcile/gql_definitions/cost_report/settings.py +77 -0
  174. reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +42 -12
  175. reconcile/gql_definitions/dynatrace_token_provider/__init__.py +0 -0
  176. reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +79 -0
  177. reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +84 -0
  178. reconcile/gql_definitions/endpoints_discovery/__init__.py +0 -0
  179. reconcile/gql_definitions/endpoints_discovery/namespaces.py +127 -0
  180. reconcile/gql_definitions/external_resources/__init__.py +0 -0
  181. reconcile/gql_definitions/external_resources/aws_accounts.py +73 -0
  182. reconcile/gql_definitions/external_resources/external_resources_modules.py +78 -0
  183. reconcile/gql_definitions/external_resources/external_resources_namespaces.py +1111 -0
  184. reconcile/gql_definitions/external_resources/external_resources_settings.py +98 -0
  185. reconcile/gql_definitions/fragments/aus_organization.py +34 -39
  186. reconcile/gql_definitions/fragments/aws_account_common.py +62 -0
  187. reconcile/gql_definitions/fragments/aws_account_managed.py +57 -0
  188. reconcile/gql_definitions/fragments/aws_account_sso.py +35 -0
  189. reconcile/gql_definitions/fragments/aws_infra_management_account.py +2 -2
  190. reconcile/gql_definitions/fragments/aws_vpc.py +47 -0
  191. reconcile/gql_definitions/fragments/aws_vpc_request.py +65 -0
  192. reconcile/gql_definitions/fragments/aws_vpc_request_subnet.py +29 -0
  193. reconcile/gql_definitions/fragments/deplopy_resources.py +7 -7
  194. reconcile/gql_definitions/fragments/disable.py +28 -0
  195. reconcile/gql_definitions/fragments/jumphost_common_fields.py +2 -2
  196. reconcile/gql_definitions/fragments/membership_source.py +47 -0
  197. reconcile/gql_definitions/fragments/minimal_ocm_organization.py +29 -0
  198. reconcile/gql_definitions/fragments/oc_connection_cluster.py +4 -9
  199. reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
  200. reconcile/gql_definitions/fragments/pipeline_provider_retention.py +30 -0
  201. reconcile/gql_definitions/fragments/prometheus_instance.py +48 -0
  202. reconcile/gql_definitions/fragments/resource_limits_requirements.py +29 -0
  203. reconcile/gql_definitions/fragments/{resource_requirements.py → resource_requests_requirements.py} +3 -3
  204. reconcile/gql_definitions/fragments/resource_values.py +2 -2
  205. reconcile/gql_definitions/fragments/saas_target_namespace.py +55 -12
  206. reconcile/gql_definitions/fragments/serviceaccount_token.py +38 -0
  207. reconcile/gql_definitions/fragments/terraform_state.py +36 -0
  208. reconcile/gql_definitions/fragments/upgrade_policy.py +5 -3
  209. reconcile/gql_definitions/fragments/user.py +3 -2
  210. reconcile/gql_definitions/fragments/vault_secret.py +2 -2
  211. reconcile/gql_definitions/gitlab_members/gitlab_instances.py +6 -2
  212. reconcile/gql_definitions/gitlab_members/permissions.py +3 -5
  213. reconcile/gql_definitions/glitchtip/glitchtip_instance.py +16 -2
  214. reconcile/gql_definitions/glitchtip/glitchtip_project.py +22 -23
  215. reconcile/gql_definitions/glitchtip_project_alerts/__init__.py +0 -0
  216. reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +173 -0
  217. reconcile/gql_definitions/integrations/integrations.py +62 -45
  218. reconcile/gql_definitions/introspection.json +51176 -0
  219. reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +13 -5
  220. reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +79 -0
  221. reconcile/gql_definitions/jira/__init__.py +0 -0
  222. reconcile/gql_definitions/jira/jira_servers.py +80 -0
  223. reconcile/gql_definitions/jira_permissions_validator/__init__.py +0 -0
  224. reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +131 -0
  225. reconcile/gql_definitions/jumphosts/jumphosts.py +3 -5
  226. reconcile/gql_definitions/ldap_groups/__init__.py +0 -0
  227. reconcile/gql_definitions/ldap_groups/roles.py +111 -0
  228. reconcile/gql_definitions/ldap_groups/settings.py +79 -0
  229. reconcile/gql_definitions/maintenance/__init__.py +0 -0
  230. reconcile/gql_definitions/maintenance/maintenances.py +101 -0
  231. reconcile/gql_definitions/membershipsources/__init__.py +0 -0
  232. reconcile/gql_definitions/membershipsources/roles.py +112 -0
  233. reconcile/gql_definitions/ocm_labels/__init__.py +0 -0
  234. reconcile/gql_definitions/ocm_labels/clusters.py +112 -0
  235. reconcile/gql_definitions/ocm_labels/organizations.py +78 -0
  236. reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
  237. reconcile/gql_definitions/openshift_cluster_bots/__init__.py +0 -0
  238. reconcile/gql_definitions/openshift_cluster_bots/clusters.py +126 -0
  239. reconcile/gql_definitions/openshift_groups/managed_groups.py +2 -2
  240. reconcile/gql_definitions/openshift_groups/managed_roles.py +3 -2
  241. reconcile/gql_definitions/openshift_serviceaccount_tokens/__init__.py +0 -0
  242. reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +132 -0
  243. reconcile/gql_definitions/quay_membership/quay_membership.py +3 -5
  244. reconcile/gql_definitions/rhidp/__init__.py +0 -0
  245. reconcile/gql_definitions/rhidp/organizations.py +96 -0
  246. reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +2 -2
  247. reconcile/gql_definitions/service_dependencies/service_dependencies.py +9 -31
  248. reconcile/gql_definitions/sharding/aws_accounts.py +2 -2
  249. reconcile/gql_definitions/sharding/ocm_organization.py +63 -0
  250. reconcile/gql_definitions/skupper_network/site_controller_template.py +2 -2
  251. reconcile/gql_definitions/skupper_network/skupper_networks.py +12 -38
  252. reconcile/gql_definitions/slack_usergroups/clusters.py +2 -2
  253. reconcile/gql_definitions/slack_usergroups/permissions.py +8 -15
  254. reconcile/gql_definitions/slack_usergroups/users.py +3 -2
  255. reconcile/gql_definitions/slo_documents/__init__.py +0 -0
  256. reconcile/gql_definitions/slo_documents/slo_documents.py +142 -0
  257. reconcile/gql_definitions/status_board/__init__.py +0 -0
  258. reconcile/gql_definitions/status_board/status_board.py +163 -0
  259. reconcile/gql_definitions/statuspage/statuspages.py +56 -7
  260. reconcile/gql_definitions/templating/__init__.py +0 -0
  261. reconcile/gql_definitions/templating/template_collection.py +130 -0
  262. reconcile/gql_definitions/templating/templates.py +108 -0
  263. reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +4 -8
  264. reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +8 -8
  265. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +6 -8
  266. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +45 -56
  267. reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +4 -8
  268. reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +4 -8
  269. reconcile/gql_definitions/terraform_init/__init__.py +0 -0
  270. reconcile/gql_definitions/terraform_init/aws_accounts.py +93 -0
  271. reconcile/gql_definitions/terraform_repo/__init__.py +0 -0
  272. reconcile/gql_definitions/terraform_repo/terraform_repo.py +141 -0
  273. reconcile/gql_definitions/terraform_resources/database_access_manager.py +158 -0
  274. reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +153 -162
  275. reconcile/gql_definitions/terraform_tgw_attachments/__init__.py +0 -0
  276. reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +119 -0
  277. reconcile/gql_definitions/unleash_feature_toggles/__init__.py +0 -0
  278. reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +113 -0
  279. reconcile/gql_definitions/vault_instances/vault_instances.py +17 -50
  280. reconcile/gql_definitions/vault_policies/vault_policies.py +2 -2
  281. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +49 -12
  282. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +7 -2
  283. reconcile/integrations_manager.py +25 -13
  284. reconcile/jenkins/types.py +5 -1
  285. reconcile/jenkins_base.py +36 -0
  286. reconcile/jenkins_job_builder.py +10 -48
  287. reconcile/jenkins_job_builds_cleaner.py +40 -25
  288. reconcile/jenkins_job_cleaner.py +1 -3
  289. reconcile/jenkins_roles.py +22 -26
  290. reconcile/jenkins_webhooks.py +9 -6
  291. reconcile/jenkins_worker_fleets.py +11 -6
  292. reconcile/jira_permissions_validator.py +340 -0
  293. reconcile/jira_watcher.py +3 -5
  294. reconcile/ldap_groups/__init__.py +0 -0
  295. reconcile/ldap_groups/integration.py +279 -0
  296. reconcile/ldap_users.py +3 -0
  297. reconcile/ocm/types.py +39 -59
  298. reconcile/ocm_additional_routers.py +0 -1
  299. reconcile/ocm_addons_upgrade_tests_trigger.py +10 -15
  300. reconcile/ocm_aws_infrastructure_access.py +30 -32
  301. reconcile/ocm_clusters.py +217 -130
  302. reconcile/ocm_external_configuration_labels.py +15 -0
  303. reconcile/ocm_github_idp.py +1 -1
  304. reconcile/ocm_groups.py +25 -5
  305. reconcile/ocm_internal_notifications/__init__.py +0 -0
  306. reconcile/ocm_internal_notifications/integration.py +119 -0
  307. reconcile/ocm_labels/__init__.py +0 -0
  308. reconcile/ocm_labels/integration.py +409 -0
  309. reconcile/ocm_machine_pools.py +517 -108
  310. reconcile/ocm_upgrade_scheduler_org_updater.py +15 -11
  311. reconcile/openshift_base.py +609 -207
  312. reconcile/openshift_cluster_bots.py +344 -0
  313. reconcile/openshift_clusterrolebindings.py +15 -15
  314. reconcile/openshift_groups.py +42 -45
  315. reconcile/openshift_limitranges.py +1 -0
  316. reconcile/openshift_namespace_labels.py +22 -28
  317. reconcile/openshift_namespaces.py +22 -22
  318. reconcile/openshift_network_policies.py +4 -8
  319. reconcile/openshift_prometheus_rules.py +43 -0
  320. reconcile/openshift_resourcequotas.py +2 -16
  321. reconcile/openshift_resources.py +12 -10
  322. reconcile/openshift_resources_base.py +304 -328
  323. reconcile/openshift_rolebindings.py +18 -20
  324. reconcile/openshift_saas_deploy.py +105 -21
  325. reconcile/openshift_saas_deploy_change_tester.py +30 -35
  326. reconcile/openshift_saas_deploy_trigger_base.py +39 -36
  327. reconcile/openshift_saas_deploy_trigger_cleaner.py +41 -27
  328. reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
  329. reconcile/openshift_saas_deploy_trigger_images.py +1 -2
  330. reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
  331. reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
  332. reconcile/openshift_serviceaccount_tokens.py +138 -74
  333. reconcile/openshift_tekton_resources.py +89 -24
  334. reconcile/openshift_upgrade_watcher.py +110 -62
  335. reconcile/openshift_users.py +16 -15
  336. reconcile/openshift_vault_secrets.py +11 -6
  337. reconcile/oum/__init__.py +0 -0
  338. reconcile/oum/base.py +387 -0
  339. reconcile/oum/labelset.py +55 -0
  340. reconcile/oum/metrics.py +71 -0
  341. reconcile/oum/models.py +69 -0
  342. reconcile/oum/providers.py +59 -0
  343. reconcile/oum/standalone.py +196 -0
  344. reconcile/prometheus_rules_tester/integration.py +31 -23
  345. reconcile/quay_base.py +4 -1
  346. reconcile/quay_membership.py +1 -2
  347. reconcile/quay_mirror.py +111 -61
  348. reconcile/quay_mirror_org.py +34 -21
  349. reconcile/quay_permissions.py +7 -3
  350. reconcile/quay_repos.py +24 -32
  351. reconcile/queries.py +263 -198
  352. reconcile/query_validator.py +3 -5
  353. reconcile/resource_scraper.py +3 -4
  354. reconcile/{template_tester.py → resource_template_tester.py} +3 -3
  355. reconcile/rhidp/__init__.py +0 -0
  356. reconcile/rhidp/common.py +214 -0
  357. reconcile/rhidp/metrics.py +20 -0
  358. reconcile/rhidp/ocm_oidc_idp/__init__.py +0 -0
  359. reconcile/rhidp/ocm_oidc_idp/base.py +221 -0
  360. reconcile/rhidp/ocm_oidc_idp/integration.py +56 -0
  361. reconcile/rhidp/ocm_oidc_idp/metrics.py +22 -0
  362. reconcile/rhidp/sso_client/__init__.py +0 -0
  363. reconcile/rhidp/sso_client/base.py +266 -0
  364. reconcile/rhidp/sso_client/integration.py +60 -0
  365. reconcile/rhidp/sso_client/metrics.py +39 -0
  366. reconcile/run_integration.py +293 -0
  367. reconcile/saas_auto_promotions_manager/integration.py +69 -24
  368. reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +208 -0
  369. reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py +28 -0
  370. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py +3 -4
  371. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +172 -0
  372. reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py +42 -0
  373. reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +226 -0
  374. reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py +23 -0
  375. reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +108 -32
  376. reconcile/saas_auto_promotions_manager/meta.py +4 -0
  377. reconcile/saas_auto_promotions_manager/publisher.py +32 -4
  378. reconcile/saas_auto_promotions_manager/s3_exporter.py +77 -0
  379. reconcile/saas_auto_promotions_manager/subscriber.py +110 -23
  380. reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +48 -41
  381. reconcile/saas_file_validator.py +16 -6
  382. reconcile/sendgrid_teammates.py +27 -12
  383. reconcile/service_dependencies.py +0 -3
  384. reconcile/signalfx_endpoint_monitoring.py +2 -5
  385. reconcile/skupper_network/integration.py +10 -11
  386. reconcile/skupper_network/models.py +3 -5
  387. reconcile/skupper_network/reconciler.py +28 -35
  388. reconcile/skupper_network/site_controller.py +8 -8
  389. reconcile/slack_base.py +4 -7
  390. reconcile/slack_usergroups.py +249 -171
  391. reconcile/sql_query.py +324 -171
  392. reconcile/status.py +0 -1
  393. reconcile/status_board.py +275 -0
  394. reconcile/statuspage/__init__.py +0 -5
  395. reconcile/statuspage/atlassian.py +219 -80
  396. reconcile/statuspage/integration.py +9 -97
  397. reconcile/statuspage/integrations/__init__.py +0 -0
  398. reconcile/statuspage/integrations/components.py +77 -0
  399. reconcile/statuspage/integrations/maintenances.py +111 -0
  400. reconcile/statuspage/page.py +107 -72
  401. reconcile/statuspage/state.py +6 -11
  402. reconcile/statuspage/status.py +8 -12
  403. reconcile/templates/rosa-classic-cluster-creation.sh.j2 +60 -0
  404. reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +61 -0
  405. reconcile/templating/__init__.py +0 -0
  406. reconcile/templating/lib/__init__.py +0 -0
  407. reconcile/templating/lib/merge_request_manager.py +180 -0
  408. reconcile/templating/lib/model.py +20 -0
  409. reconcile/templating/lib/rendering.py +191 -0
  410. reconcile/templating/renderer.py +410 -0
  411. reconcile/templating/validator.py +153 -0
  412. reconcile/terraform_aws_route53.py +13 -10
  413. reconcile/terraform_cloudflare_dns.py +92 -122
  414. reconcile/terraform_cloudflare_resources.py +15 -13
  415. reconcile/terraform_cloudflare_users.py +27 -27
  416. reconcile/terraform_init/__init__.py +0 -0
  417. reconcile/terraform_init/integration.py +165 -0
  418. reconcile/terraform_init/merge_request.py +57 -0
  419. reconcile/terraform_init/merge_request_manager.py +102 -0
  420. reconcile/terraform_repo.py +403 -0
  421. reconcile/terraform_resources.py +266 -168
  422. reconcile/terraform_tgw_attachments.py +417 -167
  423. reconcile/terraform_users.py +40 -17
  424. reconcile/terraform_vpc_peerings.py +310 -142
  425. reconcile/terraform_vpc_resources/__init__.py +0 -0
  426. reconcile/terraform_vpc_resources/integration.py +220 -0
  427. reconcile/terraform_vpc_resources/merge_request.py +57 -0
  428. reconcile/terraform_vpc_resources/merge_request_manager.py +107 -0
  429. reconcile/typed_queries/alerting_services_settings.py +1 -2
  430. reconcile/typed_queries/app_interface_custom_messages.py +24 -0
  431. reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +17 -0
  432. reconcile/typed_queries/app_interface_metrics_exporter/__init__.py +0 -0
  433. reconcile/typed_queries/app_interface_metrics_exporter/onboarding_status.py +13 -0
  434. reconcile/typed_queries/app_interface_repo_url.py +1 -2
  435. reconcile/typed_queries/app_interface_state_settings.py +1 -3
  436. reconcile/typed_queries/app_interface_vault_settings.py +1 -2
  437. reconcile/typed_queries/app_quay_repos_escalation_policies.py +14 -0
  438. reconcile/typed_queries/apps.py +11 -0
  439. reconcile/typed_queries/aws_vpc_requests.py +9 -0
  440. reconcile/typed_queries/aws_vpcs.py +12 -0
  441. reconcile/typed_queries/cloudflare.py +10 -0
  442. reconcile/typed_queries/clusters.py +7 -5
  443. reconcile/typed_queries/clusters_minimal.py +6 -5
  444. reconcile/typed_queries/clusters_with_dms.py +16 -0
  445. reconcile/typed_queries/cost_report/__init__.py +0 -0
  446. reconcile/typed_queries/cost_report/app_names.py +22 -0
  447. reconcile/typed_queries/cost_report/cost_namespaces.py +43 -0
  448. reconcile/typed_queries/cost_report/settings.py +15 -0
  449. reconcile/typed_queries/dynatrace.py +10 -0
  450. reconcile/typed_queries/dynatrace_environments.py +14 -0
  451. reconcile/typed_queries/dynatrace_token_provider_token_specs.py +14 -0
  452. reconcile/typed_queries/external_resources.py +46 -0
  453. reconcile/typed_queries/get_state_aws_account.py +20 -0
  454. reconcile/typed_queries/glitchtip.py +10 -0
  455. reconcile/typed_queries/jenkins.py +25 -0
  456. reconcile/typed_queries/jira.py +7 -0
  457. reconcile/typed_queries/jira_settings.py +16 -0
  458. reconcile/typed_queries/jiralert_settings.py +22 -0
  459. reconcile/typed_queries/ocm.py +8 -0
  460. reconcile/typed_queries/pagerduty_instances.py +2 -7
  461. reconcile/typed_queries/quay.py +23 -0
  462. reconcile/typed_queries/repos.py +20 -8
  463. reconcile/typed_queries/reserved_networks.py +12 -0
  464. reconcile/typed_queries/saas_files.py +221 -167
  465. reconcile/typed_queries/slack.py +7 -0
  466. reconcile/typed_queries/slo_documents.py +12 -0
  467. reconcile/typed_queries/status_board.py +58 -0
  468. reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
  469. reconcile/typed_queries/terraform_namespaces.py +1 -2
  470. reconcile/typed_queries/terraform_tgw_attachments/__init__.py +0 -0
  471. reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +16 -0
  472. reconcile/typed_queries/unleash.py +10 -0
  473. reconcile/typed_queries/users.py +11 -0
  474. reconcile/typed_queries/vault.py +10 -0
  475. reconcile/unleash_feature_toggles/__init__.py +0 -0
  476. reconcile/unleash_feature_toggles/integration.py +287 -0
  477. reconcile/utils/acs/__init__.py +0 -0
  478. reconcile/utils/acs/base.py +81 -0
  479. reconcile/utils/acs/notifiers.py +143 -0
  480. reconcile/utils/acs/policies.py +163 -0
  481. reconcile/utils/acs/rbac.py +277 -0
  482. reconcile/utils/aggregated_list.py +11 -9
  483. reconcile/utils/amtool.py +6 -4
  484. reconcile/utils/aws_api.py +279 -66
  485. reconcile/utils/aws_api_typed/__init__.py +0 -0
  486. reconcile/utils/aws_api_typed/account.py +23 -0
  487. reconcile/utils/aws_api_typed/api.py +273 -0
  488. reconcile/utils/aws_api_typed/dynamodb.py +16 -0
  489. reconcile/utils/aws_api_typed/iam.py +67 -0
  490. reconcile/utils/aws_api_typed/organization.py +152 -0
  491. reconcile/utils/aws_api_typed/s3.py +26 -0
  492. reconcile/utils/aws_api_typed/service_quotas.py +79 -0
  493. reconcile/utils/aws_api_typed/sts.py +36 -0
  494. reconcile/utils/aws_api_typed/support.py +79 -0
  495. reconcile/utils/aws_helper.py +42 -3
  496. reconcile/utils/batches.py +11 -0
  497. reconcile/utils/binary.py +7 -9
  498. reconcile/utils/cloud_resource_best_practice/__init__.py +0 -0
  499. reconcile/utils/cloud_resource_best_practice/aws_rds.py +66 -0
  500. reconcile/utils/clusterhealth/__init__.py +0 -0
  501. reconcile/utils/clusterhealth/providerbase.py +39 -0
  502. reconcile/utils/clusterhealth/telemeter.py +39 -0
  503. reconcile/utils/config.py +3 -4
  504. reconcile/utils/deadmanssnitch_api.py +86 -0
  505. reconcile/utils/differ.py +205 -0
  506. reconcile/utils/disabled_integrations.py +4 -6
  507. reconcile/utils/dynatrace/__init__.py +0 -0
  508. reconcile/utils/dynatrace/client.py +93 -0
  509. reconcile/utils/early_exit_cache.py +289 -0
  510. reconcile/utils/elasticsearch_exceptions.py +5 -0
  511. reconcile/utils/environ.py +2 -2
  512. reconcile/utils/exceptions.py +4 -0
  513. reconcile/utils/expiration.py +4 -8
  514. reconcile/utils/extended_early_exit.py +210 -0
  515. reconcile/utils/external_resource_spec.py +34 -12
  516. reconcile/utils/external_resources.py +48 -20
  517. reconcile/utils/filtering.py +16 -0
  518. reconcile/utils/git.py +49 -16
  519. reconcile/utils/github_api.py +10 -9
  520. reconcile/utils/gitlab_api.py +333 -190
  521. reconcile/utils/glitchtip/client.py +97 -100
  522. reconcile/utils/glitchtip/models.py +89 -11
  523. reconcile/utils/gql.py +157 -58
  524. reconcile/utils/grouping.py +17 -0
  525. reconcile/utils/helm.py +89 -18
  526. reconcile/utils/helpers.py +51 -0
  527. reconcile/utils/imap_client.py +5 -6
  528. reconcile/utils/internal_groups/__init__.py +0 -0
  529. reconcile/utils/internal_groups/client.py +160 -0
  530. reconcile/utils/internal_groups/models.py +71 -0
  531. reconcile/utils/jenkins_api.py +10 -34
  532. reconcile/utils/jinja2/__init__.py +0 -0
  533. reconcile/utils/{jinja2_ext.py → jinja2/extensions.py} +6 -4
  534. reconcile/utils/jinja2/filters.py +142 -0
  535. reconcile/utils/jinja2/utils.py +278 -0
  536. reconcile/utils/jira_client.py +165 -8
  537. reconcile/utils/jjb_client.py +47 -35
  538. reconcile/utils/jobcontroller/__init__.py +0 -0
  539. reconcile/utils/jobcontroller/controller.py +413 -0
  540. reconcile/utils/jobcontroller/models.py +195 -0
  541. reconcile/utils/jsonpath.py +4 -5
  542. reconcile/utils/jump_host.py +13 -12
  543. reconcile/utils/keycloak.py +106 -0
  544. reconcile/utils/ldap_client.py +35 -6
  545. reconcile/utils/lean_terraform_client.py +115 -6
  546. reconcile/utils/membershipsources/__init__.py +0 -0
  547. reconcile/utils/membershipsources/app_interface_resolver.py +60 -0
  548. reconcile/utils/membershipsources/models.py +91 -0
  549. reconcile/utils/membershipsources/resolver.py +110 -0
  550. reconcile/utils/merge_request_manager/__init__.py +0 -0
  551. reconcile/utils/merge_request_manager/merge_request_manager.py +99 -0
  552. reconcile/utils/merge_request_manager/parser.py +67 -0
  553. reconcile/utils/metrics.py +511 -1
  554. reconcile/utils/models.py +123 -0
  555. reconcile/utils/mr/README.md +198 -0
  556. reconcile/utils/mr/__init__.py +14 -10
  557. reconcile/utils/mr/app_interface_reporter.py +2 -2
  558. reconcile/utils/mr/aws_access.py +4 -4
  559. reconcile/utils/mr/base.py +51 -31
  560. reconcile/utils/mr/clusters_updates.py +10 -7
  561. reconcile/utils/mr/glitchtip_access_reporter.py +2 -4
  562. reconcile/utils/mr/labels.py +14 -1
  563. reconcile/utils/mr/notificator.py +1 -3
  564. reconcile/utils/mr/ocm_update_recommended_version.py +1 -2
  565. reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +7 -3
  566. reconcile/utils/mr/promote_qontract.py +203 -0
  567. reconcile/utils/mr/user_maintenance.py +24 -4
  568. reconcile/utils/oauth2_backend_application_session.py +132 -0
  569. reconcile/utils/oc.py +194 -170
  570. reconcile/utils/oc_connection_parameters.py +40 -51
  571. reconcile/utils/oc_filters.py +11 -13
  572. reconcile/utils/oc_map.py +14 -35
  573. reconcile/utils/ocm/__init__.py +30 -1
  574. reconcile/utils/ocm/addons.py +228 -0
  575. reconcile/utils/ocm/base.py +618 -5
  576. reconcile/utils/ocm/cluster_groups.py +5 -56
  577. reconcile/utils/ocm/clusters.py +111 -99
  578. reconcile/utils/ocm/identity_providers.py +66 -0
  579. reconcile/utils/ocm/label_sources.py +75 -0
  580. reconcile/utils/ocm/labels.py +139 -54
  581. reconcile/utils/ocm/manifests.py +39 -0
  582. reconcile/utils/ocm/ocm.py +182 -928
  583. reconcile/utils/ocm/products.py +758 -0
  584. reconcile/utils/ocm/search_filters.py +20 -28
  585. reconcile/utils/ocm/service_log.py +32 -79
  586. reconcile/utils/ocm/sre_capability_labels.py +51 -0
  587. reconcile/utils/ocm/status_board.py +66 -0
  588. reconcile/utils/ocm/subscriptions.py +49 -59
  589. reconcile/utils/ocm/syncsets.py +39 -0
  590. reconcile/utils/ocm/upgrades.py +181 -0
  591. reconcile/utils/ocm_base_client.py +71 -36
  592. reconcile/utils/openshift_resource.py +113 -67
  593. reconcile/utils/output.py +18 -11
  594. reconcile/utils/pagerduty_api.py +16 -10
  595. reconcile/utils/parse_dhms_duration.py +13 -1
  596. reconcile/utils/prometheus.py +123 -0
  597. reconcile/utils/promotion_state.py +56 -19
  598. reconcile/utils/promtool.py +5 -8
  599. reconcile/utils/quay_api.py +13 -25
  600. reconcile/utils/raw_github_api.py +3 -5
  601. reconcile/utils/repo_owners.py +2 -8
  602. reconcile/utils/rest_api_base.py +126 -0
  603. reconcile/utils/rosa/__init__.py +0 -0
  604. reconcile/utils/rosa/rosa_cli.py +310 -0
  605. reconcile/utils/rosa/session.py +201 -0
  606. reconcile/utils/ruamel.py +16 -0
  607. reconcile/utils/runtime/__init__.py +0 -1
  608. reconcile/utils/runtime/desired_state_diff.py +9 -20
  609. reconcile/utils/runtime/environment.py +33 -8
  610. reconcile/utils/runtime/integration.py +28 -12
  611. reconcile/utils/runtime/meta.py +1 -3
  612. reconcile/utils/runtime/runner.py +8 -11
  613. reconcile/utils/runtime/sharding.py +93 -36
  614. reconcile/utils/saasherder/__init__.py +1 -1
  615. reconcile/utils/saasherder/interfaces.py +143 -138
  616. reconcile/utils/saasherder/models.py +201 -43
  617. reconcile/utils/saasherder/saasherder.py +508 -378
  618. reconcile/utils/secret_reader.py +22 -27
  619. reconcile/utils/semver_helper.py +15 -1
  620. reconcile/utils/slack_api.py +124 -36
  621. reconcile/utils/smtp_client.py +1 -2
  622. reconcile/utils/sqs_gateway.py +10 -6
  623. reconcile/utils/state.py +276 -127
  624. reconcile/utils/terraform/config_client.py +6 -7
  625. reconcile/utils/terraform_client.py +284 -125
  626. reconcile/utils/terrascript/cloudflare_client.py +38 -17
  627. reconcile/utils/terrascript/cloudflare_resources.py +67 -18
  628. reconcile/utils/terrascript/models.py +2 -3
  629. reconcile/utils/terrascript/resources.py +1 -2
  630. reconcile/utils/terrascript_aws_client.py +1292 -540
  631. reconcile/utils/three_way_diff_strategy.py +157 -0
  632. reconcile/utils/unleash/__init__.py +11 -0
  633. reconcile/utils/{unleash.py → unleash/client.py} +35 -29
  634. reconcile/utils/unleash/server.py +145 -0
  635. reconcile/utils/vault.py +42 -32
  636. reconcile/utils/vaultsecretref.py +2 -4
  637. reconcile/utils/vcs.py +250 -0
  638. reconcile/vault_replication.py +38 -31
  639. reconcile/vpc_peerings_validator.py +82 -13
  640. tools/app_interface_metrics_exporter.py +70 -0
  641. tools/app_interface_reporter.py +44 -157
  642. tools/cli_commands/container_images_report.py +154 -0
  643. tools/cli_commands/cost_report/__init__.py +0 -0
  644. tools/cli_commands/cost_report/aws.py +137 -0
  645. tools/cli_commands/cost_report/cost_management_api.py +155 -0
  646. tools/cli_commands/cost_report/model.py +49 -0
  647. tools/cli_commands/cost_report/openshift.py +166 -0
  648. tools/cli_commands/cost_report/openshift_cost_optimization.py +187 -0
  649. tools/cli_commands/cost_report/response.py +124 -0
  650. tools/cli_commands/cost_report/util.py +72 -0
  651. tools/cli_commands/cost_report/view.py +524 -0
  652. tools/cli_commands/erv2.py +620 -0
  653. tools/cli_commands/gpg_encrypt.py +5 -8
  654. tools/cli_commands/systems_and_tools.py +489 -0
  655. tools/glitchtip_access_revalidation.py +1 -1
  656. tools/qontract_cli.py +2301 -673
  657. tools/saas_metrics_exporter/__init__.py +0 -0
  658. tools/saas_metrics_exporter/commit_distance/__init__.py +0 -0
  659. tools/saas_metrics_exporter/commit_distance/channel.py +63 -0
  660. tools/saas_metrics_exporter/commit_distance/commit_distance.py +103 -0
  661. tools/saas_metrics_exporter/commit_distance/metrics.py +19 -0
  662. tools/saas_metrics_exporter/main.py +99 -0
  663. tools/saas_promotion_state/__init__.py +0 -0
  664. tools/saas_promotion_state/saas_promotion_state.py +105 -0
  665. tools/sd_app_sre_alert_report.py +145 -0
  666. tools/template_validation.py +107 -0
  667. e2e_tests/cli.py +0 -83
  668. e2e_tests/create_namespace.py +0 -43
  669. e2e_tests/dedicated_admin_rolebindings.py +0 -44
  670. e2e_tests/dedicated_admin_test_base.py +0 -39
  671. e2e_tests/default_network_policies.py +0 -47
  672. e2e_tests/default_project_labels.py +0 -52
  673. e2e_tests/network_policy_test_base.py +0 -17
  674. e2e_tests/test_base.py +0 -56
  675. qontract_reconcile-0.9.1rc298.dist-info/METADATA +0 -63
  676. qontract_reconcile-0.9.1rc298.dist-info/RECORD +0 -585
  677. qontract_reconcile-0.9.1rc298.dist-info/top_level.txt +0 -4
  678. reconcile/ecr_mirror.py +0 -152
  679. reconcile/github_scanner.py +0 -74
  680. reconcile/gitlab_integrations.py +0 -63
  681. reconcile/gql_definitions/ocm_oidc_idp/clusters.py +0 -195
  682. reconcile/gql_definitions/ocp_release_mirror/ocp_release_mirror.py +0 -287
  683. reconcile/integrations_validator.py +0 -18
  684. reconcile/jenkins_plugins.py +0 -129
  685. reconcile/kafka_clusters.py +0 -208
  686. reconcile/ocm_cluster_admin.py +0 -42
  687. reconcile/ocm_oidc_idp.py +0 -198
  688. reconcile/ocp_release_mirror.py +0 -373
  689. reconcile/prometheus_rules_tester_old.py +0 -436
  690. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -279
  691. reconcile/saas_auto_promotions_manager/utils/vcs.py +0 -141
  692. reconcile/sentry_config.py +0 -613
  693. reconcile/sentry_helper.py +0 -69
  694. reconcile/test/conftest.py +0 -187
  695. reconcile/test/fixtures.py +0 -24
  696. reconcile/test/saas_auto_promotions_manager/conftest.py +0 -69
  697. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -110
  698. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -10
  699. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_housekeeping.py +0 -200
  700. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -151
  701. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -63
  702. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
  703. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -46
  704. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -94
  705. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -44
  706. reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -74
  707. reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
  708. reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -155
  709. reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -173
  710. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -226
  711. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -224
  712. reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -350
  713. reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -129
  714. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -70
  715. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -63
  716. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -74
  717. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -65
  718. reconcile/test/test_aggregated_list.py +0 -237
  719. reconcile/test/test_amtool.py +0 -37
  720. reconcile/test/test_auto_promoter.py +0 -295
  721. reconcile/test/test_aws_ami_share.py +0 -68
  722. reconcile/test/test_aws_iam_keys.py +0 -70
  723. reconcile/test/test_aws_iam_password_reset.py +0 -35
  724. reconcile/test/test_aws_support_cases_sos.py +0 -23
  725. reconcile/test/test_checkpoint.py +0 -178
  726. reconcile/test/test_cli.py +0 -41
  727. reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
  728. reconcile/test/test_gabi_authorized_users.py +0 -72
  729. reconcile/test/test_github_org.py +0 -154
  730. reconcile/test/test_github_repo_invites.py +0 -123
  731. reconcile/test/test_gitlab_housekeeping.py +0 -88
  732. reconcile/test/test_gitlab_labeler.py +0 -129
  733. reconcile/test/test_gitlab_members.py +0 -283
  734. reconcile/test/test_instrumented_wrappers.py +0 -18
  735. reconcile/test/test_integrations_manager.py +0 -995
  736. reconcile/test/test_jenkins_worker_fleets.py +0 -55
  737. reconcile/test/test_jump_host.py +0 -117
  738. reconcile/test/test_ldap_users.py +0 -123
  739. reconcile/test/test_make.py +0 -28
  740. reconcile/test/test_ocm_additional_routers.py +0 -134
  741. reconcile/test/test_ocm_addons_upgrade_scheduler_org.py +0 -149
  742. reconcile/test/test_ocm_clusters.py +0 -598
  743. reconcile/test/test_ocm_clusters_manifest_updates.py +0 -89
  744. reconcile/test/test_ocm_oidc_idp.py +0 -315
  745. reconcile/test/test_ocm_update_recommended_version.py +0 -145
  746. reconcile/test/test_ocm_upgrade_scheduler.py +0 -614
  747. reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -129
  748. reconcile/test/test_openshift_base.py +0 -730
  749. reconcile/test/test_openshift_namespace_labels.py +0 -345
  750. reconcile/test/test_openshift_namespaces.py +0 -256
  751. reconcile/test/test_openshift_resource.py +0 -415
  752. reconcile/test/test_openshift_resources_base.py +0 -440
  753. reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -310
  754. reconcile/test/test_openshift_tekton_resources.py +0 -253
  755. reconcile/test/test_openshift_upgrade_watcher.py +0 -146
  756. reconcile/test/test_prometheus_rules_tester.py +0 -151
  757. reconcile/test/test_prometheus_rules_tester_old.py +0 -77
  758. reconcile/test/test_quay_membership.py +0 -86
  759. reconcile/test/test_quay_mirror.py +0 -109
  760. reconcile/test/test_quay_mirror_org.py +0 -70
  761. reconcile/test/test_quay_repos.py +0 -59
  762. reconcile/test/test_queries.py +0 -53
  763. reconcile/test/test_repo_owners.py +0 -47
  764. reconcile/test/test_requests_sender.py +0 -139
  765. reconcile/test/test_saasherder.py +0 -1074
  766. reconcile/test/test_saasherder_allowed_secret_paths.py +0 -127
  767. reconcile/test/test_secret_reader.py +0 -153
  768. reconcile/test/test_slack_base.py +0 -185
  769. reconcile/test/test_slack_usergroups.py +0 -744
  770. reconcile/test/test_sql_query.py +0 -19
  771. reconcile/test/test_terraform_cloudflare_dns.py +0 -117
  772. reconcile/test/test_terraform_cloudflare_resources.py +0 -106
  773. reconcile/test/test_terraform_cloudflare_users.py +0 -749
  774. reconcile/test/test_terraform_resources.py +0 -257
  775. reconcile/test/test_terraform_tgw_attachments.py +0 -631
  776. reconcile/test/test_terraform_users.py +0 -57
  777. reconcile/test/test_terraform_vpc_peerings.py +0 -499
  778. reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1061
  779. reconcile/test/test_unleash.py +0 -138
  780. reconcile/test/test_utils_aws_api.py +0 -240
  781. reconcile/test/test_utils_aws_helper.py +0 -80
  782. reconcile/test/test_utils_cluster_version_data.py +0 -177
  783. reconcile/test/test_utils_data_structures.py +0 -13
  784. reconcile/test/test_utils_disabled_integrations.py +0 -86
  785. reconcile/test/test_utils_expiration.py +0 -109
  786. reconcile/test/test_utils_external_resource_spec.py +0 -383
  787. reconcile/test/test_utils_external_resources.py +0 -247
  788. reconcile/test/test_utils_github_api.py +0 -73
  789. reconcile/test/test_utils_gitlab_api.py +0 -20
  790. reconcile/test/test_utils_gpg.py +0 -69
  791. reconcile/test/test_utils_gql.py +0 -81
  792. reconcile/test/test_utils_helm.py +0 -306
  793. reconcile/test/test_utils_helpers.py +0 -55
  794. reconcile/test/test_utils_imap_client.py +0 -65
  795. reconcile/test/test_utils_jjb_client.py +0 -52
  796. reconcile/test/test_utils_jsonpath.py +0 -286
  797. reconcile/test/test_utils_ldap_client.py +0 -51
  798. reconcile/test/test_utils_mr.py +0 -226
  799. reconcile/test/test_utils_mr_clusters_updates.py +0 -77
  800. reconcile/test/test_utils_oc.py +0 -984
  801. reconcile/test/test_utils_ocm.py +0 -110
  802. reconcile/test/test_utils_pagerduty_api.py +0 -251
  803. reconcile/test/test_utils_parse_dhms_duration.py +0 -34
  804. reconcile/test/test_utils_password_validator.py +0 -155
  805. reconcile/test/test_utils_quay_api.py +0 -86
  806. reconcile/test/test_utils_semver_helper.py +0 -19
  807. reconcile/test/test_utils_sharding.py +0 -56
  808. reconcile/test/test_utils_slack_api.py +0 -439
  809. reconcile/test/test_utils_smtp_client.py +0 -73
  810. reconcile/test/test_utils_state.py +0 -256
  811. reconcile/test/test_utils_terraform.py +0 -13
  812. reconcile/test/test_utils_terraform_client.py +0 -585
  813. reconcile/test/test_utils_terraform_config_client.py +0 -219
  814. reconcile/test/test_utils_terrascript_aws_client.py +0 -277
  815. reconcile/test/test_utils_terrascript_cloudflare_client.py +0 -597
  816. reconcile/test/test_utils_terrascript_cloudflare_resources.py +0 -26
  817. reconcile/test/test_vault_replication.py +0 -515
  818. reconcile/test/test_vault_utils.py +0 -47
  819. reconcile/test/test_version_bump.py +0 -18
  820. reconcile/test/test_vpc_peerings_validator.py +0 -103
  821. reconcile/test/test_wrong_region.py +0 -78
  822. reconcile/typed_queries/glitchtip_settings.py +0 -18
  823. reconcile/typed_queries/ocp_release_mirror.py +0 -11
  824. reconcile/unleash_watcher.py +0 -120
  825. reconcile/utils/git_secrets.py +0 -63
  826. reconcile/utils/mr/auto_promoter.py +0 -218
  827. reconcile/utils/sentry_client.py +0 -383
  828. release/test_version.py +0 -50
  829. release/version.py +0 -100
  830. tools/test/test_qontract_cli.py +0 -60
  831. tools/test/test_sre_checkpoints.py +0 -79
  832. /e2e_tests/__init__.py → /reconcile/aus/upgrades.py +0 -0
  833. /reconcile/{gql_definitions/ocp_release_mirror → aws_account_manager}/__init__.py +0 -0
  834. /reconcile/{test → aws_ami_cleanup}/__init__.py +0 -0
  835. /reconcile/{test/saas_auto_promotions_manager → aws_cloudwatch_log_retention}/__init__.py +0 -0
  836. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager → aws_saml_idp}/__init__.py +0 -0
  837. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager → aws_saml_roles}/__init__.py +0 -0
  838. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/renderer → aws_version_sync}/__init__.py +0 -0
  839. /reconcile/{test/saas_auto_promotions_manager/subscriber → aws_version_sync/merge_request_manager}/__init__.py +0 -0
  840. /reconcile/{test/saas_auto_promotions_manager/utils → cluster_auth_rhidp}/__init__.py +0 -0
  841. /reconcile/{test/saas_auto_promotions_manager/utils/saas_files_inventory → dynatrace_token_provider}/__init__.py +0 -0
  842. {release → reconcile/endpoints_discovery}/__init__.py +0 -0
  843. {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, (list, tuple)) else 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["kind"]
170
- resource_name = msg.resource["metadata"]["name"]
171
- annotations = msg.resource["metadata"].get("annotations", {})
172
- except KeyError as e:
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
- try:
241
+ with suppress(KeyError):
234
242
  del t1_copy["metadata"]["labels"]["pod-template-hash"]
235
- except KeyError:
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 OCDeprecatedApiResource:
249
+ class OCCliApiResource:
246
250
  """This class mimics kubernetes.dynamic.resource.Resource and it's used
247
- To get Api Resources with the OCDeprecated client"""
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 "{}/{}".format(self.group, self.api_version)
261
+ return f"{self.group}/{self.api_version}"
258
262
  return self.api_version
259
263
 
260
264
 
261
- class OCDeprecated: # pylint: disable=too-many-public-methods
265
+ class OCCli: # pylint: disable=too-many-public-methods
262
266
  def __init__(
263
267
  self,
264
- cluster_name: Optional[str],
265
- server: Optional[str],
266
- token: Optional[str],
267
- jh: Optional[Mapping[Any, Any]] = None,
268
- settings: Optional[Mapping[Any, Any]] = None,
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: Optional[OCConnectionParameters] = None,
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: Optional[str],
313
- token: Optional[str],
314
- jh: Optional[Mapping[Any, Any]] = None,
315
- settings: Optional[Mapping[Any, Any]] = None,
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 = [p["metadata"]["name"] for p in self.get_all(kind)["items"]]
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 ["true", "yes"]
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 = [p["metadata"]["name"] for p in self.get_all(kind)["items"]]
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 ["true", "yes"]
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.body)
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.body)
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.body)
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.init_projects:
631
- return name in self.projects
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 = OCDeprecatedApiResource(kind, group, api_version, namespaced)
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 ("Running", "Succeeded")
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(self, namespace, name, follow, output):
754
- self.wait_for_job_running(namespace, name)
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
- # pylint: disable=consider-using-with
759
- output_file = open(os.path.join(output, name), "w")
760
- # collect logs to file async
761
- Popen(self.oc_base_cmd + cmd, stdout=output_file)
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:{}:{}".format(namespace, name)
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
- [self.validate_pod_ready.__name__, self.cluster_name, namespace, name]
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
- "skipping_pod_recycle_unsupported",
874
- self.cluster_name,
875
- namespace,
876
- dep_kind,
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
- "skipping_pod_recycle_no_annotation",
889
- self.cluster_name,
890
- namespace,
891
- dep_kind,
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 ("Secret", "ConfigMap"):
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
- class OCNative(OCDeprecated):
1225
+ REQUEST_TIMEOUT = 60
1226
+
1227
+
1228
+ class OCNative(OCCli):
1198
1229
  def __init__(
1199
1230
  self,
1200
- cluster_name: Optional[str],
1201
- server: Optional[str],
1202
- token: Optional[str],
1203
- jh: Optional[Mapping[Any, Any]] = None,
1204
- settings: Optional[Mapping[Any, Any]] = None,
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: Optional[OCConnectionParameters] = None,
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 = [p["metadata"]["name"] for p in self.get_all(kind)["items"]]
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 = dict(
1261
- api_key={"authorization": f"Bearer {token}"},
1262
- host=server,
1263
- verify_ssl=False,
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=5,
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, namespace=namespace, label_selector=labels
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, label_selector=labels
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(name=name, namespace=namespace)
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 = Union[OCNative, OCDeprecated]
1401
+ OCClient = OCNative | OCCli
1365
1402
 
1366
1403
 
1367
- class OCLocal(OCDeprecated):
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: Optional[str] = None,
1393
- server: Optional[str] = None,
1394
- token: Optional[str] = None,
1395
- jh: Optional[Mapping[Any, Any]] = None,
1396
- settings: Optional[Mapping[Any, Any]] = None,
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: Optional[OCConnectionParameters] = None,
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 ["true", "yes"]
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 OCDeprecated(
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 ("kubernetes.io", "k8s.io"):
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
- [isinstance(x, ResourceList) for x in results]
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) > 1
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 {}".format(kwargs))
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}")