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