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,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
+ )