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,25 +1,638 @@
1
+ import logging
2
+ from collections import defaultdict
3
+ from datetime import timedelta
1
4
  from typing import Optional
2
5
 
3
- from reconcile.aus.models import OrganizationUpgradeSpec
6
+ from pydantic import (
7
+ BaseModel,
8
+ Field,
9
+ ValidationError,
10
+ validator,
11
+ )
12
+ from pydantic.dataclasses import dataclass
13
+
14
+ from reconcile.aus.healthchecks import (
15
+ AUSClusterHealthCheckProvider,
16
+ build_cluster_health_providers_for_organization,
17
+ )
18
+ from reconcile.aus.metrics import AUSOCMEnvironmentError
19
+ from reconcile.aus.models import (
20
+ ClusterUpgradeSpec,
21
+ NodePoolSpec,
22
+ OrganizationUpgradeSpec,
23
+ )
24
+ from reconcile.aus.node_pool_spec import (
25
+ get_node_pool_specs_by_org_cluster,
26
+ )
4
27
  from reconcile.aus.ocm_upgrade_scheduler_org import (
5
28
  OCMClusterUpgradeSchedulerOrgIntegration,
6
29
  )
30
+ from reconcile.gql_definitions.fragments.aus_organization import (
31
+ AUSOCMOrganization,
32
+ OpenShiftClusterManagerSectorDependenciesV1,
33
+ OpenShiftClusterManagerSectorV1,
34
+ OpenShiftClusterManagerV1_OpenShiftClusterManagerV1,
35
+ OpenShiftClusterManagerV1_OpenShiftClusterManagerV1_OpenShiftClusterManagerEnvironmentV1,
36
+ )
37
+ from reconcile.gql_definitions.fragments.minimal_ocm_organization import (
38
+ MinimalOCMOrganization,
39
+ )
7
40
  from reconcile.gql_definitions.fragments.ocm_environment import OCMEnvironment
41
+ from reconcile.gql_definitions.fragments.upgrade_policy import (
42
+ ClusterUpgradePolicyConditionsV1,
43
+ ClusterUpgradePolicyV1,
44
+ )
45
+ from reconcile.utils import metrics
46
+ from reconcile.utils.clusterhealth.providerbase import ClusterHealthProvider
47
+ from reconcile.utils.models import (
48
+ CSV,
49
+ cron_validator,
50
+ )
51
+ from reconcile.utils.ocm.base import (
52
+ LabelContainer,
53
+ OCMClusterServiceLogCreateModel,
54
+ OCMOrganizationLabel,
55
+ OCMServiceLogSeverity,
56
+ build_label_container,
57
+ )
58
+ from reconcile.utils.ocm.clusters import (
59
+ ClusterDetails,
60
+ discover_clusters_by_labels,
61
+ )
62
+ from reconcile.utils.ocm.labels import (
63
+ get_org_labels,
64
+ get_organization_labels,
65
+ subscription_label_filter,
66
+ )
67
+ from reconcile.utils.ocm.search_filters import Filter
68
+ from reconcile.utils.ocm.service_log import create_service_log
69
+ from reconcile.utils.ocm.sre_capability_labels import (
70
+ build_labelset,
71
+ labelset_groupfield,
72
+ sre_capability_label_key,
73
+ )
74
+ from reconcile.utils.ocm_base_client import (
75
+ OCMBaseClient,
76
+ init_ocm_base_client,
77
+ )
8
78
 
9
79
  QONTRACT_INTEGRATION = "advanced-upgrade-scheduler"
10
80
 
11
81
 
12
82
  class AdvancedUpgradeServiceIntegration(OCMClusterUpgradeSchedulerOrgIntegration):
83
+ """
84
+ A flavour of the OCM organization based upgrade scheduler, that uses
85
+ OCM labels to discover clusters and their upgrade policies.
86
+ """
87
+
13
88
  @property
14
89
  def name(self) -> str:
15
90
  return QONTRACT_INTEGRATION
16
91
 
