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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (843) hide show
  1. qontract_reconcile-0.10.1.dev1203.dist-info/METADATA +500 -0
  2. qontract_reconcile-0.10.1.dev1203.dist-info/RECORD +771 -0
  3. {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
  4. {qontract_reconcile-0.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/entry_points.txt +4 -2
  5. reconcile/acs_notifiers.py +126 -0
  6. reconcile/acs_policies.py +243 -0
  7. reconcile/acs_rbac.py +596 -0
  8. reconcile/aus/advanced_upgrade_service.py +621 -8
  9. reconcile/aus/aus_label_source.py +115 -0
  10. reconcile/aus/base.py +1053 -353
  11. reconcile/{utils → aus}/cluster_version_data.py +27 -12
  12. reconcile/aus/healthchecks.py +77 -0
  13. reconcile/aus/metrics.py +158 -0
  14. reconcile/aus/models.py +245 -5
  15. reconcile/aus/node_pool_spec.py +35 -0
  16. reconcile/aus/ocm_addons_upgrade_scheduler_org.py +225 -110
  17. reconcile/aus/ocm_upgrade_scheduler.py +76 -71
  18. reconcile/aus/ocm_upgrade_scheduler_org.py +81 -23
  19. reconcile/aus/version_gate_approver.py +204 -0
  20. reconcile/aus/version_gates/__init__.py +12 -0
  21. reconcile/aus/version_gates/handler.py +33 -0
  22. reconcile/aus/version_gates/ingress_gate_handler.py +32 -0
  23. reconcile/aus/version_gates/ocp_gate_handler.py +26 -0
  24. reconcile/aus/version_gates/sts_version_gate_handler.py +100 -0
  25. reconcile/aws_account_manager/README.md +5 -0
  26. reconcile/aws_account_manager/integration.py +373 -0
  27. reconcile/aws_account_manager/merge_request_manager.py +114 -0
  28. reconcile/aws_account_manager/metrics.py +39 -0
  29. reconcile/aws_account_manager/reconciler.py +403 -0
  30. reconcile/aws_account_manager/utils.py +41 -0
  31. reconcile/aws_ami_cleanup/integration.py +273 -0
  32. reconcile/aws_ami_share.py +18 -14
  33. reconcile/aws_cloudwatch_log_retention/integration.py +253 -0
  34. reconcile/aws_iam_keys.py +1 -1
  35. reconcile/aws_iam_password_reset.py +56 -20
  36. reconcile/aws_saml_idp/integration.py +204 -0
  37. reconcile/aws_saml_roles/integration.py +322 -0
  38. reconcile/aws_support_cases_sos.py +2 -2
  39. reconcile/aws_version_sync/integration.py +430 -0
  40. reconcile/aws_version_sync/merge_request_manager/merge_request.py +156 -0
  41. reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py +160 -0
  42. reconcile/aws_version_sync/utils.py +64 -0
  43. reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
  44. reconcile/change_owners/README.md +34 -0
  45. reconcile/change_owners/approver.py +7 -9
  46. reconcile/change_owners/bundle.py +134 -9
  47. reconcile/change_owners/change_log_tracking.py +236 -0
  48. reconcile/change_owners/change_owners.py +204 -194
  49. reconcile/change_owners/change_types.py +183 -265
  50. reconcile/change_owners/changes.py +488 -0
  51. reconcile/change_owners/decision.py +120 -41
  52. reconcile/change_owners/diff.py +63 -92
  53. reconcile/change_owners/implicit_ownership.py +19 -16
  54. reconcile/change_owners/self_service_roles.py +158 -35
  55. reconcile/change_owners/tester.py +20 -18
  56. reconcile/checkpoint.py +4 -6
  57. reconcile/cli.py +1523 -242
  58. reconcile/closedbox_endpoint_monitoring_base.py +10 -17
  59. reconcile/cluster_auth_rhidp/integration.py +257 -0
  60. reconcile/cluster_deployment_mapper.py +2 -5
  61. reconcile/cna/assets/asset.py +4 -7
  62. reconcile/cna/assets/null.py +2 -5
  63. reconcile/cna/integration.py +2 -3
  64. reconcile/cna/state.py +6 -9
  65. reconcile/dashdotdb_base.py +31 -10
  66. reconcile/dashdotdb_cso.py +3 -6
  67. reconcile/dashdotdb_dora.py +530 -0
  68. reconcile/dashdotdb_dvo.py +10 -13
  69. reconcile/dashdotdb_slo.py +75 -19
  70. reconcile/database_access_manager.py +753 -0
  71. reconcile/deadmanssnitch.py +207 -0
  72. reconcile/dynatrace_token_provider/dependencies.py +69 -0
  73. reconcile/dynatrace_token_provider/integration.py +656 -0
  74. reconcile/dynatrace_token_provider/metrics.py +62 -0
  75. reconcile/dynatrace_token_provider/model.py +14 -0
  76. reconcile/dynatrace_token_provider/ocm.py +140 -0
  77. reconcile/dynatrace_token_provider/validate.py +48 -0
  78. reconcile/endpoints_discovery/integration.py +348 -0
  79. reconcile/endpoints_discovery/merge_request.py +96 -0
  80. reconcile/endpoints_discovery/merge_request_manager.py +178 -0
  81. reconcile/external_resources/aws.py +204 -0
  82. reconcile/external_resources/factories.py +163 -0
  83. reconcile/external_resources/integration.py +194 -0
  84. reconcile/external_resources/integration_secrets_sync.py +47 -0
  85. reconcile/external_resources/manager.py +405 -0
  86. reconcile/external_resources/meta.py +17 -0
  87. reconcile/external_resources/metrics.py +95 -0
  88. reconcile/external_resources/model.py +350 -0
  89. reconcile/external_resources/reconciler.py +265 -0
  90. reconcile/external_resources/secrets_sync.py +465 -0
  91. reconcile/external_resources/state.py +258 -0
  92. reconcile/gabi_authorized_users.py +19 -11
  93. reconcile/gcr_mirror.py +43 -34
  94. reconcile/github_org.py +4 -6
  95. reconcile/github_owners.py +1 -1
  96. reconcile/github_repo_invites.py +2 -5
  97. reconcile/gitlab_fork_compliance.py +14 -13
  98. reconcile/gitlab_housekeeping.py +185 -91
  99. reconcile/gitlab_labeler.py +15 -14
  100. reconcile/gitlab_members.py +126 -120
  101. reconcile/gitlab_owners.py +53 -66
  102. reconcile/gitlab_permissions.py +167 -6
  103. reconcile/glitchtip/README.md +150 -0
  104. reconcile/glitchtip/integration.py +99 -51
  105. reconcile/glitchtip/reconciler.py +99 -70
  106. reconcile/glitchtip_project_alerts/__init__.py +0 -0
  107. reconcile/glitchtip_project_alerts/integration.py +333 -0
  108. reconcile/glitchtip_project_dsn/integration.py +43 -43
  109. reconcile/gql_definitions/acs/__init__.py +0 -0
  110. reconcile/gql_definitions/acs/acs_instances.py +83 -0
  111. reconcile/gql_definitions/acs/acs_policies.py +239 -0
  112. reconcile/gql_definitions/acs/acs_rbac.py +111 -0
  113. reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +46 -8
  114. reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +38 -8
  115. reconcile/gql_definitions/app_interface_metrics_exporter/__init__.py +0 -0
  116. reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +61 -0
  117. reconcile/gql_definitions/aws_account_manager/__init__.py +0 -0
  118. reconcile/gql_definitions/aws_account_manager/aws_accounts.py +177 -0
  119. reconcile/gql_definitions/aws_ami_cleanup/__init__.py +0 -0
  120. reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +161 -0
  121. reconcile/gql_definitions/aws_saml_idp/__init__.py +0 -0
  122. reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +117 -0
  123. reconcile/gql_definitions/aws_saml_roles/__init__.py +0 -0
  124. reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +117 -0
  125. reconcile/gql_definitions/aws_saml_roles/roles.py +97 -0
  126. reconcile/gql_definitions/aws_version_sync/__init__.py +0 -0
  127. reconcile/gql_definitions/aws_version_sync/clusters.py +83 -0
  128. reconcile/gql_definitions/aws_version_sync/namespaces.py +143 -0
  129. reconcile/gql_definitions/change_owners/queries/change_types.py +16 -29
  130. reconcile/gql_definitions/change_owners/queries/self_service_roles.py +45 -11
  131. reconcile/gql_definitions/cluster_auth_rhidp/__init__.py +0 -0
  132. reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +128 -0
  133. reconcile/gql_definitions/cna/queries/cna_provisioners.py +6 -8
  134. reconcile/gql_definitions/cna/queries/cna_resources.py +3 -5
  135. reconcile/gql_definitions/common/alerting_services_settings.py +2 -2
  136. reconcile/gql_definitions/common/app_code_component_repos.py +9 -5
  137. reconcile/gql_definitions/{glitchtip/glitchtip_settings.py → common/app_interface_custom_messages.py} +14 -16
  138. reconcile/gql_definitions/common/app_interface_dms_settings.py +86 -0
  139. reconcile/gql_definitions/common/app_interface_repo_settings.py +2 -2
  140. reconcile/gql_definitions/common/app_interface_state_settings.py +3 -5
  141. reconcile/gql_definitions/common/app_interface_vault_settings.py +3 -5
  142. reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +120 -0
  143. reconcile/gql_definitions/common/apps.py +72 -0
  144. reconcile/gql_definitions/common/aws_vpc_requests.py +109 -0
  145. reconcile/gql_definitions/common/aws_vpcs.py +84 -0
  146. reconcile/gql_definitions/common/clusters.py +120 -254
  147. reconcile/gql_definitions/common/clusters_minimal.py +11 -35
  148. reconcile/gql_definitions/common/clusters_with_dms.py +72 -0
  149. reconcile/gql_definitions/common/clusters_with_peering.py +70 -98
  150. reconcile/gql_definitions/common/github_orgs.py +2 -2
  151. reconcile/gql_definitions/common/jira_settings.py +68 -0
  152. reconcile/gql_definitions/common/jiralert_settings.py +68 -0
  153. reconcile/gql_definitions/common/namespaces.py +74 -32
  154. reconcile/gql_definitions/common/namespaces_minimal.py +4 -10
  155. reconcile/gql_definitions/common/ocm_env_telemeter.py +95 -0
  156. reconcile/gql_definitions/common/ocm_environments.py +4 -2
  157. reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
  158. reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -11
  159. reconcile/gql_definitions/common/pipeline_providers.py +45 -90
  160. reconcile/gql_definitions/common/quay_instances.py +64 -0
  161. reconcile/gql_definitions/common/quay_orgs.py +68 -0
  162. reconcile/gql_definitions/common/reserved_networks.py +94 -0
  163. reconcile/gql_definitions/common/saas_files.py +133 -95
  164. reconcile/gql_definitions/common/saas_target_namespaces.py +41 -26
  165. reconcile/gql_definitions/common/saasherder_settings.py +2 -2
  166. reconcile/gql_definitions/common/slack_workspaces.py +62 -0
  167. reconcile/gql_definitions/common/smtp_client_settings.py +2 -2
  168. reconcile/gql_definitions/common/state_aws_account.py +77 -0
  169. reconcile/gql_definitions/common/users.py +3 -2
  170. reconcile/gql_definitions/cost_report/__init__.py +0 -0
  171. reconcile/gql_definitions/cost_report/app_names.py +68 -0
  172. reconcile/gql_definitions/cost_report/cost_namespaces.py +86 -0
  173. reconcile/gql_definitions/cost_report/settings.py +77 -0
  174. reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +42 -12
  175. reconcile/gql_definitions/dynatrace_token_provider/__init__.py +0 -0
  176. reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +79 -0
  177. reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +84 -0
  178. reconcile/gql_definitions/endpoints_discovery/__init__.py +0 -0
  179. reconcile/gql_definitions/endpoints_discovery/namespaces.py +127 -0
  180. reconcile/gql_definitions/external_resources/__init__.py +0 -0
  181. reconcile/gql_definitions/external_resources/aws_accounts.py +73 -0
  182. reconcile/gql_definitions/external_resources/external_resources_modules.py +78 -0
  183. reconcile/gql_definitions/external_resources/external_resources_namespaces.py +1111 -0
  184. reconcile/gql_definitions/external_resources/external_resources_settings.py +98 -0
  185. reconcile/gql_definitions/fragments/aus_organization.py +34 -39
  186. reconcile/gql_definitions/fragments/aws_account_common.py +62 -0
  187. reconcile/gql_definitions/fragments/aws_account_managed.py +57 -0
  188. reconcile/gql_definitions/fragments/aws_account_sso.py +35 -0
  189. reconcile/gql_definitions/fragments/aws_infra_management_account.py +2 -2
  190. reconcile/gql_definitions/fragments/aws_vpc.py +47 -0
  191. reconcile/gql_definitions/fragments/aws_vpc_request.py +65 -0
  192. reconcile/gql_definitions/fragments/aws_vpc_request_subnet.py +29 -0
  193. reconcile/gql_definitions/fragments/deplopy_resources.py +7 -7
  194. reconcile/gql_definitions/fragments/disable.py +28 -0
  195. reconcile/gql_definitions/fragments/jumphost_common_fields.py +2 -2
  196. reconcile/gql_definitions/fragments/membership_source.py +47 -0
  197. reconcile/gql_definitions/fragments/minimal_ocm_organization.py +29 -0
  198. reconcile/gql_definitions/fragments/oc_connection_cluster.py +4 -9
  199. reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
  200. reconcile/gql_definitions/fragments/pipeline_provider_retention.py +30 -0
  201. reconcile/gql_definitions/fragments/prometheus_instance.py +48 -0
  202. reconcile/gql_definitions/fragments/resource_limits_requirements.py +29 -0
  203. reconcile/gql_definitions/fragments/{resource_requirements.py → resource_requests_requirements.py} +3 -3
  204. reconcile/gql_definitions/fragments/resource_values.py +2 -2
  205. reconcile/gql_definitions/fragments/saas_target_namespace.py +55 -12
  206. reconcile/gql_definitions/fragments/serviceaccount_token.py +38 -0
  207. reconcile/gql_definitions/fragments/terraform_state.py +36 -0
  208. reconcile/gql_definitions/fragments/upgrade_policy.py +5 -3
  209. reconcile/gql_definitions/fragments/user.py +3 -2
  210. reconcile/gql_definitions/fragments/vault_secret.py +2 -2
  211. reconcile/gql_definitions/gitlab_members/gitlab_instances.py +6 -2
  212. reconcile/gql_definitions/gitlab_members/permissions.py +3 -5
  213. reconcile/gql_definitions/glitchtip/glitchtip_instance.py +16 -2
  214. reconcile/gql_definitions/glitchtip/glitchtip_project.py +22 -23
  215. reconcile/gql_definitions/glitchtip_project_alerts/__init__.py +0 -0
  216. reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +173 -0
  217. reconcile/gql_definitions/integrations/integrations.py +62 -45
  218. reconcile/gql_definitions/introspection.json +51176 -0
  219. reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +13 -5
  220. reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +79 -0
  221. reconcile/gql_definitions/jira/__init__.py +0 -0
  222. reconcile/gql_definitions/jira/jira_servers.py +80 -0
  223. reconcile/gql_definitions/jira_permissions_validator/__init__.py +0 -0
  224. reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +131 -0
  225. reconcile/gql_definitions/jumphosts/jumphosts.py +3 -5
  226. reconcile/gql_definitions/ldap_groups/__init__.py +0 -0
  227. reconcile/gql_definitions/ldap_groups/roles.py +111 -0
  228. reconcile/gql_definitions/ldap_groups/settings.py +79 -0
  229. reconcile/gql_definitions/maintenance/__init__.py +0 -0
  230. reconcile/gql_definitions/maintenance/maintenances.py +101 -0
  231. reconcile/gql_definitions/membershipsources/__init__.py +0 -0
  232. reconcile/gql_definitions/membershipsources/roles.py +112 -0
  233. reconcile/gql_definitions/ocm_labels/__init__.py +0 -0
  234. reconcile/gql_definitions/ocm_labels/clusters.py +112 -0
  235. reconcile/gql_definitions/ocm_labels/organizations.py +78 -0
  236. reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
  237. reconcile/gql_definitions/openshift_cluster_bots/__init__.py +0 -0
  238. reconcile/gql_definitions/openshift_cluster_bots/clusters.py +126 -0
  239. reconcile/gql_definitions/openshift_groups/managed_groups.py +2 -2
  240. reconcile/gql_definitions/openshift_groups/managed_roles.py +3 -2
  241. reconcile/gql_definitions/openshift_serviceaccount_tokens/__init__.py +0 -0
  242. reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +132 -0
  243. reconcile/gql_definitions/quay_membership/quay_membership.py +3 -5
  244. reconcile/gql_definitions/rhidp/__init__.py +0 -0
  245. reconcile/gql_definitions/rhidp/organizations.py +96 -0
  246. reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +2 -2
  247. reconcile/gql_definitions/service_dependencies/service_dependencies.py +9 -31
  248. reconcile/gql_definitions/sharding/aws_accounts.py +2 -2
  249. reconcile/gql_definitions/sharding/ocm_organization.py +63 -0
  250. reconcile/gql_definitions/skupper_network/site_controller_template.py +2 -2
  251. reconcile/gql_definitions/skupper_network/skupper_networks.py +12 -38
  252. reconcile/gql_definitions/slack_usergroups/clusters.py +2 -2
  253. reconcile/gql_definitions/slack_usergroups/permissions.py +8 -15
  254. reconcile/gql_definitions/slack_usergroups/users.py +3 -2
  255. reconcile/gql_definitions/slo_documents/__init__.py +0 -0
  256. reconcile/gql_definitions/slo_documents/slo_documents.py +142 -0
  257. reconcile/gql_definitions/status_board/__init__.py +0 -0
  258. reconcile/gql_definitions/status_board/status_board.py +163 -0
  259. reconcile/gql_definitions/statuspage/statuspages.py +56 -7
  260. reconcile/gql_definitions/templating/__init__.py +0 -0
  261. reconcile/gql_definitions/templating/template_collection.py +130 -0
  262. reconcile/gql_definitions/templating/templates.py +108 -0
  263. reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +4 -8
  264. reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +8 -8
  265. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +6 -8
  266. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +45 -56
  267. reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +4 -8
  268. reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +4 -8
  269. reconcile/gql_definitions/terraform_init/__init__.py +0 -0
  270. reconcile/gql_definitions/terraform_init/aws_accounts.py +93 -0
  271. reconcile/gql_definitions/terraform_repo/__init__.py +0 -0
  272. reconcile/gql_definitions/terraform_repo/terraform_repo.py +141 -0
  273. reconcile/gql_definitions/terraform_resources/database_access_manager.py +158 -0
  274. reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +153 -162
  275. reconcile/gql_definitions/terraform_tgw_attachments/__init__.py +0 -0
  276. reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +119 -0
  277. reconcile/gql_definitions/unleash_feature_toggles/__init__.py +0 -0
  278. reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +113 -0
  279. reconcile/gql_definitions/vault_instances/vault_instances.py +17 -50
  280. reconcile/gql_definitions/vault_policies/vault_policies.py +2 -2
  281. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +49 -12
  282. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +7 -2
  283. reconcile/integrations_manager.py +25 -13
  284. reconcile/jenkins/types.py +5 -1
  285. reconcile/jenkins_base.py +36 -0
  286. reconcile/jenkins_job_builder.py +10 -48
  287. reconcile/jenkins_job_builds_cleaner.py +40 -25
  288. reconcile/jenkins_job_cleaner.py +1 -3
  289. reconcile/jenkins_roles.py +22 -26
  290. reconcile/jenkins_webhooks.py +9 -6
  291. reconcile/jenkins_worker_fleets.py +11 -6
  292. reconcile/jira_permissions_validator.py +340 -0
  293. reconcile/jira_watcher.py +3 -5
  294. reconcile/ldap_groups/__init__.py +0 -0
  295. reconcile/ldap_groups/integration.py +279 -0
  296. reconcile/ldap_users.py +3 -0
  297. reconcile/ocm/types.py +39 -59
  298. reconcile/ocm_additional_routers.py +0 -1
  299. reconcile/ocm_addons_upgrade_tests_trigger.py +10 -15
  300. reconcile/ocm_aws_infrastructure_access.py +30 -32
  301. reconcile/ocm_clusters.py +217 -130
  302. reconcile/ocm_external_configuration_labels.py +15 -0
  303. reconcile/ocm_github_idp.py +1 -1
  304. reconcile/ocm_groups.py +25 -5
  305. reconcile/ocm_internal_notifications/__init__.py +0 -0
  306. reconcile/ocm_internal_notifications/integration.py +119 -0
  307. reconcile/ocm_labels/__init__.py +0 -0
  308. reconcile/ocm_labels/integration.py +409 -0
  309. reconcile/ocm_machine_pools.py +517 -108
  310. reconcile/ocm_upgrade_scheduler_org_updater.py +15 -11
  311. reconcile/openshift_base.py +609 -207
  312. reconcile/openshift_cluster_bots.py +344 -0
  313. reconcile/openshift_clusterrolebindings.py +15 -15
  314. reconcile/openshift_groups.py +42 -45
  315. reconcile/openshift_limitranges.py +1 -0
  316. reconcile/openshift_namespace_labels.py +22 -28
  317. reconcile/openshift_namespaces.py +22 -22
  318. reconcile/openshift_network_policies.py +4 -8
  319. reconcile/openshift_prometheus_rules.py +43 -0
  320. reconcile/openshift_resourcequotas.py +2 -16
  321. reconcile/openshift_resources.py +12 -10
  322. reconcile/openshift_resources_base.py +304 -328
  323. reconcile/openshift_rolebindings.py +18 -20
  324. reconcile/openshift_saas_deploy.py +105 -21
  325. reconcile/openshift_saas_deploy_change_tester.py +30 -35
  326. reconcile/openshift_saas_deploy_trigger_base.py +39 -36
  327. reconcile/openshift_saas_deploy_trigger_cleaner.py +41 -27
  328. reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
  329. reconcile/openshift_saas_deploy_trigger_images.py +1 -2
  330. reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
  331. reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
  332. reconcile/openshift_serviceaccount_tokens.py +138 -74
  333. reconcile/openshift_tekton_resources.py +89 -24
  334. reconcile/openshift_upgrade_watcher.py +110 -62
  335. reconcile/openshift_users.py +16 -15
  336. reconcile/openshift_vault_secrets.py +11 -6
  337. reconcile/oum/__init__.py +0 -0
  338. reconcile/oum/base.py +387 -0
  339. reconcile/oum/labelset.py +55 -0
  340. reconcile/oum/metrics.py +71 -0
  341. reconcile/oum/models.py +69 -0
  342. reconcile/oum/providers.py +59 -0
  343. reconcile/oum/standalone.py +196 -0
  344. reconcile/prometheus_rules_tester/integration.py +31 -23
  345. reconcile/quay_base.py +4 -1
  346. reconcile/quay_membership.py +1 -2
  347. reconcile/quay_mirror.py +111 -61
  348. reconcile/quay_mirror_org.py +34 -21
  349. reconcile/quay_permissions.py +7 -3
  350. reconcile/quay_repos.py +24 -32
  351. reconcile/queries.py +263 -198
  352. reconcile/query_validator.py +3 -5
  353. reconcile/resource_scraper.py +3 -4
  354. reconcile/{template_tester.py → resource_template_tester.py} +3 -3
  355. reconcile/rhidp/__init__.py +0 -0
  356. reconcile/rhidp/common.py +214 -0
  357. reconcile/rhidp/metrics.py +20 -0
  358. reconcile/rhidp/ocm_oidc_idp/__init__.py +0 -0
  359. reconcile/rhidp/ocm_oidc_idp/base.py +221 -0
  360. reconcile/rhidp/ocm_oidc_idp/integration.py +56 -0
  361. reconcile/rhidp/ocm_oidc_idp/metrics.py +22 -0
  362. reconcile/rhidp/sso_client/__init__.py +0 -0
  363. reconcile/rhidp/sso_client/base.py +266 -0
  364. reconcile/rhidp/sso_client/integration.py +60 -0
  365. reconcile/rhidp/sso_client/metrics.py +39 -0
  366. reconcile/run_integration.py +293 -0
  367. reconcile/saas_auto_promotions_manager/integration.py +69 -24
  368. reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +208 -0
  369. reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py +28 -0
  370. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py +3 -4
  371. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +172 -0
  372. reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py +42 -0
  373. reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +226 -0
  374. reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py +23 -0
  375. reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +108 -32
  376. reconcile/saas_auto_promotions_manager/meta.py +4 -0
  377. reconcile/saas_auto_promotions_manager/publisher.py +32 -4
  378. reconcile/saas_auto_promotions_manager/s3_exporter.py +77 -0
  379. reconcile/saas_auto_promotions_manager/subscriber.py +110 -23
  380. reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +48 -41
  381. reconcile/saas_file_validator.py +16 -6
  382. reconcile/sendgrid_teammates.py +27 -12
  383. reconcile/service_dependencies.py +0 -3
  384. reconcile/signalfx_endpoint_monitoring.py +2 -5
  385. reconcile/skupper_network/integration.py +10 -11
  386. reconcile/skupper_network/models.py +3 -5
  387. reconcile/skupper_network/reconciler.py +28 -35
  388. reconcile/skupper_network/site_controller.py +8 -8
  389. reconcile/slack_base.py +4 -7
  390. reconcile/slack_usergroups.py +249 -171
  391. reconcile/sql_query.py +324 -171
  392. reconcile/status.py +0 -1
  393. reconcile/status_board.py +275 -0
  394. reconcile/statuspage/__init__.py +0 -5
  395. reconcile/statuspage/atlassian.py +219 -80
  396. reconcile/statuspage/integration.py +9 -97
  397. reconcile/statuspage/integrations/__init__.py +0 -0
  398. reconcile/statuspage/integrations/components.py +77 -0
  399. reconcile/statuspage/integrations/maintenances.py +111 -0
  400. reconcile/statuspage/page.py +107 -72
  401. reconcile/statuspage/state.py +6 -11
  402. reconcile/statuspage/status.py +8 -12
  403. reconcile/templates/rosa-classic-cluster-creation.sh.j2 +60 -0
  404. reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +61 -0
  405. reconcile/templating/__init__.py +0 -0
  406. reconcile/templating/lib/__init__.py +0 -0
  407. reconcile/templating/lib/merge_request_manager.py +180 -0
  408. reconcile/templating/lib/model.py +20 -0
  409. reconcile/templating/lib/rendering.py +191 -0
  410. reconcile/templating/renderer.py +410 -0
  411. reconcile/templating/validator.py +153 -0
  412. reconcile/terraform_aws_route53.py +13 -10
  413. reconcile/terraform_cloudflare_dns.py +92 -122
  414. reconcile/terraform_cloudflare_resources.py +15 -13
  415. reconcile/terraform_cloudflare_users.py +27 -27
  416. reconcile/terraform_init/__init__.py +0 -0
  417. reconcile/terraform_init/integration.py +165 -0
  418. reconcile/terraform_init/merge_request.py +57 -0
  419. reconcile/terraform_init/merge_request_manager.py +102 -0
  420. reconcile/terraform_repo.py +403 -0
  421. reconcile/terraform_resources.py +266 -168
  422. reconcile/terraform_tgw_attachments.py +417 -167
  423. reconcile/terraform_users.py +40 -17
  424. reconcile/terraform_vpc_peerings.py +310 -142
  425. reconcile/terraform_vpc_resources/__init__.py +0 -0
  426. reconcile/terraform_vpc_resources/integration.py +220 -0
  427. reconcile/terraform_vpc_resources/merge_request.py +57 -0
  428. reconcile/terraform_vpc_resources/merge_request_manager.py +107 -0
  429. reconcile/typed_queries/alerting_services_settings.py +1 -2
  430. reconcile/typed_queries/app_interface_custom_messages.py +24 -0
  431. reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +17 -0
  432. reconcile/typed_queries/app_interface_metrics_exporter/__init__.py +0 -0
  433. reconcile/typed_queries/app_interface_metrics_exporter/onboarding_status.py +13 -0
  434. reconcile/typed_queries/app_interface_repo_url.py +1 -2
  435. reconcile/typed_queries/app_interface_state_settings.py +1 -3
  436. reconcile/typed_queries/app_interface_vault_settings.py +1 -2
  437. reconcile/typed_queries/app_quay_repos_escalation_policies.py +14 -0
  438. reconcile/typed_queries/apps.py +11 -0
  439. reconcile/typed_queries/aws_vpc_requests.py +9 -0
  440. reconcile/typed_queries/aws_vpcs.py +12 -0
  441. reconcile/typed_queries/cloudflare.py +10 -0
  442. reconcile/typed_queries/clusters.py +7 -5
  443. reconcile/typed_queries/clusters_minimal.py +6 -5
  444. reconcile/typed_queries/clusters_with_dms.py +16 -0
  445. reconcile/typed_queries/cost_report/__init__.py +0 -0
  446. reconcile/typed_queries/cost_report/app_names.py +22 -0
  447. reconcile/typed_queries/cost_report/cost_namespaces.py +43 -0
  448. reconcile/typed_queries/cost_report/settings.py +15 -0
  449. reconcile/typed_queries/dynatrace.py +10 -0
  450. reconcile/typed_queries/dynatrace_environments.py +14 -0
  451. reconcile/typed_queries/dynatrace_token_provider_token_specs.py +14 -0
  452. reconcile/typed_queries/external_resources.py +46 -0
  453. reconcile/typed_queries/get_state_aws_account.py +20 -0
  454. reconcile/typed_queries/glitchtip.py +10 -0
  455. reconcile/typed_queries/jenkins.py +25 -0
  456. reconcile/typed_queries/jira.py +7 -0
  457. reconcile/typed_queries/jira_settings.py +16 -0
  458. reconcile/typed_queries/jiralert_settings.py +22 -0
  459. reconcile/typed_queries/ocm.py +8 -0
  460. reconcile/typed_queries/pagerduty_instances.py +2 -7
  461. reconcile/typed_queries/quay.py +23 -0
  462. reconcile/typed_queries/repos.py +20 -8
  463. reconcile/typed_queries/reserved_networks.py +12 -0
  464. reconcile/typed_queries/saas_files.py +221 -167
  465. reconcile/typed_queries/slack.py +7 -0
  466. reconcile/typed_queries/slo_documents.py +12 -0
  467. reconcile/typed_queries/status_board.py +58 -0
  468. reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
  469. reconcile/typed_queries/terraform_namespaces.py +1 -2
  470. reconcile/typed_queries/terraform_tgw_attachments/__init__.py +0 -0
  471. reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +16 -0
  472. reconcile/typed_queries/unleash.py +10 -0
  473. reconcile/typed_queries/users.py +11 -0
  474. reconcile/typed_queries/vault.py +10 -0
  475. reconcile/unleash_feature_toggles/__init__.py +0 -0
  476. reconcile/unleash_feature_toggles/integration.py +287 -0
  477. reconcile/utils/acs/__init__.py +0 -0
  478. reconcile/utils/acs/base.py +81 -0
  479. reconcile/utils/acs/notifiers.py +143 -0
  480. reconcile/utils/acs/policies.py +163 -0
  481. reconcile/utils/acs/rbac.py +277 -0
  482. reconcile/utils/aggregated_list.py +11 -9
  483. reconcile/utils/amtool.py +6 -4
  484. reconcile/utils/aws_api.py +279 -66
  485. reconcile/utils/aws_api_typed/__init__.py +0 -0
  486. reconcile/utils/aws_api_typed/account.py +23 -0
  487. reconcile/utils/aws_api_typed/api.py +273 -0
  488. reconcile/utils/aws_api_typed/dynamodb.py +16 -0
  489. reconcile/utils/aws_api_typed/iam.py +67 -0
  490. reconcile/utils/aws_api_typed/organization.py +152 -0
  491. reconcile/utils/aws_api_typed/s3.py +26 -0
  492. reconcile/utils/aws_api_typed/service_quotas.py +79 -0
  493. reconcile/utils/aws_api_typed/sts.py +36 -0
  494. reconcile/utils/aws_api_typed/support.py +79 -0
  495. reconcile/utils/aws_helper.py +42 -3
  496. reconcile/utils/batches.py +11 -0
  497. reconcile/utils/binary.py +7 -9
  498. reconcile/utils/cloud_resource_best_practice/__init__.py +0 -0
  499. reconcile/utils/cloud_resource_best_practice/aws_rds.py +66 -0
  500. reconcile/utils/clusterhealth/__init__.py +0 -0
  501. reconcile/utils/clusterhealth/providerbase.py +39 -0
  502. reconcile/utils/clusterhealth/telemeter.py +39 -0
  503. reconcile/utils/config.py +3 -4
  504. reconcile/utils/deadmanssnitch_api.py +86 -0
  505. reconcile/utils/differ.py +205 -0
  506. reconcile/utils/disabled_integrations.py +4 -6
  507. reconcile/utils/dynatrace/__init__.py +0 -0
  508. reconcile/utils/dynatrace/client.py +93 -0
  509. reconcile/utils/early_exit_cache.py +289 -0
  510. reconcile/utils/elasticsearch_exceptions.py +5 -0
  511. reconcile/utils/environ.py +2 -2
  512. reconcile/utils/exceptions.py +4 -0
  513. reconcile/utils/expiration.py +4 -8
  514. reconcile/utils/extended_early_exit.py +210 -0
  515. reconcile/utils/external_resource_spec.py +34 -12
  516. reconcile/utils/external_resources.py +48 -20
  517. reconcile/utils/filtering.py +16 -0
  518. reconcile/utils/git.py +49 -16
  519. reconcile/utils/github_api.py +10 -9
  520. reconcile/utils/gitlab_api.py +333 -190
  521. reconcile/utils/glitchtip/client.py +97 -100
  522. reconcile/utils/glitchtip/models.py +89 -11
  523. reconcile/utils/gql.py +157 -58
  524. reconcile/utils/grouping.py +17 -0
  525. reconcile/utils/helm.py +89 -18
  526. reconcile/utils/helpers.py +51 -0
  527. reconcile/utils/imap_client.py +5 -6
  528. reconcile/utils/internal_groups/__init__.py +0 -0
  529. reconcile/utils/internal_groups/client.py +160 -0
  530. reconcile/utils/internal_groups/models.py +71 -0
  531. reconcile/utils/jenkins_api.py +10 -34
  532. reconcile/utils/jinja2/__init__.py +0 -0
  533. reconcile/utils/{jinja2_ext.py → jinja2/extensions.py} +6 -4
  534. reconcile/utils/jinja2/filters.py +142 -0
  535. reconcile/utils/jinja2/utils.py +278 -0
  536. reconcile/utils/jira_client.py +165 -8
  537. reconcile/utils/jjb_client.py +47 -35
  538. reconcile/utils/jobcontroller/__init__.py +0 -0
  539. reconcile/utils/jobcontroller/controller.py +413 -0
  540. reconcile/utils/jobcontroller/models.py +195 -0
  541. reconcile/utils/jsonpath.py +4 -5
  542. reconcile/utils/jump_host.py +13 -12
  543. reconcile/utils/keycloak.py +106 -0
  544. reconcile/utils/ldap_client.py +35 -6
  545. reconcile/utils/lean_terraform_client.py +115 -6
  546. reconcile/utils/membershipsources/__init__.py +0 -0
  547. reconcile/utils/membershipsources/app_interface_resolver.py +60 -0
  548. reconcile/utils/membershipsources/models.py +91 -0
  549. reconcile/utils/membershipsources/resolver.py +110 -0
  550. reconcile/utils/merge_request_manager/__init__.py +0 -0
  551. reconcile/utils/merge_request_manager/merge_request_manager.py +99 -0
  552. reconcile/utils/merge_request_manager/parser.py +67 -0
  553. reconcile/utils/metrics.py +511 -1
  554. reconcile/utils/models.py +123 -0
  555. reconcile/utils/mr/README.md +198 -0
  556. reconcile/utils/mr/__init__.py +14 -10
  557. reconcile/utils/mr/app_interface_reporter.py +2 -2
  558. reconcile/utils/mr/aws_access.py +4 -4
  559. reconcile/utils/mr/base.py +51 -31
  560. reconcile/utils/mr/clusters_updates.py +10 -7
  561. reconcile/utils/mr/glitchtip_access_reporter.py +2 -4
  562. reconcile/utils/mr/labels.py +14 -1
  563. reconcile/utils/mr/notificator.py +1 -3
  564. reconcile/utils/mr/ocm_update_recommended_version.py +1 -2
  565. reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +7 -3
  566. reconcile/utils/mr/promote_qontract.py +203 -0
  567. reconcile/utils/mr/user_maintenance.py +24 -4
  568. reconcile/utils/oauth2_backend_application_session.py +132 -0
  569. reconcile/utils/oc.py +194 -170
  570. reconcile/utils/oc_connection_parameters.py +40 -51
  571. reconcile/utils/oc_filters.py +11 -13
  572. reconcile/utils/oc_map.py +14 -35
  573. reconcile/utils/ocm/__init__.py +30 -1
  574. reconcile/utils/ocm/addons.py +228 -0
  575. reconcile/utils/ocm/base.py +618 -5
  576. reconcile/utils/ocm/cluster_groups.py +5 -56
  577. reconcile/utils/ocm/clusters.py +111 -99
  578. reconcile/utils/ocm/identity_providers.py +66 -0
  579. reconcile/utils/ocm/label_sources.py +75 -0
  580. reconcile/utils/ocm/labels.py +139 -54
  581. reconcile/utils/ocm/manifests.py +39 -0
  582. reconcile/utils/ocm/ocm.py +182 -928
  583. reconcile/utils/ocm/products.py +758 -0
  584. reconcile/utils/ocm/search_filters.py +20 -28
  585. reconcile/utils/ocm/service_log.py +32 -79
  586. reconcile/utils/ocm/sre_capability_labels.py +51 -0
  587. reconcile/utils/ocm/status_board.py +66 -0
  588. reconcile/utils/ocm/subscriptions.py +49 -59
  589. reconcile/utils/ocm/syncsets.py +39 -0
  590. reconcile/utils/ocm/upgrades.py +181 -0
  591. reconcile/utils/ocm_base_client.py +71 -36
  592. reconcile/utils/openshift_resource.py +113 -67
  593. reconcile/utils/output.py +18 -11
  594. reconcile/utils/pagerduty_api.py +16 -10
  595. reconcile/utils/parse_dhms_duration.py +13 -1
  596. reconcile/utils/prometheus.py +123 -0
  597. reconcile/utils/promotion_state.py +56 -19
  598. reconcile/utils/promtool.py +5 -8
  599. reconcile/utils/quay_api.py +13 -25
  600. reconcile/utils/raw_github_api.py +3 -5
  601. reconcile/utils/repo_owners.py +2 -8
  602. reconcile/utils/rest_api_base.py +126 -0
  603. reconcile/utils/rosa/__init__.py +0 -0
  604. reconcile/utils/rosa/rosa_cli.py +310 -0
  605. reconcile/utils/rosa/session.py +201 -0
  606. reconcile/utils/ruamel.py +16 -0
  607. reconcile/utils/runtime/__init__.py +0 -1
  608. reconcile/utils/runtime/desired_state_diff.py +9 -20
  609. reconcile/utils/runtime/environment.py +33 -8
  610. reconcile/utils/runtime/integration.py +28 -12
  611. reconcile/utils/runtime/meta.py +1 -3
  612. reconcile/utils/runtime/runner.py +8 -11
  613. reconcile/utils/runtime/sharding.py +93 -36
  614. reconcile/utils/saasherder/__init__.py +1 -1
  615. reconcile/utils/saasherder/interfaces.py +143 -138
  616. reconcile/utils/saasherder/models.py +201 -43
  617. reconcile/utils/saasherder/saasherder.py +508 -378
  618. reconcile/utils/secret_reader.py +22 -27
  619. reconcile/utils/semver_helper.py +15 -1
  620. reconcile/utils/slack_api.py +124 -36
  621. reconcile/utils/smtp_client.py +1 -2
  622. reconcile/utils/sqs_gateway.py +10 -6
  623. reconcile/utils/state.py +276 -127
  624. reconcile/utils/terraform/config_client.py +6 -7
  625. reconcile/utils/terraform_client.py +284 -125
  626. reconcile/utils/terrascript/cloudflare_client.py +38 -17
  627. reconcile/utils/terrascript/cloudflare_resources.py +67 -18
  628. reconcile/utils/terrascript/models.py +2 -3
  629. reconcile/utils/terrascript/resources.py +1 -2
  630. reconcile/utils/terrascript_aws_client.py +1292 -540
  631. reconcile/utils/three_way_diff_strategy.py +157 -0
  632. reconcile/utils/unleash/__init__.py +11 -0
  633. reconcile/utils/{unleash.py → unleash/client.py} +35 -29
  634. reconcile/utils/unleash/server.py +145 -0
  635. reconcile/utils/vault.py +42 -32
  636. reconcile/utils/vaultsecretref.py +2 -4
  637. reconcile/utils/vcs.py +250 -0
  638. reconcile/vault_replication.py +38 -31
  639. reconcile/vpc_peerings_validator.py +82 -13
  640. tools/app_interface_metrics_exporter.py +70 -0
  641. tools/app_interface_reporter.py +44 -157
  642. tools/cli_commands/container_images_report.py +154 -0
  643. tools/cli_commands/cost_report/__init__.py +0 -0
  644. tools/cli_commands/cost_report/aws.py +137 -0
  645. tools/cli_commands/cost_report/cost_management_api.py +155 -0
  646. tools/cli_commands/cost_report/model.py +49 -0
  647. tools/cli_commands/cost_report/openshift.py +166 -0
  648. tools/cli_commands/cost_report/openshift_cost_optimization.py +187 -0
  649. tools/cli_commands/cost_report/response.py +124 -0
  650. tools/cli_commands/cost_report/util.py +72 -0
  651. tools/cli_commands/cost_report/view.py +524 -0
  652. tools/cli_commands/erv2.py +620 -0
  653. tools/cli_commands/gpg_encrypt.py +5 -8
  654. tools/cli_commands/systems_and_tools.py +489 -0
  655. tools/glitchtip_access_revalidation.py +1 -1
  656. tools/qontract_cli.py +2301 -673
  657. tools/saas_metrics_exporter/__init__.py +0 -0
  658. tools/saas_metrics_exporter/commit_distance/__init__.py +0 -0
  659. tools/saas_metrics_exporter/commit_distance/channel.py +63 -0
  660. tools/saas_metrics_exporter/commit_distance/commit_distance.py +103 -0
  661. tools/saas_metrics_exporter/commit_distance/metrics.py +19 -0
  662. tools/saas_metrics_exporter/main.py +99 -0
  663. tools/saas_promotion_state/__init__.py +0 -0
  664. tools/saas_promotion_state/saas_promotion_state.py +105 -0
  665. tools/sd_app_sre_alert_report.py +145 -0
  666. tools/template_validation.py +107 -0
  667. e2e_tests/cli.py +0 -83
  668. e2e_tests/create_namespace.py +0 -43
  669. e2e_tests/dedicated_admin_rolebindings.py +0 -44
  670. e2e_tests/dedicated_admin_test_base.py +0 -39
  671. e2e_tests/default_network_policies.py +0 -47
  672. e2e_tests/default_project_labels.py +0 -52
  673. e2e_tests/network_policy_test_base.py +0 -17
  674. e2e_tests/test_base.py +0 -56
  675. qontract_reconcile-0.9.1rc298.dist-info/METADATA +0 -63
  676. qontract_reconcile-0.9.1rc298.dist-info/RECORD +0 -585
  677. qontract_reconcile-0.9.1rc298.dist-info/top_level.txt +0 -4
  678. reconcile/ecr_mirror.py +0 -152
  679. reconcile/github_scanner.py +0 -74
  680. reconcile/gitlab_integrations.py +0 -63
  681. reconcile/gql_definitions/ocm_oidc_idp/clusters.py +0 -195
  682. reconcile/gql_definitions/ocp_release_mirror/ocp_release_mirror.py +0 -287
  683. reconcile/integrations_validator.py +0 -18
  684. reconcile/jenkins_plugins.py +0 -129
  685. reconcile/kafka_clusters.py +0 -208
  686. reconcile/ocm_cluster_admin.py +0 -42
  687. reconcile/ocm_oidc_idp.py +0 -198
  688. reconcile/ocp_release_mirror.py +0 -373
  689. reconcile/prometheus_rules_tester_old.py +0 -436
  690. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -279
  691. reconcile/saas_auto_promotions_manager/utils/vcs.py +0 -141
  692. reconcile/sentry_config.py +0 -613
  693. reconcile/sentry_helper.py +0 -69
  694. reconcile/test/conftest.py +0 -187
  695. reconcile/test/fixtures.py +0 -24
  696. reconcile/test/saas_auto_promotions_manager/conftest.py +0 -69
  697. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -110
  698. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -10
  699. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_housekeeping.py +0 -200
  700. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -151
  701. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -63
  702. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
  703. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -46
  704. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -94
  705. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -44
  706. reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -74
  707. reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
  708. reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -155
  709. reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -173
  710. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -226
  711. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -224
  712. reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -350
  713. reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -129
  714. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -70
  715. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -63
  716. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -74
  717. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -65
  718. reconcile/test/test_aggregated_list.py +0 -237
  719. reconcile/test/test_amtool.py +0 -37
  720. reconcile/test/test_auto_promoter.py +0 -295
  721. reconcile/test/test_aws_ami_share.py +0 -68
  722. reconcile/test/test_aws_iam_keys.py +0 -70
  723. reconcile/test/test_aws_iam_password_reset.py +0 -35
  724. reconcile/test/test_aws_support_cases_sos.py +0 -23
  725. reconcile/test/test_checkpoint.py +0 -178
  726. reconcile/test/test_cli.py +0 -41
  727. reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
  728. reconcile/test/test_gabi_authorized_users.py +0 -72
  729. reconcile/test/test_github_org.py +0 -154
  730. reconcile/test/test_github_repo_invites.py +0 -123
  731. reconcile/test/test_gitlab_housekeeping.py +0 -88
  732. reconcile/test/test_gitlab_labeler.py +0 -129
  733. reconcile/test/test_gitlab_members.py +0 -283
  734. reconcile/test/test_instrumented_wrappers.py +0 -18
  735. reconcile/test/test_integrations_manager.py +0 -995
  736. reconcile/test/test_jenkins_worker_fleets.py +0 -55
  737. reconcile/test/test_jump_host.py +0 -117
  738. reconcile/test/test_ldap_users.py +0 -123
  739. reconcile/test/test_make.py +0 -28
  740. reconcile/test/test_ocm_additional_routers.py +0 -134
  741. reconcile/test/test_ocm_addons_upgrade_scheduler_org.py +0 -149
  742. reconcile/test/test_ocm_clusters.py +0 -598
  743. reconcile/test/test_ocm_clusters_manifest_updates.py +0 -89
  744. reconcile/test/test_ocm_oidc_idp.py +0 -315
  745. reconcile/test/test_ocm_update_recommended_version.py +0 -145
  746. reconcile/test/test_ocm_upgrade_scheduler.py +0 -614
  747. reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -129
  748. reconcile/test/test_openshift_base.py +0 -730
  749. reconcile/test/test_openshift_namespace_labels.py +0 -345
  750. reconcile/test/test_openshift_namespaces.py +0 -256
  751. reconcile/test/test_openshift_resource.py +0 -415
  752. reconcile/test/test_openshift_resources_base.py +0 -440
  753. reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -310
  754. reconcile/test/test_openshift_tekton_resources.py +0 -253
  755. reconcile/test/test_openshift_upgrade_watcher.py +0 -146
  756. reconcile/test/test_prometheus_rules_tester.py +0 -151
  757. reconcile/test/test_prometheus_rules_tester_old.py +0 -77
  758. reconcile/test/test_quay_membership.py +0 -86
  759. reconcile/test/test_quay_mirror.py +0 -109
  760. reconcile/test/test_quay_mirror_org.py +0 -70
  761. reconcile/test/test_quay_repos.py +0 -59
  762. reconcile/test/test_queries.py +0 -53
  763. reconcile/test/test_repo_owners.py +0 -47
  764. reconcile/test/test_requests_sender.py +0 -139
  765. reconcile/test/test_saasherder.py +0 -1074
  766. reconcile/test/test_saasherder_allowed_secret_paths.py +0 -127
  767. reconcile/test/test_secret_reader.py +0 -153
  768. reconcile/test/test_slack_base.py +0 -185
  769. reconcile/test/test_slack_usergroups.py +0 -744
  770. reconcile/test/test_sql_query.py +0 -19
  771. reconcile/test/test_terraform_cloudflare_dns.py +0 -117
  772. reconcile/test/test_terraform_cloudflare_resources.py +0 -106
  773. reconcile/test/test_terraform_cloudflare_users.py +0 -749
  774. reconcile/test/test_terraform_resources.py +0 -257
  775. reconcile/test/test_terraform_tgw_attachments.py +0 -631
  776. reconcile/test/test_terraform_users.py +0 -57
  777. reconcile/test/test_terraform_vpc_peerings.py +0 -499
  778. reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1061
  779. reconcile/test/test_unleash.py +0 -138
  780. reconcile/test/test_utils_aws_api.py +0 -240
  781. reconcile/test/test_utils_aws_helper.py +0 -80
  782. reconcile/test/test_utils_cluster_version_data.py +0 -177
  783. reconcile/test/test_utils_data_structures.py +0 -13
  784. reconcile/test/test_utils_disabled_integrations.py +0 -86
  785. reconcile/test/test_utils_expiration.py +0 -109
  786. reconcile/test/test_utils_external_resource_spec.py +0 -383
  787. reconcile/test/test_utils_external_resources.py +0 -247
  788. reconcile/test/test_utils_github_api.py +0 -73
  789. reconcile/test/test_utils_gitlab_api.py +0 -20
  790. reconcile/test/test_utils_gpg.py +0 -69
  791. reconcile/test/test_utils_gql.py +0 -81
  792. reconcile/test/test_utils_helm.py +0 -306
  793. reconcile/test/test_utils_helpers.py +0 -55
  794. reconcile/test/test_utils_imap_client.py +0 -65
  795. reconcile/test/test_utils_jjb_client.py +0 -52
  796. reconcile/test/test_utils_jsonpath.py +0 -286
  797. reconcile/test/test_utils_ldap_client.py +0 -51
  798. reconcile/test/test_utils_mr.py +0 -226
  799. reconcile/test/test_utils_mr_clusters_updates.py +0 -77
  800. reconcile/test/test_utils_oc.py +0 -984
  801. reconcile/test/test_utils_ocm.py +0 -110
  802. reconcile/test/test_utils_pagerduty_api.py +0 -251
  803. reconcile/test/test_utils_parse_dhms_duration.py +0 -34
  804. reconcile/test/test_utils_password_validator.py +0 -155
  805. reconcile/test/test_utils_quay_api.py +0 -86
  806. reconcile/test/test_utils_semver_helper.py +0 -19
  807. reconcile/test/test_utils_sharding.py +0 -56
  808. reconcile/test/test_utils_slack_api.py +0 -439
  809. reconcile/test/test_utils_smtp_client.py +0 -73
  810. reconcile/test/test_utils_state.py +0 -256
  811. reconcile/test/test_utils_terraform.py +0 -13
  812. reconcile/test/test_utils_terraform_client.py +0 -585
  813. reconcile/test/test_utils_terraform_config_client.py +0 -219
  814. reconcile/test/test_utils_terrascript_aws_client.py +0 -277
  815. reconcile/test/test_utils_terrascript_cloudflare_client.py +0 -597
  816. reconcile/test/test_utils_terrascript_cloudflare_resources.py +0 -26
  817. reconcile/test/test_vault_replication.py +0 -515
  818. reconcile/test/test_vault_utils.py +0 -47
  819. reconcile/test/test_version_bump.py +0 -18
  820. reconcile/test/test_vpc_peerings_validator.py +0 -103
  821. reconcile/test/test_wrong_region.py +0 -78
  822. reconcile/typed_queries/glitchtip_settings.py +0 -18
  823. reconcile/typed_queries/ocp_release_mirror.py +0 -11
  824. reconcile/unleash_watcher.py +0 -120
  825. reconcile/utils/git_secrets.py +0 -63
  826. reconcile/utils/mr/auto_promoter.py +0 -218
  827. reconcile/utils/sentry_client.py +0 -383
  828. release/test_version.py +0 -50
  829. release/version.py +0 -100
  830. tools/test/test_qontract_cli.py +0 -60
  831. tools/test/test_sre_checkpoints.py +0 -79
  832. /e2e_tests/__init__.py → /reconcile/aus/upgrades.py +0 -0
  833. /reconcile/{gql_definitions/ocp_release_mirror → aws_account_manager}/__init__.py +0 -0
  834. /reconcile/{test → aws_ami_cleanup}/__init__.py +0 -0
  835. /reconcile/{test/saas_auto_promotions_manager → aws_cloudwatch_log_retention}/__init__.py +0 -0
  836. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager → aws_saml_idp}/__init__.py +0 -0
  837. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager → aws_saml_roles}/__init__.py +0 -0
  838. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/renderer → aws_version_sync}/__init__.py +0 -0
  839. /reconcile/{test/saas_auto_promotions_manager/subscriber → aws_version_sync/merge_request_manager}/__init__.py +0 -0
  840. /reconcile/{test/saas_auto_promotions_manager/utils → cluster_auth_rhidp}/__init__.py +0 -0
  841. /reconcile/{test/saas_auto_promotions_manager/utils/saas_files_inventory → dynatrace_token_provider}/__init__.py +0 -0
  842. {release → reconcile/endpoints_discovery}/__init__.py +0 -0
  843. {tools/test → reconcile/external_resources}/__init__.py +0 -0
