qontract-reconcile 0.10.0__py3-none-any.whl → 0.10.1.dev1203__py3-none-any.whl

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