17
- def get_ocm_env_upgrade_specs(
18
- self, ocm_env: OCMEnvironment, org_name: Optional[str] = None
92
+ def get_upgrade_specs(self) -> dict[str, dict[str, OrganizationUpgradeSpec]]:
93
+ inheritance_network = self.init_version_data_network()
94
+ envs_org_upgrade_specs: dict[str, dict[str, OrganizationUpgradeSpec]] = {}
95
+ for ocm_env in self.get_ocm_environments():
96
+ try:
97
+ envs_org_upgrade_specs[ocm_env.name] = (
98
+ self._build_ocm_env_upgrade_specs(
99
+ ocm_env=ocm_env,
100
+ inheritance_network=inheritance_network,
101
+ )
102
+ )
103
+ except Exception as e:
104
+ logging.exception(
105
+ "Failed to get org upgrade specs for OCM environment %s. Skipping. %s",
106
+ ocm_env.name,
107
+ e,
108
+ )
109
+ metrics.inc_counter(
110
+ AUSOCMEnvironmentError(
111
+ integration=self.name,
112
+ ocm_env=ocm_env.name,
113
+ )
114
+ )
115
+ return envs_org_upgrade_specs
116
+
117
+ def init_version_data_network(self) -> dict["OrgRef", "VersionDataInheritance"]:
118
+ # collect all version data labels from all OCM environments ...
119
+ org_to_env: dict[str, OCMEnvironment] = {}
120
+ labels_by_org: dict[str, list[OCMOrganizationLabel]] = defaultdict(list)
121
+ for env in self.get_ocm_environments(filter=False):
122
+ with init_ocm_base_client(env, self.secret_reader) as ocm_api:
123
+ for label in get_organization_labels(
124
+ ocm_api=ocm_api,
125
+ filter=Filter().like("key", aus_label_key("version-data.%")),
126
+ ):
127
+ labels_by_org[label.organization_id].append(label)
128
+ org_to_env[label.organization_id] = env
129
+
130
+ # ... and build the inheritance network
131
+ return build_version_data_inheritance_network({
132
+ OrgRef(
133
+ org_id=org_id, env_name=org_to_env[org_id].name
134
+ ): build_label_container(labels)
135
+ for org_id, labels in labels_by_org.items()
136
+ })
137
+
138
+ def _build_ocm_env_upgrade_specs(
139
+ self,
140
+ ocm_env: OCMEnvironment,
141
+ inheritance_network: dict["OrgRef", "VersionDataInheritance"],
19
142
  ) -> dict[str, OrganizationUpgradeSpec]:
20
- return {
21
- # todo
22
- # discover orgs + clusters via labels
23
- # and create OrganizationUpgradeSpec objects
24
- # from them
143
+ organizations = {
144
+ org.org_id: org for org in self.get_orgs_for_environment(ocm_env)
25
145
  }
146
+ with init_ocm_base_client(ocm_env, self.secret_reader) as ocm_api:
147
+ clusters_by_org = discover_clusters(
148
+ ocm_api=ocm_api,
149
+ org_ids=set(organizations.keys()),
150
+ ignore_sts_clusters=self.params.ignore_sts_clusters,
151
+ )
152
+ labels_by_org = _get_org_labels(
153
+ ocm_api=ocm_api, org_ids=set(organizations.keys())
154
+ )
155
+ node_pool_specs_by_org_cluster = get_node_pool_specs_by_org_cluster(
156
+ ocm_api, clusters_by_org
157
+ )
158
+
159
+ cluster_health_providers = self._health_check_providers_for_env(ocm_env.name)
160
+
161
+ return _build_org_upgrade_specs_for_ocm_env(
162
+ orgs=organizations,
163
+ clusters_by_org=clusters_by_org,
164
+ labels_by_org=labels_by_org,
165
+ inheritance_network={
166
+ org_ref.org_id: vdi for org_ref, vdi in inheritance_network.items()
167
+ },
168
+ cluster_health_providers=cluster_health_providers,
169
+ node_pool_specs_by_org_cluster=node_pool_specs_by_org_cluster,
170
+ )
171
+
172
+ def signal_validation_issues(
173
+ self, dry_run: bool, org_upgrade_spec: OrganizationUpgradeSpec
174
+ ) -> None:
175
+ if not dry_run:
176
+ with init_ocm_base_client(
177
+ org_upgrade_spec.org.environment, self.secret_reader
178
+ ) as ocm_api:
179
+ _signal_validation_issues_for_org(
180
+ ocm_api=ocm_api, org_upgrade_spec=org_upgrade_spec
181
+ )
182
+
183
+ def signal_reconcile_issues(
184
+ self,
185
+ dry_run: bool,
186
+ org_upgrade_spec: OrganizationUpgradeSpec,
187
+ exception: Exception,
188
+ ) -> bool:
189
+ """
190
+ AUS will not fail on a reconcile issue. If issues should be noticed by an SRE team,
191
+ alerts based on the metrics in the `reconcile.aus.metrics` module should be set up.
192
+
193
+ The function is an override on the default behaviour to not ignore errors.
194
+ It returns true to indicate that the exception was properly handled by logging it.
195
+ Users / org owners will not be notified about the exception via service logs.
196
+ AppSRE team members will be notified about the exception via the logs.
197
+
198
+ """
199
+ logging.error(
200
+ f"Failed to reconcile cluster upgrades in OCM organization {org_upgrade_spec.org.org_id}",
201
+ exc_info=exception,
202
+ )
203
+ return True
204
+
205
+
206
+ def discover_clusters(
207
+ ocm_api: OCMBaseClient,
208
+ org_ids: set[str] | None = None,
209
+ ignore_sts_clusters: bool = False,
210
+ ) -> dict[str, list[ClusterDetails]]:
211
+ """
212
+ Discover all clusters that are part of the AUS service.
213
+ Discovery is driven by OCM cluster labels.
214
+ """
215
+ clusters = discover_clusters_by_labels(
216
+ ocm_api=ocm_api,
217
+ label_filter=subscription_label_filter().like("key", aus_label_key("%")),
218
+ )
219
+
220
+ # group by org and filter if org_id is specified
221
+ clusters_by_org: dict[str, list[ClusterDetails]] = defaultdict(list)
222
+ for c in clusters:
223
+ is_sts_cluster = c.ocm_cluster.aws and c.ocm_cluster.aws.sts_enabled
224
+ passed_sts_filter = not ignore_sts_clusters or not is_sts_cluster
225
+ passed_ocm_filters = not org_ids or c.organization_id in org_ids
226
+ if passed_ocm_filters and passed_sts_filter:
227
+ clusters_by_org[c.organization_id].append(c)
228
+
229
+ return clusters_by_org
230
+
231
+
232
+ def _get_org_labels(
233
+ ocm_api: OCMBaseClient, org_ids: set[str] | None
234
+ ) -> dict[str, LabelContainer]:
235
+ """
236
+ Fetch all AUS OCM org labels from organizations. They hold config
237
+ parameters like blocked versions etc.
238
+
239
+ The result is a dict with organization IDs as keys and label containers as values.
240
+ """
241
+ return get_org_labels(
242
+ ocm_api=ocm_api,
243
+ org_ids=org_ids or set(),
244
+ label_filter=Filter().like("key", aus_label_key("%")),
245
+ )
246
+
247
+
248
+ def _build_org_upgrade_specs_for_ocm_env(
249
+ orgs: dict[str, AUSOCMOrganization],
250
+ clusters_by_org: dict[str, list[ClusterDetails]],
251
+ labels_by_org: dict[str, LabelContainer],
252
+ inheritance_network: dict[str, "VersionDataInheritance"],
253
+ cluster_health_providers: dict[str, ClusterHealthProvider],
254
+ node_pool_specs_by_org_cluster: dict[str, dict[str, list[NodePoolSpec]]],
255
+ ) -> dict[str, OrganizationUpgradeSpec]:
256
+ """
257
+ Builds the cluster upgrade specs for the given OCM environment.
258
+ The specs are returned grouped by organization.
259
+ """
260
+ return {
261
+ org_id: _build_org_upgrade_spec(
262
+ org=orgs[org_id],
263
+ clusters=clusters,
264
+ org_labels=labels_by_org.get(org_id) or build_label_container(),
265
+ version_data_inheritance=inheritance_network.get(org_id),
266
+ cluster_health_provider=build_cluster_health_providers_for_organization(
267
+ org=orgs[org_id],
268
+ providers=cluster_health_providers,
269
+ ),
270
+ node_pool_specs_by_cluster_id=node_pool_specs_by_org_cluster.get(org_id)
271
+ or {},
272
+ )
273
+ for org_id, clusters in clusters_by_org.items()
274
+ }
275
+
276
+
277
+ def aus_label_key(config_atom: str | None = None) -> str:
278
+ """
279
+ Generates label keys for aus, compliant with the naming schema defined in
280
+ https://service.pages.redhat.com/dev-guidelines/docs/sre-capabilities/framework/ocm-labels/
281
+ """
282
+ return sre_capability_label_key("aus", config_atom)
283
+
284
+
285
+ class OrganizationLabelSet(BaseModel):
286
+ """
287
+ Parses, represents and validates a set of organization labels for AUS.
288
+ """
289
+
290
+ blocked_versions: CSV | None = Field(alias=aus_label_key("blocked-versions"))
291
+
292
+ sector_deps: dict[str, CSV] = labelset_groupfield(
293
+ group_prefix=aus_label_key("sector-deps.")
294
+ )
295
+ """
296
+ Each sector with dependencies is represented as a `sector-deps.<sector-name>` label
297
+ with a CSV formatted list of dependant sectors. The custom `labelset_groupfield``
298
+ FieldMeta combined with the CSV field type takes care of grouping and parsing
299
+ labels into a dict where each sector is a key and their dependencies are the value.
300
+ """
301
+
302
+ def sector_dependencies(self) -> list[OpenShiftClusterManagerSectorV1]:
303
+ """
304
+ Transforms the sector dependencies into the appropriate dataclasses
305
+ required by the upgrade policy spec.
306
+ """
307
+ all_sectors = set()
308
+ for s, deps in self.sector_deps.items():
309
+ all_sectors.add(s)
310
+ all_sectors.update(deps)
311
+ return [
312
+ OpenShiftClusterManagerSectorV1(
313
+ name=s,
314
+ dependencies=[
315
+ OpenShiftClusterManagerSectorDependenciesV1(name=d, ocm=None)
316
+ for d in self.sector_deps.get(s, [])
317
+ ],
318
+ )
319
+ for s in all_sectors
320
+ ]
321
+
322
+
323
+ def _build_org_upgrade_spec(
324
+ org: AUSOCMOrganization,
325
+ clusters: list[ClusterDetails],
326
+ org_labels: LabelContainer,
327
+ version_data_inheritance: Optional["VersionDataInheritance"],
328
+ cluster_health_provider: AUSClusterHealthCheckProvider,
329
+ node_pool_specs_by_cluster_id: dict[str, list[NodePoolSpec]],
330
+ ) -> OrganizationUpgradeSpec:
331
+ """
332
+ Build a upgrade policy spec for each cluster in the organization that
333
+ has a valid set of labels. Clusters without a set of labels are ignored. Clusters
334
+ with an invalid/incomplete set of labels are reported as an error.
335
+ """
336
+
337
+ # build version inheritance config
338
+ inherit_version_data = None
339
+ if version_data_inheritance and version_data_inheritance.inherit_from_orgs:
340
+ inherit_version_data = [
341
+ OpenShiftClusterManagerV1_OpenShiftClusterManagerV1(
342
+ name=source_org_ref.org_id,
343
+ orgId=source_org_ref.org_id,
344
+ environment=OpenShiftClusterManagerV1_OpenShiftClusterManagerV1_OpenShiftClusterManagerEnvironmentV1(
345
+ name=source_org_ref.env_name
346
+ ),
347
+ publishVersionData=[
348
+ MinimalOCMOrganization(orgId=org.org_id, name=org.name)
349
+ ],
350
+ )
351
+ for source_org_ref in version_data_inheritance.inherit_from_orgs
352
+ ]
353
+
354
+ org_labelset = build_labelset(org_labels, OrganizationLabelSet)
355
+ final_org = org.copy(deep=True)
356
+ final_org.blocked_versions = org_labelset.blocked_versions
357
+ final_org.sectors = org_labelset.sector_dependencies()
358
+ final_org.inherit_version_data = inherit_version_data
359
+ org_upgrade_spec = OrganizationUpgradeSpec(org=final_org)
360
+
361
+ # init policy for each cluster
362
+ for c in clusters:
363
+ try:
364
+ upgrade_policy = _build_policy_from_labels(c.labels)
365
+ cluster_health = cluster_health_provider.cluster_health(
366
+ cluster_external_id=c.ocm_cluster.external_id, org_id=org.org_id
367
+ )
368
+ org_upgrade_spec.add_spec(
369
+ ClusterUpgradeSpec(
370
+ org=org_upgrade_spec.org,
371
+ upgradePolicy=upgrade_policy,
372
+ cluster=c.ocm_cluster,
373
+ health=cluster_health,
374
+ nodePools=node_pool_specs_by_cluster_id.get(c.ocm_cluster.id) or [],
375
+ )
376
+ )
377
+ except ValidationError as validation_error:
378
+ for e in validation_error.errors():
379
+ org_upgrade_spec.add_cluster_error(
380
+ c.ocm_cluster.external_id, f"label {e['loc'][0]}: {e['msg']}"
381
+ )
382
+ except Exception as ex:
383
+ org_upgrade_spec.add_cluster_error(c.ocm_cluster.external_id, str(ex))
384
+
385
+ # register organization errors
386
+ if (
387
+ version_data_inheritance
388
+ and version_data_inheritance.unverified_inheritance_from_orgs
389
+ ):
390
+ unverified_org_ids = [
391
+ org.org_id
392
+ for org in version_data_inheritance.unverified_inheritance_from_orgs
393
+ ]
394
+ org_upgrade_spec.add_organization_error(
395
+ f"Version data inheritance from organizations {', '.join(sorted(unverified_org_ids))} "
396
+ f"are unverified. Ask the owner of these organizations to publish version data to the organization ID {org.org_id}. "
397
+ "See https://source.redhat.com/groups/public/sre/wiki/advanced_upgrade_service_aus"
398
+ )
399
+
400
+ return org_upgrade_spec
401
+
402
+
403
+ class ClusterUpgradePolicyLabelSet(BaseModel):
404
+ """
405
+ Parses, represents and validates a set of subscription labels for AUS.
406
+ """
407
+
408
+ soak_days: int = Field(alias=aus_label_key("soak-days"), ge=0)
409
+ workloads: CSV = Field(alias=aus_label_key("workloads"), csv_min_items=1)
410
+ schedule: str = Field(alias=aus_label_key("schedule"))
411
+ mutexes: CSV | None = Field(alias=aus_label_key("mutexes"))
412
+ sector: str | None = Field(alias=aus_label_key("sector"))
413
+ blocked_versions: CSV | None = Field(alias=aus_label_key("blocked-versions"))
414
+ version_gate_approvals: CSV | None = Field(
415
+ alias=aus_label_key("version-gate-approvals")
416
+ )
417
+ _schedule_validator = validator("schedule", allow_reuse=True)(cron_validator)
418
+
419
+ def build_labels_dict(self) -> dict[str, str]:
420
+ """
421
+ Build a dictionary of all labels in this labelset.
422
+ """
423
+ labels = {}
424
+ for k, v in self.dict(by_alias=True).items():
425
+ if v is None:
426
+ continue
427
+ if isinstance(v, list):
428
+ labels[k] = ",".join(sorted(v))
429
+ else:
430
+ labels[k] = str(v)
431
+ return labels
432
+
433
+
434
+ def build_cluster_upgrade_policy_label_set(
435
+ workloads: list[str],
436
+ schedule: str,
437
+ soak_days: int,
438
+ mutexes: list[str] | None = None,
439
+ sector: str | None = None,
440
+ blocked_versions: list[str] | None = None,
441
+ version_gate_approvals: list[str] | None = None,
442
+ ) -> ClusterUpgradePolicyLabelSet:
443
+ return ClusterUpgradePolicyLabelSet(**{
444
+ aus_label_key("workloads"): ",".join(workloads),
445
+ aus_label_key("schedule"): schedule,
446
+ aus_label_key("soak-days"): soak_days,
447
+ aus_label_key("mutexes"): ",".join(mutexes) if mutexes else None,
448
+ aus_label_key("sector"): sector,
449
+ aus_label_key("blocked-versions"): ",".join(blocked_versions)
450
+ if blocked_versions
451
+ else None,
452
+ aus_label_key("version-gate-approvals"): ",".join(version_gate_approvals)
453
+ if version_gate_approvals
454
+ else None,
455
+ })
456
+
457
+
458
+ def _build_policy_from_labels(labels: LabelContainer) -> ClusterUpgradePolicyV1:
459
+ """
460
+ Build a cluster upgrade policy object from a set of OCM labels. Parsing
461
+ and validation of the labels is delegated to the pydantic dataclass
462
+ ClusterUpgradePolicyLabelSet.
463
+ """
464
+ policy_labelset = build_labelset(labels, ClusterUpgradePolicyLabelSet)
465
+ return ClusterUpgradePolicyV1(
466
+ workloads=policy_labelset.workloads,
467
+ versionGateApprovals=policy_labelset.version_gate_approvals,
468
+ schedule=policy_labelset.schedule,
469
+ conditions=ClusterUpgradePolicyConditionsV1(
470
+ soakDays=policy_labelset.soak_days,
471
+ mutexes=policy_labelset.mutexes,
472
+ sector=policy_labelset.sector,
473
+ blockedVersions=policy_labelset.blocked_versions,
474
+ ),
475
+ )
476
+
477
+
478
+ class VersionDataInheritanceLabelSet(BaseModel):
479
+ inherit_version_data: CSV | None = Field(
480
+ alias=aus_label_key("version-data.inherit")
481
+ )
482
+ """
483
+ A list of OCM organization IDs to inherit version data from. These organization also need
484
+ to publish their version data via the `publish-version-data` label to the inheriting version.
485
+ Version data publishing/inheritance can also be defined between OCM environments.
486
+ """
487
+
488
+ publish_version_data: CSV | None = Field(
489
+ alias=aus_label_key("version-data.publish")
490
+ )
491
+ """
492
+ A list of OCM organization IDs to publish version data to. These organization also need
493
+ to explicitely inherit version data via the `inherit-version-data` label from this organization.
494
+ Version data publishing/inheritance can also be defined between OCM environments.
495
+ """
496
+
497
+
498
+ @dataclass(frozen=True, eq=True)
499
+ class OrgRef:
500
+ org_id: str
501
+ env_name: str
502
+
503
+
504
+ class VersionDataInheritance(BaseModel):
505
+ org_id: str
506
+ inherit_from_orgs: set[OrgRef]
507
+ unverified_inheritance_from_orgs: set[OrgRef]
508
+
509
+
510
+ def build_version_data_inheritance_network(
511
+ labels_per_org: dict[OrgRef, LabelContainer],
512
+ ) -> dict[OrgRef, VersionDataInheritance]:
513
+ """
514
+ Validates publish/inherit relationships between OCM organizations and environments from the
515
+ provided label containers.
516
+
517
+ This function returns a dictionary of OCM organizations and their version data
518
+ inheritance relationships.
519
+ """
520
+ label_set_per_org = {
521
+ org_ref: build_labelset(labels, VersionDataInheritanceLabelSet)
522
+ for org_ref, labels in labels_per_org.items()
523
+ }
524
+ org_ref_lookup = {org_ref.org_id: org_ref for org_ref in labels_per_org}
525
+
526
+ return {
527
+ org_ref: _build_version_data_inheritance(
528
+ org_ref,
529
+ label_set,
530
+ org_ref_lookup,
531
+ label_set_per_org,
532
+ )
533
+ for org_ref, label_set in label_set_per_org.items()
534
+ if label_set.inherit_version_data
535
+ }
536
+
537
+
538
+ def _build_version_data_inheritance(
539
+ org_ref: OrgRef,
540
+ label_set: VersionDataInheritanceLabelSet,
541
+ org_ref_lookup: dict[str, OrgRef],
542
+ label_set_per_org: dict[OrgRef, VersionDataInheritanceLabelSet],
543
+ ) -> VersionDataInheritance:
544
+ inherit_from_orgs_org_ids = {
545
+ source_org_id
546
+ for source_org_id in label_set.inherit_version_data or []
547
+ if source_org_id in org_ref_lookup
548
+ and org_ref.org_id
549
+ in (label_set_per_org[org_ref_lookup[source_org_id]].publish_version_data or [])
550
+ }
551
+ unverified_inheritance_from_orgs_org_ids = (
552
+ set(label_set.inherit_version_data or []) - inherit_from_orgs_org_ids
553
+ )
554
+
555
+ return VersionDataInheritance(
556
+ org_id=org_ref.org_id,
557
+ inherit_from_orgs={
558
+ org_ref_lookup[source_org_id] for source_org_id in inherit_from_orgs_org_ids
559
+ },
560
+ unverified_inheritance_from_orgs={
561
+ org_ref_lookup.get(
562
+ source_org_id, OrgRef(org_id=source_org_id, env_name="unknown")
563
+ )
564
+ for source_org_id in unverified_inheritance_from_orgs_org_ids
565
+ },
566
+ )
567
+
568
+
569
+ #
570
+ # Feedback mechanism
571
+ #
572
+
573
+
574
+ def _signal_validation_issues_for_org(
575
+ ocm_api: OCMBaseClient,
576
+ org_upgrade_spec: OrganizationUpgradeSpec,
577
+ ) -> None:
578
+ """
579
+ Signal the validation errors of an organization to the users.
580
+ Right now it uses OCM service logs, but it could be extended to use
581
+ other mechanisms like slack etc.
582
+ """
583
+ org_id = org_upgrade_spec.org.org_id
584
+ ocm_env_name = org_upgrade_spec.org.environment.name
585
+
586
+ if org_upgrade_spec.cluster_errors:
587
+ logging.warning(
588
+ f"Cluster config errors found in {ocm_env_name} org {org_id}: "
589
+ f"{org_upgrade_spec.cluster_errors}"
590
+ )
591
+ for cluster_error in org_upgrade_spec.cluster_errors:
592
+ _expose_cluster_validation_errors_as_service_log(
593
+ ocm_api=ocm_api,
594
+ cluster_uuid=cluster_error.cluster_uuid,
595
+ errors=cluster_error.messages,
596
+ )
597
+
598
+ if org_upgrade_spec.organization_errors:
599
+ logging.warning(
600
+ f"Organization config errors found in {ocm_env_name} org {org_id}: "
601
+ f"{org_upgrade_spec.organization_errors}"
602
+ )
603
+ org_error_msg = "\n".join(
604
+ o.message for o in org_upgrade_spec.organization_errors
605
+ )
606
+ for cluster in org_upgrade_spec.specs:
607
+ create_service_log(
608
+ ocm_api=ocm_api,
609
+ service_log=OCMClusterServiceLogCreateModel(
610
+ cluster_uuid=cluster.cluster_uuid,
611
+ severity=OCMServiceLogSeverity.Warning,
612
+ summary="AUS configuration error on organization",
613
+ description=org_error_msg,
614
+ service_name=QONTRACT_INTEGRATION,
615
+ ),
616
+ dedup_interval=timedelta(days=1),
617
+ )
618
+
619
+
620
+ def _expose_cluster_validation_errors_as_service_log(
621
+ ocm_api: OCMBaseClient, cluster_uuid: str, errors: list[str]
622
+ ) -> None:
623
+ """
624
+ Highlight cluster upgrade policy validation errors to the cluster
625
+ owners via OCM service logs.
626
+ """
627
+ description = "\n".join([f"- {e}" for e in errors])
628
+ create_service_log(
629
+ ocm_api=ocm_api,
630
+ service_log=OCMClusterServiceLogCreateModel(
631
+ cluster_uuid=cluster_uuid,
632
+ severity=OCMServiceLogSeverity.Warning,
633
+ summary="Cluster upgrade policy validation errors",
634
+ description=description,
635
+ service_name=QONTRACT_INTEGRATION,
636
+ ),
637
+ dedup_interval=timedelta(days=1),
638
+ )