qontract-reconcile 0.9.1rc298__py3-none-any.whl → 0.10.1.dev1203__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (843) hide show
  1. qontract_reconcile-0.10.1.dev1203.dist-info/METADATA +500 -0
  2. qontract_reconcile-0.10.1.dev1203.dist-info/RECORD +771 -0
  3. {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
  4. {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/entry_points.txt +4 -2
  5. reconcile/acs_notifiers.py +126 -0
  6. reconcile/acs_policies.py +243 -0
  7. reconcile/acs_rbac.py +596 -0
  8. reconcile/aus/advanced_upgrade_service.py +621 -8
  9. reconcile/aus/aus_label_source.py +115 -0
  10. reconcile/aus/base.py +1053 -353
  11. reconcile/{utils → aus}/cluster_version_data.py +27 -12
  12. reconcile/aus/healthchecks.py +77 -0
  13. reconcile/aus/metrics.py +158 -0
  14. reconcile/aus/models.py +245 -5
  15. reconcile/aus/node_pool_spec.py +35 -0
  16. reconcile/aus/ocm_addons_upgrade_scheduler_org.py +225 -110
  17. reconcile/aus/ocm_upgrade_scheduler.py +76 -71
  18. reconcile/aus/ocm_upgrade_scheduler_org.py +81 -23
  19. reconcile/aus/version_gate_approver.py +204 -0
  20. reconcile/aus/version_gates/__init__.py +12 -0
  21. reconcile/aus/version_gates/handler.py +33 -0
  22. reconcile/aus/version_gates/ingress_gate_handler.py +32 -0
  23. reconcile/aus/version_gates/ocp_gate_handler.py +26 -0
  24. reconcile/aus/version_gates/sts_version_gate_handler.py +100 -0
  25. reconcile/aws_account_manager/README.md +5 -0
  26. reconcile/aws_account_manager/integration.py +373 -0
  27. reconcile/aws_account_manager/merge_request_manager.py +114 -0
  28. reconcile/aws_account_manager/metrics.py +39 -0
  29. reconcile/aws_account_manager/reconciler.py +403 -0
  30. reconcile/aws_account_manager/utils.py +41 -0
  31. reconcile/aws_ami_cleanup/integration.py +273 -0
  32. reconcile/aws_ami_share.py +18 -14
  33. reconcile/aws_cloudwatch_log_retention/integration.py +253 -0
  34. reconcile/aws_iam_keys.py +1 -1
  35. reconcile/aws_iam_password_reset.py +56 -20
  36. reconcile/aws_saml_idp/integration.py +204 -0
  37. reconcile/aws_saml_roles/integration.py +322 -0
  38. reconcile/aws_support_cases_sos.py +2 -2
  39. reconcile/aws_version_sync/integration.py +430 -0
  40. reconcile/aws_version_sync/merge_request_manager/merge_request.py +156 -0
  41. reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py +160 -0
  42. reconcile/aws_version_sync/utils.py +64 -0
  43. reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
  44. reconcile/change_owners/README.md +34 -0
  45. reconcile/change_owners/approver.py +7 -9
  46. reconcile/change_owners/bundle.py +134 -9
  47. reconcile/change_owners/change_log_tracking.py +236 -0
  48. reconcile/change_owners/change_owners.py +204 -194
  49. reconcile/change_owners/change_types.py +183 -265
  50. reconcile/change_owners/changes.py +488 -0
  51. reconcile/change_owners/decision.py +120 -41
  52. reconcile/change_owners/diff.py +63 -92
  53. reconcile/change_owners/implicit_ownership.py +19 -16
  54. reconcile/change_owners/self_service_roles.py +158 -35
  55. reconcile/change_owners/tester.py +20 -18
  56. reconcile/checkpoint.py +4 -6
  57. reconcile/cli.py +1523 -242
  58. reconcile/closedbox_endpoint_monitoring_base.py +10 -17
  59. reconcile/cluster_auth_rhidp/integration.py +257 -0
  60. reconcile/cluster_deployment_mapper.py +2 -5
  61. reconcile/cna/assets/asset.py +4 -7
  62. reconcile/cna/assets/null.py +2 -5
  63. reconcile/cna/integration.py +2 -3
  64. reconcile/cna/state.py +6 -9
  65. reconcile/dashdotdb_base.py +31 -10
  66. reconcile/dashdotdb_cso.py +3 -6
  67. reconcile/dashdotdb_dora.py +530 -0
  68. reconcile/dashdotdb_dvo.py +10 -13
  69. reconcile/dashdotdb_slo.py +75 -19
  70. reconcile/database_access_manager.py +753 -0
  71. reconcile/deadmanssnitch.py +207 -0
  72. reconcile/dynatrace_token_provider/dependencies.py +69 -0
  73. reconcile/dynatrace_token_provider/integration.py +656 -0
  74. reconcile/dynatrace_token_provider/metrics.py +62 -0
  75. reconcile/dynatrace_token_provider/model.py +14 -0
  76. reconcile/dynatrace_token_provider/ocm.py +140 -0
  77. reconcile/dynatrace_token_provider/validate.py +48 -0
  78. reconcile/endpoints_discovery/integration.py +348 -0
  79. reconcile/endpoints_discovery/merge_request.py +96 -0
  80. reconcile/endpoints_discovery/merge_request_manager.py +178 -0
  81. reconcile/external_resources/aws.py +204 -0
  82. reconcile/external_resources/factories.py +163 -0
  83. reconcile/external_resources/integration.py +194 -0
  84. reconcile/external_resources/integration_secrets_sync.py +47 -0
  85. reconcile/external_resources/manager.py +405 -0
  86. reconcile/external_resources/meta.py +17 -0
  87. reconcile/external_resources/metrics.py +95 -0
  88. reconcile/external_resources/model.py +350 -0
  89. reconcile/external_resources/reconciler.py +265 -0
  90. reconcile/external_resources/secrets_sync.py +465 -0
  91. reconcile/external_resources/state.py +258 -0
  92. reconcile/gabi_authorized_users.py +19 -11
  93. reconcile/gcr_mirror.py +43 -34
  94. reconcile/github_org.py +4 -6
  95. reconcile/github_owners.py +1 -1
  96. reconcile/github_repo_invites.py +2 -5
  97. reconcile/gitlab_fork_compliance.py +14 -13
  98. reconcile/gitlab_housekeeping.py +185 -91
  99. reconcile/gitlab_labeler.py +15 -14
  100. reconcile/gitlab_members.py +126 -120
  101. reconcile/gitlab_owners.py +53 -66
  102. reconcile/gitlab_permissions.py +167 -6
  103. reconcile/glitchtip/README.md +150 -0
  104. reconcile/glitchtip/integration.py +99 -51
  105. reconcile/glitchtip/reconciler.py +99 -70
  106. reconcile/glitchtip_project_alerts/__init__.py +0 -0
  107. reconcile/glitchtip_project_alerts/integration.py +333 -0
  108. reconcile/glitchtip_project_dsn/integration.py +43 -43
  109. reconcile/gql_definitions/acs/__init__.py +0 -0
  110. reconcile/gql_definitions/acs/acs_instances.py +83 -0
  111. reconcile/gql_definitions/acs/acs_policies.py +239 -0
  112. reconcile/gql_definitions/acs/acs_rbac.py +111 -0
  113. reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +46 -8
  114. reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +38 -8
  115. reconcile/gql_definitions/app_interface_metrics_exporter/__init__.py +0 -0
  116. reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +61 -0
  117. reconcile/gql_definitions/aws_account_manager/__init__.py +0 -0
  118. reconcile/gql_definitions/aws_account_manager/aws_accounts.py +177 -0
  119. reconcile/gql_definitions/aws_ami_cleanup/__init__.py +0 -0
  120. reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +161 -0
  121. reconcile/gql_definitions/aws_saml_idp/__init__.py +0 -0
  122. reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +117 -0
  123. reconcile/gql_definitions/aws_saml_roles/__init__.py +0 -0
  124. reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +117 -0
  125. reconcile/gql_definitions/aws_saml_roles/roles.py +97 -0
  126. reconcile/gql_definitions/aws_version_sync/__init__.py +0 -0
  127. reconcile/gql_definitions/aws_version_sync/clusters.py +83 -0
  128. reconcile/gql_definitions/aws_version_sync/namespaces.py +143 -0
  129. reconcile/gql_definitions/change_owners/queries/change_types.py +16 -29
  130. reconcile/gql_definitions/change_owners/queries/self_service_roles.py +45 -11
  131. reconcile/gql_definitions/cluster_auth_rhidp/__init__.py +0 -0
  132. reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +128 -0
  133. reconcile/gql_definitions/cna/queries/cna_provisioners.py +6 -8
  134. reconcile/gql_definitions/cna/queries/cna_resources.py +3 -5
  135. reconcile/gql_definitions/common/alerting_services_settings.py +2 -2
  136. reconcile/gql_definitions/common/app_code_component_repos.py +9 -5
  137. reconcile/gql_definitions/{glitchtip/glitchtip_settings.py → common/app_interface_custom_messages.py} +14 -16
  138. reconcile/gql_definitions/common/app_interface_dms_settings.py +86 -0
  139. reconcile/gql_definitions/common/app_interface_repo_settings.py +2 -2
  140. reconcile/gql_definitions/common/app_interface_state_settings.py +3 -5
  141. reconcile/gql_definitions/common/app_interface_vault_settings.py +3 -5
  142. reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +120 -0
  143. reconcile/gql_definitions/common/apps.py +72 -0
  144. reconcile/gql_definitions/common/aws_vpc_requests.py +109 -0
  145. reconcile/gql_definitions/common/aws_vpcs.py +84 -0
  146. reconcile/gql_definitions/common/clusters.py +120 -254
  147. reconcile/gql_definitions/common/clusters_minimal.py +11 -35
  148. reconcile/gql_definitions/common/clusters_with_dms.py +72 -0
  149. reconcile/gql_definitions/common/clusters_with_peering.py +70 -98
  150. reconcile/gql_definitions/common/github_orgs.py +2 -2
  151. reconcile/gql_definitions/common/jira_settings.py +68 -0
  152. reconcile/gql_definitions/common/jiralert_settings.py +68 -0
  153. reconcile/gql_definitions/common/namespaces.py +74 -32
  154. reconcile/gql_definitions/common/namespaces_minimal.py +4 -10
  155. reconcile/gql_definitions/common/ocm_env_telemeter.py +95 -0
  156. reconcile/gql_definitions/common/ocm_environments.py +4 -2
  157. reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
  158. reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -11
  159. reconcile/gql_definitions/common/pipeline_providers.py +45 -90
  160. reconcile/gql_definitions/common/quay_instances.py +64 -0
  161. reconcile/gql_definitions/common/quay_orgs.py +68 -0
  162. reconcile/gql_definitions/common/reserved_networks.py +94 -0
  163. reconcile/gql_definitions/common/saas_files.py +133 -95
  164. reconcile/gql_definitions/common/saas_target_namespaces.py +41 -26
  165. reconcile/gql_definitions/common/saasherder_settings.py +2 -2
  166. reconcile/gql_definitions/common/slack_workspaces.py +62 -0
  167. reconcile/gql_definitions/common/smtp_client_settings.py +2 -2
  168. reconcile/gql_definitions/common/state_aws_account.py +77 -0
  169. reconcile/gql_definitions/common/users.py +3 -2
  170. reconcile/gql_definitions/cost_report/__init__.py +0 -0
  171. reconcile/gql_definitions/cost_report/app_names.py +68 -0
  172. reconcile/gql_definitions/cost_report/cost_namespaces.py +86 -0
  173. reconcile/gql_definitions/cost_report/settings.py +77 -0
  174. reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +42 -12
  175. reconcile/gql_definitions/dynatrace_token_provider/__init__.py +0 -0
  176. reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +79 -0
  177. reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +84 -0
  178. reconcile/gql_definitions/endpoints_discovery/__init__.py +0 -0
  179. reconcile/gql_definitions/endpoints_discovery/namespaces.py +127 -0
  180. reconcile/gql_definitions/external_resources/__init__.py +0 -0
  181. reconcile/gql_definitions/external_resources/aws_accounts.py +73 -0
  182. reconcile/gql_definitions/external_resources/external_resources_modules.py +78 -0
  183. reconcile/gql_definitions/external_resources/external_resources_namespaces.py +1111 -0
  184. reconcile/gql_definitions/external_resources/external_resources_settings.py +98 -0
  185. reconcile/gql_definitions/fragments/aus_organization.py +34 -39
  186. reconcile/gql_definitions/fragments/aws_account_common.py +62 -0
  187. reconcile/gql_definitions/fragments/aws_account_managed.py +57 -0
  188. reconcile/gql_definitions/fragments/aws_account_sso.py +35 -0
  189. reconcile/gql_definitions/fragments/aws_infra_management_account.py +2 -2
  190. reconcile/gql_definitions/fragments/aws_vpc.py +47 -0
  191. reconcile/gql_definitions/fragments/aws_vpc_request.py +65 -0
  192. reconcile/gql_definitions/fragments/aws_vpc_request_subnet.py +29 -0
  193. reconcile/gql_definitions/fragments/deplopy_resources.py +7 -7
  194. reconcile/gql_definitions/fragments/disable.py +28 -0
  195. reconcile/gql_definitions/fragments/jumphost_common_fields.py +2 -2
  196. reconcile/gql_definitions/fragments/membership_source.py +47 -0
  197. reconcile/gql_definitions/fragments/minimal_ocm_organization.py +29 -0
  198. reconcile/gql_definitions/fragments/oc_connection_cluster.py +4 -9
  199. reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
  200. reconcile/gql_definitions/fragments/pipeline_provider_retention.py +30 -0
  201. reconcile/gql_definitions/fragments/prometheus_instance.py +48 -0
  202. reconcile/gql_definitions/fragments/resource_limits_requirements.py +29 -0
  203. reconcile/gql_definitions/fragments/{resource_requirements.py → resource_requests_requirements.py} +3 -3
  204. reconcile/gql_definitions/fragments/resource_values.py +2 -2
  205. reconcile/gql_definitions/fragments/saas_target_namespace.py +55 -12
  206. reconcile/gql_definitions/fragments/serviceaccount_token.py +38 -0
  207. reconcile/gql_definitions/fragments/terraform_state.py +36 -0
  208. reconcile/gql_definitions/fragments/upgrade_policy.py +5 -3
  209. reconcile/gql_definitions/fragments/user.py +3 -2
  210. reconcile/gql_definitions/fragments/vault_secret.py +2 -2
  211. reconcile/gql_definitions/gitlab_members/gitlab_instances.py +6 -2
  212. reconcile/gql_definitions/gitlab_members/permissions.py +3 -5
  213. reconcile/gql_definitions/glitchtip/glitchtip_instance.py +16 -2
  214. reconcile/gql_definitions/glitchtip/glitchtip_project.py +22 -23
  215. reconcile/gql_definitions/glitchtip_project_alerts/__init__.py +0 -0
  216. reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +173 -0
  217. reconcile/gql_definitions/integrations/integrations.py +62 -45
  218. reconcile/gql_definitions/introspection.json +51176 -0
  219. reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +13 -5
  220. reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +79 -0
  221. reconcile/gql_definitions/jira/__init__.py +0 -0
  222. reconcile/gql_definitions/jira/jira_servers.py +80 -0
  223. reconcile/gql_definitions/jira_permissions_validator/__init__.py +0 -0
  224. reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +131 -0
  225. reconcile/gql_definitions/jumphosts/jumphosts.py +3 -5
  226. reconcile/gql_definitions/ldap_groups/__init__.py +0 -0
  227. reconcile/gql_definitions/ldap_groups/roles.py +111 -0
  228. reconcile/gql_definitions/ldap_groups/settings.py +79 -0
  229. reconcile/gql_definitions/maintenance/__init__.py +0 -0
  230. reconcile/gql_definitions/maintenance/maintenances.py +101 -0
  231. reconcile/gql_definitions/membershipsources/__init__.py +0 -0
  232. reconcile/gql_definitions/membershipsources/roles.py +112 -0
  233. reconcile/gql_definitions/ocm_labels/__init__.py +0 -0
  234. reconcile/gql_definitions/ocm_labels/clusters.py +112 -0
  235. reconcile/gql_definitions/ocm_labels/organizations.py +78 -0
  236. reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
  237. reconcile/gql_definitions/openshift_cluster_bots/__init__.py +0 -0
  238. reconcile/gql_definitions/openshift_cluster_bots/clusters.py +126 -0
  239. reconcile/gql_definitions/openshift_groups/managed_groups.py +2 -2
  240. reconcile/gql_definitions/openshift_groups/managed_roles.py +3 -2
  241. reconcile/gql_definitions/openshift_serviceaccount_tokens/__init__.py +0 -0
  242. reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +132 -0
  243. reconcile/gql_definitions/quay_membership/quay_membership.py +3 -5
  244. reconcile/gql_definitions/rhidp/__init__.py +0 -0
  245. reconcile/gql_definitions/rhidp/organizations.py +96 -0
  246. reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +2 -2
  247. reconcile/gql_definitions/service_dependencies/service_dependencies.py +9 -31
  248. reconcile/gql_definitions/sharding/aws_accounts.py +2 -2
  249. reconcile/gql_definitions/sharding/ocm_organization.py +63 -0
  250. reconcile/gql_definitions/skupper_network/site_controller_template.py +2 -2
  251. reconcile/gql_definitions/skupper_network/skupper_networks.py +12 -38
  252. reconcile/gql_definitions/slack_usergroups/clusters.py +2 -2
  253. reconcile/gql_definitions/slack_usergroups/permissions.py +8 -15
  254. reconcile/gql_definitions/slack_usergroups/users.py +3 -2
  255. reconcile/gql_definitions/slo_documents/__init__.py +0 -0
  256. reconcile/gql_definitions/slo_documents/slo_documents.py +142 -0
  257. reconcile/gql_definitions/status_board/__init__.py +0 -0
  258. reconcile/gql_definitions/status_board/status_board.py +163 -0
  259. reconcile/gql_definitions/statuspage/statuspages.py +56 -7
  260. reconcile/gql_definitions/templating/__init__.py +0 -0
  261. reconcile/gql_definitions/templating/template_collection.py +130 -0
  262. reconcile/gql_definitions/templating/templates.py +108 -0
  263. reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +4 -8
  264. reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +8 -8
  265. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +6 -8
  266. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +45 -56
  267. reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +4 -8
  268. reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +4 -8
  269. reconcile/gql_definitions/terraform_init/__init__.py +0 -0
  270. reconcile/gql_definitions/terraform_init/aws_accounts.py +93 -0
  271. reconcile/gql_definitions/terraform_repo/__init__.py +0 -0
  272. reconcile/gql_definitions/terraform_repo/terraform_repo.py +141 -0
  273. reconcile/gql_definitions/terraform_resources/database_access_manager.py +158 -0
  274. reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +153 -162
  275. reconcile/gql_definitions/terraform_tgw_attachments/__init__.py +0 -0
  276. reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +119 -0
  277. reconcile/gql_definitions/unleash_feature_toggles/__init__.py +0 -0
  278. reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +113 -0
  279. reconcile/gql_definitions/vault_instances/vault_instances.py +17 -50
  280. reconcile/gql_definitions/vault_policies/vault_policies.py +2 -2
  281. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +49 -12
  282. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +7 -2
  283. reconcile/integrations_manager.py +25 -13
  284. reconcile/jenkins/types.py +5 -1
  285. reconcile/jenkins_base.py +36 -0
  286. reconcile/jenkins_job_builder.py +10 -48
  287. reconcile/jenkins_job_builds_cleaner.py +40 -25
  288. reconcile/jenkins_job_cleaner.py +1 -3
  289. reconcile/jenkins_roles.py +22 -26
  290. reconcile/jenkins_webhooks.py +9 -6
  291. reconcile/jenkins_worker_fleets.py +11 -6
  292. reconcile/jira_permissions_validator.py +340 -0
  293. reconcile/jira_watcher.py +3 -5
  294. reconcile/ldap_groups/__init__.py +0 -0
  295. reconcile/ldap_groups/integration.py +279 -0
  296. reconcile/ldap_users.py +3 -0
  297. reconcile/ocm/types.py +39 -59
  298. reconcile/ocm_additional_routers.py +0 -1
  299. reconcile/ocm_addons_upgrade_tests_trigger.py +10 -15
  300. reconcile/ocm_aws_infrastructure_access.py +30 -32
  301. reconcile/ocm_clusters.py +217 -130
  302. reconcile/ocm_external_configuration_labels.py +15 -0
  303. reconcile/ocm_github_idp.py +1 -1
  304. reconcile/ocm_groups.py +25 -5
  305. reconcile/ocm_internal_notifications/__init__.py +0 -0
  306. reconcile/ocm_internal_notifications/integration.py +119 -0
  307. reconcile/ocm_labels/__init__.py +0 -0
  308. reconcile/ocm_labels/integration.py +409 -0
  309. reconcile/ocm_machine_pools.py +517 -108
  310. reconcile/ocm_upgrade_scheduler_org_updater.py +15 -11
  311. reconcile/openshift_base.py +609 -207
  312. reconcile/openshift_cluster_bots.py +344 -0
  313. reconcile/openshift_clusterrolebindings.py +15 -15
  314. reconcile/openshift_groups.py +42 -45
  315. reconcile/openshift_limitranges.py +1 -0
  316. reconcile/openshift_namespace_labels.py +22 -28
  317. reconcile/openshift_namespaces.py +22 -22
  318. reconcile/openshift_network_policies.py +4 -8
  319. reconcile/openshift_prometheus_rules.py +43 -0
  320. reconcile/openshift_resourcequotas.py +2 -16
  321. reconcile/openshift_resources.py +12 -10
  322. reconcile/openshift_resources_base.py +304 -328
  323. reconcile/openshift_rolebindings.py +18 -20
  324. reconcile/openshift_saas_deploy.py +105 -21
  325. reconcile/openshift_saas_deploy_change_tester.py +30 -35
  326. reconcile/openshift_saas_deploy_trigger_base.py +39 -36
  327. reconcile/openshift_saas_deploy_trigger_cleaner.py +41 -27
  328. reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
  329. reconcile/openshift_saas_deploy_trigger_images.py +1 -2
  330. reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
  331. reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
  332. reconcile/openshift_serviceaccount_tokens.py +138 -74
  333. reconcile/openshift_tekton_resources.py +89 -24
  334. reconcile/openshift_upgrade_watcher.py +110 -62
  335. reconcile/openshift_users.py +16 -15
  336. reconcile/openshift_vault_secrets.py +11 -6
  337. reconcile/oum/__init__.py +0 -0
  338. reconcile/oum/base.py +387 -0
  339. reconcile/oum/labelset.py +55 -0
  340. reconcile/oum/metrics.py +71 -0
  341. reconcile/oum/models.py +69 -0
  342. reconcile/oum/providers.py +59 -0
  343. reconcile/oum/standalone.py +196 -0
  344. reconcile/prometheus_rules_tester/integration.py +31 -23
  345. reconcile/quay_base.py +4 -1
  346. reconcile/quay_membership.py +1 -2
  347. reconcile/quay_mirror.py +111 -61
  348. reconcile/quay_mirror_org.py +34 -21
  349. reconcile/quay_permissions.py +7 -3
  350. reconcile/quay_repos.py +24 -32
  351. reconcile/queries.py +263 -198
  352. reconcile/query_validator.py +3 -5
  353. reconcile/resource_scraper.py +3 -4
  354. reconcile/{template_tester.py → resource_template_tester.py} +3 -3
  355. reconcile/rhidp/__init__.py +0 -0
  356. reconcile/rhidp/common.py +214 -0
  357. reconcile/rhidp/metrics.py +20 -0
  358. reconcile/rhidp/ocm_oidc_idp/__init__.py +0 -0
  359. reconcile/rhidp/ocm_oidc_idp/base.py +221 -0
  360. reconcile/rhidp/ocm_oidc_idp/integration.py +56 -0
  361. reconcile/rhidp/ocm_oidc_idp/metrics.py +22 -0
  362. reconcile/rhidp/sso_client/__init__.py +0 -0
  363. reconcile/rhidp/sso_client/base.py +266 -0
  364. reconcile/rhidp/sso_client/integration.py +60 -0
  365. reconcile/rhidp/sso_client/metrics.py +39 -0
  366. reconcile/run_integration.py +293 -0
  367. reconcile/saas_auto_promotions_manager/integration.py +69 -24
  368. reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +208 -0
  369. reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py +28 -0
  370. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py +3 -4
  371. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +172 -0
  372. reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py +42 -0
  373. reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +226 -0
  374. reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py +23 -0
  375. reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +108 -32
  376. reconcile/saas_auto_promotions_manager/meta.py +4 -0
  377. reconcile/saas_auto_promotions_manager/publisher.py +32 -4
  378. reconcile/saas_auto_promotions_manager/s3_exporter.py +77 -0
  379. reconcile/saas_auto_promotions_manager/subscriber.py +110 -23
  380. reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +48 -41
  381. reconcile/saas_file_validator.py +16 -6
  382. reconcile/sendgrid_teammates.py +27 -12
  383. reconcile/service_dependencies.py +0 -3
  384. reconcile/signalfx_endpoint_monitoring.py +2 -5
  385. reconcile/skupper_network/integration.py +10 -11
  386. reconcile/skupper_network/models.py +3 -5
  387. reconcile/skupper_network/reconciler.py +28 -35
  388. reconcile/skupper_network/site_controller.py +8 -8
  389. reconcile/slack_base.py +4 -7
  390. reconcile/slack_usergroups.py +249 -171
  391. reconcile/sql_query.py +324 -171
  392. reconcile/status.py +0 -1
  393. reconcile/status_board.py +275 -0
  394. reconcile/statuspage/__init__.py +0 -5
  395. reconcile/statuspage/atlassian.py +219 -80
  396. reconcile/statuspage/integration.py +9 -97
  397. reconcile/statuspage/integrations/__init__.py +0 -0
  398. reconcile/statuspage/integrations/components.py +77 -0
  399. reconcile/statuspage/integrations/maintenances.py +111 -0
  400. reconcile/statuspage/page.py +107 -72
  401. reconcile/statuspage/state.py +6 -11
  402. reconcile/statuspage/status.py +8 -12
  403. reconcile/templates/rosa-classic-cluster-creation.sh.j2 +60 -0
  404. reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +61 -0
  405. reconcile/templating/__init__.py +0 -0
  406. reconcile/templating/lib/__init__.py +0 -0
  407. reconcile/templating/lib/merge_request_manager.py +180 -0
  408. reconcile/templating/lib/model.py +20 -0
  409. reconcile/templating/lib/rendering.py +191 -0
  410. reconcile/templating/renderer.py +410 -0
  411. reconcile/templating/validator.py +153 -0
  412. reconcile/terraform_aws_route53.py +13 -10
  413. reconcile/terraform_cloudflare_dns.py +92 -122
  414. reconcile/terraform_cloudflare_resources.py +15 -13
  415. reconcile/terraform_cloudflare_users.py +27 -27
  416. reconcile/terraform_init/__init__.py +0 -0
  417. reconcile/terraform_init/integration.py +165 -0
  418. reconcile/terraform_init/merge_request.py +57 -0
  419. reconcile/terraform_init/merge_request_manager.py +102 -0
  420. reconcile/terraform_repo.py +403 -0
  421. reconcile/terraform_resources.py +266 -168
  422. reconcile/terraform_tgw_attachments.py +417 -167
  423. reconcile/terraform_users.py +40 -17
  424. reconcile/terraform_vpc_peerings.py +310 -142
  425. reconcile/terraform_vpc_resources/__init__.py +0 -0
  426. reconcile/terraform_vpc_resources/integration.py +220 -0
  427. reconcile/terraform_vpc_resources/merge_request.py +57 -0
  428. reconcile/terraform_vpc_resources/merge_request_manager.py +107 -0
  429. reconcile/typed_queries/alerting_services_settings.py +1 -2
  430. reconcile/typed_queries/app_interface_custom_messages.py +24 -0
  431. reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +17 -0
  432. reconcile/typed_queries/app_interface_metrics_exporter/__init__.py +0 -0
  433. reconcile/typed_queries/app_interface_metrics_exporter/onboarding_status.py +13 -0
  434. reconcile/typed_queries/app_interface_repo_url.py +1 -2
  435. reconcile/typed_queries/app_interface_state_settings.py +1 -3
  436. reconcile/typed_queries/app_interface_vault_settings.py +1 -2
  437. reconcile/typed_queries/app_quay_repos_escalation_policies.py +14 -0
  438. reconcile/typed_queries/apps.py +11 -0
  439. reconcile/typed_queries/aws_vpc_requests.py +9 -0
  440. reconcile/typed_queries/aws_vpcs.py +12 -0
  441. reconcile/typed_queries/cloudflare.py +10 -0
  442. reconcile/typed_queries/clusters.py +7 -5
  443. reconcile/typed_queries/clusters_minimal.py +6 -5
  444. reconcile/typed_queries/clusters_with_dms.py +16 -0
  445. reconcile/typed_queries/cost_report/__init__.py +0 -0
  446. reconcile/typed_queries/cost_report/app_names.py +22 -0
  447. reconcile/typed_queries/cost_report/cost_namespaces.py +43 -0
  448. reconcile/typed_queries/cost_report/settings.py +15 -0
  449. reconcile/typed_queries/dynatrace.py +10 -0
  450. reconcile/typed_queries/dynatrace_environments.py +14 -0
  451. reconcile/typed_queries/dynatrace_token_provider_token_specs.py +14 -0
  452. reconcile/typed_queries/external_resources.py +46 -0
  453. reconcile/typed_queries/get_state_aws_account.py +20 -0
  454. reconcile/typed_queries/glitchtip.py +10 -0
  455. reconcile/typed_queries/jenkins.py +25 -0
  456. reconcile/typed_queries/jira.py +7 -0
  457. reconcile/typed_queries/jira_settings.py +16 -0
  458. reconcile/typed_queries/jiralert_settings.py +22 -0
  459. reconcile/typed_queries/ocm.py +8 -0
  460. reconcile/typed_queries/pagerduty_instances.py +2 -7
  461. reconcile/typed_queries/quay.py +23 -0
  462. reconcile/typed_queries/repos.py +20 -8
  463. reconcile/typed_queries/reserved_networks.py +12 -0
  464. reconcile/typed_queries/saas_files.py +221 -167
  465. reconcile/typed_queries/slack.py +7 -0
  466. reconcile/typed_queries/slo_documents.py +12 -0
  467. reconcile/typed_queries/status_board.py +58 -0
  468. reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
  469. reconcile/typed_queries/terraform_namespaces.py +1 -2
  470. reconcile/typed_queries/terraform_tgw_attachments/__init__.py +0 -0
  471. reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +16 -0
  472. reconcile/typed_queries/unleash.py +10 -0
  473. reconcile/typed_queries/users.py +11 -0
  474. reconcile/typed_queries/vault.py +10 -0
  475. reconcile/unleash_feature_toggles/__init__.py +0 -0
  476. reconcile/unleash_feature_toggles/integration.py +287 -0
  477. reconcile/utils/acs/__init__.py +0 -0
  478. reconcile/utils/acs/base.py +81 -0
  479. reconcile/utils/acs/notifiers.py +143 -0
  480. reconcile/utils/acs/policies.py +163 -0
  481. reconcile/utils/acs/rbac.py +277 -0
  482. reconcile/utils/aggregated_list.py +11 -9
  483. reconcile/utils/amtool.py +6 -4
  484. reconcile/utils/aws_api.py +279 -66
  485. reconcile/utils/aws_api_typed/__init__.py +0 -0
  486. reconcile/utils/aws_api_typed/account.py +23 -0
  487. reconcile/utils/aws_api_typed/api.py +273 -0
  488. reconcile/utils/aws_api_typed/dynamodb.py +16 -0
  489. reconcile/utils/aws_api_typed/iam.py +67 -0
  490. reconcile/utils/aws_api_typed/organization.py +152 -0
  491. reconcile/utils/aws_api_typed/s3.py +26 -0
  492. reconcile/utils/aws_api_typed/service_quotas.py +79 -0
  493. reconcile/utils/aws_api_typed/sts.py +36 -0
  494. reconcile/utils/aws_api_typed/support.py +79 -0
  495. reconcile/utils/aws_helper.py +42 -3
  496. reconcile/utils/batches.py +11 -0
  497. reconcile/utils/binary.py +7 -9
  498. reconcile/utils/cloud_resource_best_practice/__init__.py +0 -0
  499. reconcile/utils/cloud_resource_best_practice/aws_rds.py +66 -0
  500. reconcile/utils/clusterhealth/__init__.py +0 -0
  501. reconcile/utils/clusterhealth/providerbase.py +39 -0
  502. reconcile/utils/clusterhealth/telemeter.py +39 -0
  503. reconcile/utils/config.py +3 -4
  504. reconcile/utils/deadmanssnitch_api.py +86 -0
  505. reconcile/utils/differ.py +205 -0
  506. reconcile/utils/disabled_integrations.py +4 -6
  507. reconcile/utils/dynatrace/__init__.py +0 -0
  508. reconcile/utils/dynatrace/client.py +93 -0
  509. reconcile/utils/early_exit_cache.py +289 -0
  510. reconcile/utils/elasticsearch_exceptions.py +5 -0
  511. reconcile/utils/environ.py +2 -2
  512. reconcile/utils/exceptions.py +4 -0
  513. reconcile/utils/expiration.py +4 -8
  514. reconcile/utils/extended_early_exit.py +210 -0
  515. reconcile/utils/external_resource_spec.py +34 -12
  516. reconcile/utils/external_resources.py +48 -20
  517. reconcile/utils/filtering.py +16 -0
  518. reconcile/utils/git.py +49 -16
  519. reconcile/utils/github_api.py +10 -9
  520. reconcile/utils/gitlab_api.py +333 -190
  521. reconcile/utils/glitchtip/client.py +97 -100
  522. reconcile/utils/glitchtip/models.py +89 -11
  523. reconcile/utils/gql.py +157 -58
  524. reconcile/utils/grouping.py +17 -0
  525. reconcile/utils/helm.py +89 -18
  526. reconcile/utils/helpers.py +51 -0
  527. reconcile/utils/imap_client.py +5 -6
  528. reconcile/utils/internal_groups/__init__.py +0 -0
  529. reconcile/utils/internal_groups/client.py +160 -0
  530. reconcile/utils/internal_groups/models.py +71 -0
  531. reconcile/utils/jenkins_api.py +10 -34
  532. reconcile/utils/jinja2/__init__.py +0 -0
  533. reconcile/utils/{jinja2_ext.py → jinja2/extensions.py} +6 -4
  534. reconcile/utils/jinja2/filters.py +142 -0
  535. reconcile/utils/jinja2/utils.py +278 -0
  536. reconcile/utils/jira_client.py +165 -8
  537. reconcile/utils/jjb_client.py +47 -35
  538. reconcile/utils/jobcontroller/__init__.py +0 -0
  539. reconcile/utils/jobcontroller/controller.py +413 -0
  540. reconcile/utils/jobcontroller/models.py +195 -0
  541. reconcile/utils/jsonpath.py +4 -5
  542. reconcile/utils/jump_host.py +13 -12
  543. reconcile/utils/keycloak.py +106 -0
  544. reconcile/utils/ldap_client.py +35 -6
  545. reconcile/utils/lean_terraform_client.py +115 -6
  546. reconcile/utils/membershipsources/__init__.py +0 -0
  547. reconcile/utils/membershipsources/app_interface_resolver.py +60 -0
  548. reconcile/utils/membershipsources/models.py +91 -0
  549. reconcile/utils/membershipsources/resolver.py +110 -0
  550. reconcile/utils/merge_request_manager/__init__.py +0 -0
  551. reconcile/utils/merge_request_manager/merge_request_manager.py +99 -0
  552. reconcile/utils/merge_request_manager/parser.py +67 -0
  553. reconcile/utils/metrics.py +511 -1
  554. reconcile/utils/models.py +123 -0
  555. reconcile/utils/mr/README.md +198 -0
  556. reconcile/utils/mr/__init__.py +14 -10
  557. reconcile/utils/mr/app_interface_reporter.py +2 -2
  558. reconcile/utils/mr/aws_access.py +4 -4
  559. reconcile/utils/mr/base.py +51 -31
  560. reconcile/utils/mr/clusters_updates.py +10 -7
  561. reconcile/utils/mr/glitchtip_access_reporter.py +2 -4
  562. reconcile/utils/mr/labels.py +14 -1
  563. reconcile/utils/mr/notificator.py +1 -3
  564. reconcile/utils/mr/ocm_update_recommended_version.py +1 -2
  565. reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +7 -3
  566. reconcile/utils/mr/promote_qontract.py +203 -0
  567. reconcile/utils/mr/user_maintenance.py +24 -4
  568. reconcile/utils/oauth2_backend_application_session.py +132 -0
  569. reconcile/utils/oc.py +194 -170
  570. reconcile/utils/oc_connection_parameters.py +40 -51
  571. reconcile/utils/oc_filters.py +11 -13
  572. reconcile/utils/oc_map.py +14 -35
  573. reconcile/utils/ocm/__init__.py +30 -1
  574. reconcile/utils/ocm/addons.py +228 -0
  575. reconcile/utils/ocm/base.py +618 -5
  576. reconcile/utils/ocm/cluster_groups.py +5 -56
  577. reconcile/utils/ocm/clusters.py +111 -99
  578. reconcile/utils/ocm/identity_providers.py +66 -0
  579. reconcile/utils/ocm/label_sources.py +75 -0
  580. reconcile/utils/ocm/labels.py +139 -54
  581. reconcile/utils/ocm/manifests.py +39 -0
  582. reconcile/utils/ocm/ocm.py +182 -928
  583. reconcile/utils/ocm/products.py +758 -0
  584. reconcile/utils/ocm/search_filters.py +20 -28
  585. reconcile/utils/ocm/service_log.py +32 -79
  586. reconcile/utils/ocm/sre_capability_labels.py +51 -0
  587. reconcile/utils/ocm/status_board.py +66 -0
  588. reconcile/utils/ocm/subscriptions.py +49 -59
  589. reconcile/utils/ocm/syncsets.py +39 -0
  590. reconcile/utils/ocm/upgrades.py +181 -0
  591. reconcile/utils/ocm_base_client.py +71 -36
  592. reconcile/utils/openshift_resource.py +113 -67
  593. reconcile/utils/output.py +18 -11
  594. reconcile/utils/pagerduty_api.py +16 -10
  595. reconcile/utils/parse_dhms_duration.py +13 -1
  596. reconcile/utils/prometheus.py +123 -0
  597. reconcile/utils/promotion_state.py +56 -19
  598. reconcile/utils/promtool.py +5 -8
  599. reconcile/utils/quay_api.py +13 -25
  600. reconcile/utils/raw_github_api.py +3 -5
  601. reconcile/utils/repo_owners.py +2 -8
  602. reconcile/utils/rest_api_base.py +126 -0
  603. reconcile/utils/rosa/__init__.py +0 -0
  604. reconcile/utils/rosa/rosa_cli.py +310 -0
  605. reconcile/utils/rosa/session.py +201 -0
  606. reconcile/utils/ruamel.py +16 -0
  607. reconcile/utils/runtime/__init__.py +0 -1
  608. reconcile/utils/runtime/desired_state_diff.py +9 -20
  609. reconcile/utils/runtime/environment.py +33 -8
  610. reconcile/utils/runtime/integration.py +28 -12
  611. reconcile/utils/runtime/meta.py +1 -3
  612. reconcile/utils/runtime/runner.py +8 -11
  613. reconcile/utils/runtime/sharding.py +93 -36
  614. reconcile/utils/saasherder/__init__.py +1 -1
  615. reconcile/utils/saasherder/interfaces.py +143 -138
  616. reconcile/utils/saasherder/models.py +201 -43
  617. reconcile/utils/saasherder/saasherder.py +508 -378
  618. reconcile/utils/secret_reader.py +22 -27
  619. reconcile/utils/semver_helper.py +15 -1
  620. reconcile/utils/slack_api.py +124 -36
  621. reconcile/utils/smtp_client.py +1 -2
  622. reconcile/utils/sqs_gateway.py +10 -6
  623. reconcile/utils/state.py +276 -127
  624. reconcile/utils/terraform/config_client.py +6 -7
  625. reconcile/utils/terraform_client.py +284 -125
  626. reconcile/utils/terrascript/cloudflare_client.py +38 -17
  627. reconcile/utils/terrascript/cloudflare_resources.py +67 -18
  628. reconcile/utils/terrascript/models.py +2 -3
  629. reconcile/utils/terrascript/resources.py +1 -2
  630. reconcile/utils/terrascript_aws_client.py +1292 -540
  631. reconcile/utils/three_way_diff_strategy.py +157 -0
  632. reconcile/utils/unleash/__init__.py +11 -0
  633. reconcile/utils/{unleash.py → unleash/client.py} +35 -29
  634. reconcile/utils/unleash/server.py +145 -0
  635. reconcile/utils/vault.py +42 -32
  636. reconcile/utils/vaultsecretref.py +2 -4
  637. reconcile/utils/vcs.py +250 -0
  638. reconcile/vault_replication.py +38 -31
  639. reconcile/vpc_peerings_validator.py +82 -13
  640. tools/app_interface_metrics_exporter.py +70 -0
  641. tools/app_interface_reporter.py +44 -157
  642. tools/cli_commands/container_images_report.py +154 -0
  643. tools/cli_commands/cost_report/__init__.py +0 -0
  644. tools/cli_commands/cost_report/aws.py +137 -0
  645. tools/cli_commands/cost_report/cost_management_api.py +155 -0
  646. tools/cli_commands/cost_report/model.py +49 -0
  647. tools/cli_commands/cost_report/openshift.py +166 -0
  648. tools/cli_commands/cost_report/openshift_cost_optimization.py +187 -0
  649. tools/cli_commands/cost_report/response.py +124 -0
  650. tools/cli_commands/cost_report/util.py +72 -0
  651. tools/cli_commands/cost_report/view.py +524 -0
  652. tools/cli_commands/erv2.py +620 -0
  653. tools/cli_commands/gpg_encrypt.py +5 -8
  654. tools/cli_commands/systems_and_tools.py +489 -0
  655. tools/glitchtip_access_revalidation.py +1 -1
  656. tools/qontract_cli.py +2301 -673
  657. tools/saas_metrics_exporter/__init__.py +0 -0
  658. tools/saas_metrics_exporter/commit_distance/__init__.py +0 -0
  659. tools/saas_metrics_exporter/commit_distance/channel.py +63 -0
  660. tools/saas_metrics_exporter/commit_distance/commit_distance.py +103 -0
  661. tools/saas_metrics_exporter/commit_distance/metrics.py +19 -0
  662. tools/saas_metrics_exporter/main.py +99 -0
  663. tools/saas_promotion_state/__init__.py +0 -0
  664. tools/saas_promotion_state/saas_promotion_state.py +105 -0
  665. tools/sd_app_sre_alert_report.py +145 -0
  666. tools/template_validation.py +107 -0
  667. e2e_tests/cli.py +0 -83
  668. e2e_tests/create_namespace.py +0 -43
  669. e2e_tests/dedicated_admin_rolebindings.py +0 -44
  670. e2e_tests/dedicated_admin_test_base.py +0 -39
  671. e2e_tests/default_network_policies.py +0 -47
  672. e2e_tests/default_project_labels.py +0 -52
  673. e2e_tests/network_policy_test_base.py +0 -17
  674. e2e_tests/test_base.py +0 -56
  675. qontract_reconcile-0.9.1rc298.dist-info/METADATA +0 -63
  676. qontract_reconcile-0.9.1rc298.dist-info/RECORD +0 -585
  677. qontract_reconcile-0.9.1rc298.dist-info/top_level.txt +0 -4
  678. reconcile/ecr_mirror.py +0 -152
  679. reconcile/github_scanner.py +0 -74
  680. reconcile/gitlab_integrations.py +0 -63
  681. reconcile/gql_definitions/ocm_oidc_idp/clusters.py +0 -195
  682. reconcile/gql_definitions/ocp_release_mirror/ocp_release_mirror.py +0 -287
  683. reconcile/integrations_validator.py +0 -18
  684. reconcile/jenkins_plugins.py +0 -129
  685. reconcile/kafka_clusters.py +0 -208
  686. reconcile/ocm_cluster_admin.py +0 -42
  687. reconcile/ocm_oidc_idp.py +0 -198
  688. reconcile/ocp_release_mirror.py +0 -373
  689. reconcile/prometheus_rules_tester_old.py +0 -436
  690. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -279
  691. reconcile/saas_auto_promotions_manager/utils/vcs.py +0 -141
  692. reconcile/sentry_config.py +0 -613
  693. reconcile/sentry_helper.py +0 -69
  694. reconcile/test/conftest.py +0 -187
  695. reconcile/test/fixtures.py +0 -24
  696. reconcile/test/saas_auto_promotions_manager/conftest.py +0 -69
  697. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -110
  698. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -10
  699. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_housekeeping.py +0 -200
  700. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -151
  701. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -63
  702. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
  703. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -46
  704. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -94
  705. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -44
  706. reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -74
  707. reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
  708. reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -155
  709. reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -173
  710. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -226
  711. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -224
  712. reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -350
  713. reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -129
  714. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -70
  715. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -63
  716. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -74
  717. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -65
  718. reconcile/test/test_aggregated_list.py +0 -237
  719. reconcile/test/test_amtool.py +0 -37
  720. reconcile/test/test_auto_promoter.py +0 -295
  721. reconcile/test/test_aws_ami_share.py +0 -68
  722. reconcile/test/test_aws_iam_keys.py +0 -70
  723. reconcile/test/test_aws_iam_password_reset.py +0 -35
  724. reconcile/test/test_aws_support_cases_sos.py +0 -23
  725. reconcile/test/test_checkpoint.py +0 -178
  726. reconcile/test/test_cli.py +0 -41
  727. reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
  728. reconcile/test/test_gabi_authorized_users.py +0 -72
  729. reconcile/test/test_github_org.py +0 -154
  730. reconcile/test/test_github_repo_invites.py +0 -123
  731. reconcile/test/test_gitlab_housekeeping.py +0 -88
  732. reconcile/test/test_gitlab_labeler.py +0 -129
  733. reconcile/test/test_gitlab_members.py +0 -283
  734. reconcile/test/test_instrumented_wrappers.py +0 -18
  735. reconcile/test/test_integrations_manager.py +0 -995
  736. reconcile/test/test_jenkins_worker_fleets.py +0 -55
  737. reconcile/test/test_jump_host.py +0 -117
  738. reconcile/test/test_ldap_users.py +0 -123
  739. reconcile/test/test_make.py +0 -28
  740. reconcile/test/test_ocm_additional_routers.py +0 -134
  741. reconcile/test/test_ocm_addons_upgrade_scheduler_org.py +0 -149
  742. reconcile/test/test_ocm_clusters.py +0 -598
  743. reconcile/test/test_ocm_clusters_manifest_updates.py +0 -89
  744. reconcile/test/test_ocm_oidc_idp.py +0 -315
  745. reconcile/test/test_ocm_update_recommended_version.py +0 -145
  746. reconcile/test/test_ocm_upgrade_scheduler.py +0 -614
  747. reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -129
  748. reconcile/test/test_openshift_base.py +0 -730
  749. reconcile/test/test_openshift_namespace_labels.py +0 -345
  750. reconcile/test/test_openshift_namespaces.py +0 -256
  751. reconcile/test/test_openshift_resource.py +0 -415
  752. reconcile/test/test_openshift_resources_base.py +0 -440
  753. reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -310
  754. reconcile/test/test_openshift_tekton_resources.py +0 -253
  755. reconcile/test/test_openshift_upgrade_watcher.py +0 -146
  756. reconcile/test/test_prometheus_rules_tester.py +0 -151
  757. reconcile/test/test_prometheus_rules_tester_old.py +0 -77
  758. reconcile/test/test_quay_membership.py +0 -86
  759. reconcile/test/test_quay_mirror.py +0 -109
  760. reconcile/test/test_quay_mirror_org.py +0 -70
  761. reconcile/test/test_quay_repos.py +0 -59
  762. reconcile/test/test_queries.py +0 -53
  763. reconcile/test/test_repo_owners.py +0 -47
  764. reconcile/test/test_requests_sender.py +0 -139
  765. reconcile/test/test_saasherder.py +0 -1074
  766. reconcile/test/test_saasherder_allowed_secret_paths.py +0 -127
  767. reconcile/test/test_secret_reader.py +0 -153
  768. reconcile/test/test_slack_base.py +0 -185
  769. reconcile/test/test_slack_usergroups.py +0 -744
  770. reconcile/test/test_sql_query.py +0 -19
  771. reconcile/test/test_terraform_cloudflare_dns.py +0 -117
  772. reconcile/test/test_terraform_cloudflare_resources.py +0 -106
  773. reconcile/test/test_terraform_cloudflare_users.py +0 -749
  774. reconcile/test/test_terraform_resources.py +0 -257
  775. reconcile/test/test_terraform_tgw_attachments.py +0 -631
  776. reconcile/test/test_terraform_users.py +0 -57
  777. reconcile/test/test_terraform_vpc_peerings.py +0 -499
  778. reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1061
  779. reconcile/test/test_unleash.py +0 -138
  780. reconcile/test/test_utils_aws_api.py +0 -240
  781. reconcile/test/test_utils_aws_helper.py +0 -80
  782. reconcile/test/test_utils_cluster_version_data.py +0 -177
  783. reconcile/test/test_utils_data_structures.py +0 -13
  784. reconcile/test/test_utils_disabled_integrations.py +0 -86
  785. reconcile/test/test_utils_expiration.py +0 -109
  786. reconcile/test/test_utils_external_resource_spec.py +0 -383
  787. reconcile/test/test_utils_external_resources.py +0 -247
  788. reconcile/test/test_utils_github_api.py +0 -73
  789. reconcile/test/test_utils_gitlab_api.py +0 -20
  790. reconcile/test/test_utils_gpg.py +0 -69
  791. reconcile/test/test_utils_gql.py +0 -81
  792. reconcile/test/test_utils_helm.py +0 -306
  793. reconcile/test/test_utils_helpers.py +0 -55
  794. reconcile/test/test_utils_imap_client.py +0 -65
  795. reconcile/test/test_utils_jjb_client.py +0 -52
  796. reconcile/test/test_utils_jsonpath.py +0 -286
  797. reconcile/test/test_utils_ldap_client.py +0 -51
  798. reconcile/test/test_utils_mr.py +0 -226
  799. reconcile/test/test_utils_mr_clusters_updates.py +0 -77
  800. reconcile/test/test_utils_oc.py +0 -984
  801. reconcile/test/test_utils_ocm.py +0 -110
  802. reconcile/test/test_utils_pagerduty_api.py +0 -251
  803. reconcile/test/test_utils_parse_dhms_duration.py +0 -34
  804. reconcile/test/test_utils_password_validator.py +0 -155
  805. reconcile/test/test_utils_quay_api.py +0 -86
  806. reconcile/test/test_utils_semver_helper.py +0 -19
  807. reconcile/test/test_utils_sharding.py +0 -56
  808. reconcile/test/test_utils_slack_api.py +0 -439
  809. reconcile/test/test_utils_smtp_client.py +0 -73
  810. reconcile/test/test_utils_state.py +0 -256
  811. reconcile/test/test_utils_terraform.py +0 -13
  812. reconcile/test/test_utils_terraform_client.py +0 -585
  813. reconcile/test/test_utils_terraform_config_client.py +0 -219
  814. reconcile/test/test_utils_terrascript_aws_client.py +0 -277
  815. reconcile/test/test_utils_terrascript_cloudflare_client.py +0 -597
  816. reconcile/test/test_utils_terrascript_cloudflare_resources.py +0 -26
  817. reconcile/test/test_vault_replication.py +0 -515
  818. reconcile/test/test_vault_utils.py +0 -47
  819. reconcile/test/test_version_bump.py +0 -18
  820. reconcile/test/test_vpc_peerings_validator.py +0 -103
  821. reconcile/test/test_wrong_region.py +0 -78
  822. reconcile/typed_queries/glitchtip_settings.py +0 -18
  823. reconcile/typed_queries/ocp_release_mirror.py +0 -11
  824. reconcile/unleash_watcher.py +0 -120
  825. reconcile/utils/git_secrets.py +0 -63
  826. reconcile/utils/mr/auto_promoter.py +0 -218
  827. reconcile/utils/sentry_client.py +0 -383
  828. release/test_version.py +0 -50
  829. release/version.py +0 -100
  830. tools/test/test_qontract_cli.py +0 -60
  831. tools/test/test_sre_checkpoints.py +0 -79
  832. /e2e_tests/__init__.py → /reconcile/aus/upgrades.py +0 -0
  833. /reconcile/{gql_definitions/ocp_release_mirror → aws_account_manager}/__init__.py +0 -0
  834. /reconcile/{test → aws_ami_cleanup}/__init__.py +0 -0
  835. /reconcile/{test/saas_auto_promotions_manager → aws_cloudwatch_log_retention}/__init__.py +0 -0
  836. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager → aws_saml_idp}/__init__.py +0 -0
  837. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager → aws_saml_roles}/__init__.py +0 -0
  838. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/renderer → aws_version_sync}/__init__.py +0 -0
  839. /reconcile/{test/saas_auto_promotions_manager/subscriber → aws_version_sync/merge_request_manager}/__init__.py +0 -0
  840. /reconcile/{test/saas_auto_promotions_manager/utils → cluster_auth_rhidp}/__init__.py +0 -0
  841. /reconcile/{test/saas_auto_promotions_manager/utils/saas_files_inventory → dynatrace_token_provider}/__init__.py +0 -0
  842. {release → reconcile/endpoints_discovery}/__init__.py +0 -0
  843. {tools/test → reconcile/external_resources}/__init__.py +0 -0
