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,13 +1,10 @@
1
+ import hashlib
1
2
  import json
2
3
  from collections.abc import Callable
3
- from typing import (
4
- Any,
5
- Optional,
6
- Union,
7
- )
4
+ from threading import Lock
5
+ from typing import Any
8
6
 
9
7
  from jsonpath_ng.exceptions import JsonPathParserError
10
- from jsonpath_ng.ext import parser
11
8
  from pydantic import (
12
9
  BaseModel,
13
10
  Extra,
@@ -19,6 +16,7 @@ from reconcile.gql_definitions.common.saas_files import (
19
16
  AppV1,
20
17
  ConfiguredBaseModel,
21
18
  DeployResourcesV1,
19
+ ManagedResourceNamesV1,
22
20
  PipelinesProviderTektonV1,
23
21
  PipelinesProviderV1,
24
22
  RoleV1,
@@ -49,27 +47,35 @@ from reconcile.utils.exceptions import (
49
47
  AppInterfaceSettingsError,
50
48
  ParameterError,
51
49
  )
50
+ from reconcile.utils.jsonpath import parse_jsonpath
52
51
 
53
52
 
54
53
  class SaasResourceTemplateTarget(ConfiguredBaseModel):
55
- path: Optional[str] = Field(..., alias="path")
56
- name: Optional[str] = Field(..., alias="name")
54
+ path: str | None = Field(..., alias="path")
55
+ name: str | None = Field(..., alias="name")
57
56
  # the namespace must be required to fulfill the saas file schema (utils.saasherder.interface.SaasFile)
58
57
  namespace: SaasTargetNamespace = Field(..., alias="namespace")
59
58
  ref: str = Field(..., alias="ref")
60
- promotion: Optional[SaasResourceTemplateTargetPromotionV1] = Field(
59
+ promotion: SaasResourceTemplateTargetPromotionV1 | None = Field(
61
60
  ..., alias="promotion"
62
61
  )
63
- parameters: Optional[Json] = Field(..., alias="parameters")
64
- secret_parameters: Optional[
65
- list[SaasResourceTemplateTargetV2_SaasSecretParametersV1]
66
- ] = Field(..., alias="secretParameters")
67
- upstream: Optional[SaasResourceTemplateTargetUpstreamV1] = Field(
68
- ..., alias="upstream"
69
- )
70
- image: Optional[SaasResourceTemplateTargetImageV1] = Field(..., alias="image")
71
- disable: Optional[bool] = Field(..., alias="disable")
72
- delete: Optional[bool] = Field(..., alias="delete")
62
+ parameters: Json | None = Field(..., alias="parameters")
63
+ secret_parameters: (
64
+ list[SaasResourceTemplateTargetV2_SaasSecretParametersV1] | None
65
+ ) = Field(..., alias="secretParameters")
66
+ upstream: SaasResourceTemplateTargetUpstreamV1 | None = Field(..., alias="upstream")
67
+ image: SaasResourceTemplateTargetImageV1 | None = Field(..., alias="image")
68
+ disable: bool | None = Field(..., alias="disable")
69
+ delete: bool | None = Field(..., alias="delete")
70
+
71
+ def uid(
72
+ self, parent_saas_file_name: str, parent_resource_template_name: str
73
+ ) -> str:
74
+ """Returns a unique identifier for a target."""
75
+ return hashlib.blake2s(
76
+ f"{parent_saas_file_name}:{parent_resource_template_name}:{self.name if self.name else 'default'}:{self.namespace.cluster.name}:{self.namespace.name}".encode(),
77
+ digest_size=20,
78
+ ).hexdigest()
73
79
 
74
80
  class Config:
75
81
  # ignore `namespaceSelector` and 'provider' fields from the GQL schema
@@ -80,102 +86,220 @@ class SaasResourceTemplate(ConfiguredBaseModel):
80
86
  name: str = Field(..., alias="name")
81
87
  url: str = Field(..., alias="url")
82
88
  path: str = Field(..., alias="path")
83
- provider: Optional[str] = Field(..., alias="provider")
84
- hash_length: Optional[int] = Field(..., alias="hash_length")
85
- parameters: Optional[Json] = Field(..., alias="parameters")
86
- secret_parameters: Optional[
87
- list[SaasResourceTemplateV2_SaasSecretParametersV1]
88
- ] = Field(..., alias="secretParameters")
89
+ provider: str | None = Field(..., alias="provider")
90
+ hash_length: int | None = Field(..., alias="hash_length")
91
+ parameters: Json | None = Field(..., alias="parameters")
92
+ secret_parameters: list[SaasResourceTemplateV2_SaasSecretParametersV1] | None = (
93
+ Field(..., alias="secretParameters")
94
+ )
89
95
  targets: list[SaasResourceTemplateTarget] = Field(..., alias="targets")
90
96
 
91
97
 
92
98
  class SaasFile(ConfiguredBaseModel):
93
99
  path: str = Field(..., alias="path")
94
100
  name: str = Field(..., alias="name")
101
+ labels: Json | None = Field(..., alias="labels")
95
102
  app: AppV1 = Field(..., alias="app")
96
- pipelines_provider: Union[PipelinesProviderTektonV1, PipelinesProviderV1] = Field(
103
+ pipelines_provider: PipelinesProviderTektonV1 | PipelinesProviderV1 = Field(
97
104
  ..., alias="pipelinesProvider"
98
105
  )
99
- deploy_resources: Optional[DeployResourcesV1] = Field(..., alias="deployResources")
100
- slack: Optional[SlackOutputV1] = Field(..., alias="slack")
106
+ deploy_resources: DeployResourcesV1 | None = Field(..., alias="deployResources")
107
+ slack: SlackOutputV1 | None = Field(..., alias="slack")
101
108
  managed_resource_types: list[str] = Field(..., alias="managedResourceTypes")
102
- takeover: Optional[bool] = Field(..., alias="takeover")
103
- deprecated: Optional[bool] = Field(..., alias="deprecated")
104
- compare: Optional[bool] = Field(..., alias="compare")
105
- timeout: Optional[str] = Field(..., alias="timeout")
106
- publish_job_logs: Optional[bool] = Field(..., alias="publishJobLogs")
107
- cluster_admin: Optional[bool] = Field(..., alias="clusterAdmin")
109
+ takeover: bool | None = Field(..., alias="takeover")
110
+ deprecated: bool | None = Field(..., alias="deprecated")
111
+ compare: bool | None = Field(..., alias="compare")
112
+ timeout: str | None = Field(..., alias="timeout")
113
+ skip_successful_deploy_notifications: bool | None = Field(
114
+ ..., alias="skipSuccessfulDeployNotifications"
115
+ )
116
+ publish_job_logs: bool | None = Field(..., alias="publishJobLogs")
117
+ cluster_admin: bool | None = Field(..., alias="clusterAdmin")
108
118
  image_patterns: list[str] = Field(..., alias="imagePatterns")
109
- allowed_secret_parameter_paths: Optional[list[str]] = Field(
119
+ allowed_secret_parameter_paths: list[str] | None = Field(
110
120
  ..., alias="allowedSecretParameterPaths"
111
121
  )
112
- use_channel_in_image_tag: Optional[bool] = Field(
113
- ..., alias="use_channel_in_image_tag"
114
- )
115
- authentication: Optional[SaasFileAuthenticationV1] = Field(
116
- ..., alias="authentication"
117
- )
118
- parameters: Optional[Json] = Field(..., alias="parameters")
119
- secret_parameters: Optional[list[SaasSecretParametersV1]] = Field(
122
+ use_channel_in_image_tag: bool | None = Field(..., alias="use_channel_in_image_tag")
123
+ authentication: SaasFileAuthenticationV1 | None = Field(..., alias="authentication")
124
+ parameters: Json | None = Field(..., alias="parameters")
125
+ secret_parameters: list[SaasSecretParametersV1] | None = Field(
120
126
  ..., alias="secretParameters"
121
127
  )
128
+ validate_targets_in_app: bool | None = Field(..., alias="validateTargetsInApp")
129
+ validate_planned_data: bool | None = Field(..., alias="validatePlannedData")
130
+ managed_resource_names: list[ManagedResourceNamesV1] | None = Field(
131
+ ..., alias="managedResourceNames"
132
+ )
122
133
  resource_templates: list[SaasResourceTemplate] = Field(
123
134
  ..., alias="resourceTemplates"
124
135
  )
125
- self_service_roles: Optional[list[RoleV1]] = Field(..., alias="selfServiceRoles")
126
-
127
-
128
- def get_namespaces_by_selector(
129
- namespaces: list[SaasTargetNamespace],
130
- namespace_selector: SaasResourceTemplateTargetNamespaceSelectorV1,
131
- ) -> list[SaasTargetNamespace]:
132
- # json representation of all the namespaces to filter on
133
- # remove all the None values to simplify the jsonpath expressions
134
- namespaces_as_dict = {
135
- "namespace": [ns.dict(by_alias=True, exclude_none=True) for ns in namespaces]
136
- }
137
-
138
- def _get_namespace_by_cluster_and_name(
139
- cluster_name: str, name: str
140
- ) -> SaasTargetNamespace:
141
- for ns in namespaces:
142
- if ns.cluster.name == cluster_name and ns.name == name:
143
- return ns
144
- # this should never ever happen - just make mypy happy
145
- raise RuntimeError(f"namespace '{name}' not found in cluster '{cluster_name}'")
146
-
147
- filtered_namespaces: dict[str, Any] = {}
148
-
149
- try:
136
+ self_service_roles: list[RoleV1] | None = Field(..., alias="selfServiceRoles")
137
+
138
+
139
+ class SaasFileList:
140
+ def __init__(
141
+ self,
142
+ name: str | None = None,
143
+ query_func: Callable | None = None,
144
+ namespaces: list[SaasTargetNamespace] | None = None,
145
+ ) -> None:
146
+ # query_func and namespaces are optional args mostly used in tests
147
+ if not query_func:
148
+ query_func = gql.get_api().query
149
+ if not namespaces:
150
+ namespaces = namespaces_query(query_func).namespaces or []
151
+ self.namespaces = namespaces
152
+ self.cluster_namespaces = {
153
+ (ns.cluster.name, ns.name): ns for ns in self.namespaces
154
+ }
155
+
156
+ self._init_caches()
157
+
158
+ self.saas_files_v2 = saas_files_query(query_func).saas_files or []
159
+ if name:
160
+ self.saas_files_v2 = [sf for sf in self.saas_files_v2 if sf.name == name]
161
+ self.saas_files = self._resolve_namespace_selectors()
162
+
163
+ def _init_caches(self) -> None:
164
+ self._namespaces_as_dict_cache: dict[str, list[Any]] | None = None
165
+ self._namespaces_as_dict_lock = Lock()
166
+ self._matching_namespaces_cache: dict[str, Any] = {}
167
+ self._matching_namespaces_lock = Lock()
168
+
169
+ def _resolve_namespace_selectors(self) -> list[SaasFile]:
170
+ saas_files: list[SaasFile] = []
171
+ # resolve namespaceSelectors to real namespaces
172
+ for sfv2 in self.saas_files_v2:
173
+ for rt_gql in sfv2.resource_templates:
174
+ for target_gql in rt_gql.targets[:]:
175
+ # either namespace or namespaceSelector must be set
176
+ if target_gql.namespace and target_gql.namespace_selector:
177
+ raise ParameterError(
178
+ f"SaasFile {sfv2.name}: namespace and namespaceSelector are mutually exclusive"
179
+ )
180
+ if not target_gql.provider:
181
+ target_gql.provider = "static"
182
+
183
+ if (
184
+ target_gql.namespace_selector
185
+ and target_gql.provider != "dynamic"
186
+ ):
187
+ raise ParameterError(
188
+ f"SaasFile {sfv2.name}: namespaceSelector can only be used with 'provider: dynamic'"
189
+ )
190
+ if (
191
+ target_gql.namespace_selector
192
+ and target_gql.provider == "dynamic"
193
+ ):
194
+ rt_gql.targets.remove(target_gql)
195
+ rt_gql.targets += self.create_targets_for_namespace_selector(
196
+ target_gql, target_gql.namespace_selector
197
+ )
198
+ # convert SaasFileV2 (with optional resource_templates.targets.namespace field)
199
+ # to SaasFile (with required resource_templates.targets.namespace field)
200
+ saas_files.append(SaasFile(**export_model(sfv2)))
201
+ return saas_files
202
+
203
+ def create_targets_for_namespace_selector(
204
+ self,
205
+ target: SaasResourceTemplateTargetV2,
206
+ namespace_selector: SaasResourceTemplateTargetNamespaceSelectorV1,
207
+ ) -> list[SaasResourceTemplateTargetV2]:
208
+ targets = []
209
+ for namespace in self.get_namespaces_by_selector(namespace_selector):
210
+ target_dict = export_model(target)
211
+ target_dict["namespace"] = export_model(namespace)
212
+ targets.append(SaasResourceTemplateTargetV2(**target_dict))
213
+ return targets
214
+
215
+ def _get_namespaces_as_dict(self) -> dict[str, list[Any]]:
216
+ # json representation of all the namespaces to filter on
217
+ # remove all the None values to simplify the jsonpath expressions
218
+ if self._namespaces_as_dict_cache is None:
219
+ with self._namespaces_as_dict_lock:
220
+ self._namespaces_as_dict_cache = {
221
+ "namespace": [
222
+ ns.dict(by_alias=True, exclude_none=True)
223
+ for ns in self.namespaces
224
+ ]
225
+ }
226
+ return self._namespaces_as_dict_cache
227
+
228
+ def _matching_namespaces(self, selector: str) -> Any:
229
+ if selector not in self._matching_namespaces_cache:
230
+ with self._matching_namespaces_lock:
231
+ namespaces_as_dict = self._get_namespaces_as_dict()
232
+ try:
233
+ self._matching_namespaces_cache[selector] = parse_jsonpath(
234
+ selector
235
+ ).find(namespaces_as_dict)
236
+ except JsonPathParserError as e:
237
+ raise ParameterError(
238
+ f"Invalid jsonpath expression in namespaceSelector '{selector}' :{e}"
239
+ ) from None
240
+
241
+ return self._matching_namespaces_cache[selector]
242
+
243
+ def get_namespaces_by_selector(
244
+ self, namespace_selector: SaasResourceTemplateTargetNamespaceSelectorV1
245
+ ) -> list[SaasTargetNamespace]:
246
+ filtered_namespaces: dict[tuple[str, str], Any] = {}
247
+
150
248
  for include in namespace_selector.json_path_selectors.include:
151
- for match in parser.parse(include).find(namespaces_as_dict):
249
+ for match in self._matching_namespaces(include):
152
250
  cluster_name = match.value["cluster"]["name"]
153
251
  ns_name = match.value["name"]
154
- filtered_namespaces[
155
- f"{cluster_name}-{ns_name}"
156
- ] = _get_namespace_by_cluster_and_name(cluster_name, ns_name)
157
- except JsonPathParserError as e:
158
- raise ParameterError(
159
- f"Invalid jsonpath expression in namespaceSelector '{include}' :{e}"
160
- )
252
+ filtered_namespaces[cluster_name, ns_name] = self.cluster_namespaces[
253
+ cluster_name, ns_name
254
+ ]
161
255
 
162
- try:
163
256
  for exclude in namespace_selector.json_path_selectors.exclude or []:
164
- for match in parser.parse(exclude).find(namespaces_as_dict):
257
+ for match in self._matching_namespaces(exclude):
165
258
  cluster_name = match.value["cluster"]["name"]
166
259
  ns_name = match.value["name"]
167
- filtered_namespaces.pop(f"{cluster_name}-{ns_name}", None)
168
- except JsonPathParserError as e:
169
- raise ParameterError(
170
- f"Invalid jsonpath expression in namespaceSelector '{exclude}' :{e}"
171
- )
172
- return list(filtered_namespaces.values())
260
+ filtered_namespaces.pop((cluster_name, ns_name), None)
261
+
262
+ return list(filtered_namespaces.values())
263
+
264
+ def where(
265
+ self,
266
+ name: str | None = None,
267
+ env_name: str | None = None,
268
+ app_name: str | None = None,
269
+ ) -> list[SaasFile]:
270
+ if name is None and env_name is None and app_name is None:
271
+ return self.saas_files
272
+
273
+ if name == "" or env_name == "" or app_name == "": # noqa: PLC1901
274
+ return []
275
+
276
+ filtered: list[SaasFile] = []
277
+ for saas_file in self.saas_files[:]:
278
+ if name and saas_file.name != name:
279
+ continue
280
+
281
+ if app_name and saas_file.app.name != app_name:
282
+ continue
283
+
284
+ sf = saas_file.copy(deep=True)
285
+ if env_name:
286
+ for rt in sf.resource_templates[:]:
287
+ for target in rt.targets[:]:
288
+ if target.namespace.environment.name != env_name:
289
+ rt.targets.remove(target)
290
+ if not rt.targets:
291
+ sf.resource_templates.remove(rt)
292
+ if not sf.resource_templates:
293
+ continue
294
+ filtered.append(sf)
295
+
296
+ return filtered
173
297
 
174
298
 
175
299
  def convert_parameters_to_json_string(root: dict[str, Any]) -> dict[str, Any]:
176
300
  """Find all parameter occurrences and convert them to a json string."""
177
301
  for key, value in root.items():
178
- if key in ["parameters", "labels"]:
302
+ if key in {"parameters", "labels"}:
179
303
  root[key] = json.dumps(value) if value is not None else None
180
304
  elif isinstance(value, dict):
181
305
  root[key] = convert_parameters_to_json_string(value)
@@ -191,93 +315,23 @@ def export_model(model: BaseModel) -> dict[str, Any]:
191
315
  return convert_parameters_to_json_string(model.dict(by_alias=True))
192
316
 
193
317
 
194
- def create_targets_for_namespace_selector(
195
- target: SaasResourceTemplateTargetV2,
196
- namespaces: list[SaasTargetNamespace],
197
- namespace_selector: SaasResourceTemplateTargetNamespaceSelectorV1,
198
- ) -> list[SaasResourceTemplateTargetV2]:
199
- targets = []
200
- for namespace in get_namespaces_by_selector(namespaces, namespace_selector):
201
- target_dict = export_model(target)
202
- target_dict["namespace"] = export_model(namespace)
203
- targets.append(SaasResourceTemplateTargetV2(**target_dict))
204
- return targets
205
-
206
-
207
318
  def get_saas_files(
208
- name: Optional[str] = None,
209
- env_name: Optional[str] = None,
210
- app_name: Optional[str] = None,
211
- query_func: Optional[Callable] = None,
212
- namespaces: Optional[list[SaasTargetNamespace]] = None,
319
+ name: str | None = None,
320
+ env_name: str | None = None,
321
+ app_name: str | None = None,
322
+ query_func: Callable | None = None,
323
+ namespaces: list[SaasTargetNamespace] | None = None,
324
+ saas_file_list: SaasFileList | None = None,
213
325
  ) -> list[SaasFile]:
214
- if not query_func:
215
- query_func = gql.get_api().query
216
- data = saas_files_query(query_func)
217
- saas_files: list[SaasFile] = []
218
- if not namespaces:
219
- namespaces = namespaces_query(query_func).namespaces or []
220
-
221
- # resolve namespaceSelectors to real namespaces
222
- for saas_file_gql in list(data.saas_files or []):
223
- for rt_gql in saas_file_gql.resource_templates:
224
- for target_gql in rt_gql.targets[:]:
225
- # either namespace or namespaceSelector must be set
226
- if target_gql.namespace and target_gql.namespace_selector:
227
- raise ParameterError(
228
- f"SaasFile {saas_file_gql.name}: namespace and namespaceSelector are mutually exclusive"
229
- )
230
- if not target_gql.provider:
231
- target_gql.provider = "static"
232
-
233
- if (
234
- target_gql.namespace_selector
235
- and not target_gql.provider == "dynamic"
236
- ):
237
- raise ParameterError(
238
- f"SaasFile {saas_file_gql.name}: namespaceSelector can only be used with 'provider: dynamic'"
239
- )
240
- if target_gql.namespace_selector and target_gql.provider == "dynamic":
241
- rt_gql.targets.remove(target_gql)
242
- rt_gql.targets += create_targets_for_namespace_selector(
243
- target_gql, namespaces, target_gql.namespace_selector
244
- )
245
- # convert SaasFileV2 (with optional resource_templates.targets.namespace field)
246
- # to SaasFile (with required resource_templates.targets.namespace field)
247
- saas_files.append(SaasFile(**export_model(saas_file_gql)))
248
-
249
- if name is None and env_name is None and app_name is None:
250
- return saas_files
251
- if name == "" or env_name == "" or app_name == "":
252
- return []
253
-
254
- for saas_file in saas_files[:]:
255
- if name:
256
- if saas_file.name != name:
257
- saas_files.remove(saas_file)
258
- continue
259
-
260
- if env_name:
261
- for rt in saas_file.resource_templates[:]:
262
- for target in rt.targets[:]:
263
- if target.namespace.environment.name != env_name:
264
- rt.targets.remove(target)
265
- if not rt.targets:
266
- saas_file.resource_templates.remove(rt)
267
- if not saas_file.resource_templates:
268
- saas_files.remove(saas_file)
269
- continue
270
-
271
- if app_name:
272
- if saas_file.app.name != app_name:
273
- saas_files.remove(saas_file)
274
- continue
275
-
276
- return saas_files
326
+ if not saas_file_list:
327
+ saas_file_list = SaasFileList(
328
+ name=name, query_func=query_func, namespaces=namespaces
329
+ )
330
+ return saas_file_list.where(env_name=env_name, app_name=app_name)
277
331
 
278
332
 
279
333
  def get_saasherder_settings(
280
- query_func: Optional[Callable] = None,
334
+ query_func: Callable | None = None,
281
335
  ) -> AppInterfaceSettingsV1:
282
336
  if not query_func:
283
337
  query_func = gql.get_api().query
@@ -0,0 +1,7 @@
1
+ from reconcile.gql_definitions.common.slack_workspaces import SlackWorkspaceV1, query
2
+ from reconcile.utils import gql
3
+
4
+
5
+ def get_slack_workspaces() -> list[SlackWorkspaceV1]:
6
+ data = query(gql.get_api().query)
7
+ return list(data.workspaces or [])
@@ -0,0 +1,12 @@
1
+ from reconcile.gql_definitions.slo_documents.slo_documents import (
2
+ SLODocumentV1,
3
+ query,
4
+ )
5
+ from reconcile.utils import gql
6
+ from reconcile.utils.gql import GqlApi
7
+
8
+
9
+ def get_slo_documents(gql_api: GqlApi | None = None) -> list[SLODocumentV1]:
10
+ api = gql_api if gql_api else gql.get_api()
11
+ data = query(query_func=api.query)
12
+ return data.slo_document_v1 or []
@@ -0,0 +1,58 @@
1
+ from collections.abc import Callable, Iterable
2
+ from typing import Any
3
+
4
+ from jsonpath_ng.ext import parser
5
+
6
+ from reconcile.gql_definitions.status_board.status_board import (
7
+ StatusBoardProductV1,
8
+ StatusBoardV1,
9
+ query,
10
+ )
11
+ from reconcile.utils import gql
12
+
13
+
14
+ def get_status_board(
15
+ query_func: Callable | None = None,
16
+ ) -> list[StatusBoardV1]:
17
+ if not query_func:
18
+ query_func = gql.get_api().query
19
+ return query(query_func).status_board_v1 or []
20
+
21
+
22
+ def get_selected_app_names(
23
+ global_selectors: Iterable[str],
24
+ product: StatusBoardProductV1,
25
+ ) -> set[str]:
26
+ selected_app_names: set[str] = set()
27
+
28
+ apps: dict[str, Any] = {"apps": []}
29
+ for namespace in product.product_environment.namespaces or []:
30
+ prefix = ""
31
+ if namespace.app.parent_app:
32
+ prefix = f"{namespace.app.parent_app.name}-"
33
+ name = f"{prefix}{namespace.app.name}"
34
+ selected_app_names.add(name)
35
+ app = namespace.app.dict(by_alias=True)
36
+ app["name"] = name
37
+ apps["apps"].append(app)
38
+
39
+ for child in namespace.app.children_apps or []:
40
+ name = f"{namespace.app.name}-{child.name}"
41
+ if name not in selected_app_names:
42
+ selected_app_names.add(f"{namespace.app.name}-{child.name}")
43
+ child_dict = child.dict(by_alias=True)
44
+ child_dict["name"] = name
45
+ apps["apps"].append(child_dict)
46
+
47
+ selectors = set(global_selectors)
48
+ if product.app_selectors:
49
+ selectors.update(product.app_selectors.exclude or [])
50
+
51
+ for selector in selectors:
52
+ apps_to_remove: set[str] = set()
53
+ results = parser.parse(selector).find(apps)
54
+ for match in results:
55
+ apps_to_remove.add(match.value["name"])
56
+ selected_app_names -= apps_to_remove
57
+
58
+ return selected_app_names
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.pipeline_providers import (
5
4
  PipelinesProviderTektonV1,
@@ -9,7 +8,7 @@ from reconcile.utils import gql
9
8
 
10
9
 
11
10
  def get_tekton_pipeline_providers(
12
- query_func: Optional[Callable] = None,
11
+ query_func: Callable | None = None,
13
12
  ) -> list[PipelinesProviderTektonV1]:
14
13
  if not query_func:
15
14
  query_func = gql.get_api().query
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.terraform_resources.terraform_resources_namespaces import (
5
4
  NamespaceV1,
@@ -8,7 +7,7 @@ from reconcile.gql_definitions.terraform_resources.terraform_resources_namespace
8
7
  from reconcile.utils import gql
9
8
 
10
9
 
11
- def get_namespaces(query_func: Optional[Callable] = None) -> list[NamespaceV1]:
10
+ def get_namespaces(query_func: Callable | None = None) -> list[NamespaceV1]:
12
11
  if not query_func:
13
12
  query_func = gql.get_api().query
14
13
  data = query(query_func=query_func)
@@ -0,0 +1,16 @@
1
+ from reconcile.gql_definitions.terraform_tgw_attachments.aws_accounts import (
2
+ AWSAccountV1,
3
+ query,
4
+ )
5
+ from reconcile.utils.gql import GqlApi
6
+
7
+
8
+ def get_aws_accounts(
9
+ gql_api: GqlApi,
10
+ name: str | None = None,
11
+ ) -> list[AWSAccountV1]:
12
+ variables = {
13
+ "name": name,
14
+ }
15
+ data = query(gql_api.query, variables=variables)
16
+ return data.accounts or []
@@ -0,0 +1,10 @@
1
+ from reconcile.gql_definitions.unleash_feature_toggles.feature_toggles import (
2
+ UnleashInstanceV1,
3
+ query,
4
+ )
5
+ from reconcile.utils import gql
6
+
7
+
8
+ def get_unleash_instances() -> list[UnleashInstanceV1]:
9
+ data = query(gql.get_api().query)
10
+ return list(data.instances or [])
@@ -0,0 +1,11 @@
1
+ from collections.abc import Callable
2
+
3
+ from reconcile.gql_definitions.common.users import query
4
+ from reconcile.gql_definitions.fragments.user import User
5
+ from reconcile.utils import gql
6
+
7
+
8
+ def get_users(query_func: Callable | None = None) -> list[User]:
9
+ if not query_func:
10
+ query_func = gql.get_api().query
11
+ return query(query_func=gql.get_api().query).users or []
@@ -0,0 +1,10 @@
1
+ from reconcile.gql_definitions.vault_instances.vault_instances import (
2
+ VaultInstanceV1,
3
+ query,
4
+ )
5
+ from reconcile.utils import gql
6
+
7
+
8
+ def get_vault_instances() -> list[VaultInstanceV1]:
9
+ data = query(gql.get_api().query)
10
+ return list(data.vault_instances or [])
File without changes