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
reconcile/cli.py CHANGED
@@ -1,3 +1,4 @@
1
+ # ruff: noqa: PLC0415 - `import` should be at the top-level of a file
1
2
  import faulthandler
2
3
  import json
3
4
  import logging
@@ -5,12 +6,13 @@ import os
5
6
  import re
6
7
  import sys
7
8
  import traceback
9
+ from collections.abc import Iterable
8
10
  from signal import SIGUSR1
9
11
  from types import ModuleType
10
- from typing import Optional
11
12
 
12
13
  import click
13
14
  import sentry_sdk
15
+ from sentry_sdk.integrations.logging import LoggingIntegration
14
16
 
15
17
  from reconcile.status import (
16
18
  ExitCodes,
@@ -18,16 +20,21 @@ from reconcile.status import (
18
20
  )
19
21
  from reconcile.utils import gql
20
22
  from reconcile.utils.aggregated_list import RunnerException
23
+ from reconcile.utils.amtool import AMTOOL_VERSION, AMTOOL_VERSION_REGEX
21
24
  from reconcile.utils.binary import (
22
25
  binary,
23
26
  binary_version,
24
27
  )
25
28
  from reconcile.utils.exceptions import PrintToFileInGitRepositoryError
26
29
  from reconcile.utils.git import is_file_in_git_repo
30
+ from reconcile.utils.gql import GqlApiSingleton
31
+ from reconcile.utils.promtool import PROMTOOL_VERSION, PROMTOOL_VERSION_REGEX
27
32
  from reconcile.utils.runtime.environment import init_env
28
33
  from reconcile.utils.runtime.integration import (
29
34
  ModuleArgsKwargsRunParams,
30
35
  ModuleBasedQontractReconcileIntegration,
36
+ NoParams,
37
+ PydanticRunParams,
31
38
  QontractReconcileIntegration,
32
39
  )
33
40
  from reconcile.utils.runtime.meta import IntegrationMeta
@@ -37,12 +44,15 @@ from reconcile.utils.runtime.runner import (
37
44
  )
38
45
  from reconcile.utils.unleash import get_feature_toggle_state
39
46
 
40
- TERRAFORM_VERSION = "0.13.7"
47
+ TERRAFORM_VERSION = ["1.6.6"]
41
48
  TERRAFORM_VERSION_REGEX = r"^Terraform\sv([\d]+\.[\d]+\.[\d]+)$"
42
49
 
43
- OC_VERSION = "4.10.15"
50
+ OC_VERSIONS = ["4.12.46", "4.10.15"]
44
51
  OC_VERSION_REGEX = r"^Client\sVersion:\s([\d]+\.[\d]+\.[\d]+)$"
45
52
 
53
+ HELM_VERSIONS = ["3.11.1"]
54
+ HELM_VERSION_REGEX = r"^version.BuildInfo{Version:\"v([\d]+\.[\d]+\.[\d]+)\".*$"
55
+
46
56
 
47
57
  def before_breadcrumb(crumb, hint):
48
58
  # https://docs.sentry.io/platforms/python/configuration/filtering/
@@ -60,8 +70,22 @@ def before_breadcrumb(crumb, hint):
60
70
 
61
71
  # Enable Sentry
62
72
  if os.getenv("SENTRY_DSN"):
63
- sentry_sdk.init( # type: ignore[abstract] # pylint: disable=abstract-class-instantiated
64
- os.environ["SENTRY_DSN"], before_breadcrumb=before_breadcrumb
73
+ match os.environ.get("SENTRY_EVENT_LEVEL", "CRITICAL").upper():
74
+ case "CRITICAL":
75
+ sentry_event_level = logging.CRITICAL
76
+ case "ERROR":
77
+ sentry_event_level = logging.ERROR
78
+ case _:
79
+ raise ValueError(
80
+ "Invalid value for SENTRY_EVENT_LEVEL. Must be CRITICAL or ERROR."
81
+ )
82
+
83
+ sentry_sdk.init(
84
+ os.environ["SENTRY_DSN"],
85
+ before_breadcrumb=before_breadcrumb,
86
+ integrations=[
87
+ LoggingIntegration(event_level=sentry_event_level),
88
+ ],
65
89
  )
66
90
 
67
91
 
@@ -292,8 +316,23 @@ def vault_throughput_path(function):
292
316
 
293
317
 
294
318
  def cluster_name(function):
319
+ """This option can be used when more than one cluster needs to be passed as argument"""
320
+ function = click.option(
321
+ "--cluster-name",
322
+ default=None,
323
+ multiple=True,
324
+ help="openshift cluster names to act on i.e.: --cluster-name cluster-1 --cluster-name cluster-2",
325
+ )(function)
326
+
327
+ return function
328
+
329
+
330
+ def exclude_cluster(function):
295
331
  function = click.option(
296
- "--cluster-name", help="cluster name to act on.", default=None
332
+ "--exclude-cluster",
333
+ multiple=True,
334
+ help="openshift cluster names to remove from execution when in dry-run",
335
+ default=[],
297
336
  )(function)
298
337
 
299
338
  return function
@@ -362,6 +401,29 @@ def exclude_aws_accounts(function):
362
401
  return function
363
402
 
364
403
 
404
+ def org_id_multiple(function):
405
+ """This option can be used when more than one OCM organization ID needs to be passed as argument"""
406
+ function = click.option(
407
+ "--org-id",
408
+ default=None,
409
+ multiple=True,
410
+ help="OCM organization IDs to act on",
411
+ )(function)
412
+
413
+ return function
414
+
415
+
416
+ def exclude_org_id(function):
417
+ function = click.option(
418
+ "--exclude-org-id",
419
+ multiple=True,
420
+ help="OCM organization to exclude from execution when in dry-run",
421
+ default=[],
422
+ )(function)
423
+
424
+ return function
425
+
426
+
365
427
  def workspace_name(function):
366
428
  function = click.option(
367
429
  "--workspace-name", help="slack workspace name to act on.", default=None
@@ -445,6 +507,50 @@ def include_trigger_trace(function):
445
507
  return function
446
508
 
447
509
 
510
+ def trigger_reason(function):
511
+ function = click.option(
512
+ "--trigger-reason",
513
+ help="reason deployment was triggered.",
514
+ default=None,
515
+ )(function)
516
+
517
+ return function
518
+
519
+
520
+ def trigger_integration(function):
521
+ function = click.option(
522
+ "--trigger-integration",
523
+ help="integration deployment was triggered.",
524
+ default=None,
525
+ )(function)
526
+
527
+ return function
528
+
529
+
530
+ def enable_extended_early_exit(function):
531
+ return click.option(
532
+ "--enable-extended-early-exit/--no-enable-extended-early-exit",
533
+ default=False,
534
+ help="enable extended early exit.",
535
+ )(function)
536
+
537
+
538
+ def extended_early_exit_cache_ttl_seconds(function):
539
+ return click.option(
540
+ "--extended-early-exit-cache-ttl-seconds",
541
+ default=3600,
542
+ help="TTL of extended early exit cache in seconds.",
543
+ )(function)
544
+
545
+
546
+ def log_cached_log_output(function):
547
+ return click.option(
548
+ "--log-cached-log-output/--no-log-cached-log-output",
549
+ default=False,
550
+ help="log the cached log output.",
551
+ )(function)
552
+
553
+
448
554
  def register_faulthandler(fileobj=sys.__stderr__):
449
555
  if fileobj:
450
556
  if not faulthandler.is_enabled():
@@ -526,7 +632,7 @@ def run_class_integration(
526
632
  finally:
527
633
  if dump_schemas_file:
528
634
  gqlapi = gql.get_api()
529
- with open(dump_schemas_file, "w") as f:
635
+ with open(dump_schemas_file, "w", encoding="locale") as f:
530
636
  f.write(json.dumps(gqlapi.get_queried_schemas()))
531
637
 
532
638
 
@@ -558,6 +664,7 @@ def integration(
558
664
  init_env(
559
665
  log_level=log_level,
560
666
  config_file=configfile,
667
+ dry_run=dry_run,
561
668
  # don't print gql url in dry-run mode - less noisy PR check logs and
562
669
  # the actual SHA is not that important during PR checks
563
670
  print_gql_url=(not dry_run and bool(gql_url_print)),
@@ -572,6 +679,22 @@ def integration(
572
679
  ctx.obj["dump_schemas_file"] = dump_schemas_file
573
680
 
574
681
 
682
+ @integration.result_callback()
683
+ def exit_integration(
684
+ ctx,
685
+ configfile,
686
+ dry_run,
687
+ early_exit_compare_sha,
688
+ check_only_affected_shards,
689
+ validate_schemas,
690
+ dump_schemas_file,
691
+ log_level,
692
+ gql_sha_url,
693
+ gql_url_print,
694
+ ):
695
+ GqlApiSingleton.close()
696
+
697
+
575
698
  @integration.command(short_help="Manage AWS Route53 resources using Terraform.")
576
699
  @print_to_file
577
700
  @threaded()
@@ -595,6 +718,64 @@ def terraform_aws_route53(
595
718
  )
596
719
 
597
720
 
721
+ @integration.command(short_help="Manage the SAML IDP config for all AWS accounts.")
722
+ @print_to_file
723
+ @threaded()
724
+ @binary(["terraform", "git"])
725
+ @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
726
+ @enable_deletion(default=True)
727
+ @account_name
728
+ @click.option(
729
+ "--saml-idp-name",
730
+ help="Name of the SAML IDP. Must match the name the SAML response!",
731
+ required=True,
732
+ default="RedHatInternal",
733
+ )
734
+ @click.option(
735
+ "--saml-metadata-url",
736
+ help="URL of the SAML metadata xml file. Must be a valid URL!",
737
+ required=True,
738
+ default="https://auth.redhat.com/auth/realms/EmployeeIDP/protocol/saml/descriptor",
739
+ )
740
+ @enable_extended_early_exit
741
+ @extended_early_exit_cache_ttl_seconds
742
+ @log_cached_log_output
743
+ @click.pass_context
744
+ def aws_saml_idp(
745
+ ctx,
746
+ print_to_file,
747
+ enable_deletion,
748
+ thread_pool_size,
749
+ account_name,
750
+ saml_idp_name,
751
+ saml_metadata_url,
752
+ enable_extended_early_exit,
753
+ extended_early_exit_cache_ttl_seconds,
754
+ log_cached_log_output,
755
+ ):
756
+ from reconcile.aws_saml_idp.integration import (
757
+ AwsSamlIdpIntegration,
758
+ AwsSamlIdpIntegrationParams,
759
+ )
760
+
761
+ run_class_integration(
762
+ integration=AwsSamlIdpIntegration(
763
+ AwsSamlIdpIntegrationParams(
764
+ thread_pool_size=thread_pool_size,
765
+ print_to_file=print_to_file,
766
+ enable_deletion=enable_deletion,
767
+ saml_idp_name=saml_idp_name,
768
+ saml_metadata_url=saml_metadata_url,
769
+ account_name=account_name,
770
+ enable_extended_early_exit=enable_extended_early_exit,
771
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
772
+ log_cached_log_output=log_cached_log_output,
773
+ )
774
+ ),
775
+ ctx=ctx.obj,
776
+ )
777
+
778
+
598
779
  @integration.command(short_help="Configures the teams and members in a GitHub org.")
599
780
  @click.pass_context
600
781
  def github(ctx):
@@ -630,22 +811,6 @@ def github_users(ctx, gitlab_project_id, thread_pool_size, enable_deletion, send
630
811
  )
631
812
 
632
813
 
633
- @integration.command(
634
- short_help="Scan GitHub repositories for leaked keys "
635
- "and remove them (only submits PR)."
636
- )
637
- @gitlab_project_id
638
- @threaded()
639
- @binary(["git", "git-secrets"])
640
- @click.pass_context
641
- def github_scanner(ctx, gitlab_project_id, thread_pool_size):
642
- import reconcile.github_scanner
643
-
644
- run_integration(
645
- reconcile.github_scanner, ctx.obj, gitlab_project_id, thread_pool_size
646
- )
647
-
648
-
649
814
  @integration.command(short_help="Validates GitHub organization settings.")
650
815
  @click.pass_context
651
816
  def github_validator(ctx):
@@ -657,7 +822,7 @@ def github_validator(ctx):
657
822
  @integration.command(short_help="Configures ClusterRolebindings in OpenShift clusters.")
658
823
  @threaded()
659
824
  @binary(["oc", "ssh"])
660
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
825
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
661
826
  @internal()
662
827
  @use_jump_host()
663
828
  @click.pass_context
@@ -676,7 +841,7 @@ def openshift_clusterrolebindings(ctx, thread_pool_size, internal, use_jump_host
676
841
  @integration.command(short_help="Configures Rolebindings in OpenShift clusters.")
677
842
  @threaded()
678
843
  @binary(["oc", "ssh"])
679
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
844
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
680
845
  @internal()
681
846
  @use_jump_host()
682
847
  @click.pass_context
@@ -695,7 +860,7 @@ def openshift_rolebindings(ctx, thread_pool_size, internal, use_jump_host):
695
860
  @integration.command(short_help="Manages OpenShift Groups.")
696
861
  @threaded()
697
862
  @binary(["oc", "ssh"])
698
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
863
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
699
864
  @internal()
700
865
  @use_jump_host()
701
866
  @click.pass_context
@@ -710,7 +875,7 @@ def openshift_groups(ctx, thread_pool_size, internal, use_jump_host):
710
875
  @integration.command(short_help="Deletion of users from OpenShift clusters.")
711
876
  @threaded()
712
877
  @binary(["oc", "ssh"])
713
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
878
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
714
879
  @internal()
715
880
  @use_jump_host()
716
881
  @click.pass_context
@@ -727,7 +892,7 @@ def openshift_users(ctx, thread_pool_size, internal, use_jump_host):
727
892
  )
728
893
  @threaded()
729
894
  @binary(["oc", "ssh"])
730
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
895
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
731
896
  @internal()
732
897
  @use_jump_host()
733
898
  @vault_output_path
@@ -747,20 +912,186 @@ def openshift_serviceaccount_tokens(
747
912
  )
748
913
 
749
914
 
750
- @integration.command(short_help="Manage Jenkins roles association via REST API.")
915
+ @integration.command(
916
+ short_help="Manage the SAML IAM roles for all AWS accounts with SSO enabled."
917
+ )
918
+ @print_to_file
919
+ @threaded()
920
+ @binary(["terraform", "git"])
921
+ @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
922
+ @enable_deletion(default=True)
923
+ @account_name
924
+ @click.option(
925
+ "--saml-idp-name",
926
+ help="Name of the SAML IDP. Must match the name the SAML response!",
927
+ required=True,
928
+ default="RedHatInternal",
929
+ )
930
+ @click.option(
931
+ "--max-session-duration-hours",
932
+ help="Maximum session duration (in hours) that you want to set for the specified role",
933
+ required=True,
934
+ default=6,
935
+ )
936
+ @enable_extended_early_exit
937
+ @extended_early_exit_cache_ttl_seconds
938
+ @log_cached_log_output
751
939
  @click.pass_context
752
- def jenkins_roles(ctx):
753
- import reconcile.jenkins_roles
940
+ def aws_saml_roles(
941
+ ctx,
942
+ print_to_file,
943
+ enable_deletion,
944
+ thread_pool_size,
945
+ account_name,
946
+ saml_idp_name,
947
+ max_session_duration_hours,
948
+ enable_extended_early_exit,
949
+ extended_early_exit_cache_ttl_seconds,
950
+ log_cached_log_output,
951
+ ):
952
+ from reconcile.aws_saml_roles.integration import (
953
+ AwsSamlRolesIntegration,
954
+ AwsSamlRolesIntegrationParams,
955
+ )
754
956
 
755
- run_integration(reconcile.jenkins_roles, ctx.obj)
957
+ run_class_integration(
958
+ integration=AwsSamlRolesIntegration(
959
+ AwsSamlRolesIntegrationParams(
960
+ thread_pool_size=thread_pool_size,
961
+ print_to_file=print_to_file,
962
+ enable_deletion=enable_deletion,
963
+ saml_idp_name=saml_idp_name,
964
+ max_session_duration_hours=max_session_duration_hours,
965
+ account_name=account_name,
966
+ enable_extended_early_exit=enable_extended_early_exit,
967
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
968
+ log_cached_log_output=log_cached_log_output,
969
+ )
970
+ ),
971
+ ctx=ctx.obj,
972
+ )
973
+
974
+
975
+ @integration.command(short_help="Create and manage AWS accounts.")
976
+ @account_name
977
+ @click.option(
978
+ "--flavor",
979
+ help="Flavor of the AWS account manager.",
980
+ required=True,
981
+ default="app-interface-commercial",
982
+ )
983
+ @click.option(
984
+ "--tag",
985
+ "-t",
986
+ type=(str, str),
987
+ multiple=True,
988
+ default=[("managed-by", "app-interface")],
989
+ )
990
+ @click.option(
991
+ "--initial-user-name",
992
+ help="The name of the initial user to be created in the account.",
993
+ required=True,
994
+ default="terraform",
995
+ )
996
+ @click.option(
997
+ "--initial-user-policy-arn",
998
+ help="The ARN of the policy that is attached to the initial user.",
999
+ required=True,
1000
+ default="arn:aws:iam::aws:policy/AdministratorAccess",
1001
+ )
1002
+ @click.option(
1003
+ "--initial-user-secret-vault-path",
1004
+ help="The path in Vault to store the initial user secret. Python format string with access to 'account_name' attribute.",
1005
+ required=True,
1006
+ default="app-sre-v2/creds/terraform/{account_name}/config", # noqa: RUF027
1007
+ )
1008
+ @click.option(
1009
+ "--account-tmpl-resource",
1010
+ help="Resource name of the account template-collection template in the app-interface.",
1011
+ required=True,
1012
+ default="/aws-account-manager/account-tmpl.yml",
1013
+ )
1014
+ @click.option(
1015
+ "--template-collection-root-path",
1016
+ help="File path to the root directory to store new account template-collections.",
1017
+ required=True,
1018
+ default="data/templating/collections/aws-account",
1019
+ )
1020
+ @click.pass_context
1021
+ def aws_account_manager(
1022
+ ctx,
1023
+ account_name,
1024
+ flavor,
1025
+ tag,
1026
+ initial_user_name,
1027
+ initial_user_policy_arn,
1028
+ initial_user_secret_vault_path,
1029
+ account_tmpl_resource,
1030
+ template_collection_root_path,
1031
+ ):
1032
+ from reconcile.aws_account_manager.integration import (
1033
+ AwsAccountMgmtIntegration,
1034
+ AwsAccountMgmtIntegrationParams,
1035
+ )
1036
+
1037
+ run_class_integration(
1038
+ integration=AwsAccountMgmtIntegration(
1039
+ AwsAccountMgmtIntegrationParams(
1040
+ account_name=account_name,
1041
+ flavor=flavor,
1042
+ default_tags=dict(tag),
1043
+ initial_user_name=initial_user_name,
1044
+ initial_user_policy_arn=initial_user_policy_arn,
1045
+ initial_user_secret_vault_path=initial_user_secret_vault_path,
1046
+ account_tmpl_resource=account_tmpl_resource,
1047
+ template_collection_root_path=template_collection_root_path,
1048
+ )
1049
+ ),
1050
+ ctx=ctx.obj,
1051
+ )
1052
+
1053
+
1054
+ @integration.command(short_help="Initialize AWS accounts for Terraform usage.")
1055
+ @account_name
1056
+ @click.option(
1057
+ "--state-tmpl-resource",
1058
+ help="Resource name of the state template-collection template in the app-interface.",
1059
+ required=True,
1060
+ default="/terraform-init/terraform-state.yml",
1061
+ )
1062
+ @click.option(
1063
+ "--template-collection-root-path",
1064
+ help="File path to the root directory to store new state template-collections.",
1065
+ required=True,
1066
+ default="data/templating/collections/terraform-init",
1067
+ )
1068
+ @click.pass_context
1069
+ def terraform_init(
1070
+ ctx, account_name, state_tmpl_resource, template_collection_root_path
1071
+ ):
1072
+ from reconcile.terraform_init.integration import (
1073
+ TerraformInitIntegration,
1074
+ TerraformInitIntegrationParams,
1075
+ )
1076
+
1077
+ run_class_integration(
1078
+ integration=TerraformInitIntegration(
1079
+ TerraformInitIntegrationParams(
1080
+ account_name=account_name,
1081
+ state_tmpl_resource=state_tmpl_resource,
1082
+ template_collection_root_path=template_collection_root_path,
1083
+ )
1084
+ ),
1085
+ ctx=ctx.obj,
1086
+ )
756
1087
 
757
1088
 
758
- @integration.command(short_help="Manage Jenkins plugins installation via REST API.")
1089
+ @integration.command(short_help="Manage Jenkins roles association via REST API.")
759
1090
  @click.pass_context
760
- def jenkins_plugins(ctx):
761
- import reconcile.jenkins_plugins
1091
+ def jenkins_roles(ctx):
1092
+ import reconcile.jenkins_roles
762
1093
 
763
- run_integration(reconcile.jenkins_plugins, ctx.obj)
1094
+ run_integration(reconcile.jenkins_roles, ctx.obj)
764
1095
 
765
1096
 
766
1097
  @integration.command(short_help="Manage Jenkins worker fleets via JCasC.")
@@ -826,29 +1157,41 @@ def jenkins_webhooks_cleaner(ctx):
826
1157
  run_integration(reconcile.jenkins_webhooks_cleaner, ctx.obj)
827
1158
 
828
1159
 
829
- @integration.command(short_help="Watch for changes in Jira boards and notify on Slack.")
1160
+ @integration.command(short_help="Validate permissions in Jira.")
1161
+ @enable_extended_early_exit
1162
+ @extended_early_exit_cache_ttl_seconds
1163
+ @log_cached_log_output
830
1164
  @click.pass_context
831
- def jira_watcher(ctx):
832
- import reconcile.jira_watcher
1165
+ def jira_permissions_validator(
1166
+ ctx,
1167
+ enable_extended_early_exit,
1168
+ extended_early_exit_cache_ttl_seconds,
1169
+ log_cached_log_output,
1170
+ ):
1171
+ import reconcile.jira_permissions_validator
833
1172
 
834
- run_integration(reconcile.jira_watcher, ctx.obj)
1173
+ run_integration(
1174
+ reconcile.jira_permissions_validator,
1175
+ ctx.obj,
1176
+ enable_extended_early_exit=enable_extended_early_exit,
1177
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
1178
+ log_cached_log_output=log_cached_log_output,
1179
+ )
835
1180
 
836
1181
 
837
- @integration.command(
838
- short_help="Watch for changes in Unleah feature toggles " "and notify on Slack."
839
- )
1182
+ @integration.command(short_help="Watch for changes in Jira boards and notify on Slack.")
840
1183
  @click.pass_context
841
- def unleash_watcher(ctx):
842
- import reconcile.unleash_watcher
1184
+ def jira_watcher(ctx):
1185
+ import reconcile.jira_watcher
843
1186
 
844
- run_integration(reconcile.unleash_watcher, ctx.obj)
1187
+ run_integration(reconcile.jira_watcher, ctx.obj)
845
1188
 
846
1189
 
847
1190
  @integration.command(
848
1191
  short_help="Watches for OpenShift upgrades and sends notifications."
849
1192
  )
850
1193
  @binary(["oc", "ssh"])
851
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1194
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
852
1195
  @threaded()
853
1196
  @internal()
854
1197
  @use_jump_host()
@@ -868,8 +1211,18 @@ def openshift_upgrade_watcher(ctx, thread_pool_size, internal, use_jump_host):
868
1211
  @integration.command(short_help="Manage Slack User Groups (channels and users).")
869
1212
  @workspace_name
870
1213
  @usergroup_name
1214
+ @enable_extended_early_exit
1215
+ @extended_early_exit_cache_ttl_seconds
1216
+ @log_cached_log_output
871
1217
  @click.pass_context
872
- def slack_usergroups(ctx, workspace_name, usergroup_name):
1218
+ def slack_usergroups(
1219
+ ctx,
1220
+ workspace_name,
1221
+ usergroup_name,
1222
+ enable_extended_early_exit,
1223
+ extended_early_exit_cache_ttl_seconds,
1224
+ log_cached_log_output,
1225
+ ):
873
1226
  import reconcile.slack_usergroups
874
1227
 
875
1228
  run_integration(
@@ -877,17 +1230,12 @@ def slack_usergroups(ctx, workspace_name, usergroup_name):
877
1230
  ctx.obj,
878
1231
  workspace_name,
879
1232
  usergroup_name,
1233
+ enable_extended_early_exit,
1234
+ extended_early_exit_cache_ttl_seconds,
1235
+ log_cached_log_output,
880
1236
  )
881
1237
 
882
1238
 
883
- @integration.command(short_help="Manage integrations on GitLab projects.")
884
- @click.pass_context
885
- def gitlab_integrations(ctx):
886
- import reconcile.gitlab_integrations
887
-
888
- run_integration(reconcile.gitlab_integrations, ctx.obj)
889
-
890
-
891
1239
  @integration.command(short_help="Manage permissions on GitLab projects.")
892
1240
  @threaded()
893
1241
  @click.pass_context
@@ -956,6 +1304,26 @@ def aws_ami_share(ctx):
956
1304
  run_integration(reconcile.aws_ami_share, ctx.obj)
957
1305
 
958
1306
 
1307
+ @integration.command(short_help="Cleanup old and unused AMIs.")
1308
+ @threaded()
1309
+ @click.pass_context
1310
+ def aws_ami_cleanup(ctx, thread_pool_size):
1311
+ import reconcile.aws_ami_cleanup.integration
1312
+
1313
+ run_integration(reconcile.aws_ami_cleanup.integration, ctx.obj, thread_pool_size)
1314
+
1315
+
1316
+ @integration.command(short_help="Set up retention period for Cloudwatch logs.")
1317
+ @threaded()
1318
+ @click.pass_context
1319
+ def aws_cloudwatch_log_retention(ctx, thread_pool_size):
1320
+ import reconcile.aws_cloudwatch_log_retention.integration
1321
+
1322
+ run_integration(
1323
+ reconcile.aws_cloudwatch_log_retention.integration, ctx.obj, thread_pool_size
1324
+ )
1325
+
1326
+
959
1327
  @integration.command(
960
1328
  short_help="Generate AWS ECR image pull secrets and store them in Vault."
961
1329
  )
@@ -983,16 +1351,24 @@ def aws_support_cases_sos(ctx, gitlab_project_id, thread_pool_size):
983
1351
 
984
1352
 
985
1353
  @integration.command(short_help="Manages OpenShift Resources.")
986
- @threaded(default=20)
1354
+ @threaded()
987
1355
  @binary(["oc", "ssh", "amtool"])
988
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1356
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1357
+ @binary_version("amtool", ["--version"], AMTOOL_VERSION_REGEX, AMTOOL_VERSION)
989
1358
  @internal()
990
1359
  @use_jump_host()
991
1360
  @cluster_name
1361
+ @exclude_cluster
992
1362
  @namespace_name
993
1363
  @click.pass_context
994
1364
  def openshift_resources(
995
- ctx, thread_pool_size, internal, use_jump_host, cluster_name, namespace_name
1365
+ ctx,
1366
+ thread_pool_size,
1367
+ internal,
1368
+ use_jump_host,
1369
+ cluster_name,
1370
+ exclude_cluster,
1371
+ namespace_name,
996
1372
  ):
997
1373
  import reconcile.openshift_resources
998
1374
 
@@ -1003,19 +1379,22 @@ def openshift_resources(
1003
1379
  internal,
1004
1380
  use_jump_host,
1005
1381
  cluster_name=cluster_name,
1382
+ exclude_cluster=exclude_cluster,
1006
1383
  namespace_name=namespace_name,
1007
1384
  )
1008
1385
 
1009
1386
 
1010
1387
  @integration.command(short_help="Manage OpenShift resources defined in Saas files.")
1011
- @gitlab_project_id
1012
1388
  @threaded()
1013
1389
  @throughput
1014
1390
  @use_jump_host()
1015
1391
  @binary(["oc", "ssh"])
1016
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1392
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1393
+ @binary_version("helm", ["version"], HELM_VERSION_REGEX, HELM_VERSIONS)
1017
1394
  @click.option("--saas-file-name", default=None, help="saas-file to act on.")
1018
1395
  @click.option("--env-name", default=None, help="environment to deploy to.")
1396
+ @trigger_integration
1397
+ @trigger_reason
1019
1398
  @click.pass_context
1020
1399
  def openshift_saas_deploy(
1021
1400
  ctx,
@@ -1024,7 +1403,8 @@ def openshift_saas_deploy(
1024
1403
  use_jump_host,
1025
1404
  saas_file_name,
1026
1405
  env_name,
1027
- gitlab_project_id,
1406
+ trigger_integration,
1407
+ trigger_reason,
1028
1408
  ):
1029
1409
  import reconcile.openshift_saas_deploy
1030
1410
 
@@ -1036,7 +1416,8 @@ def openshift_saas_deploy(
1036
1416
  use_jump_host=use_jump_host,
1037
1417
  saas_file_name=saas_file_name,
1038
1418
  env_name=env_name,
1039
- gitlab_project_id=gitlab_project_id,
1419
+ trigger_integration=trigger_integration,
1420
+ trigger_reason=trigger_reason,
1040
1421
  )
1041
1422
 
1042
1423
 
@@ -1051,7 +1432,7 @@ def openshift_saas_deploy(
1051
1432
  help="bundle sha to compare to to find changes",
1052
1433
  )
1053
1434
  @binary(["oc", "ssh"])
1054
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1435
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1055
1436
  @use_jump_host()
1056
1437
  @click.pass_context
1057
1438
  def openshift_saas_deploy_change_tester(
@@ -1086,7 +1467,7 @@ def saas_file_validator(ctx):
1086
1467
  @integration.command(short_help="Trigger deployments when a commit changed for a ref.")
1087
1468
  @threaded()
1088
1469
  @binary(["oc", "ssh"])
1089
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1470
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1090
1471
  @internal()
1091
1472
  @use_jump_host()
1092
1473
  @include_trigger_trace
@@ -1109,7 +1490,7 @@ def openshift_saas_deploy_trigger_moving_commits(
1109
1490
  @integration.command(short_help="Trigger deployments when upstream job runs.")
1110
1491
  @threaded()
1111
1492
  @binary(["oc", "ssh"])
1112
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1493
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1113
1494
  @internal()
1114
1495
  @use_jump_host()
1115
1496
  @include_trigger_trace
@@ -1132,7 +1513,7 @@ def openshift_saas_deploy_trigger_upstream_jobs(
1132
1513
  @integration.command(short_help="Trigger deployments when images are pushed.")
1133
1514
  @threaded()
1134
1515
  @binary(["oc", "ssh"])
1135
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1516
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1136
1517
  @internal()
1137
1518
  @use_jump_host()
1138
1519
  @include_trigger_trace
@@ -1155,7 +1536,7 @@ def openshift_saas_deploy_trigger_images(
1155
1536
  @integration.command(short_help="Trigger deployments when configuration changes.")
1156
1537
  @threaded()
1157
1538
  @binary(["oc", "ssh"])
1158
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1539
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1159
1540
  @internal()
1160
1541
  @use_jump_host()
1161
1542
  @include_trigger_trace
@@ -1178,7 +1559,7 @@ def openshift_saas_deploy_trigger_configs(
1178
1559
  @integration.command(short_help="Clean up deployment related resources.")
1179
1560
  @threaded()
1180
1561
  @binary(["oc", "ssh"])
1181
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1562
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1182
1563
  @internal()
1183
1564
  @use_jump_host()
1184
1565
  @click.pass_context
@@ -1237,7 +1618,7 @@ def gitlab_labeler(ctx, gitlab_project_id, gitlab_merge_request_id):
1237
1618
  @integration.command(short_help="Manages labels on OpenShift namespaces.")
1238
1619
  @threaded()
1239
1620
  @binary(["oc", "ssh"])
1240
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1621
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1241
1622
  @internal()
1242
1623
  @use_jump_host()
1243
1624
  @click.pass_context
@@ -1256,7 +1637,7 @@ def openshift_namespace_labels(ctx, thread_pool_size, internal, use_jump_host):
1256
1637
  @integration.command(short_help="Manages OpenShift Namespaces.")
1257
1638
  @threaded()
1258
1639
  @binary(["oc", "ssh"])
1259
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1640
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1260
1641
  @internal()
1261
1642
  @use_jump_host()
1262
1643
  @cluster_name
@@ -1281,7 +1662,7 @@ def openshift_namespaces(
1281
1662
  @integration.command(short_help="Manages OpenShift NetworkPolicies.")
1282
1663
  @threaded()
1283
1664
  @binary(["oc", "ssh"])
1284
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1665
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1285
1666
  @internal()
1286
1667
  @use_jump_host()
1287
1668
  @click.pass_context
@@ -1301,7 +1682,7 @@ def openshift_network_policies(ctx, thread_pool_size, internal, use_jump_host):
1301
1682
  @threaded()
1302
1683
  @take_over()
1303
1684
  @binary(["oc", "ssh"])
1304
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1685
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1305
1686
  @internal()
1306
1687
  @use_jump_host()
1307
1688
  @click.pass_context
@@ -1322,7 +1703,7 @@ def openshift_limitranges(ctx, thread_pool_size, internal, use_jump_host, take_o
1322
1703
  @threaded()
1323
1704
  @take_over()
1324
1705
  @binary(["oc", "ssh"])
1325
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1706
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1326
1707
  @internal()
1327
1708
  @use_jump_host()
1328
1709
  @click.pass_context
@@ -1342,7 +1723,7 @@ def openshift_resourcequotas(ctx, thread_pool_size, internal, use_jump_host, tak
1342
1723
  @integration.command(short_help="Manages OpenShift Secrets from Vault.")
1343
1724
  @threaded()
1344
1725
  @binary(["oc", "ssh"])
1345
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1726
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1346
1727
  @internal()
1347
1728
  @use_jump_host()
1348
1729
  @cluster_name
@@ -1367,7 +1748,7 @@ def openshift_vault_secrets(
1367
1748
  @integration.command(short_help="Manages OpenShift Routes.")
1368
1749
  @threaded()
1369
1750
  @binary(["oc", "ssh"])
1370
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
1751
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1371
1752
  @internal()
1372
1753
  @use_jump_host()
1373
1754
  @cluster_name
@@ -1389,19 +1770,96 @@ def openshift_routes(
1389
1770
  )
1390
1771
 
1391
1772
 
1392
- @integration.command(short_help="Configures the teams and members in Quay.")
1773
+ @integration.command(short_help="Manages OpenShift Prometheus Rules.")
1774
+ @threaded()
1775
+ @binary(["oc", "ssh"])
1776
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1777
+ @internal()
1778
+ @use_jump_host()
1779
+ @cluster_name
1780
+ @namespace_name
1393
1781
  @click.pass_context
1394
- def quay_membership(ctx):
1395
- import reconcile.quay_membership
1782
+ def openshift_prometheus_rules(
1783
+ ctx, thread_pool_size, internal, use_jump_host, cluster_name, namespace_name
1784
+ ):
1785
+ import reconcile.openshift_prometheus_rules
1396
1786
 
1397
- run_integration(reconcile.quay_membership, ctx.obj)
1787
+ run_integration(
1788
+ reconcile.openshift_prometheus_rules,
1789
+ ctx.obj,
1790
+ thread_pool_size,
1791
+ internal,
1792
+ use_jump_host,
1793
+ cluster_name=cluster_name,
1794
+ namespace_name=namespace_name,
1795
+ )
1398
1796
 
1399
1797
 
1400
- @integration.command(
1401
- short_help="Mirrors external images into Google Container Registry."
1402
- )
1403
- @click.pass_context
1404
- @binary(["skopeo"])
1798
+ @integration.command(short_help="Discover routes and update endpoints")
1799
+ @threaded()
1800
+ @binary(["oc"])
1801
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1802
+ @internal()
1803
+ @use_jump_host()
1804
+ @cluster_name
1805
+ @namespace_name
1806
+ @enable_extended_early_exit
1807
+ @extended_early_exit_cache_ttl_seconds
1808
+ @log_cached_log_output
1809
+ @click.option(
1810
+ "--endpoint-tmpl-resource",
1811
+ help="Resource name of the endpoint template in the app-interface.",
1812
+ required=False,
1813
+ )
1814
+ @click.pass_context
1815
+ def endpoints_discovery(
1816
+ ctx,
1817
+ thread_pool_size,
1818
+ internal,
1819
+ use_jump_host,
1820
+ cluster_name,
1821
+ namespace_name,
1822
+ enable_extended_early_exit,
1823
+ extended_early_exit_cache_ttl_seconds,
1824
+ log_cached_log_output,
1825
+ endpoint_tmpl_resource,
1826
+ ):
1827
+ from reconcile.endpoints_discovery.integration import (
1828
+ EndpointsDiscoveryIntegration,
1829
+ EndpointsDiscoveryIntegrationParams,
1830
+ )
1831
+
1832
+ params = EndpointsDiscoveryIntegrationParams(
1833
+ thread_pool_size=thread_pool_size,
1834
+ internal=internal,
1835
+ use_jump_host=use_jump_host,
1836
+ cluster_name=cluster_name,
1837
+ namespace_name=namespace_name,
1838
+ enable_extended_early_exit=enable_extended_early_exit,
1839
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
1840
+ log_cached_log_output=log_cached_log_output,
1841
+ )
1842
+ if endpoint_tmpl_resource:
1843
+ params.endpoint_tmpl_resource = endpoint_tmpl_resource
1844
+ run_class_integration(
1845
+ integration=EndpointsDiscoveryIntegration(params),
1846
+ ctx=ctx.obj,
1847
+ )
1848
+
1849
+
1850
+ @integration.command(short_help="Configures the teams and members in Quay.")
1851
+ @click.pass_context
1852
+ def quay_membership(ctx):
1853
+ import reconcile.quay_membership
1854
+
1855
+ run_integration(reconcile.quay_membership, ctx.obj)
1856
+
1857
+
1858
+ @integration.command(
1859
+ short_help="Mirrors external images into Google Container Registry."
1860
+ )
1861
+ @click.pass_context
1862
+ @binary(["skopeo"])
1405
1863
  def gcr_mirror(ctx):
1406
1864
  import reconcile.gcr_mirror
1407
1865
 
@@ -1431,14 +1889,27 @@ def gcr_mirror(ctx):
1431
1889
  default=86400,
1432
1890
  )
1433
1891
  @click.option(
1434
- "-i",
1435
- "--image",
1436
- help="Only considers this image to mirror. It can be specified multiple times.",
1892
+ "-r",
1893
+ "--repository-url",
1894
+ help="Only considers this repository to mirror. It can be specified multiple times.",
1895
+ multiple=True,
1896
+ )
1897
+ @click.option(
1898
+ "-e",
1899
+ "--exclude-repository-url",
1900
+ help="excludes this repository to mirror. It can be specified multiple times.",
1437
1901
  multiple=True,
1438
1902
  )
1439
1903
  @click.pass_context
1440
1904
  @binary(["skopeo"])
1441
- def quay_mirror(ctx, control_file_dir, compare_tags, compare_tags_interval, image):
1905
+ def quay_mirror(
1906
+ ctx,
1907
+ control_file_dir,
1908
+ compare_tags,
1909
+ compare_tags_interval,
1910
+ repository_url,
1911
+ exclude_repository_url,
1912
+ ):
1442
1913
  import reconcile.quay_mirror
1443
1914
 
1444
1915
  run_integration(
@@ -1447,7 +1918,8 @@ def quay_mirror(ctx, control_file_dir, compare_tags, compare_tags_interval, imag
1447
1918
  control_file_dir,
1448
1919
  compare_tags,
1449
1920
  compare_tags_interval,
1450
- image,
1921
+ repository_url,
1922
+ exclude_repository_url,
1451
1923
  )
1452
1924
 
1453
1925
 
@@ -1533,18 +2005,175 @@ def ldap_users(ctx, infra_project_id, app_interface_project_id):
1533
2005
  )
1534
2006
 
1535
2007
 
2008
+ @integration.command(short_help="Manages LDAP groups based on App-Interface roles.")
2009
+ @click.option(
2010
+ "--aws-sso-namespace",
2011
+ help="Namespace used to store AWS SSO groups.",
2012
+ required=True,
2013
+ default="it-cloud-aws",
2014
+ )
2015
+ @click.pass_context
2016
+ def ldap_groups(ctx, aws_sso_namespace):
2017
+ from reconcile.ldap_groups.integration import (
2018
+ LdapGroupsIntegration,
2019
+ LdapGroupsIntegrationParams,
2020
+ )
2021
+
2022
+ run_class_integration(
2023
+ integration=LdapGroupsIntegration(
2024
+ LdapGroupsIntegrationParams(aws_sso_namespace=aws_sso_namespace)
2025
+ ),
2026
+ ctx=ctx.obj,
2027
+ )
2028
+
2029
+
2030
+ @integration.command(short_help="Sync AWS asset version numbers to App-Interface")
2031
+ @click.option(
2032
+ "--aws-resource-exporter-clusters",
2033
+ help="A comma seperated list of cluster names where aws-resource-exporter is deployed.",
2034
+ required=True,
2035
+ envvar="AVS_AWS_RESOURCE_EXPORTER_CLUSTERS",
2036
+ )
2037
+ @click.option(
2038
+ "--clusters",
2039
+ help="A comma seperated list of cluster names to operator on. If none is specified, all clusters are considered.",
2040
+ required=False,
2041
+ envvar="AVS_CLUSTERS",
2042
+ )
2043
+ @click.option(
2044
+ "--supported-providers",
2045
+ help="A comma seperated list of supported external resource providers to operator on. Default: rds, elasticache",
2046
+ required=False,
2047
+ envvar="AVS_SUPPORTED_PROVIDERS",
2048
+ )
2049
+ @click.option(
2050
+ "--prometheus-timeout",
2051
+ help="Prometheus timeout in seconds. Default: 10",
2052
+ required=False,
2053
+ envvar="AVS_PROMETHEUS_TIMEOUT",
2054
+ )
2055
+ @click.pass_context
2056
+ def aws_version_sync(
2057
+ ctx,
2058
+ aws_resource_exporter_clusters,
2059
+ clusters,
2060
+ supported_providers,
2061
+ prometheus_timeout,
2062
+ ):
2063
+ from reconcile.aws_version_sync.integration import (
2064
+ AVSIntegration,
2065
+ AVSIntegrationParams,
2066
+ )
2067
+
2068
+ run_class_integration(
2069
+ integration=AVSIntegration(
2070
+ AVSIntegrationParams(
2071
+ aws_resource_exporter_clusters=aws_resource_exporter_clusters.split(
2072
+ ","
2073
+ ),
2074
+ supported_providers=supported_providers.split(",")
2075
+ if supported_providers
2076
+ else ["rds", "elasticache"],
2077
+ clusters=clusters.split(",") if clusters else [],
2078
+ prometheus_timeout=int(prometheus_timeout)
2079
+ if prometheus_timeout
2080
+ else 10,
2081
+ )
2082
+ ),
2083
+ ctx=ctx.obj,
2084
+ )
2085
+
2086
+
2087
+ @integration.command(short_help="Manages raw HCL Terraform from a separate repository.")
2088
+ @click.option(
2089
+ "-o",
2090
+ "--output-file",
2091
+ help="Specify where to place the output of the integration",
2092
+ )
2093
+ @click.argument("gitlab-project-id", required=False)
2094
+ @click.argument("gitlab-merge-request-id", required=False)
2095
+ @click.pass_context
2096
+ def terraform_repo(ctx, output_file, gitlab_project_id, gitlab_merge_request_id):
2097
+ from reconcile import terraform_repo
2098
+
2099
+ run_class_integration(
2100
+ integration=terraform_repo.TerraformRepoIntegration(
2101
+ terraform_repo.TerraformRepoIntegrationParams(
2102
+ output_file=output_file,
2103
+ validate_git=True,
2104
+ gitlab_project_id=gitlab_project_id,
2105
+ gitlab_merge_request_id=gitlab_merge_request_id,
2106
+ )
2107
+ ),
2108
+ ctx=ctx.obj,
2109
+ )
2110
+
2111
+
2112
+ @integration.command(short_help="Test app-interface templates.")
2113
+ @click.pass_context
2114
+ def template_validator(ctx):
2115
+ from reconcile.templating import validator
2116
+
2117
+ run_class_integration(
2118
+ integration=validator.TemplateValidatorIntegration(PydanticRunParams()),
2119
+ ctx=ctx.obj,
2120
+ )
2121
+
2122
+
2123
+ @integration.command(short_help="Render datafile templates in app-interface.")
2124
+ @click.option(
2125
+ "--app-interface-data-path",
2126
+ help="Path to data dir in app-interface repo. Use this for local rendering or in MR checks.",
2127
+ required=False,
2128
+ envvar="APP_INTERFACE_DATA_PATH",
2129
+ )
2130
+ @click.option(
2131
+ "--clone-repo",
2132
+ is_flag=True,
2133
+ help="Flag to enable cloning of the app-interface repo. Use this for regular integration run.",
2134
+ default=False,
2135
+ )
2136
+ @click.option(
2137
+ "--template-collection-name",
2138
+ help="specific template collection name to render",
2139
+ required=False,
2140
+ )
2141
+ @click.pass_context
2142
+ def template_renderer(
2143
+ ctx, app_interface_data_path, clone_repo, template_collection_name
2144
+ ):
2145
+ from reconcile.templating.renderer import (
2146
+ TemplateRendererIntegration,
2147
+ TemplateRendererIntegrationParams,
2148
+ )
2149
+
2150
+ run_class_integration(
2151
+ integration=TemplateRendererIntegration(
2152
+ TemplateRendererIntegrationParams(
2153
+ app_interface_data_path=app_interface_data_path,
2154
+ clone_repo=clone_repo,
2155
+ template_collection_name=template_collection_name,
2156
+ )
2157
+ ),
2158
+ ctx=ctx.obj,
2159
+ )
2160
+
2161
+
1536
2162
  @integration.command(short_help="Manage AWS Resources using Terraform.")
1537
2163
  @print_to_file
1538
2164
  @vault_output_path
1539
- @threaded(default=20)
2165
+ @threaded()
1540
2166
  @binary(["terraform", "oc", "git"])
1541
2167
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
1542
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
2168
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
1543
2169
  @internal()
1544
2170
  @use_jump_host()
1545
2171
  @enable_deletion(default=False)
1546
2172
  @account_name_multiple
1547
2173
  @exclude_aws_accounts
2174
+ @enable_extended_early_exit
2175
+ @extended_early_exit_cache_ttl_seconds
2176
+ @log_cached_log_output
1548
2177
  @click.option(
1549
2178
  "--light/--full",
1550
2179
  default=False,
@@ -1562,6 +2191,9 @@ def terraform_resources(
1562
2191
  vault_output_path,
1563
2192
  account_name,
1564
2193
  exclude_accounts,
2194
+ enable_extended_early_exit,
2195
+ extended_early_exit_cache_ttl_seconds,
2196
+ log_cached_log_output,
1565
2197
  ):
1566
2198
  import reconcile.terraform_resources
1567
2199
 
@@ -1579,13 +2211,16 @@ def terraform_resources(
1579
2211
  vault_output_path,
1580
2212
  account_name=account_name,
1581
2213
  exclude_accounts=exclude_accounts,
2214
+ enable_extended_early_exit=enable_extended_early_exit,
2215
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
2216
+ log_cached_log_output=log_cached_log_output,
1582
2217
  )
1583
2218
 
1584
2219
 
1585
2220
  @integration.command(short_help="Manage Cloudflare Resources using Terraform.")
1586
2221
  @print_to_file
1587
2222
  @enable_deletion(default=False)
1588
- @threaded(default=20)
2223
+ @threaded()
1589
2224
  @binary(["terraform"])
1590
2225
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
1591
2226
  @account_name
@@ -1621,7 +2256,7 @@ def terraform_cloudflare_resources(
1621
2256
  @integration.command(short_help="Manage Cloudflare DNS using Terraform.")
1622
2257
  @print_to_file
1623
2258
  @enable_deletion(default=False)
1624
- @threaded(default=10)
2259
+ @threaded()
1625
2260
  @binary(["terraform"])
1626
2261
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
1627
2262
  @account_name
@@ -1649,7 +2284,7 @@ def terraform_cloudflare_dns(
1649
2284
  @integration.command(short_help="Manage Cloudflare Users using Terraform.")
1650
2285
  @print_to_file
1651
2286
  @binary(["terraform"])
1652
- @threaded(default=20)
2287
+ @threaded()
1653
2288
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
1654
2289
  @account_name
1655
2290
  @enable_deletion(default=True)
@@ -1679,7 +2314,7 @@ def terraform_cloudflare_users(
1679
2314
  short_help="Manage Cloud Resources using Cloud Native Assets (CNA)."
1680
2315
  )
1681
2316
  @enable_deletion(default=False)
1682
- @threaded(default=20)
2317
+ @threaded()
1683
2318
  @click.pass_context
1684
2319
  def cna_resources(
1685
2320
  ctx,
@@ -1697,11 +2332,15 @@ def cna_resources(
1697
2332
 
1698
2333
 
1699
2334
  @integration.command(short_help="Manage auto-promotions defined in SaaS files")
1700
- @threaded(default=10)
2335
+ @threaded()
2336
+ @click.option("--env-name", default=None, help="environment to filter saas files by")
2337
+ @click.option("--app-name", default=None, help="app to filter saas files by.")
1701
2338
  @click.pass_context
1702
2339
  def saas_auto_promotions_manager(
1703
2340
  ctx,
1704
2341
  thread_pool_size,
2342
+ env_name,
2343
+ app_name,
1705
2344
  ):
1706
2345
  import reconcile.saas_auto_promotions_manager.integration
1707
2346
 
@@ -1709,12 +2348,14 @@ def saas_auto_promotions_manager(
1709
2348
  reconcile.saas_auto_promotions_manager.integration,
1710
2349
  ctx.obj,
1711
2350
  thread_pool_size,
2351
+ env_name=env_name,
2352
+ app_name=app_name,
1712
2353
  )
1713
2354
 
1714
2355
 
1715
2356
  @integration.command(short_help="Manage AWS users using Terraform.")
1716
2357
  @print_to_file
1717
- @threaded(default=20)
2358
+ @threaded()
1718
2359
  @binary(["terraform", "gpg", "git"])
1719
2360
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
1720
2361
  @enable_deletion(default=True)
@@ -1744,6 +2385,35 @@ def terraform_users(
1744
2385
  )
1745
2386
 
1746
2387
 
2388
+ @integration.command(short_help="Manage VPC creation")
2389
+ @binary(["terraform"])
2390
+ @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
2391
+ @account_name
2392
+ @print_to_file
2393
+ @threaded()
2394
+ @enable_deletion(default=False)
2395
+ @click.pass_context
2396
+ def terraform_vpc_resources(
2397
+ ctx, account_name, print_to_file, thread_pool_size, enable_deletion
2398
+ ):
2399
+ from reconcile.terraform_vpc_resources.integration import (
2400
+ TerraformVpcResources,
2401
+ TerraformVpcResourcesParams,
2402
+ )
2403
+
2404
+ run_class_integration(
2405
+ TerraformVpcResources(
2406
+ TerraformVpcResourcesParams(
2407
+ account_name=account_name,
2408
+ print_to_file=print_to_file,
2409
+ thread_pool_size=thread_pool_size,
2410
+ enable_deletion=enable_deletion,
2411
+ )
2412
+ ),
2413
+ ctx.obj,
2414
+ )
2415
+
2416
+
1747
2417
  @integration.command(
1748
2418
  short_help="Manage VPC peerings between OSD clusters and AWS accounts or other OSD clusters."
1749
2419
  )
@@ -1753,9 +2423,19 @@ def terraform_users(
1753
2423
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
1754
2424
  @enable_deletion(default=False)
1755
2425
  @account_name
2426
+ @enable_extended_early_exit
2427
+ @extended_early_exit_cache_ttl_seconds
2428
+ @log_cached_log_output
1756
2429
  @click.pass_context
1757
2430
  def terraform_vpc_peerings(
1758
- ctx, print_to_file, enable_deletion, thread_pool_size, account_name
2431
+ ctx,
2432
+ print_to_file,
2433
+ enable_deletion,
2434
+ thread_pool_size,
2435
+ account_name,
2436
+ enable_extended_early_exit,
2437
+ extended_early_exit_cache_ttl_seconds,
2438
+ log_cached_log_output,
1759
2439
  ):
1760
2440
  import reconcile.terraform_vpc_peerings
1761
2441
 
@@ -1768,6 +2448,9 @@ def terraform_vpc_peerings(
1768
2448
  enable_deletion,
1769
2449
  thread_pool_size,
1770
2450
  account_name,
2451
+ enable_extended_early_exit=enable_extended_early_exit,
2452
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
2453
+ log_cached_log_output=log_cached_log_output,
1771
2454
  )
1772
2455
 
1773
2456
 
@@ -1789,9 +2472,22 @@ def vpc_peerings_validator(ctx):
1789
2472
  @threaded()
1790
2473
  @binary(["terraform", "git"])
1791
2474
  @binary_version("terraform", ["version"], TERRAFORM_VERSION_REGEX, TERRAFORM_VERSION)
2475
+ @enable_extended_early_exit
2476
+ @extended_early_exit_cache_ttl_seconds
2477
+ @log_cached_log_output
1792
2478
  @enable_deletion(default=False)
2479
+ @account_name
1793
2480
  @click.pass_context
1794
- def terraform_tgw_attachments(ctx, print_to_file, enable_deletion, thread_pool_size):
2481
+ def terraform_tgw_attachments(
2482
+ ctx,
2483
+ print_to_file,
2484
+ enable_deletion,
2485
+ thread_pool_size,
2486
+ account_name,
2487
+ enable_extended_early_exit,
2488
+ extended_early_exit_cache_ttl_seconds,
2489
+ log_cached_log_output,
2490
+ ):
1795
2491
  import reconcile.terraform_tgw_attachments
1796
2492
 
1797
2493
  if print_to_file and is_file_in_git_repo(print_to_file):
@@ -1802,6 +2498,10 @@ def terraform_tgw_attachments(ctx, print_to_file, enable_deletion, thread_pool_s
1802
2498
  print_to_file,
1803
2499
  enable_deletion,
1804
2500
  thread_pool_size,
2501
+ account_name=account_name,
2502
+ enable_extended_early_exit=enable_extended_early_exit,
2503
+ extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
2504
+ log_cached_log_output=log_cached_log_output,
1805
2505
  )
1806
2506
 
1807
2507
 
@@ -1852,12 +2552,142 @@ def ocm_groups(ctx, thread_pool_size):
1852
2552
  @integration.command(short_help="Manages clusters via OCM.")
1853
2553
  @gitlab_project_id
1854
2554
  @threaded()
2555
+ @click.option(
2556
+ "--job-controller-cluster",
2557
+ help="The cluster holding the job-controller namepsace",
2558
+ required=False,
2559
+ envvar="JOB_CONTROLLER_CLUSTER",
2560
+ )
2561
+ @click.option(
2562
+ "--job-controller-namespace",
2563
+ help="The namespace used for ROSA jobs",
2564
+ required=False,
2565
+ envvar="JOB_CONTROLLER_NAMESPACE",
2566
+ )
2567
+ @click.option(
2568
+ "--rosa-job-service-account",
2569
+ help="The service-account used for ROSA jobs",
2570
+ required=False,
2571
+ envvar="ROSA_JOB_SERVICE_ACCOUNT",
2572
+ )
2573
+ @click.option(
2574
+ "--rosa-job-image",
2575
+ help="The container image to use to run ROSA cli command jobs",
2576
+ required=False,
2577
+ envvar="ROSA_JOB_IMAGE",
2578
+ )
2579
+ @click.option(
2580
+ "--rosa-role",
2581
+ help="The role to assume in the ROSA cluster account",
2582
+ required=False,
2583
+ envvar="ROSA_ROLE",
2584
+ )
2585
+ @click.pass_context
2586
+ def ocm_clusters(
2587
+ ctx,
2588
+ gitlab_project_id: str | None,
2589
+ thread_pool_size: int,
2590
+ job_controller_cluster: str | None,
2591
+ job_controller_namespace: str | None,
2592
+ rosa_job_service_account: str | None,
2593
+ rosa_role: str | None,
2594
+ rosa_job_image: str | None,
2595
+ ):
2596
+ from reconcile.ocm_clusters import (
2597
+ OcmClusters,
2598
+ OcmClustersParams,
2599
+ )
2600
+
2601
+ run_class_integration(
2602
+ integration=OcmClusters(
2603
+ OcmClustersParams(
2604
+ gitlab_project_id=gitlab_project_id,
2605
+ thread_pool_size=thread_pool_size,
2606
+ job_controller_cluster=job_controller_cluster,
2607
+ job_controller_namespace=job_controller_namespace,
2608
+ rosa_job_service_account=rosa_job_service_account,
2609
+ rosa_job_image=rosa_job_image,
2610
+ rosa_role=rosa_role,
2611
+ )
2612
+ ),
2613
+ ctx=ctx.obj,
2614
+ )
2615
+
2616
+
2617
+ def vault_creds_path(function):
2618
+ function = click.option(
2619
+ "--vault-creds-path",
2620
+ help="path in Vault to store creds.",
2621
+ default="app-sre/creds/kube-configs",
2622
+ )(function)
2623
+
2624
+ return function
2625
+
2626
+
2627
+ def dedicated_admin_namespace(function):
2628
+ function = click.option(
2629
+ "--dedicated-admin-namespace",
2630
+ default="dedicated-admin",
2631
+ help="namespace for the dedicated-admin bot",
2632
+ )(function)
2633
+ return function
2634
+
2635
+
2636
+ def dedicated_admin_service_account(function):
2637
+ function = click.option(
2638
+ "--dedicated-admin-service-account",
2639
+ default="app-sre",
2640
+ help="service account name for the dedicated-admin bot",
2641
+ )(function)
2642
+ return function
2643
+
2644
+
2645
+ def cluster_admin_namespace(function):
2646
+ function = click.option(
2647
+ "--cluster-admin-namespace",
2648
+ default="app-sre",
2649
+ help="namespace for the cluster-admin bot",
2650
+ )(function)
2651
+ return function
2652
+
2653
+
2654
+ def cluster_admin_service_account(function):
2655
+ function = click.option(
2656
+ "--cluster-admin-service-account",
2657
+ default="app-sre-cluster-admin-bot",
2658
+ help="service account name for the cluster-admin bot",
2659
+ )(function)
2660
+ return function
2661
+
2662
+
2663
+ @integration.command(short_help="Manages dedicated-admin and cluster-admin creds.")
2664
+ @gitlab_project_id
2665
+ @vault_creds_path
2666
+ @dedicated_admin_namespace
2667
+ @dedicated_admin_service_account
2668
+ @cluster_admin_namespace
2669
+ @cluster_admin_service_account
1855
2670
  @click.pass_context
1856
- def ocm_clusters(ctx, gitlab_project_id, thread_pool_size):
1857
- import reconcile.ocm_clusters
2671
+ def openshift_cluster_bots(
2672
+ ctx,
2673
+ gitlab_project_id,
2674
+ vault_creds_path,
2675
+ dedicated_admin_namespace,
2676
+ dedicated_admin_service_account,
2677
+ cluster_admin_namespace,
2678
+ cluster_admin_service_account,
2679
+ ):
2680
+ import reconcile.openshift_cluster_bots
1858
2681
 
1859
2682
  run_integration(
1860
- reconcile.ocm_clusters, ctx.obj, gitlab_project_id, thread_pool_size
2683
+ reconcile.openshift_cluster_bots,
2684
+ ctx.obj,
2685
+ gitlab_project_id,
2686
+ vault_creds_path,
2687
+ dedicated_admin_ns=dedicated_admin_namespace,
2688
+ dedicated_admin_sa=dedicated_admin_service_account,
2689
+ cluster_admin_ns=cluster_admin_namespace,
2690
+ cluster_admin_sa=cluster_admin_service_account,
1861
2691
  )
1862
2692
 
1863
2693
 
@@ -1872,14 +2702,6 @@ def ocm_external_configuration_labels(ctx, thread_pool_size):
1872
2702
  )
1873
2703
 
1874
2704
 
1875
- @integration.command(short_help="Manage Cluster Admin in OCM.")
1876
- @click.pass_context
1877
- def ocm_cluster_admin(ctx):
1878
- import reconcile.ocm_cluster_admin
1879
-
1880
- run_integration(reconcile.ocm_cluster_admin, ctx.obj)
1881
-
1882
-
1883
2705
  @integration.command(short_help="Trigger jenkins jobs following Addon upgrades.")
1884
2706
  @click.pass_context
1885
2707
  def ocm_addons_upgrade_tests_trigger(ctx):
@@ -1889,33 +2711,20 @@ def ocm_addons_upgrade_tests_trigger(ctx):
1889
2711
 
1890
2712
 
1891
2713
  @integration.command(short_help="Manage Machine Pools in OCM.")
1892
- @threaded()
1893
2714
  @click.pass_context
1894
- def ocm_machine_pools(ctx, thread_pool_size):
2715
+ def ocm_machine_pools(ctx):
1895
2716
  import reconcile.ocm_machine_pools
1896
2717
 
1897
- run_integration(reconcile.ocm_machine_pools, ctx.obj, thread_pool_size)
1898
-
1899
-
1900
- @integration.command(short_help="Manage Upgrade Policy schedules in OCM.")
1901
- @click.pass_context
1902
- def ocm_upgrade_scheduler(ctx):
1903
- from reconcile.aus.base import AdvancedUpgradeSchedulerBaseIntegrationParams
1904
- from reconcile.aus.ocm_upgrade_scheduler import (
1905
- OCMClusterUpgradeSchedulerIntegration,
1906
- )
1907
-
1908
- run_class_integration(
1909
- integration=OCMClusterUpgradeSchedulerIntegration(
1910
- AdvancedUpgradeSchedulerBaseIntegrationParams()
1911
- ),
1912
- ctx=ctx.obj,
1913
- )
2718
+ run_integration(reconcile.ocm_machine_pools, ctx.obj)
1914
2719
 
1915
2720
 
1916
2721
  @integration.command(short_help="Manage Upgrade Policy schedules in OCM organizations.")
2722
+ @org_id_multiple
2723
+ @exclude_org_id
1917
2724
  @click.pass_context
1918
- def ocm_upgrade_scheduler_org(ctx):
2725
+ def ocm_upgrade_scheduler_org(
2726
+ ctx, org_id: Iterable[str], exclude_org_id: Iterable[str]
2727
+ ) -> None:
1919
2728
  from reconcile.aus.base import AdvancedUpgradeSchedulerBaseIntegrationParams
1920
2729
  from reconcile.aus.ocm_upgrade_scheduler_org import (
1921
2730
  OCMClusterUpgradeSchedulerOrgIntegration,
@@ -1924,7 +2733,8 @@ def ocm_upgrade_scheduler_org(ctx):
1924
2733
  run_class_integration(
1925
2734
  integration=OCMClusterUpgradeSchedulerOrgIntegration(
1926
2735
  AdvancedUpgradeSchedulerBaseIntegrationParams(
1927
- # pass in env or org here for sharding
2736
+ ocm_organization_ids=set(org_id),
2737
+ excluded_ocm_organization_ids=set(exclude_org_id),
1928
2738
  )
1929
2739
  ),
1930
2740
  ctx=ctx.obj,
@@ -1945,9 +2755,21 @@ def ocm_upgrade_scheduler_org_updater(ctx, gitlab_project_id):
1945
2755
  @integration.command(
1946
2756
  short_help="Manage Addons Upgrade Policy schedules in OCM organizations."
1947
2757
  )
2758
+ @click.option(
2759
+ "--ocm-env",
2760
+ help="The OCM environment the integration should operator on. If none is specified, all environments will be operated on.",
2761
+ required=False,
2762
+ envvar="OCM_ENV",
2763
+ )
2764
+ @org_id_multiple
2765
+ @exclude_org_id
1948
2766
  @click.pass_context
1949
- def ocm_addons_upgrade_scheduler_org(ctx):
1950
-
2767
+ def ocm_addons_upgrade_scheduler_org(
2768
+ ctx,
2769
+ ocm_env: str,
2770
+ org_id: Iterable[str],
2771
+ exclude_org_id: Iterable[str],
2772
+ ) -> None:
1951
2773
  from reconcile.aus.base import AdvancedUpgradeSchedulerBaseIntegrationParams
1952
2774
  from reconcile.aus.ocm_addons_upgrade_scheduler_org import (
1953
2775
  OCMAddonsUpgradeSchedulerOrgIntegration,
@@ -1955,7 +2777,11 @@ def ocm_addons_upgrade_scheduler_org(ctx):
1955
2777
 
1956
2778
  run_class_integration(
1957
2779
  integration=OCMAddonsUpgradeSchedulerOrgIntegration(
1958
- AdvancedUpgradeSchedulerBaseIntegrationParams()
2780
+ AdvancedUpgradeSchedulerBaseIntegrationParams(
2781
+ ocm_environment=ocm_env,
2782
+ ocm_organization_ids=set(org_id),
2783
+ excluded_ocm_organization_ids=set(exclude_org_id),
2784
+ )
1959
2785
  ),
1960
2786
  ctx=ctx.obj,
1961
2787
  )
@@ -1964,31 +2790,144 @@ def ocm_addons_upgrade_scheduler_org(ctx):
1964
2790
  @integration.command(
1965
2791
  short_help="Manage Cluster Upgrade Policy schedules in OCM organizations based on OCM labels."
1966
2792
  )
2793
+ @click.option(
2794
+ "--ocm-env",
2795
+ help="The OCM environment AUS should operator on. If none is specified, all environments will be operated on.",
2796
+ required=False,
2797
+ envvar="AUS_OCM_ENV",
2798
+ )
2799
+ @org_id_multiple
2800
+ @exclude_org_id
2801
+ @click.option(
2802
+ "--ignore-sts-clusters",
2803
+ is_flag=True,
2804
+ default=os.environ.get("IGNORE_STS_CLUSTERS", False),
2805
+ help="Ignore STS clusters",
2806
+ )
1967
2807
  @click.pass_context
1968
- def aus_upgrade_scheduler_org(ctx):
1969
-
2808
+ def advanced_upgrade_scheduler(
2809
+ ctx,
2810
+ ocm_env: str,
2811
+ org_id: Iterable[str],
2812
+ exclude_org_id: Iterable[str],
2813
+ ignore_sts_clusters: bool,
2814
+ ) -> None:
1970
2815
  from reconcile.aus.advanced_upgrade_service import AdvancedUpgradeServiceIntegration
1971
2816
  from reconcile.aus.base import AdvancedUpgradeSchedulerBaseIntegrationParams
1972
2817
 
1973
2818
  run_class_integration(
1974
2819
  integration=AdvancedUpgradeServiceIntegration(
1975
- AdvancedUpgradeSchedulerBaseIntegrationParams()
2820
+ AdvancedUpgradeSchedulerBaseIntegrationParams(
2821
+ ocm_environment=ocm_env,
2822
+ ocm_organization_ids=set(org_id),
2823
+ excluded_ocm_organization_ids=set(exclude_org_id),
2824
+ ignore_sts_clusters=ignore_sts_clusters,
2825
+ )
1976
2826
  ),
1977
2827
  ctx=ctx.obj,
1978
2828
  )
1979
2829
 
1980
2830
 
1981
- @integration.command(short_help="Update recommended version for OCM orgs")
1982
- @gitlab_project_id
1983
- @click.pass_context
1984
- def ocm_update_recommended_version(ctx, gitlab_project_id):
1985
- import reconcile.ocm_update_recommended_version
1986
-
1987
- run_integration(
1988
- reconcile.ocm_update_recommended_version, ctx.obj, gitlab_project_id
1989
- )
1990
-
1991
-
2831
+ @integration.command(short_help="Approves OCM cluster upgrade version gates.")
2832
+ @click.option(
2833
+ "--job-controller-cluster",
2834
+ help="The cluster holding the job-controller namepsace",
2835
+ required=True,
2836
+ envvar="JOB_CONTROLLER_CLUSTER",
2837
+ )
2838
+ @click.option(
2839
+ "--job-controller-namespace",
2840
+ help="The namespace used for ROSA jobs",
2841
+ required=True,
2842
+ envvar="JOB_CONTROLLER_NAMESPACE",
2843
+ )
2844
+ @click.option(
2845
+ "--rosa-job-service-account",
2846
+ help="The service-account used for ROSA jobs",
2847
+ required=True,
2848
+ envvar="ROSA_JOB_SERVICE_ACCOUNT",
2849
+ )
2850
+ @click.option(
2851
+ "--rosa-job-image",
2852
+ help="The container image to use to run ROSA cli command jobs",
2853
+ required=False,
2854
+ envvar="ROSA_JOB_IMAGE",
2855
+ )
2856
+ @click.option(
2857
+ "--rosa-role",
2858
+ help="The role to assume in the ROSA cluster account",
2859
+ required=True,
2860
+ envvar="ROSA_ROLE",
2861
+ )
2862
+ @click.pass_context
2863
+ def version_gate_approver(
2864
+ ctx,
2865
+ job_controller_cluster: str,
2866
+ job_controller_namespace: str,
2867
+ rosa_job_service_account: str,
2868
+ rosa_role: str,
2869
+ rosa_job_image: str | None,
2870
+ ) -> None:
2871
+ from reconcile.aus.version_gate_approver import (
2872
+ VersionGateApprover,
2873
+ VersionGateApproverParams,
2874
+ )
2875
+
2876
+ run_class_integration(
2877
+ integration=VersionGateApprover(
2878
+ VersionGateApproverParams(
2879
+ job_controller_cluster=job_controller_cluster,
2880
+ job_controller_namespace=job_controller_namespace,
2881
+ rosa_job_service_account=rosa_job_service_account,
2882
+ rosa_job_image=rosa_job_image,
2883
+ rosa_role=rosa_role,
2884
+ )
2885
+ ),
2886
+ ctx=ctx.obj,
2887
+ )
2888
+
2889
+
2890
+ @integration.command(short_help="Manage Databases and Database Users.")
2891
+ @vault_output_path
2892
+ @click.pass_context
2893
+ def database_access_manager(ctx, vault_output_path: str):
2894
+ from reconcile.database_access_manager import (
2895
+ DatabaseAccessManagerIntegration,
2896
+ DBAMIntegrationParams,
2897
+ )
2898
+
2899
+ run_class_integration(
2900
+ integration=DatabaseAccessManagerIntegration(
2901
+ DBAMIntegrationParams(vault_output_path=vault_output_path)
2902
+ ),
2903
+ ctx=ctx.obj,
2904
+ )
2905
+
2906
+
2907
+ @integration.command(
2908
+ short_help="Export Product and Application informnation to Status Board."
2909
+ )
2910
+ @click.pass_context
2911
+ def status_board_exporter(ctx):
2912
+ from reconcile.status_board import StatusBoardExporterIntegration
2913
+
2914
+ run_class_integration(
2915
+ integration=StatusBoardExporterIntegration(PydanticRunParams()),
2916
+ ctx=ctx.obj,
2917
+ )
2918
+
2919
+
2920
+ @integration.command(short_help="Update recommended version for OCM orgs")
2921
+ @gitlab_project_id
2922
+ @click.pass_context
2923
+ def ocm_update_recommended_version(ctx, gitlab_project_id):
2924
+ import reconcile.ocm_update_recommended_version
2925
+
2926
+ run_integration(
2927
+ reconcile.ocm_update_recommended_version, ctx.obj, gitlab_project_id
2928
+ )
2929
+
2930
+
1992
2931
  @integration.command(short_help="Manages cluster Addons in OCM.")
1993
2932
  @threaded()
1994
2933
  @click.pass_context
@@ -2017,13 +2956,160 @@ def ocm_github_idp(ctx, vault_input_path):
2017
2956
  run_integration(reconcile.ocm_github_idp, ctx.obj, vault_input_path)
2018
2957
 
2019
2958
 
2020
- @integration.command(short_help="Manage OIDC Identity Providers in OCM.")
2021
- @vault_input_path
2959
+ @integration.command(
2960
+ short_help="Manage OIDC cluster configuration in OCM organizations based on OCM labels. Part of RHIDP."
2961
+ )
2962
+ @click.option(
2963
+ "--ocm-env",
2964
+ help="The OCM environment RHIDP should operator on. If none is specified, all environments will be operated on.",
2965
+ required=False,
2966
+ envvar="RHIDP_OCM_ENV",
2967
+ )
2968
+ @click.option(
2969
+ "--default-auth-name",
2970
+ default="redhat-sso",
2971
+ help="The authentication name must match that one used in the redirect URL.",
2972
+ required=True,
2973
+ envvar="RHIDP_DEFAULT_AUTH_NAME",
2974
+ )
2975
+ @click.option(
2976
+ "--default-auth-issuer-url",
2977
+ default="https://auth.redhat.com/auth/realms/EmployeeIDP",
2978
+ help="Use this Issuer (SSO server) URL if nothing else is specified for a cluster in the OCM cluster labels.",
2979
+ required=True,
2980
+ envvar="RHIDP_DEFAULT_AUTH_ISSUER_URL",
2981
+ )
2982
+ @click.option(
2983
+ "--vault-input-path",
2984
+ help="path in Vault to find input resources.",
2985
+ required=True,
2986
+ )
2987
+ @click.pass_context
2988
+ def ocm_oidc_idp(
2989
+ ctx,
2990
+ ocm_env,
2991
+ default_auth_name,
2992
+ default_auth_issuer_url,
2993
+ vault_input_path,
2994
+ ):
2995
+ from reconcile.rhidp.ocm_oidc_idp.integration import (
2996
+ OCMOidcIdp,
2997
+ OCMOidcIdpParams,
2998
+ )
2999
+
3000
+ run_class_integration(
3001
+ integration=OCMOidcIdp(
3002
+ OCMOidcIdpParams(
3003
+ vault_input_path=vault_input_path,
3004
+ ocm_environment=ocm_env,
3005
+ default_auth_name=default_auth_name,
3006
+ default_auth_issuer_url=default_auth_issuer_url,
3007
+ )
3008
+ ),
3009
+ ctx=ctx.obj,
3010
+ )
3011
+
3012
+
3013
+ @integration.command(
3014
+ short_help="Manage Keycloak SSO clients for OCM clusters. Part of RHIDP."
3015
+ )
3016
+ @click.option(
3017
+ "--keycloak-instance-vault-paths",
3018
+ help="A comma seperated list of vault paths to keycloak instance secrets.",
3019
+ required=True,
3020
+ )
3021
+ @click.option(
3022
+ "--contact-emails",
3023
+ default="sd-app-sre+auth@redhat.com",
3024
+ help="A comma seperated list of contact email addresses.",
3025
+ required=True,
3026
+ )
3027
+ @click.option(
3028
+ "--vault-input-path",
3029
+ help="path in Vault to find input resources.",
3030
+ required=True,
3031
+ )
3032
+ @click.option(
3033
+ "--ocm-env",
3034
+ help="The OCM environment RHIDP should operator on. If none is specified, all environments will be operated on.",
3035
+ required=False,
3036
+ envvar="RHIDP_OCM_ENV",
3037
+ )
3038
+ @click.option(
3039
+ "--default-auth-name",
3040
+ default="redhat-sso",
3041
+ help="The authentication name must match that one used in the redirect URL.",
3042
+ required=True,
3043
+ envvar="RHIDP_DEFAULT_AUTH_NAME",
3044
+ )
3045
+ @click.option(
3046
+ "--default-auth-issuer-url",
3047
+ default="https://auth.redhat.com/auth/realms/EmployeeIDP",
3048
+ help="Use this Issuer (SSO server) URL if nothing else is specified for a cluster in the OCM cluster labels.",
3049
+ required=True,
3050
+ envvar="RHIDP_DEFAULT_AUTH_ISSUER_URL",
3051
+ )
2022
3052
  @click.pass_context
2023
- def ocm_oidc_idp(ctx, vault_input_path):
2024
- import reconcile.ocm_oidc_idp
3053
+ def rhidp_sso_client(
3054
+ ctx,
3055
+ keycloak_instance_vault_paths,
3056
+ contact_emails,
3057
+ vault_input_path,
3058
+ ocm_env,
3059
+ default_auth_name,
3060
+ default_auth_issuer_url,
3061
+ ):
3062
+ from reconcile.rhidp.sso_client.integration import (
3063
+ SSOClient,
3064
+ SSOClientParams,
3065
+ )
3066
+
3067
+ run_class_integration(
3068
+ integration=SSOClient(
3069
+ SSOClientParams(
3070
+ keycloak_vault_paths=list(
3071
+ set(keycloak_instance_vault_paths.split(","))
3072
+ ),
3073
+ vault_input_path=vault_input_path,
3074
+ ocm_environment=ocm_env,
3075
+ default_auth_name=default_auth_name,
3076
+ default_auth_issuer_url=default_auth_issuer_url,
3077
+ contacts=list(set(contact_emails.split(","))),
3078
+ )
3079
+ ),
3080
+ ctx=ctx.obj,
3081
+ )
2025
3082
 
2026
- run_integration(reconcile.ocm_oidc_idp, ctx.obj, vault_input_path)
3083
+
3084
+ @integration.command(
3085
+ short_help="Manages the OCM subscription labels for clusters with RHIDP authentication. Part of RHIDP."
3086
+ )
3087
+ @click.pass_context
3088
+ def cluster_auth_rhidp(ctx):
3089
+ from reconcile.cluster_auth_rhidp.integration import (
3090
+ ClusterAuthRhidpIntegration,
3091
+ ClusterAuthRhidpIntegrationParams,
3092
+ )
3093
+
3094
+ run_class_integration(
3095
+ integration=ClusterAuthRhidpIntegration(ClusterAuthRhidpIntegrationParams()),
3096
+ ctx=ctx.obj,
3097
+ )
3098
+
3099
+
3100
+ @integration.command(
3101
+ short_help="Automatically provide dedicated Dynatrace tokens to management clusters"
3102
+ )
3103
+ @click.pass_context
3104
+ def dynatrace_token_provider(ctx):
3105
+ from reconcile.dynatrace_token_provider.integration import (
3106
+ DynatraceTokenProviderIntegration,
3107
+ )
3108
+
3109
+ run_class_integration(
3110
+ integration=DynatraceTokenProviderIntegration(),
3111
+ ctx=ctx.obj,
3112
+ )
2027
3113
 
2028
3114
 
2029
3115
  @integration.command(short_help="Manage additional routers in OCM.")
@@ -2042,14 +3128,6 @@ def email_sender(ctx):
2042
3128
  run_integration(reconcile.email_sender, ctx.obj)
2043
3129
 
2044
3130
 
2045
- @integration.command(short_help="Watch for Sentry access requests and notify on Slack.")
2046
- @click.pass_context
2047
- def sentry_helper(ctx):
2048
- import reconcile.sentry_helper
2049
-
2050
- run_integration(reconcile.sentry_helper, ctx.obj)
2051
-
2052
-
2053
3131
  @integration.command(
2054
3132
  short_help="Send emails to users based on " "requests submitted to app-interface."
2055
3133
  )
@@ -2068,14 +3146,6 @@ def service_dependencies(ctx):
2068
3146
  run_integration(reconcile.service_dependencies, ctx.obj)
2069
3147
 
2070
3148
 
2071
- @integration.command(short_help="Configure and enforce sentry instance configuration.")
2072
- @click.pass_context
2073
- def sentry_config(ctx):
2074
- import reconcile.sentry_config
2075
-
2076
- run_integration(reconcile.sentry_config, ctx.obj)
2077
-
2078
-
2079
3149
  @integration.command(short_help="Runs SQL Queries against app-interface RDS resources.")
2080
3150
  @enable_deletion(default=False)
2081
3151
  @click.pass_context
@@ -2153,76 +3223,22 @@ def dashdotdb_slo(ctx, thread_pool_size):
2153
3223
  run_integration(reconcile.dashdotdb_slo, ctx.obj, thread_pool_size)
2154
3224
 
2155
3225
 
2156
- @integration.command(short_help="Mirrors OCP release images.")
2157
- @click.pass_context
2158
- def ocp_release_mirror(ctx):
2159
- import reconcile.ocp_release_mirror
2160
-
2161
- run_integration(reconcile.ocp_release_mirror, ctx.obj)
2162
-
2163
-
2164
- @integration.command(short_help="Mirrors external images into AWS ECR.")
2165
- @threaded()
2166
- @click.pass_context
2167
- def ecr_mirror(ctx, thread_pool_size):
2168
- import reconcile.ecr_mirror
2169
-
2170
- run_integration(reconcile.ecr_mirror, ctx.obj, thread_pool_size)
2171
-
2172
-
2173
- @integration.command(short_help="Manages Kafka clusters via OCM.")
2174
- @threaded()
2175
- @binary(["oc", "ssh"])
2176
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
2177
- @internal()
2178
- @use_jump_host()
2179
- @vault_throughput_path
2180
- @click.pass_context
2181
- def kafka_clusters(
2182
- ctx, thread_pool_size, internal, use_jump_host, vault_throughput_path
2183
- ):
2184
- import reconcile.kafka_clusters
2185
-
2186
- run_integration(
2187
- reconcile.kafka_clusters,
2188
- ctx.obj,
2189
- thread_pool_size,
2190
- internal,
2191
- use_jump_host,
2192
- vault_throughput_path,
2193
- )
2194
-
2195
-
2196
- @integration.command(
2197
- short_help="Ensures all integrations are defined in App-Interface."
2198
- )
2199
- @click.pass_context
2200
- def integrations_validator(ctx):
2201
- import reconcile.integrations_validator
2202
-
2203
- run_integration(
2204
- reconcile.integrations_validator,
2205
- ctx.obj,
2206
- reconcile.cli.integration.commands.keys(),
2207
- )
2208
-
2209
-
2210
- @integration.command(short_help="Tests prometheus rules using promtool.")
2211
- @threaded()
2212
- @binary(["promtool"])
2213
- @cluster_name
3226
+ @integration.command(short_help="Collects dora metrics.")
3227
+ @gitlab_project_id
3228
+ @threaded(default=5)
2214
3229
  @click.pass_context
2215
- def prometheus_rules_tester_old(ctx, thread_pool_size, cluster_name):
2216
- import reconcile.prometheus_rules_tester_old
3230
+ def dashdotdb_dora(ctx, gitlab_project_id, thread_pool_size):
3231
+ import reconcile.dashdotdb_dora
2217
3232
 
2218
3233
  run_integration(
2219
- reconcile.prometheus_rules_tester_old, ctx.obj, thread_pool_size, cluster_name
3234
+ reconcile.dashdotdb_dora, ctx.obj, gitlab_project_id, thread_pool_size
2220
3235
  )
2221
3236
 
2222
3237
 
2223
3238
  @integration.command(short_help="Tests prometheus rules using promtool.")
2224
3239
  @threaded(default=5)
2225
3240
  @binary(["promtool"])
3241
+ @binary_version("promtool", ["--version"], PROMTOOL_VERSION_REGEX, PROMTOOL_VERSION)
2226
3242
  @cluster_name
2227
3243
  @click.pass_context
2228
3244
  def prometheus_rules_tester(ctx, thread_pool_size, cluster_name):
@@ -2232,16 +3248,16 @@ def prometheus_rules_tester(ctx, thread_pool_size, cluster_name):
2232
3248
  reconcile.prometheus_rules_tester.integration,
2233
3249
  ctx.obj,
2234
3250
  thread_pool_size,
2235
- cluster_name=cluster_name,
3251
+ cluster_names=cluster_name,
2236
3252
  )
2237
3253
 
2238
3254
 
2239
3255
  @integration.command(short_help="Tests templating of resources.")
2240
3256
  @click.pass_context
2241
- def template_tester(ctx):
2242
- import reconcile.template_tester
3257
+ def resource_template_tester(ctx):
3258
+ import reconcile.resource_template_tester
2243
3259
 
2244
- run_integration(reconcile.template_tester, ctx.obj)
3260
+ run_integration(reconcile.resource_template_tester, ctx.obj)
2245
3261
 
2246
3262
 
2247
3263
  @integration.command(
@@ -2291,7 +3307,7 @@ def resource_scraper(ctx, namespace_name, resource_kind, vault_output_path):
2291
3307
  @integration.command(short_help="Manages user access for GABI instances.")
2292
3308
  @threaded()
2293
3309
  @binary(["oc", "ssh"])
2294
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
3310
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
2295
3311
  @internal()
2296
3312
  @use_jump_host()
2297
3313
  @click.pass_context
@@ -2312,11 +3328,64 @@ def gabi_authorized_users(ctx, thread_pool_size, internal, use_jump_host):
2312
3328
  )
2313
3329
  @click.pass_context
2314
3330
  def status_page_components(ctx):
2315
- from reconcile.statuspage.integration import StatusPageComponentsIntegration
3331
+ from reconcile.statuspage.integrations.components import (
3332
+ StatusPageComponentsIntegration,
3333
+ )
2316
3334
 
2317
3335
  run_class_integration(StatusPageComponentsIntegration(), ctx.obj)
2318
3336
 
2319
3337
 
3338
+ @integration.command(
3339
+ short_help="Manages maintenances on statuspage.io hosted status pages."
3340
+ )
3341
+ @click.pass_context
3342
+ def status_page_maintenances(ctx):
3343
+ from reconcile.statuspage.integrations.maintenances import (
3344
+ StatusPageMaintenancesIntegration,
3345
+ )
3346
+
3347
+ run_class_integration(StatusPageMaintenancesIntegration(NoParams()), ctx.obj)
3348
+
3349
+
3350
+ @integration.command(
3351
+ short_help="Manages OCM cluster usergroups and notifications via OCM labels."
3352
+ )
3353
+ @click.option(
3354
+ "--ocm-env",
3355
+ help="The OCM environment the integration should operator on. If none is specified, all environments will be operated on.",
3356
+ required=False,
3357
+ envvar="OCM_ENV",
3358
+ )
3359
+ @click.option(
3360
+ "--ocm-org-ids",
3361
+ help="A comma seperated list of OCM organization IDs the integration should operator on. If none is specified, all organizations are considered.",
3362
+ required=False,
3363
+ envvar="OCM_ORG_IDS",
3364
+ )
3365
+ @click.option(
3366
+ "--group-provider",
3367
+ help="A group provider spec is the form of <provider-name>:<provider-type>:<provider-args>.",
3368
+ required=False,
3369
+ multiple=True,
3370
+ )
3371
+ @click.pass_context
3372
+ def ocm_standalone_user_management(ctx, ocm_env, ocm_org_ids, group_provider):
3373
+ from reconcile.oum.base import OCMUserManagementIntegrationParams
3374
+ from reconcile.oum.standalone import OCMStandaloneUserManagementIntegration
3375
+
3376
+ ocm_organization_ids = set(ocm_org_ids.split(",")) if ocm_org_ids else None
3377
+ run_class_integration(
3378
+ OCMStandaloneUserManagementIntegration(
3379
+ OCMUserManagementIntegrationParams(
3380
+ ocm_environment=ocm_env,
3381
+ ocm_organization_ids=ocm_organization_ids,
3382
+ group_provider_specs=group_provider,
3383
+ ),
3384
+ ),
3385
+ ctx.obj,
3386
+ )
3387
+
3388
+
2320
3389
  @integration.command(
2321
3390
  short_help="Manages Prometheus Probe resources for blackbox-exporter"
2322
3391
  )
@@ -2359,7 +3428,7 @@ def signalfx_prometheus_endpoint_monitoring(
2359
3428
  )
2360
3429
 
2361
3430
 
2362
- def parse_image_tag_from_ref(ctx, param, value) -> Optional[dict[str, str]]:
3431
+ def parse_image_tag_from_ref(ctx, param, value) -> dict[str, str] | None:
2363
3432
  if value:
2364
3433
  result = {}
2365
3434
  for v in value:
@@ -2386,7 +3455,7 @@ def vault_replication(ctx):
2386
3455
  @environment_name
2387
3456
  @threaded()
2388
3457
  @binary(["oc", "ssh", "helm"])
2389
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
3458
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
2390
3459
  @internal()
2391
3460
  @use_jump_host()
2392
3461
  @click.option(
@@ -2481,6 +3550,33 @@ def change_owners(
2481
3550
  )
2482
3551
 
2483
3552
 
3553
+ @integration.command(short_help="Analyze bundle diffs by change types.")
3554
+ @gitlab_project_id
3555
+ @click.option(
3556
+ "--process-existing/--no-process-existing",
3557
+ default=False,
3558
+ help="wait for pending/running pipelines before acting.",
3559
+ )
3560
+ @click.option("--commit", help="Reconcile just this commit.", default=None)
3561
+ @click.pass_context
3562
+ def change_log_tracking(ctx, gitlab_project_id, process_existing, commit):
3563
+ from reconcile.change_owners.change_log_tracking import (
3564
+ ChangeLogIntegration,
3565
+ ChangeLogIntegrationParams,
3566
+ )
3567
+
3568
+ run_class_integration(
3569
+ ChangeLogIntegration(
3570
+ ChangeLogIntegrationParams(
3571
+ gitlab_project_id=gitlab_project_id,
3572
+ process_existing=process_existing,
3573
+ commit=commit,
3574
+ )
3575
+ ),
3576
+ ctx=ctx.obj,
3577
+ )
3578
+
3579
+
2484
3580
  @integration.command(
2485
3581
  short_help="Configure and enforce glitchtip instance configuration."
2486
3582
  )
@@ -2492,10 +3588,27 @@ def glitchtip(ctx, instance):
2492
3588
  run_integration(reconcile.glitchtip.integration, ctx.obj, instance)
2493
3589
 
2494
3590
 
3591
+ @integration.command(short_help="Configure Glitchtip project alerts.")
3592
+ @click.option("--instance", help="Reconcile just this instance.", default=None)
3593
+ @click.pass_context
3594
+ def glitchtip_project_alerts(ctx, instance):
3595
+ from reconcile.glitchtip_project_alerts.integration import (
3596
+ GlitchtipProjectAlertsIntegration,
3597
+ GlitchtipProjectAlertsIntegrationParams,
3598
+ )
3599
+
3600
+ run_class_integration(
3601
+ integration=GlitchtipProjectAlertsIntegration(
3602
+ GlitchtipProjectAlertsIntegrationParams(instance=instance)
3603
+ ),
3604
+ ctx=ctx.obj,
3605
+ )
3606
+
3607
+
2495
3608
  @integration.command(short_help="Glitchtip project dsn as openshift secret.")
2496
3609
  @threaded()
2497
3610
  @binary(["oc", "ssh"])
2498
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
3611
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
2499
3612
  @internal()
2500
3613
  @use_jump_host()
2501
3614
  @click.option("--instance", help="Reconcile just this instance.", default=None)
@@ -2516,7 +3629,7 @@ def glitchtip_project_dsn(ctx, thread_pool_size, internal, use_jump_host, instan
2516
3629
  @integration.command(short_help="Manages Skupper Networks.")
2517
3630
  @threaded()
2518
3631
  @binary(["oc", "ssh"])
2519
- @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSION)
3632
+ @binary_version("oc", ["version", "--client"], OC_VERSION_REGEX, OC_VERSIONS)
2520
3633
  @internal()
2521
3634
  @use_jump_host()
2522
3635
  @click.pass_context
@@ -2532,6 +3645,170 @@ def skupper_network(ctx, thread_pool_size, internal, use_jump_host):
2532
3645
  )
2533
3646
 
2534
3647
 
3648
+ @integration.command(short_help="Manage cluster OCM labels.")
3649
+ @click.option(
3650
+ "--managed-label-prefixes",
3651
+ help="A comma list of label prefixes that are managed.",
3652
+ required=True,
3653
+ envvar="OL_MANAGED_LABEL_PREFIXES",
3654
+ default="sre-capabilities",
3655
+ )
3656
+ @click.option(
3657
+ "--ignored-label-prefixes",
3658
+ help="A comma list of label prefixes that must be ignored.",
3659
+ required=True,
3660
+ envvar="OL_IGNORED_LABEL_PREFIXES",
3661
+ default="sre-capabilities.rhidp",
3662
+ )
3663
+ @click.pass_context
3664
+ def ocm_labels(ctx, managed_label_prefixes, ignored_label_prefixes):
3665
+ from reconcile.ocm_labels.integration import (
3666
+ OcmLabelsIntegration,
3667
+ OcmLabelsIntegrationParams,
3668
+ )
3669
+
3670
+ run_class_integration(
3671
+ integration=OcmLabelsIntegration(
3672
+ OcmLabelsIntegrationParams(
3673
+ managed_label_prefixes=list(set(managed_label_prefixes.split(","))),
3674
+ ignored_label_prefixes=list(set(ignored_label_prefixes.split(","))),
3675
+ )
3676
+ ),
3677
+ ctx=ctx.obj,
3678
+ )
3679
+
3680
+
3681
+ @integration.command(
3682
+ short_help="Notifications to internal Red Hat users based on conditions in OCM."
3683
+ )
3684
+ @click.pass_context
3685
+ def ocm_internal_notifications(ctx):
3686
+ from reconcile.ocm_internal_notifications.integration import (
3687
+ OcmInternalNotifications,
3688
+ )
3689
+
3690
+ run_class_integration(
3691
+ integration=OcmInternalNotifications(),
3692
+ ctx=ctx.obj,
3693
+ )
3694
+
3695
+
3696
+ @integration.command(short_help="Manages RHACS rbac configuration")
3697
+ @click.pass_context
3698
+ def acs_rbac(ctx):
3699
+ from reconcile import acs_rbac
3700
+
3701
+ run_class_integration(
3702
+ integration=acs_rbac.AcsRbacIntegration(),
3703
+ ctx=ctx.obj,
3704
+ )
3705
+
3706
+
3707
+ @integration.command(short_help="Manages RHACS security policy configurations")
3708
+ @click.pass_context
3709
+ def acs_policies(ctx):
3710
+ from reconcile import acs_policies
3711
+
3712
+ run_class_integration(
3713
+ integration=acs_policies.AcsPoliciesIntegration(),
3714
+ ctx=ctx.obj,
3715
+ )
3716
+
3717
+
3718
+ @integration.command(short_help="Manages RHACS notifier configurations")
3719
+ @click.pass_context
3720
+ def acs_notifiers(ctx):
3721
+ from reconcile import acs_notifiers
3722
+
3723
+ run_class_integration(
3724
+ integration=acs_notifiers.AcsNotifiersIntegration(),
3725
+ ctx=ctx.obj,
3726
+ )
3727
+
3728
+
3729
+ @integration.command(short_help="Manage Unleash feature toggles.")
3730
+ @click.option("--instance", help="Reconcile just this Unlash instance.", default=None)
3731
+ @click.pass_context
3732
+ def unleash_feature_toggles(ctx, instance):
3733
+ from reconcile.unleash_feature_toggles.integration import (
3734
+ UnleashTogglesIntegration,
3735
+ UnleashTogglesIntegrationParams,
3736
+ )
3737
+
3738
+ run_class_integration(
3739
+ integration=UnleashTogglesIntegration(
3740
+ UnleashTogglesIntegrationParams(instance=instance)
3741
+ ),
3742
+ ctx=ctx.obj,
3743
+ )
3744
+
3745
+
3746
+ @integration.command(short_help="Automate Deadmanssnitch Creation/Deletion")
3747
+ @click.pass_context
3748
+ def deadmanssnitch(ctx):
3749
+ from reconcile import deadmanssnitch
3750
+
3751
+ run_class_integration(
3752
+ integration=deadmanssnitch.DeadMansSnitchIntegration(),
3753
+ ctx=ctx.obj,
3754
+ )
3755
+
3756
+
3757
+ @integration.command(short_help="Manages External Resources")
3758
+ @click.pass_context
3759
+ @threaded(default=5)
3760
+ @click.option(
3761
+ "--workers_cluster",
3762
+ help="Cluster name where the Jobs will be created",
3763
+ default=None,
3764
+ )
3765
+ @click.option(
3766
+ "--workers_namespace",
3767
+ help="Namespace name where the Jobs will be created",
3768
+ default=None,
3769
+ )
3770
+ @click.option(
3771
+ "--dry-run-job-suffix",
3772
+ help="Suffix jons run in pr_checks. e.g: gitlab merge request id",
3773
+ default="",
3774
+ )
3775
+ def external_resources(
3776
+ ctx,
3777
+ dry_run_job_suffix: str,
3778
+ thread_pool_size: int,
3779
+ workers_cluster: str,
3780
+ workers_namespace: str,
3781
+ ):
3782
+ import reconcile.external_resources.integration
3783
+
3784
+ run_integration(
3785
+ reconcile.external_resources.integration,
3786
+ ctx.obj,
3787
+ dry_run_job_suffix=dry_run_job_suffix,
3788
+ thread_pool_size=thread_pool_size,
3789
+ workers_cluster=workers_cluster,
3790
+ workers_namespace=workers_namespace,
3791
+ )
3792
+
3793
+
3794
+ @integration.command(
3795
+ short_help="Syncs External Resources Secrets from Vault to Clusters"
3796
+ )
3797
+ @click.pass_context
3798
+ @threaded(default=5)
3799
+ def external_resources_secrets_sync(
3800
+ ctx,
3801
+ thread_pool_size: int,
3802
+ ):
3803
+ import reconcile.external_resources.integration_secrets_sync
3804
+
3805
+ run_integration(
3806
+ reconcile.external_resources.integration_secrets_sync,
3807
+ ctx.obj,
3808
+ thread_pool_size,
3809
+ )
3810
+
3811
+
2535
3812
  def get_integration_cli_meta() -> dict[str, IntegrationMeta]:
2536
3813
  """
2537
3814
  returns all integrations known to cli.py via click introspection
@@ -2545,7 +3822,11 @@ def get_integration_cli_meta() -> dict[str, IntegrationMeta]:
2545
3822
  integration_cmd = integration.get_command(None, integration_name) # type: ignore
2546
3823
  integration_meta[integration_name] = IntegrationMeta(
2547
3824
  name=integration_name,
2548
- args=[p.opts[0] for p in integration_cmd.params if p.opts and len(p.opts) > 0], # type: ignore
3825
+ args=[
3826
+ p.opts[0]
3827
+ for p in integration_cmd.params # type: ignore
3828
+ if p.opts and len(p.opts) > 0
3829
+ ],
2549
3830
  short_help=integration_cmd.short_help, # type: ignore
2550
3831
  )
2551
3832
  return integration_meta