@@ -1,4 +1,3 @@
1
- import json
2
1
  import logging
3
2
  from collections.abc import (
4
3
  Callable,
@@ -8,19 +7,52 @@ from collections.abc import (
8
7
  )
9
8
  from typing import (
10
9
  Any,
11
- Optional,
10
+ TypedDict,
11
+ cast,
12
12
  )
13
13
 
14
- from reconcile import queries
14
+ from pydantic import BaseModel
15
+
16
+ from reconcile.gql_definitions.common.app_interface_vault_settings import (
17
+ AppInterfaceSettingsV1,
18
+ )
19
+ from reconcile.gql_definitions.common.clusters_with_peering import (
20
+ ClusterPeeringConnectionAccountTGWV1,
21
+ ClusterPeeringConnectionAccountV1,
22
+ ClusterPeeringConnectionAccountVPCMeshV1,
23
+ ClusterPeeringConnectionClusterRequesterV1,
24
+ ClusterPeeringConnectionV1,
25
+ ClusterSpecROSAV1,
26
+ ClusterV1,
27
+ )
28
+ from reconcile.gql_definitions.terraform_tgw_attachments.aws_accounts import (
29
+ AWSAccountV1,
30
+ )
31
+ from reconcile.typed_queries.app_interface_vault_settings import (
32
+ get_app_interface_vault_settings,
33
+ )
34
+ from reconcile.typed_queries.clusters_with_peering import get_clusters_with_peering
35
+ from reconcile.typed_queries.terraform_tgw_attachments.aws_accounts import (
36
+ get_aws_accounts,
37
+ )
38
+ from reconcile.utils import gql
15
39
  from reconcile.utils.aws_api import AWSApi
16
40
  from reconcile.utils.defer import defer
41
+ from reconcile.utils.disabled_integrations import integration_is_enabled
42
+ from reconcile.utils.extended_early_exit import (
43
+ ExtendedEarlyExitRunnerResult,
44
+ extended_early_exit_run,
45
+ )
17
46
  from reconcile.utils.ocm import (
18
47
  OCM,
19
48
  OCMMap,
20
49
  )
50
+ from reconcile.utils.runtime.integration import DesiredStateShardConfig
51
+ from reconcile.utils.secret_reader import SecretReaderBase, create_secret_reader
21
52
  from reconcile.utils.semver_helper import make_semver
22
53
  from reconcile.utils.terraform_client import TerraformClient as Terraform
23
54
  from reconcile.utils.terrascript_aws_client import TerrascriptClient as Terrascript
55
+ from reconcile.utils.unleash import get_feature_toggle_state
24
56
 
25
57
  QONTRACT_INTEGRATION = "terraform_tgw_attachments"
26
58
  QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
@@ -32,11 +64,70 @@ class ValidationError(Exception):
32
64
  pass
33
65
 
34
66
 
35
- def build_desired_state_tgw_attachments(
36
- clusters: Iterable[Mapping],
37
- ocm_map: Optional[OCMMap],
67
+ class TGWAccountProviderInfo(BaseModel):
68
+ name: str
69
+ uid: str
70
+ assume_role: str | None
71
+ assume_region: str
72
+
73
+
74
+ class ClusterAccountProviderInfo(TGWAccountProviderInfo):
75
+ assume_cidr: str
76
+
77
+
78
+ class Requester(BaseModel):
79
+ tgw_id: str
80
+ tgw_arn: str
81
+ region: str
82
+ routes: list[dict] | None
83
+ rules: list[dict] | None
84
+ hostedzones: list[str] | None
85
+ cidr_block: str | None
86
+ cidr_blocks: list[str]
87
+ account: TGWAccountProviderInfo
88
+
89
+
90
+ class Accepter(BaseModel):
91
+ cidr_block: str
92
+ region: str
93
+ vpc_id: str | None
94
+ route_table_ids: list[str] | None
95
+ subnets_id_az: list[dict] | None
96
+ account: ClusterAccountProviderInfo
97
+ api_security_group_id: str | None
98
+
99
+
100
+ class DesiredStateItem(BaseModel):
101
+ connection_provider: str
102
+ connection_name: str
103
+ infra_acount_name: str
104
+ requester: Requester
105
+ accepter: Accepter
106
+ deleted: bool
107
+
108
+
109
+ class DesiredStateDataSource(BaseModel):
110
+ clusters: list[ClusterV1]
111
+ accounts: list[AWSAccountV1]
112
+
113
+
114
+ class CacheSource(TypedDict):
115
+ terraform_configurations: dict[str, str]
116
+
117
+
118
+ class RunnerParams(TypedDict):
119
+ terraform_client: Terraform
120
+ terrascript_client: Terrascript
121
+ dry_run: bool
122
+ enable_deletion: bool
123
+
124
+
125
+ def _build_desired_state_tgw_attachments(
126
+ clusters: Iterable[ClusterV1],
127
+ ocm_map: OCMMap | None,
38
128
  awsapi: AWSApi,
39
- ) -> tuple[list[dict], bool]:
129
+ account_name: str | None = None,
130
+ ) -> tuple[list[DesiredStateItem], bool]:
40
131
  """
41
132
  Fetch state for TGW attachments between a cluster and all TGWs
42
133
  in an account in the same region as the cluster
@@ -44,7 +135,7 @@ def build_desired_state_tgw_attachments(
44
135
  desired_state = []
45
136
  error = False
46
137
 
47
- for item in _build_desired_state_tgw_attachments(clusters, ocm_map, awsapi):
138
+ for item in _build_desired_state_items(clusters, ocm_map, awsapi, account_name):
48
139
  if item is None:
49
140
  error = True
50
141
  else:
@@ -52,148 +143,185 @@ def build_desired_state_tgw_attachments(
52
143
  return desired_state, error
53
144
 
54
145
 
55
- def _build_desired_state_tgw_attachments(
56
- clusters: Iterable[Mapping],
57
- ocm_map: Optional[OCMMap],
146
+ def _build_desired_state_items(
147
+ clusters: Iterable[ClusterV1],
148
+ ocm_map: OCMMap | None,
58
149
  awsapi: AWSApi,
59
- ) -> Generator[Optional[dict], Any, None]:
150
+ account_name: str | None = None,
151
+ ) -> Generator[DesiredStateItem | None, Any, None]:
60
152
  for cluster_info in clusters:
61
- ocm = (
62
- ocm_map.get(cluster_info["name"])
63
- if ocm_map and cluster_info.get("ocm")
64
- else None
65
- )
66
- for peer_connection in cluster_info["peering"]["connections"]:
67
- if peer_connection["provider"] == TGW_CONNECTION_PROVIDER:
153
+ ocm = ocm_map.get(cluster_info.name) if ocm_map and cluster_info.ocm else None
154
+ for peer_connection in cluster_info.peering.connections: # type: ignore[union-attr]
155
+ if _is_tgw_peer_connection(peer_connection, account_name):
68
156
  yield from _build_desired_state_tgw_connection(
69
- peer_connection, cluster_info, ocm, awsapi
157
+ cast(ClusterPeeringConnectionAccountTGWV1, peer_connection),
158
+ cluster_info,
159
+ ocm,
160
+ awsapi,
70
161
  )
71
162
 
72
163
 
73
164
  def _build_desired_state_tgw_connection(
74
- peer_connection: Mapping,
75
- cluster_info: Mapping,
76
- ocm: Optional[OCM],
165
+ peer_connection: ClusterPeeringConnectionAccountTGWV1,
166
+ cluster_info: ClusterV1,
167
+ ocm: OCM | None,
77
168
  awsapi: AWSApi,
78
- ) -> Generator[Optional[dict], Any, None]:
79
- cluster_name = cluster_info["name"]
80
- cluster_region = cluster_info["spec"]["region"]
81
- cluster_cidr_block = cluster_info["network"]["vpc"]
169
+ ) -> Generator[DesiredStateItem | None, Any, None]:
170
+ cluster_name = cluster_info.name
171
+ cluster_region = cluster_info.spec.region if cluster_info.spec is not None else ""
172
+ cluster_cidr_block = (
173
+ cluster_info.network.vpc if cluster_info.network is not None else ""
174
+ )
82
175
 
83
- account = _account_with_assume_role_data(
84
- peer_connection, cluster_name, cluster_region, cluster_cidr_block, ocm
176
+ acc_account = _build_account_with_assume_role(
177
+ peer_connection, cluster_info, cluster_region, cluster_cidr_block, ocm
85
178
  )
86
179
 
87
180
  # accepter is the cluster's AWS account
88
181
  accepter = _build_accepter(
89
182
  peer_connection,
90
- account,
183
+ acc_account,
91
184
  cluster_region,
92
185
  cluster_cidr_block,
93
186
  awsapi,
187
+ private_hcp=_is_private_hosted_control_plane(cluster_info),
94
188
  )
95
- if accepter["vpc_id"] is None:
189
+ if accepter.vpc_id is None:
96
190
  logging.error(f"[{cluster_name}] could not find VPC ID for cluster")
97
191
  yield None
98
192
 
99
193
  account_tgws = awsapi.get_tgws_details(
100
- account,
194
+ peer_connection.account.dict(by_alias=True),
101
195
  cluster_region,
102
196
  cluster_cidr_block,
103
- tags=json.loads(peer_connection.get("tags") or "{}"),
104
- route_tables=peer_connection.get("manageRoutes"),
105
- security_groups=peer_connection.get("manageSecurityGroups"),
106
- route53_associations=peer_connection.get("manageRoute53Associations"),
197
+ tags=peer_connection.tags or {},
198
+ route_tables=peer_connection.manage_routes,
199
+ security_groups=peer_connection.manage_security_groups,
200
+ route53_associations=peer_connection.manage_route53_associations,
107
201
  )
108
202
  for tgw in account_tgws:
109
- connection_name = f"{peer_connection['name']}_{account['name']}-{tgw['tgw_id']}"
110
- requester = _build_requester(peer_connection, account, tgw)
111
- item = {
112
- "connection_provider": TGW_CONNECTION_PROVIDER,
113
- "connection_name": connection_name,
114
- "requester": requester,
115
- "accepter": accepter,
116
- "deleted": peer_connection.get("delete", False),
117
- }
203
+ connection_name = (
204
+ f"{peer_connection.name}_{peer_connection.account.name}-{tgw['tgw_id']}"
205
+ )
206
+ requester = _build_requester(peer_connection, tgw)
207
+ item = DesiredStateItem(
208
+ connection_provider=TGW_CONNECTION_PROVIDER,
209
+ connection_name=connection_name,
210
+ infra_acount_name=peer_connection.account.name,
211
+ requester=requester,
212
+ accepter=accepter,
213
+ deleted=peer_connection.delete or False,
214
+ )
118
215
  yield item
119
216
 
120
217
 
121
- def _account_with_assume_role_data(
122
- peer_connection: Mapping,
123
- cluster_name: str,
218
+ def _is_private_hosted_control_plane(cluster_info: ClusterV1) -> bool:
219
+ return (
220
+ cluster_info.spec is not None
221
+ and bool(cluster_info.spec.hypershift)
222
+ and bool(cluster_info.spec.private)
223
+ )
224
+
225
+
226
+ def _build_account_with_assume_role(
227
+ peer_connection: ClusterPeeringConnectionAccountTGWV1,
228
+ cluster: ClusterV1,
124
229
  region: str,
125
230
  cidr_block: str,
126
- ocm: Optional[OCM],
127
- ) -> dict[str, Any]:
128
- account = peer_connection["account"]
231
+ ocm: OCM | None,
232
+ ) -> ClusterAccountProviderInfo:
233
+ account = peer_connection.account
129
234
  # assume_role is the role to assume to provision the
130
235
  # peering connection request, through the accepter AWS account.
131
- provided_assume_role = peer_connection.get("assumeRole")
236
+ assume_role = peer_connection.assume_role
132
237
  # if an assume_role is provided, it means we don't need
133
238
  # to get the information from OCM. it likely means that
134
239
  # there is no OCM at all.
135
- if provided_assume_role:
136
- account["assume_role"] = provided_assume_role
137
- else:
240
+ if not assume_role:
241
+ if isinstance(cluster.spec, ClusterSpecROSAV1) and cluster.spec.account:
242
+ return ClusterAccountProviderInfo(
243
+ name=cluster.spec.account.name,
244
+ uid=cluster.spec.account.uid,
245
+ assume_role=assume_role,
246
+ assume_region=region,
247
+ assume_cidr=cidr_block,
248
+ )
138
249
  if not ocm:
139
250
  raise ValueError("OCM is required to get assume_role data")
140
- account[
141
- "assume_role"
142
- ] = ocm.get_aws_infrastructure_access_terraform_assume_role(
143
- cluster_name, account["uid"], account["terraformUsername"]
251
+ assume_role = ocm.get_aws_infrastructure_access_terraform_assume_role(
252
+ cluster.name, account.uid, account.terraform_username
144
253
  )
145
- account["assume_region"] = region
146
- account["assume_cidr"] = cidr_block
147
- return account
254
+ return ClusterAccountProviderInfo(
255
+ name=account.name,
256
+ uid=account.uid,
257
+ assume_role=assume_role,
258
+ assume_region=region,
259
+ assume_cidr=cidr_block,
260
+ )
148
261
 
149
262
 
150
263
  def _build_accepter(
151
- peer_connection: Mapping,
152
- account: Mapping,
264
+ peer_connection: ClusterPeeringConnectionAccountTGWV1,
265
+ account: ClusterAccountProviderInfo,
153
266
  region: str,
154
267
  cidr_block: str,
155
268
  awsapi: AWSApi,
156
- ) -> dict[str, Any]:
157
- (vpc_id, route_table_ids, subnets_id_az) = awsapi.get_cluster_vpc_details(
158
- account,
159
- route_tables=peer_connection.get("manageRoutes"),
160
- subnets=True,
269
+ private_hcp: bool = False,
270
+ ) -> Accepter:
271
+ allow_hcp_private_api_access = (
272
+ private_hcp and peer_connection.allow_private_hcp_api_access
273
+ )
274
+ (vpc_id, route_table_ids, subnets_id_az, api_security_group_id) = (
275
+ awsapi.get_cluster_vpc_details(
276
+ account.dict(by_alias=True),
277
+ route_tables=peer_connection.manage_routes,
278
+ subnets=True,
279
+ hcp_vpc_endpoint_sg=allow_hcp_private_api_access,
280
+ )
281
+ )
282
+ return Accepter(
283
+ cidr_block=cidr_block,
284
+ region=region,
285
+ vpc_id=vpc_id,
286
+ route_table_ids=route_table_ids,
287
+ subnets_id_az=subnets_id_az,
288
+ account=account,
289
+ api_security_group_id=api_security_group_id,
161
290
  )
162
- return {
163
- "cidr_block": cidr_block,
164
- "region": region,
165
- "vpc_id": vpc_id,
166
- "route_table_ids": route_table_ids,
167
- "subnets_id_az": subnets_id_az,
168
- "account": account,
169
- }
170
291
 
171
292
 
172
293
  def _build_requester(
173
- peer_connection: Mapping,
174
- account: Mapping,
294
+ peer_connection: ClusterPeeringConnectionAccountTGWV1,
175
295
  tgw: Mapping,
176
- ) -> dict[str, Any]:
177
- return {
178
- "tgw_id": tgw["tgw_id"],
179
- "tgw_arn": tgw["tgw_arn"],
180
- "region": tgw["region"],
181
- "routes": tgw.get("routes"),
182
- "rules": tgw.get("rules"),
183
- "hostedzones": tgw.get("hostedzones"),
184
- "cidr_block": peer_connection.get("cidrBlock"),
185
- "account": account,
186
- }
296
+ ) -> Requester:
297
+ tgw_account = TGWAccountProviderInfo(
298
+ name=peer_connection.account.name,
299
+ uid=peer_connection.account.uid,
300
+ assume_region=tgw["region"],
301
+ )
302
+ return Requester(
303
+ tgw_id=tgw["tgw_id"],
304
+ tgw_arn=tgw["tgw_arn"],
305
+ region=tgw["region"],
306
+ routes=tgw.get("routes"),
307
+ rules=tgw.get("rules"),
308
+ hostedzones=tgw.get("hostedzones"),
309
+ cidr_block=peer_connection.cidr_block,
310
+ cidr_blocks=peer_connection.cidr_blocks or [],
311
+ account=tgw_account,
312
+ )
187
313
 
188
314
 
189
315
  def _build_ocm_map(
190
- clusters: Iterable[Mapping],
191
- settings: Optional[Mapping[str, Any]],
192
- ) -> Optional[OCMMap]:
193
- ocm_clusters = [c for c in clusters if c.get("ocm")]
316
+ clusters: Iterable[ClusterV1],
317
+ vault_settings: AppInterfaceSettingsV1,
318
+ ) -> OCMMap | None:
319
+ ocm_clusters = [c.dict(by_alias=True) for c in clusters if c.ocm]
194
320
  return (
195
321
  OCMMap(
196
- clusters=ocm_clusters, integration=QONTRACT_INTEGRATION, settings=settings
322
+ clusters=ocm_clusters,
323
+ integration=QONTRACT_INTEGRATION,
324
+ settings=vault_settings.dict(by_alias=True),
197
325
  )
198
326
  if ocm_clusters
199
327
  # this is a case for an OCP cluster which is not provisioned
@@ -203,95 +331,137 @@ def _build_ocm_map(
203
331
  )
204
332
 
205
333
 
206
- def _validate_tgw_connection_names(desired_state: Iterable[Mapping]) -> None:
207
- connection_names = [c["connection_name"] for c in desired_state]
334
+ def _validate_tgw_connection_names(desired_state: Iterable[DesiredStateItem]) -> None:
335
+ connection_names = [c.connection_name for c in desired_state]
208
336
  if len(set(connection_names)) != len(connection_names):
209
337
  raise ValidationError("duplicate tgw connection names found")
210
338
 
211
339
 
212
340
  def _populate_tgw_attachments_working_dirs(
213
- desired_state: Iterable,
214
- accounts: Iterable,
215
- settings: Optional[Mapping[str, Any]],
216
- participating_accounts: Iterable,
217
- print_to_file: Optional[str],
218
- thread_pool_size: int,
341
+ ts: Terrascript,
342
+ desired_state: Iterable[DesiredStateItem],
343
+ print_to_file: str | None,
219
344
  ) -> dict[str, str]:
220
- ts = Terrascript(
221
- QONTRACT_INTEGRATION, "", thread_pool_size, accounts, settings=settings
222
- )
223
- ts.populate_additional_providers(participating_accounts)
345
+ accounts_by_infra_account_name: dict[str, list[dict[str, Any]]] = {}
346
+ for item in desired_state:
347
+ accounts_by_infra_account_name.setdefault(item.infra_acount_name, []).append(
348
+ item.accepter.account.dict(by_alias=True)
349
+ )
350
+ for infra_account_name, accounts in accounts_by_infra_account_name.items():
351
+ ts.populate_additional_providers(infra_account_name, accounts)
224
352
  ts.populate_tgw_attachments(desired_state)
225
353
  working_dirs = ts.dump(print_to_file=print_to_file)
226
354
  return working_dirs
227
355
 
228
356
 
229
- def _is_tgw_cluster(cluster: Mapping) -> bool:
357
+ def _is_tgw_peer_connection(
358
+ peer_connection: ClusterPeeringConnectionAccountTGWV1
359
+ | ClusterPeeringConnectionAccountV1
360
+ | ClusterPeeringConnectionAccountVPCMeshV1
361
+ | ClusterPeeringConnectionClusterRequesterV1
362
+ | ClusterPeeringConnectionV1,
363
+ account_name: str | None,
364
+ ) -> bool:
365
+ if peer_connection.provider != TGW_CONNECTION_PROVIDER:
366
+ return False
367
+ if account_name is None:
368
+ return True
369
+ tgw_peer_connection = cast(ClusterPeeringConnectionAccountTGWV1, peer_connection)
370
+ return tgw_peer_connection.account.name == account_name
371
+
372
+
373
+ def _is_tgw_cluster(
374
+ cluster: ClusterV1,
375
+ account_name: str | None = None,
376
+ ) -> bool:
230
377
  return any(
231
- pc["provider"] == TGW_CONNECTION_PROVIDER
232
- for pc in cluster["peering"]["connections"]
378
+ _is_tgw_peer_connection(pc, account_name)
379
+ for pc in cluster.peering.connections # type: ignore[union-attr]
233
380
  )
234
381
 
235
382
 
236
- def _filter_tgw_clusters(clusters: Iterable[Mapping]) -> list:
237
- return list(filter(_is_tgw_cluster, clusters))
383
+ def _filter_tgw_clusters(
384
+ clusters: Iterable[ClusterV1],
385
+ account_name: str | None = None,
386
+ ) -> list[ClusterV1]:
387
+ return [c for c in clusters if _is_tgw_cluster(c, account_name)]
238
388
 
239
389
 
240
390
  def _filter_tgw_accounts(
241
- accounts: Iterable[Mapping],
242
- tgw_clusters: Iterable[Mapping],
243
- ) -> list:
391
+ accounts: Iterable[AWSAccountV1],
392
+ tgw_clusters: Iterable[ClusterV1],
393
+ ) -> list[AWSAccountV1]:
244
394
  tgw_account_names = set()
245
395
  for cluster in tgw_clusters:
246
- for pc in cluster["peering"]["connections"]:
247
- if pc["provider"] == TGW_CONNECTION_PROVIDER:
248
- tgw_account_names.add(pc["account"]["name"])
249
- return [a for a in accounts if a["name"] in tgw_account_names]
396
+ for peer_connection in cluster.peering.connections: # type: ignore[union-attr]
397
+ if peer_connection.provider == TGW_CONNECTION_PROVIDER:
398
+ tgw_peer_connection = cast(
399
+ ClusterPeeringConnectionAccountTGWV1, peer_connection
400
+ )
401
+ tgw_account_names.add(tgw_peer_connection.account.name)
402
+ return [
403
+ a
404
+ for a in accounts
405
+ if a.name in tgw_account_names
406
+ and integration_is_enabled(QONTRACT_INTEGRATION.replace("_", "-"), a)
407
+ ]
408
+
409
+
410
+ def _fetch_desired_state_data_source(
411
+ account_name: str | None = None,
412
+ ) -> DesiredStateDataSource:
413
+ clusters = get_clusters_with_peering(gql.get_api())
414
+ tgw_clusters = _filter_tgw_clusters(clusters, account_name)
415
+ all_accounts = get_aws_accounts(gql.get_api())
416
+ return DesiredStateDataSource(
417
+ clusters=tgw_clusters,
418
+ accounts=all_accounts,
419
+ )
250
420
 
251
421
 
252
- @defer
253
- def run(
254
- dry_run: bool,
255
- print_to_file: Optional[str] = None,
256
- enable_deletion: bool = False,
422
+ def setup(
423
+ account_name: str | None,
424
+ desired_state_data_source: DesiredStateDataSource,
425
+ tgw_accounts: list[dict[str, Any]],
257
426
  thread_pool_size: int = 10,
258
- defer: Optional[Callable] = None,
259
- ) -> None:
260
- settings = queries.get_secret_reader_settings()
261
- clusters = queries.get_clusters_with_peering_settings()
262
- tgw_clusters = _filter_tgw_clusters(clusters)
263
- ocm_map = _build_ocm_map(tgw_clusters, settings)
264
- accounts = queries.get_aws_accounts(terraform_state=True, ecrs=False)
265
- tgw_accounts = _filter_tgw_accounts(accounts, tgw_clusters)
266
-
267
- aws_api = AWSApi(1, tgw_accounts, settings=settings, init_users=False)
268
- if defer:
269
- defer(aws_api.cleanup)
270
-
271
- # Fetch desired state for cluster-to-vpc(account) VPCs
272
- desired_state, err = build_desired_state_tgw_attachments(
273
- tgw_clusters, ocm_map, aws_api
427
+ print_to_file: str | None = None,
428
+ ) -> tuple[SecretReaderBase, AWSApi, Terraform, Terrascript]:
429
+ tgw_clusters = desired_state_data_source.clusters
430
+ all_accounts = [a.dict(by_alias=True) for a in desired_state_data_source.accounts]
431
+ account_by_name = {a["name"]: a for a in all_accounts}
432
+ vault_settings = get_app_interface_vault_settings()
433
+ secret_reader = create_secret_reader(vault_settings.vault)
434
+ aws_api = AWSApi(1, all_accounts, secret_reader=secret_reader, init_users=False)
435
+ ocm_map = _build_ocm_map(desired_state_data_source.clusters, vault_settings)
436
+ desired_state, err = _build_desired_state_tgw_attachments(
437
+ desired_state_data_source.clusters,
438
+ ocm_map,
439
+ aws_api,
440
+ account_name,
274
441
  )
275
442
  if err:
276
443
  raise RuntimeError("Could not find VPC ID for cluster")
277
444
 
278
- # check there are no repeated tgw connection names
279
445
  _validate_tgw_connection_names(desired_state)
280
446
 
281
- participating_accounts = [item["requester"]["account"] for item in desired_state]
282
-
447
+ ts = Terrascript(
448
+ QONTRACT_INTEGRATION,
449
+ "",
450
+ thread_pool_size,
451
+ tgw_accounts,
452
+ settings=vault_settings.dict(by_alias=True),
453
+ )
454
+ tgw_rosa_cluster_accounts = [
455
+ account_by_name[c.spec.account.name]
456
+ for c in tgw_clusters
457
+ if isinstance(c.spec, ClusterSpecROSAV1) and c.spec.account
458
+ ]
459
+ ts.populate_configs(tgw_rosa_cluster_accounts)
283
460
  working_dirs = _populate_tgw_attachments_working_dirs(
461
+ ts,
284
462
  desired_state,
285
- tgw_accounts,
286
- settings,
287
- participating_accounts,
288
463
  print_to_file,
289
- thread_pool_size,
290
464
  )
291
-
292
- if print_to_file:
293
- return
294
-
295
465
  tf = Terraform(
296
466
  QONTRACT_INTEGRATION,
297
467
  QONTRACT_INTEGRATION_VERSION,
@@ -301,30 +471,110 @@ def run(
301
471
  thread_pool_size,
302
472
  aws_api,
303
473
  )
474
+ return secret_reader, aws_api, tf, ts
304
475
 
305
- if defer:
306
- defer(tf.cleanup)
307
476
 
308
- disabled_deletions_detected, err = tf.plan(enable_deletion)
477
+ def runner(
478
+ dry_run: bool,
479
+ terraform_client: Terraform,
480
+ terrascript_client: Terrascript,
481
+ enable_deletion: bool = False,
482
+ ) -> ExtendedEarlyExitRunnerResult:
483
+ disabled_deletions_detected, err = terraform_client.plan(enable_deletion)
309
484
  if err:
310
485
  raise RuntimeError("Error running terraform plan")
311
486
  if disabled_deletions_detected:
312
487
  raise RuntimeError("Disabled deletions detected running terraform plan")
313
-
314
- if dry_run:
315
- return
316
-
317
- err = tf.apply()
318
- if err:
319
- raise RuntimeError("Error running terraform apply")
488
+ if not dry_run:
489
+ err = terraform_client.apply()
490
+ if err:
491
+ raise RuntimeError("Error running terraform apply")
492
+ return ExtendedEarlyExitRunnerResult(
493
+ payload=terrascript_client.terraform_configurations(),
494
+ applied_count=terraform_client.apply_count,
495
+ )
320
496
 
321
497
 
322
- def early_exit_desired_state(
323
- print_to_file: Optional[str] = None,
498
+ @defer
499
+ def run(
500
+ dry_run: bool,
501
+ print_to_file: str | None = None,
324
502
  enable_deletion: bool = False,
325
503
  thread_pool_size: int = 10,
326
- ) -> dict[str, Any]:
327
- return {
328
- "clusters": queries.get_clusters_with_peering_settings(),
329
- "accounts": queries.get_aws_accounts(terraform_state=True, ecrs=False),
504
+ account_name: str | None = None,
505
+ defer: Callable | None = None,
506
+ enable_extended_early_exit: bool = False,
507
+ extended_early_exit_cache_ttl_seconds: int = 3600,
508
+ log_cached_log_output: bool = False,
509
+ ) -> None:
510
+ desired_state_data_source = _fetch_desired_state_data_source(account_name)
511
+ tgw_accounts = [
512
+ a.dict(by_alias=True)
513
+ for a in _filter_tgw_accounts(
514
+ desired_state_data_source.accounts, desired_state_data_source.clusters
515
+ )
516
+ if not account_name or account_name == a.name
517
+ ]
518
+ if not tgw_accounts:
519
+ logging.warning(
520
+ f"No participating AWS accounts found, consider disabling this integration, account name: {account_name}"
521
+ )
522
+ return
523
+ secret_reader, aws_api, tf, ts = setup(
524
+ desired_state_data_source=desired_state_data_source,
525
+ account_name=account_name,
526
+ tgw_accounts=tgw_accounts,
527
+ thread_pool_size=thread_pool_size,
528
+ print_to_file=print_to_file,
529
+ )
530
+ if defer:
531
+ defer(aws_api.cleanup)
532
+ defer(tf.cleanup)
533
+ if print_to_file:
534
+ return
535
+ runner_params: RunnerParams = {
536
+ "terraform_client": tf,
537
+ "terrascript_client": ts,
538
+ "enable_deletion": enable_deletion,
539
+ "dry_run": dry_run,
330
540
  }
541
+ if enable_extended_early_exit and get_feature_toggle_state(
542
+ "terraform-tgw-attachments-extended-early-exit",
543
+ default=False,
544
+ ):
545
+ cache_source = CacheSource(
546
+ terraform_configurations=ts.terraform_configurations(),
547
+ )
548
+ extended_early_exit_run(
549
+ integration=QONTRACT_INTEGRATION,
550
+ integration_version=QONTRACT_INTEGRATION_VERSION,
551
+ dry_run=dry_run,
552
+ cache_source=cache_source,
553
+ shard="_".join(account_name) if account_name else "",
554
+ ttl_seconds=extended_early_exit_cache_ttl_seconds,
555
+ logger=logging.getLogger(),
556
+ runner=runner,
557
+ runner_params=runner_params,
558
+ secret_reader=secret_reader,
559
+ log_cached_log_output=log_cached_log_output,
560
+ )
561
+ else:
562
+ runner(**runner_params)
563
+
564
+
565
+ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
566
+ desired_state = _fetch_desired_state_data_source()
567
+ for a in desired_state.accounts:
568
+ a.deletion_approvals = []
569
+ return desired_state.dict(by_alias=True)
570
+
571
+
572
+ def desired_state_shard_config() -> DesiredStateShardConfig:
573
+ return DesiredStateShardConfig(
574
+ shard_arg_name="account_name",
575
+ shard_path_selectors={
576
+ "accounts[*].name",
577
+ "clusters[*].peering.connections[*].account.name",
578
+ },
579
+ sharded_run_review=lambda proposal: len(proposal.proposed_shards) <= 2,
580
+ )