qontract-reconcile 0.10.0__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 (844) 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.10.0.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
  4. {qontract_reconcile-0.10.0.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.10.0.dist-info/LICENSE +0 -201
  676. qontract_reconcile-0.10.0.dist-info/METADATA +0 -63
  677. qontract_reconcile-0.10.0.dist-info/RECORD +0 -586
  678. qontract_reconcile-0.10.0.dist-info/top_level.txt +0 -4
  679. reconcile/ecr_mirror.py +0 -152
  680. reconcile/github_scanner.py +0 -74
  681. reconcile/gitlab_integrations.py +0 -63
  682. reconcile/gql_definitions/ocm_oidc_idp/clusters.py +0 -195
  683. reconcile/gql_definitions/ocp_release_mirror/ocp_release_mirror.py +0 -287
  684. reconcile/integrations_validator.py +0 -18
  685. reconcile/jenkins_plugins.py +0 -129
  686. reconcile/kafka_clusters.py +0 -208
  687. reconcile/ocm_cluster_admin.py +0 -42
  688. reconcile/ocm_oidc_idp.py +0 -198
  689. reconcile/ocp_release_mirror.py +0 -373
  690. reconcile/prometheus_rules_tester_old.py +0 -436
  691. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -279
  692. reconcile/saas_auto_promotions_manager/utils/vcs.py +0 -141
  693. reconcile/sentry_config.py +0 -613
  694. reconcile/sentry_helper.py +0 -69
  695. reconcile/test/conftest.py +0 -187
  696. reconcile/test/fixtures.py +0 -24
  697. reconcile/test/saas_auto_promotions_manager/conftest.py +0 -69
  698. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -110
  699. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -10
  700. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_housekeeping.py +0 -200
  701. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -151
  702. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -63
  703. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
  704. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -46
  705. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -94
  706. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -44
  707. reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -74
  708. reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
  709. reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -155
  710. reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -173
  711. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -226
  712. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -224
  713. reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -350
  714. reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -129
  715. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -70
  716. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -63
  717. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -74
  718. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -65
  719. reconcile/test/test_aggregated_list.py +0 -237
  720. reconcile/test/test_amtool.py +0 -37
  721. reconcile/test/test_auto_promoter.py +0 -295
  722. reconcile/test/test_aws_ami_share.py +0 -68
  723. reconcile/test/test_aws_iam_keys.py +0 -70
  724. reconcile/test/test_aws_iam_password_reset.py +0 -35
  725. reconcile/test/test_aws_support_cases_sos.py +0 -23
  726. reconcile/test/test_checkpoint.py +0 -178
  727. reconcile/test/test_cli.py +0 -41
  728. reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
  729. reconcile/test/test_gabi_authorized_users.py +0 -72
  730. reconcile/test/test_github_org.py +0 -154
  731. reconcile/test/test_github_repo_invites.py +0 -123
  732. reconcile/test/test_gitlab_housekeeping.py +0 -88
  733. reconcile/test/test_gitlab_labeler.py +0 -129
  734. reconcile/test/test_gitlab_members.py +0 -283
  735. reconcile/test/test_instrumented_wrappers.py +0 -18
  736. reconcile/test/test_integrations_manager.py +0 -995
  737. reconcile/test/test_jenkins_worker_fleets.py +0 -55
  738. reconcile/test/test_jump_host.py +0 -117
  739. reconcile/test/test_ldap_users.py +0 -123
  740. reconcile/test/test_make.py +0 -28
  741. reconcile/test/test_ocm_additional_routers.py +0 -134
  742. reconcile/test/test_ocm_addons_upgrade_scheduler_org.py +0 -149
  743. reconcile/test/test_ocm_clusters.py +0 -598
  744. reconcile/test/test_ocm_clusters_manifest_updates.py +0 -89
  745. reconcile/test/test_ocm_oidc_idp.py +0 -315
  746. reconcile/test/test_ocm_update_recommended_version.py +0 -145
  747. reconcile/test/test_ocm_upgrade_scheduler.py +0 -614
  748. reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -129
  749. reconcile/test/test_openshift_base.py +0 -730
  750. reconcile/test/test_openshift_namespace_labels.py +0 -345
  751. reconcile/test/test_openshift_namespaces.py +0 -256
  752. reconcile/test/test_openshift_resource.py +0 -415
  753. reconcile/test/test_openshift_resources_base.py +0 -440
  754. reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -310
  755. reconcile/test/test_openshift_tekton_resources.py +0 -253
  756. reconcile/test/test_openshift_upgrade_watcher.py +0 -146
  757. reconcile/test/test_prometheus_rules_tester.py +0 -151
  758. reconcile/test/test_prometheus_rules_tester_old.py +0 -77
  759. reconcile/test/test_quay_membership.py +0 -86
  760. reconcile/test/test_quay_mirror.py +0 -109
  761. reconcile/test/test_quay_mirror_org.py +0 -70
  762. reconcile/test/test_quay_repos.py +0 -59
  763. reconcile/test/test_queries.py +0 -53
  764. reconcile/test/test_repo_owners.py +0 -47
  765. reconcile/test/test_requests_sender.py +0 -139
  766. reconcile/test/test_saasherder.py +0 -1074
  767. reconcile/test/test_saasherder_allowed_secret_paths.py +0 -127
  768. reconcile/test/test_secret_reader.py +0 -153
  769. reconcile/test/test_slack_base.py +0 -185
  770. reconcile/test/test_slack_usergroups.py +0 -744
  771. reconcile/test/test_sql_query.py +0 -19
  772. reconcile/test/test_terraform_cloudflare_dns.py +0 -117
  773. reconcile/test/test_terraform_cloudflare_resources.py +0 -106
  774. reconcile/test/test_terraform_cloudflare_users.py +0 -749
  775. reconcile/test/test_terraform_resources.py +0 -257
  776. reconcile/test/test_terraform_tgw_attachments.py +0 -631
  777. reconcile/test/test_terraform_users.py +0 -57
  778. reconcile/test/test_terraform_vpc_peerings.py +0 -499
  779. reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1061
  780. reconcile/test/test_unleash.py +0 -138
  781. reconcile/test/test_utils_aws_api.py +0 -240
  782. reconcile/test/test_utils_aws_helper.py +0 -80
  783. reconcile/test/test_utils_cluster_version_data.py +0 -177
  784. reconcile/test/test_utils_data_structures.py +0 -13
  785. reconcile/test/test_utils_disabled_integrations.py +0 -86
  786. reconcile/test/test_utils_expiration.py +0 -109
  787. reconcile/test/test_utils_external_resource_spec.py +0 -383
  788. reconcile/test/test_utils_external_resources.py +0 -247
  789. reconcile/test/test_utils_github_api.py +0 -73
  790. reconcile/test/test_utils_gitlab_api.py +0 -20
  791. reconcile/test/test_utils_gpg.py +0 -69
  792. reconcile/test/test_utils_gql.py +0 -81
  793. reconcile/test/test_utils_helm.py +0 -306
  794. reconcile/test/test_utils_helpers.py +0 -55
  795. reconcile/test/test_utils_imap_client.py +0 -65
  796. reconcile/test/test_utils_jjb_client.py +0 -52
  797. reconcile/test/test_utils_jsonpath.py +0 -286
  798. reconcile/test/test_utils_ldap_client.py +0 -51
  799. reconcile/test/test_utils_mr.py +0 -226
  800. reconcile/test/test_utils_mr_clusters_updates.py +0 -77
  801. reconcile/test/test_utils_oc.py +0 -984
  802. reconcile/test/test_utils_ocm.py +0 -110
  803. reconcile/test/test_utils_pagerduty_api.py +0 -251
  804. reconcile/test/test_utils_parse_dhms_duration.py +0 -34
  805. reconcile/test/test_utils_password_validator.py +0 -155
  806. reconcile/test/test_utils_quay_api.py +0 -86
  807. reconcile/test/test_utils_semver_helper.py +0 -19
  808. reconcile/test/test_utils_sharding.py +0 -56
  809. reconcile/test/test_utils_slack_api.py +0 -439
  810. reconcile/test/test_utils_smtp_client.py +0 -73
  811. reconcile/test/test_utils_state.py +0 -256
  812. reconcile/test/test_utils_terraform.py +0 -13
  813. reconcile/test/test_utils_terraform_client.py +0 -585
  814. reconcile/test/test_utils_terraform_config_client.py +0 -219
  815. reconcile/test/test_utils_terrascript_aws_client.py +0 -277
  816. reconcile/test/test_utils_terrascript_cloudflare_client.py +0 -597
  817. reconcile/test/test_utils_terrascript_cloudflare_resources.py +0 -26
  818. reconcile/test/test_vault_replication.py +0 -515
  819. reconcile/test/test_vault_utils.py +0 -47
  820. reconcile/test/test_version_bump.py +0 -18
  821. reconcile/test/test_vpc_peerings_validator.py +0 -103
  822. reconcile/test/test_wrong_region.py +0 -78
  823. reconcile/typed_queries/glitchtip_settings.py +0 -18
  824. reconcile/typed_queries/ocp_release_mirror.py +0 -11
  825. reconcile/unleash_watcher.py +0 -120
  826. reconcile/utils/git_secrets.py +0 -63
  827. reconcile/utils/mr/auto_promoter.py +0 -218
  828. reconcile/utils/sentry_client.py +0 -383
  829. release/test_version.py +0 -50
  830. release/version.py +0 -100
  831. tools/test/test_qontract_cli.py +0 -60
  832. tools/test/test_sre_checkpoints.py +0 -79
  833. /e2e_tests/__init__.py → /reconcile/aus/upgrades.py +0 -0
  834. /reconcile/{gql_definitions/ocp_release_mirror → aws_account_manager}/__init__.py +0 -0
  835. /reconcile/{test → aws_ami_cleanup}/__init__.py +0 -0
  836. /reconcile/{test/saas_auto_promotions_manager → aws_cloudwatch_log_retention}/__init__.py +0 -0
  837. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager → aws_saml_idp}/__init__.py +0 -0
  838. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager → aws_saml_roles}/__init__.py +0 -0
  839. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/renderer → aws_version_sync}/__init__.py +0 -0
  840. /reconcile/{test/saas_auto_promotions_manager/subscriber → aws_version_sync/merge_request_manager}/__init__.py +0 -0
  841. /reconcile/{test/saas_auto_promotions_manager/utils → cluster_auth_rhidp}/__init__.py +0 -0
  842. /reconcile/{test/saas_auto_promotions_manager/utils/saas_files_inventory → dynatrace_token_provider}/__init__.py +0 -0
  843. {release → reconcile/endpoints_discovery}/__init__.py +0 -0
  844. {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