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
@@ -1,11 +1,8 @@
1
1
  import json
2
2
  import logging
3
3
  import sys
4
- from typing import (
5
- Any,
6
- Optional,
7
- Union,
8
- )
4
+ from collections.abc import Mapping
5
+ from typing import Any
9
6
 
10
7
  import jinja2
11
8
  import yaml
@@ -16,6 +13,10 @@ from reconcile.status import ExitCodes
16
13
  from reconcile.utils import gql
17
14
  from reconcile.utils.defer import defer
18
15
  from reconcile.utils.openshift_resource import OpenshiftResource as OR
16
+ from reconcile.utils.parse_dhms_duration import (
17
+ dhms_to_seconds,
18
+ seconds_to_hms,
19
+ )
19
20
  from reconcile.utils.saasherder import Providers
20
21
  from reconcile.utils.semver_helper import make_semver
21
22
  from reconcile.utils.sharding import is_in_shard
@@ -27,6 +28,10 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
27
28
  # it must be a single character due to resource max length
28
29
  OBJECTS_PREFIX = "o"
29
30
  RESOURCE_MAX_LENGTH = 63
31
+ # This is caused by PipelineRun names on retry. They get the name pipeline-<7 random characters>
32
+ # If pipeline names are larger than this, PR will fail to get created as names will be larger
33
+ # than 63 characters.
34
+ PIPELINE_MAX_LENGTH = RESOURCE_MAX_LENGTH - 7
30
35
 
31
36
  # Defaults
32
37
  DEFAULT_DEPLOY_RESOURCES_STEP_NAME = "qontract-reconcile"
@@ -44,6 +49,7 @@ SAAS_FILES_QUERY = """
44
49
  name
45
50
  provider
46
51
  }
52
+ timeout
47
53
  deployResources {
48
54
  requests {
49
55
  cpu
@@ -67,7 +73,7 @@ class OpenshiftTektonResourcesBadConfigError(Exception):
67
73
  pass
68
74
 
69
75
 
70
- def fetch_saas_files(saas_file_name: Optional[str]) -> list[dict[str, Any]]:
76
+ def fetch_saas_files(saas_file_name: str | None) -> list[dict[str, Any]]:
71
77
  """Fetch saas v2 files"""
72
78
  saas_files = gql.get_api().query(SAAS_FILES_QUERY)["saas_files"]
73
79
 
@@ -83,7 +89,7 @@ def fetch_saas_files(saas_file_name: Optional[str]) -> list[dict[str, Any]]:
83
89
  return saas_files
84
90
 
85
91
 
86
- def fetch_tkn_providers(saas_file_name: Optional[str]) -> dict[str, Any]:
92
+ def fetch_tkn_providers(saas_file_name: str | None) -> dict[str, Any]:
87
93
  """Fetch tekton providers data for the saas files handled here"""
88
94
  saas_files = fetch_saas_files(saas_file_name)
89
95
  if not saas_files:
@@ -127,8 +133,8 @@ def fetch_tkn_providers(saas_file_name: Optional[str]) -> dict[str, Any]:
127
133
 
128
134
 
129
135
  def fetch_desired_resources(
130
- tkn_providers: dict[str, Any]
131
- ) -> list[dict[str, Union[str, OR]]]:
136
+ tkn_providers: dict[str, Any],
137
+ ) -> list[dict[str, str | OR]]:
132
138
  """Create an array of dicts that will be used as args of ri.add_desired
133
139
  This will also add resourceNames inside tkn_providers['namespace']
134
140
  while we are migrating from the current system to this integration"""
@@ -203,7 +209,7 @@ def fetch_desired_resources(
203
209
 
204
210
 
205
211
  def build_one_per_namespace_task(
206
- task_template_config: dict[str, str]
212
+ task_template_config: dict[str, str],
207
213
  ) -> dict[str, Any]:
208
214
  """Builds onePerNamespace Task objects. The name of the task template
209
215
  will be used as Task name and there won't be any resource configuration"""