@@ -1,3 +1,4 @@
1
+ import contextlib
1
2
  import sys
2
3
 
3
4
  import reconcile.openshift_base as ob
@@ -51,10 +52,10 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 3, 0)
51
52
  def construct_user_oc_resource(role, user):
52
53
  name = f"{role}-{user}"
53
54
  body = {
54
- "apiVersion": "authorization.openshift.io/v1",
55
+ "apiVersion": "rbac.authorization.k8s.io/v1",
55
56
  "kind": "RoleBinding",
56
57
  "metadata": {"name": name},
57
- "roleRef": {"name": role},
58
+ "roleRef": {"kind": "ClusterRole", "name": role},
58
59
  "subjects": [{"kind": "User", "name": user}],
59
60
  }
60
61
  return (
@@ -68,14 +69,13 @@ def construct_user_oc_resource(role, user):
68
69
  def construct_sa_oc_resource(role, namespace, sa_name):
69
70
  name = f"{role}-{namespace}-{sa_name}"
70
71
  body = {
71
- "apiVersion": "authorization.openshift.io/v1",
72
+ "apiVersion": "rbac.authorization.k8s.io/v1",
72
73
  "kind": "RoleBinding",
73
74
  "metadata": {"name": name},
74
- "roleRef": {"name": role},
75
+ "roleRef": {"kind": "ClusterRole", "name": role},
75
76
  "subjects": [
76
77
  {"kind": "ServiceAccount", "name": sa_name, "namespace": namespace}
77
78
  ],
78
- "userNames": [f"system:serviceaccount:{namespace}:{sa_name}"],
79
79
  }
80
80
  return (
81
81
  OR(
@@ -97,7 +97,8 @@ def fetch_desired_state(ri, oc_map, enforced_user_keys=None):
97
97
  "role": a["role"],
98
98
  }
99
99
  for a in role["access"] or []
100
- if None not in [a["namespace"], a["role"]]
100
+ if a["namespace"]
101
+ and a["role"]
101
102
  and a["namespace"].get("managedRoles")
102
103
  and not ob.is_namespace_deleted(a["namespace"])
103
104
  ]
@@ -136,19 +137,18 @@ def fetch_desired_state(ri, oc_map, enforced_user_keys=None):
136
137
  oc_resource, resource_name = construct_user_oc_resource(
137
138
  permission["role"], username
138
139
  )
139
- try:
140
+ with contextlib.suppress(ResourceKeyExistsError):
141
+ # a user may have a Role assigned to them
142
+ # from multiple app-interface roles
140
143
  ri.add_desired(
141
144
  cluster,
142
145
  perm_namespace_name,
143
- "RoleBinding.authorization.openshift.io",
146
+ "RoleBinding.rbac.authorization.k8s.io",
144
147
  resource_name,
145
148
  oc_resource,
146
149
  privileged=privileged,
147
150
  )
148
- except ResourceKeyExistsError:
149
- # a user may have a Role assigned to them
150
- # from multiple app-interface roles
151
- pass
151
+
152
152
  for sa in service_accounts:
153
153
  if ri is None:
154
154
  continue
@@ -156,20 +156,17 @@ def fetch_desired_state(ri, oc_map, enforced_user_keys=None):
156
156
  oc_resource, resource_name = construct_sa_oc_resource(
157
157
  permission["role"], sa_namespace_name, sa_name
158
158
  )
159
- try:
159
+ with contextlib.suppress(ResourceKeyExistsError):
160
+ # a ServiceAccount may have a Role assigned to it
161
+ # from multiple app-interface roles
160
162
  ri.add_desired(
161
163
  cluster,
162
164
  perm_namespace_name,
163
- "RoleBinding.authorization.openshift.io",
165
+ "RoleBinding.rbac.authorization.k8s.io",
164
166
  resource_name,
165
167
  oc_resource,
166
168
  privileged=privileged,
167
169
  )
168
- except ResourceKeyExistsError:
169
- # a ServiceAccount may have a Role assigned to it
170
- # from multiple app-interface roles
171
- pass
172
-
173
170
  return users_desired_state
174
171
 
175
172
 
@@ -189,12 +186,13 @@ def run(dry_run, thread_pool_size=10, internal=None, use_jump_host=True, defer=N
189
186
  thread_pool_size=thread_pool_size,
190
187
  integration=QONTRACT_INTEGRATION,
191
188
  integration_version=QONTRACT_INTEGRATION_VERSION,
192
- override_managed_types=["RoleBinding.authorization.openshift.io"],
189
+ override_managed_types=["RoleBinding.rbac.authorization.k8s.io"],
193
190
  internal=internal,
194
191
  use_jump_host=use_jump_host,
195
192
  )
196
193
  defer(oc_map.cleanup)
197
194
  fetch_desired_state(ri, oc_map)
195
+ ob.publish_metrics(ri, QONTRACT_INTEGRATION)
198
196
  ob.realize_data(dry_run, oc_map, ri, thread_pool_size)
199
197
 
200
198
  if ri.has_error_registered():
@@ -1,34 +1,39 @@
1
+ import json
1
2
  import logging
3
+ import os
2
4
  import sys
3
5
  from collections.abc import Callable
4
- from typing import Optional
5
6
 
6
- import reconcile.jenkins_plugins as jenkins_base
7
7
  import reconcile.openshift_base as ob
8
8
  from reconcile import (
9
- mr_client_gateway,
9
+ jenkins_base,
10
+ openshift_saas_deploy_trigger_images,
11
+ openshift_saas_deploy_trigger_upstream_jobs,
10
12
  queries,
11
13
  )
12
14
  from reconcile.gql_definitions.common.saas_files import PipelinesProviderTektonV1
13
- from reconcile.openshift_tekton_resources import build_one_per_saas_file_tkn_object_name
15
+ from reconcile.openshift_tekton_resources import (
16
+ build_one_per_saas_file_tkn_pipeline_name,
17
+ )
14
18
  from reconcile.slack_base import slackapi_from_slack_workspace
15
19
  from reconcile.status import ExitCodes
16
20
  from reconcile.typed_queries.app_interface_vault_settings import (
17
21
  get_app_interface_vault_settings,
18
22
  )
19
23
  from reconcile.typed_queries.saas_files import (
20
- get_saas_files,
24
+ SaasFile,
25
+ SaasFileList,
21
26
  get_saasherder_settings,
22
27
  )
23
28
  from reconcile.utils.defer import defer
24
29
  from reconcile.utils.gitlab_api import GitLabApi
25
30
  from reconcile.utils.openshift_resource import ResourceInventory
26
31
  from reconcile.utils.saasherder import SaasHerder
27
- from reconcile.utils.saasherder.interfaces import SaasFile
28
32
  from reconcile.utils.secret_reader import create_secret_reader
29
33
  from reconcile.utils.semver_helper import make_semver
30
34
  from reconcile.utils.slack_api import SlackApi
31
35
  from reconcile.utils.state import init_state
36
+ from reconcile.utils.unleash import get_feature_toggle_state
32
37
 
33
38
  QONTRACT_INTEGRATION = "openshift-saas-deploy"
34
39
  QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
@@ -44,13 +49,15 @@ def compose_console_url(saas_file: SaasFile, env_name: str) -> str:
44
49
  if not saas_file.pipelines_provider.pipeline_templates
45
50
  else saas_file.pipelines_provider.pipeline_templates.openshift_saas_deploy.name
46
51
  )