@@ -220,6 +226,22 @@ def build_one_per_namespace_task(
220
226
  return task
221
227
 
222
228
 
229
+ def _curate_deploy_resources(deploy_resources: Mapping[str, Any]) -> dict[str, Any]:
230
+ """Removes empty (None) values in deploy_resources dicts
231
+
232
+ :param deploy_resources: dictionary with the resources returned by Gql
233
+ :return: dict with the resources without None values
234
+ """
235
+ resources = {
236
+ item: {
237
+ k: v for k, v in (deploy_resources.get(item) or {}).items() if v is not None
238
+ }
239
+ for item, values in deploy_resources.items()
240
+ if values is not None
241
+ }
242
+ return resources
243
+
244
+
223
245
  def build_one_per_saas_file_task(
224
246
  task_template_config: dict[str, str],
225
247
  saas_file: dict[str, Any],
@@ -236,7 +258,7 @@ def build_one_per_saas_file_task(
236
258
  else {}
237
259
  )
238
260
  task = load_tkn_template(task_template_config["path"], variables)
239
- task["metadata"]["name"] = build_one_per_saas_file_tkn_object_name(
261
+ task["metadata"]["name"] = build_one_per_saas_file_tkn_task_name(
240
262
  task_template_config["name"], saas_file["name"]
241
263
  )
242
264
  step_name = task_template_config.get(
@@ -246,7 +268,9 @@ def build_one_per_saas_file_task(
246
268
  resources_configured = False
247
269
  for step in task["spec"]["steps"]:
248
270
  if step["name"] == step_name:
249
- step["resources"] = saas_file.get("deployResources") or deploy_resources
271
+ step["computeResources"] = _curate_deploy_resources(
272
+ saas_file.get("deployResources") or deploy_resources
273
+ )
250
274
  resources_configured = True
251
275
  break
252
276
 
@@ -272,10 +296,15 @@ def build_one_per_saas_file_pipeline(
272
296
  else {}
273
297
  )
274
298
  pipeline = load_tkn_template(pipeline_template_config["path"], variables)
275
- pipeline["metadata"]["name"] = build_one_per_saas_file_tkn_object_name(
299
+ pipeline["metadata"]["name"] = build_one_per_saas_file_tkn_pipeline_name(
276
300
  pipeline_template_config["name"], saas_file["name"]
277
301
  )
278
302
 
303
+ timeout = saas_file.get("timeout")
304
+ if timeout:
305
+ timeout_seconds = dhms_to_seconds(timeout)
306
+ normalized_timeout = seconds_to_hms(timeout_seconds)
307
+
279
308
  for section in ["tasks", "finally"]:
280
309
  for task in pipeline["spec"].get(section, []):
281
310
  if task["name"] not in task_templates_types:
@@ -289,10 +318,13 @@ def build_one_per_saas_file_pipeline(
289
318
  task["name"]
290
319
  )
291
320
  else:
292
- task["taskRef"]["name"] = build_one_per_saas_file_tkn_object_name(
321
+ task["taskRef"]["name"] = build_one_per_saas_file_tkn_task_name(
293
322
  task["name"], saas_file["name"]
294
323
  )
295
324
 
325
+ if timeout:
326
+ task["timeout"] = normalized_timeout
327
+
296
328
  return pipeline
297
329
 
298
330
 
@@ -308,7 +340,7 @@ def load_tkn_template(path: str, variables: dict[str, str]) -> dict[str, Any]:
308
340
 
309
341
  def build_desired_resource(
310
342
  tkn_object: dict[str, Any], path: str, cluster: str, namespace: str
311
- ) -> dict[str, Union[str, OR]]:
343
+ ) -> dict[str, str | OR]:
312
344
  """Returns a dict with ResourceInventory.add_desired args"""
313
345
  openshift_resource = OR(
314
346
  tkn_object,
@@ -331,7 +363,16 @@ def check_resource_max_length(name: str) -> None:
331
363
  being applied"""
332
364
  if len(name) > RESOURCE_MAX_LENGTH:
333
365
  raise OpenshiftTektonResourcesNameTooLongError(
334
- f"name {name} is longer than {RESOURCE_MAX_LENGTH} characters"
366
+ f"Resource name {name} is longer than {RESOURCE_MAX_LENGTH} characters"
367
+ )
368
+
369
+
370
+ def check_pipeline_max_length(name: str) -> None:
371
+ """Checks the pipeline name is not too long as it may have problems when
372
+ used to generate PipelineRun names on retry"""
373
+ if len(name) > PIPELINE_MAX_LENGTH:
374
+ raise OpenshiftTektonResourcesNameTooLongError(
375
+ f"Pipeline name {name} is longer than {PIPELINE_MAX_LENGTH} characters"
335
376
  )
336
377
 
337
378
 
@@ -342,13 +383,36 @@ def build_one_per_namespace_tkn_object_name(name: str) -> str:
342
383
  return name
343
384
 
344
385
 
345
- def build_one_per_saas_file_tkn_object_name(
386
+ def _generate_one_per_saas_file_tkn_object_name(
387
+ template_name: str, saas_file_name: str
388
+ ) -> str:
389
+ """Generates a onePerSaasFile object name. Given a saas file name, it returns the
390
+ openshift-saas-deploy names used by Tasks and Pipelines created by this integration
391
+ """
392
+ return f"{OBJECTS_PREFIX}-{template_name}-{saas_file_name}"
393
+
394
+
395
+ def build_one_per_saas_file_tkn_pipeline_name(
396
+ template_name: str, saas_file_name: str
397
+ ) -> str:
398
+ """Builds a onePerSaasFile pipeline name and checks length. Given a saas file name,
399
+ it returns the openshift-saas-deploy names used by Pipelines created by this
400
+ integration. Pipeline lenghth is further limited by the fact that PipelineRuns
401
+ that are create as part of a retry have the name of the Pipeline + 7 random
402
+ characters and they have a max lenght of 63 characters.
403
+ """
404
+ name = _generate_one_per_saas_file_tkn_object_name(template_name, saas_file_name)
405
+ check_pipeline_max_length(name)
406
+ return name
407
+
408
+
409
+ def build_one_per_saas_file_tkn_task_name(
346
410
  template_name: str, saas_file_name: str
347
411
  ) -> str:
348
- """Builds a onePerSaasFile object name. Given a saas file name, it returns
349
- the openshift-saas-deploy names used by Tasks and Pipelines created by this
350
- integration"""
351
- name = f"{OBJECTS_PREFIX}-{template_name}-{saas_file_name}"
412
+ """Builds a onePerSaasFile task name and checks length. Given a saas file name, it
413
+ returns the openshift-saas-deploy names used by Tasks created by this integration
414
+ """
415
+ name = _generate_one_per_saas_file_tkn_object_name(template_name, saas_file_name)
352
416
  check_resource_max_length(name)
353
417
  return name
354
418
 
@@ -356,11 +420,10 @@ def build_one_per_saas_file_tkn_object_name(
356
420
  def run(
357
421
  dry_run: bool,
358
422
  thread_pool_size: int = 10,
359
- internal: Optional[bool] = None,
423
+ internal: bool | None = None,
360
424
  use_jump_host: bool = True,
361
- saas_file_name: Optional[str] = None,
425
+ saas_file_name: str | None = None,
362
426
  ) -> None:
363
-
364
427
  tkn_providers = fetch_tkn_providers(saas_file_name)
365
428
 
366
429
  # TODO: This will need to be an error condition in the future
@@ -392,6 +455,8 @@ def run(
392
455
  for desired_resource in desired_resources:
393
456
  ri.add_desired(**desired_resource)
394
457
 
458
+ LOG.debug("Publishing metrics")
459
+ ob.publish_metrics(ri, QONTRACT_INTEGRATION)
395
460
  LOG.debug("Realizing data")
396
461
  ob.realize_data(dry_run, oc_map, ri, thread_pool_size)
397
462
 
@@ -4,8 +4,8 @@ from collections.abc import (
4
4
  Iterable,
5
5
  )
6
6
  from datetime import datetime
7
- from typing import Optional
8
7
 
8
+ from reconcile import queries
9
9
  from reconcile.gql_definitions.common.clusters import ClusterV1
10
10
  from reconcile.slack_base import slackapi_from_queries
11
11
  from reconcile.typed_queries.app_interface_vault_settings import (
@@ -18,6 +18,9 @@ from reconcile.utils.oc_map import (
18
18
  OCMap,
19
19
  init_oc_map_from_clusters,
20
20
  )
21
+ from reconcile.utils.ocm import OCMMap
22
+ from reconcile.utils.ocm.upgrades import get_control_plane_upgrade_policies
23
+ from reconcile.utils.ocm_base_client import OCMBaseClient
21
24
  from reconcile.utils.secret_reader import create_secret_reader
22
25
  from reconcile.utils.slack_api import SlackApi
23
26
  from reconcile.utils.state import (
@@ -28,7 +31,7 @@ from reconcile.utils.state import (
28
31
  QONTRACT_INTEGRATION = "openshift-upgrade-watcher"
29
32
 
30
33
 
31
- def cluster_slack_handle(cluster: str, slack: Optional[SlackApi]) -> str:
34
+ def cluster_slack_handle(cluster: str, slack: SlackApi | None) -> str:
32
35
  usergroup = f"{cluster}-cluster"
33
36
  usergroup_id = f"@{usergroup}"
34
37
  if slack:
@@ -38,10 +41,10 @@ def cluster_slack_handle(cluster: str, slack: Optional[SlackApi]) -> str:
38
41
 
39
42
  def handle_slack_notification(
40
43
  msg: str,
41
- slack: Optional[SlackApi],
44
+ slack: SlackApi | None,
42
45
  state: State,
43
46
  state_key: str,
44
- state_value: Optional[str],
47
+ state_value: str | None,
45
48
  ) -> None:
46
49
  """Check notification status, notify if needed and update the notification status"""
47
50
  if state.exists(state_key) and state.get(state_key) == state_value:
@@ -54,86 +57,121 @@ def handle_slack_notification(
54
57
  state.add(state_key, state_value, force=True)
55
58
 
56
59
 
60
+ def _get_start_osd(oc_map: OCMap, cluster_name: str) -> tuple[str | None, str | None]:
61
+ oc = oc_map.get(cluster_name)
62
+ if isinstance(oc, OCLogMsg):
63
+ logging.log(level=oc.log_level, msg=oc.message)
64
+ return None, None
65
+
66
+ upgrade_config = oc.get(
67
+ namespace="openshift-managed-upgrade-operator",
68
+ kind="UpgradeConfig",
69
+ allow_not_found=True,
70
+ )["items"]
71
+ if not upgrade_config:
72
+ logging.debug(f"[{cluster_name}] UpgradeConfig not found.")
73
+ return None, None
74
+ [upgrade_config] = upgrade_config
75
+
76
+ upgrade_spec = upgrade_config["spec"]
77
+ upgrade_at = upgrade_spec["upgradeAt"]
78
+ version = upgrade_spec["desired"]["version"]
79
+ return upgrade_at, version
80
+
81
+
82
+ def _get_start_hypershift(
83
+ ocm_api: OCMBaseClient, cluster_id: str
84
+ ) -> tuple[str | None, str | None]:
85
+ schedules = get_control_plane_upgrade_policies(ocm_api, cluster_id)
86
+ schedule = [s for s in schedules if s["state"] == "started"]
87
+ if not schedule:
88
+ return None, None
89
+
90
+ if len(schedule) > 1:
91
+ logging.error(f"[{cluster_id}] More than one schedule started.")
92
+
93
+ return schedule[0]["next_run"], schedule[0]["version"]
94
+
95
+
57
96
  def notify_upgrades_start(
97
+ clusters: list[ClusterV1],
58
98
  oc_map: OCMap,
99
+ ocm_map: OCMMap,
59
100
  state: State,
60
- slack: Optional[SlackApi],
101
+ slack: SlackApi | None,
61
102
  ) -> None:
62
103
  now = datetime.utcnow()
63
- for cluster in oc_map.clusters(include_errors=True):
64
- oc = oc_map.get(cluster)
65
- if isinstance(oc, OCLogMsg):
66
- logging.log(level=oc.log_level, msg=oc.message)
67
- continue
68
- upgrade_config = oc.get(
69
- namespace="openshift-managed-upgrade-operator",
70
- kind="UpgradeConfig",
71
- allow_not_found=True,
72
- )["items"]
73
- if not upgrade_config:
74
- logging.debug(f"[{cluster}] UpgradeConfig not found.")
104
+ for cluster in clusters:
105
+ if cluster.spec and not cluster.spec.hypershift:
106
+ upgrade_at, version = _get_start_osd(oc_map, cluster.name)
107
+ elif cluster.spec and cluster.spec.q_id:
108
+ upgrade_at, version = _get_start_hypershift(
109
+ ocm_map.get(cluster.name)._ocm_client, cluster.spec.q_id
110
+ )
111
+ else:
75
112
  continue
76
- [upgrade_config] = upgrade_config
77
-
78
- upgrade_spec = upgrade_config["spec"]
79
- upgrade_at = upgrade_spec["upgradeAt"]
80
- version = upgrade_spec["desired"]["version"]
81
- upgrade_at_obj = datetime.strptime(upgrade_at, "%Y-%m-%dT%H:%M:%SZ")
82
- state_key = f"{cluster}-{upgrade_at}"
83
- # if this is the first iteration in which 'now' had passed
84
- # the upgrade at date time, we send a notification
85
- if upgrade_at_obj < now:
113
+
114
+ if upgrade_at and version:
115
+ upgrade_at_obj = datetime.strptime(upgrade_at, "%Y-%m-%dT%H:%M:%SZ")
116
+ state_key = f"{cluster.name}-{upgrade_at}1"
117
+ # if this is the first iteration in which 'now' had passed
118
+ # the upgrade at date time, we send a notification
119
+ if upgrade_at_obj < now:
120
+ msg = (
121
+ f"Heads up {cluster_slack_handle(cluster.name, slack)}! "
122
+ + f"cluster `{cluster.name}` is currently "
123
+ + f"being upgraded to version `{version}`"
124
+ )
125
+ handle_slack_notification(
126
+ msg=msg,
127
+ slack=slack,
128
+ state=state,
129
+ state_key=state_key,
130
+ state_value=None,
131
+ )
132
+
133
+
134
+ def notify_cluster_new_version(
135
+ clusters: Iterable[ClusterV1], state: State, slack: SlackApi | None
136
+ ) -> None:
137
+ # Send a notification, if a cluster runs a version it was not running in the past
138
+ # This does not check if an upgrade was successful or not
139
+ for cluster in clusters:
140
+ if cluster.spec:
141
+ state_key = f"{cluster.name}-{cluster.spec.version}"
86
142
  msg = (
87
- f"Heads up {cluster_slack_handle(cluster, slack)}! "
88
- + f"cluster `{cluster}` is currently "
89
- + f"being upgraded to version `{version}`"
143
+ f"{cluster_slack_handle(cluster.name, slack)}: "
144
+ + f"cluster `{cluster.name}` is now running version `{cluster.spec.version}`"
90
145
  )
91
146
  handle_slack_notification(
92
- msg=msg, slack=slack, state=state, state_key=state_key, state_value=None
147
+ msg=msg,
148
+ slack=slack,
149
+ state=state,
150
+ state_key=state_key,
151
+ state_value=cluster.spec.version,
93
152
  )
94
153
 
95
154
 
96
- def notify_upgrades_done(
97
- clusters: Iterable[ClusterV1], state: State, slack: Optional[SlackApi]
98
- ) -> None:
99
- for cluster in clusters:
100
- if not cluster.spec:
101
- raise RuntimeError(f"Cluster '{cluster.name}' does not have any spec.")
102
- state_key = f"{cluster.name}-{cluster.spec.version}"
103
- msg = (
104
- f"{cluster_slack_handle(cluster.name, slack)}: "
105
- + f"cluster `{cluster.name}` is now running version `{cluster.spec.version}`"
106
- )
107
- handle_slack_notification(
108
- msg=msg,
109
- slack=slack,
110
- state=state,
111
- state_key=state_key,
112
- state_value=cluster.spec.version,
113
- )
114
-
115
-
116
155
  @defer
117
156
  def run(
118
157
  dry_run: bool,
119
158
  thread_pool_size: int = 10,
120
- internal: Optional[bool] = None,
159
+ internal: bool | None = None,
121
160
  use_jump_host: bool = True,
122
- defer: Optional[Callable] = None,
161
+ defer: Callable | None = None,
123
162
  ) -> None:
163
+ slack: SlackApi | None = None
164
+ if not dry_run:
165
+ slack = slackapi_from_queries(QONTRACT_INTEGRATION)
166
+
124
167
  vault_settings = get_app_interface_vault_settings()
168
+ settings = queries.get_app_interface_settings()
125
169
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
126
170
  state = init_state(integration=QONTRACT_INTEGRATION, secret_reader=secret_reader)
127
171
  if defer:
128
172
  defer(state.cleanup)
129
173
 
130
- clusters = [
131
- c for c in get_clusters() if c.ocm and not (c.spec and c.spec.hypershift)
132
- ]
133
-
134
- slack: Optional[SlackApi] = None
135
- if not dry_run:
136
- slack = slackapi_from_queries(QONTRACT_INTEGRATION)
174
+ clusters = [c for c in get_clusters() if c.ocm and c.spec]
137
175
 
138
176
  oc_map = init_oc_map_from_clusters(
139
177
  clusters=clusters,
@@ -145,6 +183,16 @@ def run(
145
183
  )
146
184
  if defer:
147
185
  defer(oc_map.cleanup)
148
- notify_upgrades_start(oc_map=oc_map, state=state, slack=slack)
149
186
 
150
- notify_upgrades_done(clusters=clusters, state=state, slack=slack)
187
+ cluster_like_objects = [cluster.dict(by_alias=True) for cluster in clusters]
188
+ ocm_map = OCMMap(
189
+ clusters=cluster_like_objects,
190
+ integration=QONTRACT_INTEGRATION,
191
+ settings=settings,
192
+ )
193
+
194
+ notify_upgrades_start(
195
+ clusters=clusters, oc_map=oc_map, ocm_map=ocm_map, state=state, slack=slack
196
+ )
197
+
198
+ notify_cluster_new_version(clusters=clusters, state=state, slack=slack)
@@ -5,10 +5,7 @@ from collections.abc import (
5
5
  Iterable,
6
6
  Mapping,
7
7
  )
8
- from typing import (
9
- Any,
10
- Optional,
11
- )
8
+ from typing import Any
12
9
 
13
10
  from sretoolbox.utils import threaded
14
11
 
@@ -18,6 +15,7 @@ from reconcile import (
18
15
  )
19
16
  from reconcile.gql_definitions.common.clusters_minimal import (
20
17
  ClusterAuthOIDCV1,
18
+ ClusterAuthRHIDPV1,
21
19
  ClusterV1,
22
20
  )
23
21
  from reconcile.typed_queries.app_interface_vault_settings import (
@@ -45,13 +43,13 @@ def get_cluster_users(
45
43
  users: list[str] = []
46
44
 
47
45
  # get cluster info for current cluster name from clusters list
48
- cluster_info = next((cl for cl in clusters if cl.name == cluster))
46
+ cluster_info = next(cl for cl in clusters if cl.name == cluster)
49
47
 
50
48
  # backwarts compatibiltiy for clusters w/o auth
51
49
  identity_prefixes = ["github"]
52
50
 
53
51
  for auth in cluster_info.auth:
54
- if isinstance(auth, ClusterAuthOIDCV1):
52
+ if isinstance(auth, ClusterAuthOIDCV1 | ClusterAuthRHIDPV1):
55
53
  identity_prefixes.append(auth.name)
56
54
 
57
55
  for u in oc.get_users():
@@ -71,7 +69,7 @@ def get_cluster_users(
71
69
 
72
70
  def fetch_current_state(
73
71
  thread_pool_size: int,
74
- internal: Optional[bool],
72
+ internal: bool | None,
75
73
  use_jump_host: bool,
76
74
  ) -> tuple[OCMap, list[Any]]:
77
75
  vault_settings = get_app_interface_vault_settings()
@@ -98,7 +96,7 @@ def fetch_current_state(
98
96
 
99
97
 
100
98
  def fetch_desired_state(
101
- oc_map: Optional[OCMap], enforced_user_keys: Any = None
99
+ oc_map: OCMap | None, enforced_user_keys: Any = None
102
100
  ) -> list[Any]:
103
101
  desired_state = []
104
102
 
@@ -108,7 +106,8 @@ def fetch_desired_state(
108
106
  desired_state.extend(flat_rolebindings_desired_state)
109
107
 
110
108
  groups_desired_state = openshift_groups.fetch_desired_state(
111
- oc_map, enforced_user_keys=enforced_user_keys
109
+ clusters=oc_map.clusters() if oc_map else [],
110
+ enforced_user_keys=enforced_user_keys,
112
111
  )
113
112
  flat_groups_desired_state = [
114
113
  {"cluster": s["cluster"], "user": s["user"]} for s in groups_desired_state
@@ -141,9 +140,11 @@ def subtract_states(
141
140
  found = True
142
141
  break
143
142
  if not found:
144
- result.append(
145
- {"action": action, "cluster": f_user["cluster"], "user": f_user["user"]}
146
- )
143
+ result.append({
144
+ "action": action,
145
+ "cluster": f_user["cluster"],
146
+ "user": f_user["user"],
147
+ })
147
148
 
148
149
  return result
149
150
 
@@ -159,16 +160,16 @@ def act(diff: Mapping[str, Any], oc_map: OCMap) -> None:
159
160
  raise Exception("No proper Openshift Client for del_user operation")
160
161
  oc.delete_user(user)
161
162
  else:
162
- raise Exception("invalid action: {}".format(action))
163
+ raise Exception(f"invalid action: {action}")
163
164
 
164
165
 
165
166
  @defer
166
167
  def run(
167
168
  dry_run: bool,
168
169
  thread_pool_size: int = 10,
169
- internal: Optional[bool] = None,
170
+ internal: bool | None = None,
170
171
  use_jump_host: bool = True,
171
- defer: Optional[Callable] = None,
172
+ defer: Callable | None = None,
172
173
  ) -> None:
173
174
  oc_map, current_state = fetch_current_state(
174
175
  thread_pool_size, internal, use_jump_host
@@ -1,7 +1,9 @@
1
+ from collections import defaultdict
1
2
  from typing import Any
2
3
 
4
+ from deepdiff import DeepHash
5
+
3
6
  import reconcile.openshift_resources_base as orb
4
- from reconcile.change_owners.diff import IDENTIFIER_FIELD_NAME
5
7
  from reconcile.utils.runtime.integration import DesiredStateShardConfig
6
8
  from reconcile.utils.semver_helper import make_semver
7
9
 
@@ -36,12 +38,15 @@ def run(
36
38
  def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
37
39
  namespaces, _ = orb.get_namespaces(PROVIDERS)
38
40
 
39
- def add_ns_identify(ns):
40
- ns[IDENTIFIER_FIELD_NAME] = f"{ns['cluster']['name']}/{ns['name']}"
41
- return ns
41
+ state_for_clusters = defaultdict(list)
42
+ for ns in namespaces:
43
+ state_for_clusters[ns["cluster"]["name"]].append(ns)
42
44
 
43
45
  return {
44
- "namespaces": [add_ns_identify(ns) for ns in namespaces],
46
+ "state": {
47
+ cluster: {"shard": cluster, "hash": DeepHash(state).get(state)}
48
+ for cluster, state in state_for_clusters.items()
49
+ }
45
50
  }
46
51
 
47
52
 
@@ -49,7 +54,7 @@ def desired_state_shard_config() -> DesiredStateShardConfig:
49
54
  return DesiredStateShardConfig(
50
55
  shard_arg_name="cluster_name",
51
56
  shard_path_selectors={
52
- "namespaces[*].cluster.name",
57
+ "state.*.shard",
53
58
  },
54
59
  sharded_run_review=lambda proposal: len(proposal.proposed_shards) <= 2,
55
60
  )
File without changes