47
- pipeline_name = build_one_per_saas_file_tkn_object_name(
52
+ pipeline_name = build_one_per_saas_file_tkn_pipeline_name(
48
53
  pipeline_template_name, saas_file.name
49
54
  )
55
+ tkn_name, _ = SaasHerder.build_saas_file_env_combo(saas_file.name, env_name)
56
+
50
57
  return (
51
- f"{saas_file.pipelines_provider.namespace.cluster.console_url}/k8s/ns/{saas_file.pipelines_provider.namespace.name}/"
52
- + "tekton.dev~v1beta1~Pipeline/"
53
- + f"{pipeline_name}/Runs?name={saas_file.name}-{env_name}"
58
+ f"{saas_file.pipelines_provider.namespace.cluster.console_url}/k8s/ns/"
59
+ f"{saas_file.pipelines_provider.namespace.name}/tekton.dev~v1~Pipeline/"
60
+ f"{pipeline_name}/Runs?name={tkn_name}"
54
61
  )
55
62
 
56
63
 
@@ -61,8 +68,21 @@ def slack_notify(
61
68
  ri: ResourceInventory,
62
69
  console_url: str,
63
70
  in_progress: bool,
71
+ trigger_integration: str | None = None,
72
+ trigger_reason: str | None = None,
73
+ skip_successful_notifications: bool | None = False,
64
74
  ) -> None:
65
75
  success = not ri.has_error_registered()
76
+ # if the deployment doesn't want any notifications for successful
77
+ # deployments, then we should grant the wish. However, there's a user
78
+ # expereince concern where the deployment owners will receive a "in
79
+ # progress" notice but no subsequent notice. We handle this case by
80
+ # including an "fyi" message for in progress deployments down below.
81
+ if success and skip_successful_notifications and not in_progress:
82
+ logging.info(
83
+ f"Skipping Slack notification for {saas_file_name} to {env_name} because deploy was successful."
84
+ )
85
+ return
66
86
  if in_progress:
67
87
  icon = ":yellow_jenkins_circle:"
68
88
  description = "In Progress"
@@ -77,6 +97,12 @@ def slack_notify(
77
97
  + f"deployment to environment *{env_name}*: "
78
98
  + f"{description} (<{console_url}|Open>)"
79
99
  )
100
+ if trigger_reason:
101
+ message += f". Reason: {trigger_reason}"
102
+ if trigger_integration:
103
+ message += f" triggered by _{trigger_integration}_"
104
+ if in_progress and skip_successful_notifications:
105
+ message += ". There will not be a notice for success."
80
106
  slack.chat_post_message(message)
81
107
 
82
108
 
@@ -86,16 +112,21 @@ def run(
86
112
  thread_pool_size: int = 10,
87
113
  io_dir: str = "throughput/",
88
114
  use_jump_host: bool = True,
89
- saas_file_name: Optional[str] = None,
90
- env_name: Optional[str] = None,
91
- gitlab_project_id: Optional[str] = None,
92
- defer: Optional[Callable] = None,
115
+ saas_file_name: str | None = None,
116
+ env_name: str | None = None,
117
+ trigger_integration: str | None = None,
118
+ trigger_reason: str | None = None,
119
+ saas_file_list: SaasFileList | None = None,
120
+ defer: Callable | None = None,
93
121
  ) -> None:
94
122
  vault_settings = get_app_interface_vault_settings()
95
123
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
96
124
 
97
- all_saas_files = get_saas_files()
98
- saas_files = get_saas_files(saas_file_name, env_name)
125
+ if not saas_file_list:
126
+ saas_file_list = SaasFileList()
127
+ all_saas_files = saas_file_list.saas_files
128
+ saas_files = saas_file_list.where(name=saas_file_name, env_name=env_name)
129
+
99
130
  if not saas_files:
100
131
  logging.error("no saas files found")
101
132
  raise RuntimeError("no saas files found")
@@ -105,6 +136,9 @@ def run(
105
136
  # - this is not a dry run
106
137
  # - there is a single saas file deployed
107
138
  notify = not dry_run and len(saas_files) == 1
139
+ skip_successful_deploy_notifications = (
140
+ saas_files[0].skip_successful_deploy_notifications if saas_files else False
141
+ )
108
142
  slack = None
109
143
  if notify:
110
144
  saas_file = saas_files[0]
@@ -134,6 +168,9 @@ def run(
134
168
  ri,
135
169
  console_url,
136
170
  in_progress=False,
171
+ trigger_integration=trigger_integration,
172
+ trigger_reason=trigger_reason,
173
+ skip_successful_notifications=skip_successful_deploy_notifications,
137
174
  )
138
175
  )
139
176
  # deployment start notification
@@ -145,6 +182,9 @@ def run(
145
182
  ri,
146
183
  console_url,
147
184
  in_progress=True,
185
+ trigger_integration=trigger_integration,
186
+ trigger_reason=trigger_reason,
187
+ skip_successful_notifications=skip_successful_deploy_notifications,
148
188
  )
149
189
 
150
190
  jenkins_map = jenkins_base.get_jenkins_map()
@@ -169,6 +209,7 @@ def run(
169
209
  gitlab=gl,
170
210
  jenkins_map=jenkins_map,
171
211
  state=init_state(integration=QONTRACT_INTEGRATION, secret_reader=secret_reader),
212
+ all_saas_files=saas_file_list.saas_files,
172
213
  )
173
214
  if defer:
174
215
  defer(saasherder.cleanup)
@@ -176,6 +217,11 @@ def run(
176
217
  logging.warning("no targets found")
177
218
  sys.exit(ExitCodes.SUCCESS)
178
219
 
220
+ # check enable_init_projects flag status
221
+ enable_init_projects = get_feature_toggle_state(
222
+ "enable_init_projects",
223
+ default=False,
224
+ )
179
225
  ri, oc_map = ob.fetch_current_state(
180
226
  namespaces=[ns.dict(by_alias=True) for ns in saasherder.namespaces],
181
227
  thread_pool_size=thread_pool_size,
@@ -184,6 +230,7 @@ def run(
184
230
  init_api_resources=True,
185
231
  cluster_admin=bool(saasherder.cluster_admin),
186
232
  use_jump_host=use_jump_host,
233
+ init_projects=enable_init_projects,
187
234
  )
188
235
  if defer: # defer is provided by the method decorator. this makes just mypy happy
189
236
  defer(oc_map.cleanup)
@@ -198,7 +245,8 @@ def run(
198
245
 
199
246
  # validate that the deployment will succeed
200
247
  # to the best of our ability to predict
201
- ob.validate_planned_data(ri, oc_map)
248
+ if saasherder.validate_planned_data:
249
+ ob.validate_planned_data(ri, oc_map)
202
250
 
203
251
  # if saas_file_name is defined, the integration
204
252
  # is being called from multiple running instances
@@ -235,10 +283,7 @@ def run(
235
283
  # Auto-promotions are now created by saas-auto-promotions-manager integration
236
284
  # However, we still need saas-herder to publish the state to S3, because
237
285
  # saas-auto-promotions-manager needs that information
238
- with mr_client_gateway.init(gitlab_project_id=gitlab_project_id) as mr_cli:
239
- saasherder.publish_promotions(
240
- success, all_saas_files, mr_cli, auto_promote=False
241
- )
286
+ saasherder.publish_promotions(success, all_saas_files)
242
287
 
243
288
  if not success:
244
289
  sys.exit(ExitCodes.ERROR)
@@ -262,3 +307,42 @@ def run(
262
307
  + f"{action['kind']} {action['name']} {action['action']}"
263
308
  )
264
309
  slack.chat_post_message(message)
310
+
311
+ # get upstream repo info for sast scan
312
+ # get image info for clamav scan
313
+ # we only do this if:
314
+ # - this is not a dry run
315
+ # - there is a single saas file deployed
316
+ # - saas-deploy triggered by upstream job or image build
317
+ allowed_integration = [
318
+ openshift_saas_deploy_trigger_upstream_jobs.QONTRACT_INTEGRATION,
319
+ openshift_saas_deploy_trigger_images.QONTRACT_INTEGRATION,
320
+ ]
321
+ scan = (
322
+ not dry_run
323
+ and len(saas_files) == 1
324
+ and trigger_integration
325
+ and trigger_integration in allowed_integration
326
+ and trigger_reason
327
+ )
328
+ if scan:
329
+ saas_file = saas_files[0]
330
+ owners = saas_file.app.service_owners or []
331
+ emails = " ".join([o.email for o in owners])
332
+ file, url = saasherder.get_archive_info(saas_file, trigger_reason)
333
+ sast_file = os.path.join(io_dir, "sast")
334
+ with open(sast_file, "w", encoding="locale") as f:
335
+ f.write(file + "\n")
336
+ f.write(url + "\n")
337
+ f.write(emails + "\n")
338
+ images = " ".join(saasherder.images)
339
+ app_name = saas_file.app.name
340
+ clamav_file = os.path.join(io_dir, "clamav")
341
+ with open(clamav_file, "w", encoding="locale") as f:
342
+ f.write(images + "\n")
343
+ f.write(app_name + "\n")
344
+ image_auth = saasherder._initiate_image_auth(saas_file)
345
+ if image_auth.auth_server:
346
+ json_file = os.path.join(io_dir, "dockerconfigjson")
347
+ with open(json_file, "w", encoding="locale") as f:
348
+ f.write(json.dumps(image_auth.getDockerConfigJson(), indent=2))
@@ -1,10 +1,7 @@
1
1
  import logging
2
2
  import sys
3
3
  from collections.abc import Iterable
4
- from typing import (
5
- Any,
6
- Optional,
7
- )
4
+ from typing import Any
8
5
 
9
6
  from pydantic import BaseModel
10
7
  from sretoolbox.utils import threaded
@@ -18,7 +15,7 @@ from reconcile.gql_definitions.common.saas_files import (
18
15
  from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
19
16
  from reconcile.typed_queries.saas_files import (
20
17
  SaasFile,
21
- get_saas_files,
18
+ SaasFileList,
22
19
  )
23
20
  from reconcile.utils import gql
24
21
  from reconcile.utils.gitlab_api import GitLabApi
@@ -37,7 +34,7 @@ class Definition(BaseModel):
37
34
  class State(BaseModel):
38
35
  saas_file_path: str
39
36
  saas_file_name: str
40
- saas_file_deploy_resources: Optional[DeployResourcesV1]
37
+ saas_file_deploy_resources: DeployResourcesV1 | None
41
38
  resource_template_name: str
42
39
  cluster: str
43
40
  namespace: str
@@ -47,10 +44,10 @@ class State(BaseModel):
47
44
  parameters: dict[str, Any]
48
45
  secret_parameters: dict[str, VaultSecret]
49
46
  saas_file_definitions: Definition
50
- upstream: Optional[SaasResourceTemplateTargetUpstreamV1]
51
- disable: Optional[bool]
52
- delete: Optional[bool]
53
- target_path: Optional[str]
47
+ upstream: SaasResourceTemplateTargetUpstreamV1 | None
48
+ disable: bool | None
49
+ delete: bool | None
50
+ target_path: str | None
54
51
 
55
52
 
56
53
  def osd_run_wrapper(
@@ -58,7 +55,7 @@ def osd_run_wrapper(
58
55
  dry_run: bool,
59
56
  available_thread_pool_size: int,
60
57
  use_jump_host: bool,
61
- gitlab_project_id: str,
58
+ saas_file_list: SaasFileList | None,
62
59
  ) -> int:
63
60
  saas_file_name, env_name = spec
64
61
  exit_code = 0
@@ -69,7 +66,7 @@ def osd_run_wrapper(
69
66
  use_jump_host=use_jump_host,
70
67
  saas_file_name=saas_file_name,
71
68
  env_name=env_name,
72
- gitlab_project_id=gitlab_project_id,
69
+ saas_file_list=saas_file_list,
73
70
  )
74
71
  except SystemExit as e:
75
72
  exit_code = e.code if isinstance(e.code, int) else 1
@@ -98,18 +95,15 @@ def collect_state(saas_files: list[SaasFile]) -> list[State]:
98
95
  parameters.update(resource_template.parameters or {})
99
96
  parameters.update(target.parameters or {})
100
97
  secret_parameters: dict[str, VaultSecret] = {}
101
- secret_parameters.update(
102
- {s.name: s.secret for s in saas_file.secret_parameters or []}
103
- )
104
- secret_parameters.update(
105
- {
106
- s.name: s.secret
107
- for s in resource_template.secret_parameters or []
108
- }
109
- )
110
- secret_parameters.update(
111
- {s.name: s.secret for s in target.secret_parameters or []}
112
- )
98
+ secret_parameters.update({
99
+ s.name: s.secret for s in saas_file.secret_parameters or []
100
+ })
101
+ secret_parameters.update({
102
+ s.name: s.secret for s in resource_template.secret_parameters or []
103
+ })
104
+ secret_parameters.update({
105
+ s.name: s.secret for s in target.secret_parameters or []
106
+ })
113
107
  state.append(
114
108
  State(
115
109
  saas_file_path=saas_file.path,
@@ -153,7 +147,7 @@ def collect_compare_diffs(
153
147
  # that changes another saas file was merged but is not yet
154
148
  # reflected in the baseline graphql endpoint.
155
149
  # https://issues.redhat.com/browse/APPSRE-3029
156
- logging.debug(f"Diff not found in changed paths, skipping: {str(d)}")
150
+ logging.debug(f"Diff not found in changed paths, skipping: {d!s}")
157
151
  continue
158
152
  for c in current_state:
159
153
  if d.saas_file_name != c.saas_file_name:
@@ -188,17 +182,17 @@ def update_mr_with_ref_diffs(
188
182
  project_id=gitlab_project_id,
189
183
  settings=queries.get_secret_reader_settings(),
190
184
  ) as gl:
191
- changed_paths = gl.get_merge_request_changed_paths(gitlab_merge_request_id)
185
+ merge_request = gl.get_merge_request(gitlab_merge_request_id)
186
+ changed_paths = gl.get_merge_request_changed_paths(merge_request)
192
187
  compare_diffs = collect_compare_diffs(
193
188
  current_state, desired_state, changed_paths
194
189
  )
195
190
  if compare_diffs:
196
- compare_diffs_comment_body = "Diffs:\n" + "\n".join(
197
- [f"- {d}" for d in compare_diffs]
198
- )
199
- gl.add_comment_to_merge_request(
200
- gitlab_merge_request_id, compare_diffs_comment_body
201
- )
191
+ compare_diffs_comment_body = "Diffs:\n" + "\n".join([
192
+ f"- {d}" for d in compare_diffs
193
+ ])
194
+ gl.delete_merge_request_comments(merge_request, startswith="Diffs:")
195
+ gl.add_comment_to_merge_request(merge_request, compare_diffs_comment_body)
202
196
 
203
197
 
204
198
  def run(
@@ -214,9 +208,10 @@ def run(
214
208
  )
215
209
  # find the differences in saas-file state
216
210
  comparison_saas_file_state = collect_state(
217
- get_saas_files(query_func=comparison_gql_api.query)
211
+ SaasFileList(query_func=comparison_gql_api.query).saas_files
218
212
  )
219
- desired_saas_file_state = collect_state(get_saas_files())
213
+ saas_file_list = SaasFileList()
214
+ desired_saas_file_state = collect_state(saas_file_list.saas_files)
220
215
  # compare dicts against dicts which is much faster than comparing BaseModel objects
221
216
  comparison_saas_file_state_dicts = [s.dict() for s in comparison_saas_file_state]
222
217
  saas_file_state_diffs = [
@@ -248,7 +243,7 @@ def run(
248
243
  dry_run=dry_run,
249
244
  available_thread_pool_size=available_thread_pool_size,
250
245
  use_jump_host=use_jump_host,
251
- gitlab_project_id=gitlab_project_id,
246
+ saas_file_list=saas_file_list,
252
247
  )
253
248
 
254
249
  if [ec for ec in exit_codes if ec]:
@@ -1,18 +1,18 @@
1
- import datetime
2
1
  import logging
3
2
  from collections.abc import Callable
4
3
  from threading import Lock
5
- from typing import (
6
- Any,
7
- Optional,
8
- )
4
+ from typing import Any
9
5
 
10
6
  from sretoolbox.utils import threaded
11
7
 
12
- import reconcile.jenkins_plugins as jenkins_base
13
8
  import reconcile.openshift_base as osb
14
- from reconcile import queries
15
- from reconcile.openshift_tekton_resources import build_one_per_saas_file_tkn_object_name
9
+ from reconcile import (
10
+ jenkins_base,
11
+ queries,
12
+ )
13
+ from reconcile.openshift_tekton_resources import (
14
+ build_one_per_saas_file_tkn_pipeline_name,
15
+ )
16
16
  from reconcile.typed_queries.app_interface_vault_settings import (
17
17
  get_app_interface_vault_settings,
18
18
  )
@@ -33,7 +33,6 @@ from reconcile.utils.oc_map import (
33
33
  from reconcile.utils.openshift_resource import OpenshiftResource as OR
34
34
  from reconcile.utils.parse_dhms_duration import dhms_to_seconds
35
35
  from reconcile.utils.saasherder import (
36
- UNIQUE_SAAS_FILE_ENV_COMBO_LEN,
37
36
  Providers,
38
37
  SaasHerder,
39
38
  TriggerSpecUnion,
@@ -61,7 +60,7 @@ def run(
61
60
  internal: bool,
62
61
  use_jump_host: bool,
63
62
  include_trigger_trace: bool,
64
- defer: Optional[Callable] = None,
63
+ defer: Callable | None = None,
65
64
  ) -> bool:
66
65
  """Run trigger integration
67
66
 
@@ -247,7 +246,7 @@ def _trigger_tekton(
247
246
  if spec.pipelines_provider.pipeline_templates
248
247
  else spec.pipelines_provider.defaults.pipeline_templates.openshift_saas_deploy.name
249
248
  )
250
- tkn_pipeline_name = build_one_per_saas_file_tkn_object_name(
249
+ tkn_pipeline_name = build_one_per_saas_file_tkn_pipeline_name(
251
250
  pipeline_template_name, spec.saas_file_name
252
251
  )
253
252
  tkn_namespace_name = spec.pipelines_provider.namespace.name
@@ -298,7 +297,7 @@ def _trigger_tekton(
298
297
  logging.error(
299
298
  f"could not trigger pipeline {tkn_name} "
300
299
  + f"in {tkn_cluster_name}/{tkn_namespace_name}. "
301
- + f"details: {str(e)}"
300
+ + f"details: {e!s}"
302
301
  )
303
302
 
304
303
  if not error and not dry_run:
@@ -314,24 +313,27 @@ def _pipeline_exists(
314
313
  if isinstance(oc, OCLogMsg):
315
314
  logging.error(oc.message)
316
315
  raise RuntimeError(f"No OC client for {tkn_cluster_name}: {oc.message}")
317
- if oc.get(
318
- namespace=tkn_namespace_name, kind="Pipeline", name=name, allow_not_found=True
319
- ):
320
- return True
321
- return False
316
+ return bool(
317
+ oc.get(
318
+ namespace=tkn_namespace_name,
319
+ kind="Pipeline",
320
+ name=name,
321
+ allow_not_found=True,
322
+ )
323
+ )
322
324
 
323
325
 
324
326
  def _construct_tekton_trigger_resource(
325
327
  saas_file_name: str,
326
328
  env_name: str,
327
329
  tkn_pipeline_name: str,
328
- timeout: Optional[str],
330
+ timeout: str | None,
329
331
  tkn_cluster_console_url: str,
330
332
  tkn_namespace_name: str,
331
333
  integration: str,
332
334
  integration_version: str,
333
335
  include_trigger_trace: bool,
334
- reason: Optional[str],
336
+ reason: str | None,
335
337
  ) -> tuple[OR, str]:
336
338
  """Construct a resource (PipelineRun) to trigger a deployment via Tekton.
337
339
 
@@ -350,13 +352,10 @@ def _construct_tekton_trigger_resource(
350
352
  Returns:
351
353
  OpenshiftResource: OpenShift resource to be applied
352
354
  """
353
- long_name = f"{saas_file_name}-{env_name}".lower()
354
- # using a timestamp to make the resource name unique.
355
- # we may want to revisit traceability, but this is compatible
356
- # with what we currently have in Jenkins.
357
- ts = datetime.datetime.utcnow().strftime("%Y%m%d%H%M") # len 12
358
- # max name length can be 63. leaving 12 for the timestamp - 51
359
- name = f"{long_name[:UNIQUE_SAAS_FILE_ENV_COMBO_LEN]}-{ts}"
355
+ tkn_name, tkn_long_name = SaasHerder.build_saas_file_env_combo(
356
+ saas_file_name, env_name
357
+ )
358
+ name = tkn_name.lower()
360
359
 
361
360
  parameters = [
362
361
  {"name": "saas_file_name", "value": saas_file_name},
@@ -370,16 +369,14 @@ def _construct_tekton_trigger_resource(
370
369
  "reason must be provided if include_trigger_trace is True"
371
370
  )
372
371
 
373
- parameters.extend(
374
- [
375
- {"name": "trigger_integration", "value": integration},
376
- {"name": "trigger_reason", "value": reason},
377
- ]
378
- )
372
+ parameters.extend([
373
+ {"name": "trigger_integration", "value": integration},
374
+ {"name": "trigger_reason", "value": reason},
375
+ ])
379
376
  body: dict[str, Any] = {
380
- "apiVersion": "tekton.dev/v1beta1",
377
+ "apiVersion": "tekton.dev/v1",
381
378
  "kind": "PipelineRun",
382
- "metadata": {"name": name},
379
+ "metadata": {"generateName": f"{name}-"},
383
380
  "spec": {
384
381
  "pipelineRef": {"name": tkn_pipeline_name},
385
382
  "params": parameters,
@@ -393,9 +390,15 @@ def _construct_tekton_trigger_resource(
393
390
  f"timeout {timeout} is smaller than 60 minutes"
394
391
  )
395
392
 
396
- body["spec"]["timeout"] = timeout
393
+ body["spec"]["timeouts"] = {
394
+ "pipeline": "0",
395
+ "tasks": timeout,
396
+ }
397
397
 
398
- return OR(body, integration, integration_version, error_details=name), long_name
398
+ return (
399
+ OR(body, integration, integration_version, error_details=name),
400
+ tkn_long_name.lower(),
401
+ )
399
402
 
400
403
 
401
404
  def _register_trigger(name: str, already_triggered: set[str]) -> bool: