qontract-reconcile 0.10.2.dev310__py3-none-any.whl → 0.10.2.dev439__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.

Potentially problematic release.


This version of qontract-reconcile might be problematic. Click here for more details.

Files changed (400) hide show
  1. {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/METADATA +13 -12
  2. {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/RECORD +396 -391
  3. reconcile/acs_rbac.py +2 -2
  4. reconcile/aus/advanced_upgrade_service.py +18 -12
  5. reconcile/aus/base.py +134 -32
  6. reconcile/aus/cluster_version_data.py +15 -5
  7. reconcile/aus/models.py +3 -1
  8. reconcile/aus/ocm_addons_upgrade_scheduler_org.py +1 -0
  9. reconcile/aus/ocm_upgrade_scheduler.py +8 -1
  10. reconcile/aus/ocm_upgrade_scheduler_org.py +20 -5
  11. reconcile/aus/version_gates/sts_version_gate_handler.py +54 -1
  12. reconcile/automated_actions/config/integration.py +16 -4
  13. reconcile/aws_account_manager/integration.py +8 -8
  14. reconcile/aws_account_manager/reconciler.py +3 -3
  15. reconcile/aws_ami_cleanup/integration.py +8 -12
  16. reconcile/aws_ami_share.py +69 -62
  17. reconcile/aws_cloudwatch_log_retention/integration.py +155 -126
  18. reconcile/aws_ecr_image_pull_secrets.py +5 -5
  19. reconcile/aws_iam_keys.py +1 -0
  20. reconcile/aws_saml_idp/integration.py +12 -4
  21. reconcile/aws_saml_roles/integration.py +32 -25
  22. reconcile/aws_version_sync/integration.py +125 -84
  23. reconcile/change_owners/bundle.py +3 -3
  24. reconcile/change_owners/change_log_tracking.py +3 -2
  25. reconcile/change_owners/change_owners.py +1 -1
  26. reconcile/change_owners/diff.py +2 -4
  27. reconcile/checkpoint.py +12 -4
  28. reconcile/cli.py +111 -18
  29. reconcile/cluster_deployment_mapper.py +2 -3
  30. reconcile/dashdotdb_dora.py +5 -12
  31. reconcile/dashdotdb_slo.py +1 -1
  32. reconcile/database_access_manager.py +125 -121
  33. reconcile/deadmanssnitch.py +1 -5
  34. reconcile/dynatrace_token_provider/integration.py +1 -1
  35. reconcile/endpoints_discovery/integration.py +4 -1
  36. reconcile/endpoints_discovery/merge_request.py +1 -1
  37. reconcile/endpoints_discovery/merge_request_manager.py +9 -11
  38. reconcile/external_resources/factories.py +5 -12
  39. reconcile/external_resources/integration.py +1 -1
  40. reconcile/external_resources/manager.py +8 -5
  41. reconcile/external_resources/meta.py +0 -1
  42. reconcile/external_resources/metrics.py +1 -1
  43. reconcile/external_resources/model.py +20 -20
  44. reconcile/external_resources/reconciler.py +7 -4
  45. reconcile/external_resources/secrets_sync.py +10 -14
  46. reconcile/external_resources/state.py +26 -16
  47. reconcile/fleet_labeler/integration.py +1 -1
  48. reconcile/gabi_authorized_users.py +8 -5
  49. reconcile/gcp_image_mirror.py +2 -2
  50. reconcile/github_org.py +1 -1
  51. reconcile/github_owners.py +4 -0
  52. reconcile/gitlab_housekeeping.py +13 -15
  53. reconcile/gitlab_members.py +6 -12
  54. reconcile/gitlab_mr_sqs_consumer.py +2 -2
  55. reconcile/gitlab_owners.py +15 -11
  56. reconcile/gitlab_permissions.py +8 -12
  57. reconcile/glitchtip_project_alerts/integration.py +3 -1
  58. reconcile/gql_definitions/acs/acs_instances.py +10 -10
  59. reconcile/gql_definitions/acs/acs_policies.py +5 -5
  60. reconcile/gql_definitions/acs/acs_rbac.py +6 -6
  61. reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +32 -32
  62. reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +26 -26
  63. reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +6 -7
  64. reconcile/gql_definitions/app_sre_tekton_access_revalidation/roles.py +5 -5
  65. reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py +5 -5
  66. reconcile/gql_definitions/automated_actions/instance.py +51 -12
  67. reconcile/gql_definitions/aws_account_manager/aws_accounts.py +11 -11
  68. reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +20 -10
  69. reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +28 -68
  70. reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +20 -10
  71. reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +20 -10
  72. reconcile/gql_definitions/aws_saml_roles/roles.py +5 -5
  73. reconcile/gql_definitions/aws_version_sync/clusters.py +10 -10
  74. reconcile/gql_definitions/aws_version_sync/namespaces.py +5 -5
  75. reconcile/gql_definitions/change_owners/queries/change_types.py +5 -5
  76. reconcile/gql_definitions/change_owners/queries/self_service_roles.py +9 -9
  77. reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +18 -18
  78. reconcile/gql_definitions/common/alerting_services_settings.py +9 -9
  79. reconcile/gql_definitions/common/app_code_component_repos.py +5 -5
  80. reconcile/gql_definitions/common/app_interface_custom_messages.py +5 -5
  81. reconcile/gql_definitions/common/app_interface_dms_settings.py +5 -5
  82. reconcile/gql_definitions/common/app_interface_repo_settings.py +5 -5
  83. reconcile/gql_definitions/common/app_interface_roles.py +120 -0
  84. reconcile/gql_definitions/common/app_interface_state_settings.py +10 -10
  85. reconcile/gql_definitions/common/app_interface_vault_settings.py +5 -5
  86. reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +5 -5
  87. reconcile/gql_definitions/common/apps.py +5 -5
  88. reconcile/gql_definitions/common/aws_vpc_requests.py +22 -9
  89. reconcile/gql_definitions/common/aws_vpcs.py +11 -11
  90. reconcile/gql_definitions/common/clusters.py +37 -35
  91. reconcile/gql_definitions/common/clusters_minimal.py +14 -14
  92. reconcile/gql_definitions/common/clusters_with_dms.py +6 -6
  93. reconcile/gql_definitions/common/clusters_with_peering.py +29 -30
  94. reconcile/gql_definitions/common/github_orgs.py +10 -10
  95. reconcile/gql_definitions/common/jira_settings.py +10 -10
  96. reconcile/gql_definitions/common/jiralert_settings.py +5 -5
  97. reconcile/gql_definitions/common/ldap_settings.py +5 -5
  98. reconcile/gql_definitions/common/namespaces.py +42 -44
  99. reconcile/gql_definitions/common/namespaces_minimal.py +15 -13
  100. reconcile/gql_definitions/common/ocm_env_telemeter.py +12 -12
  101. reconcile/gql_definitions/common/ocm_environments.py +19 -19
  102. reconcile/gql_definitions/common/pagerduty_instances.py +9 -9
  103. reconcile/gql_definitions/common/pgp_reencryption_settings.py +6 -6
  104. reconcile/gql_definitions/common/pipeline_providers.py +29 -29
  105. reconcile/gql_definitions/common/quay_instances.py +5 -5
  106. reconcile/gql_definitions/common/quay_orgs.py +5 -5
  107. reconcile/gql_definitions/common/reserved_networks.py +5 -5
  108. reconcile/gql_definitions/common/rhcs_provider_settings.py +5 -5
  109. reconcile/gql_definitions/common/saas_files.py +44 -44
  110. reconcile/gql_definitions/common/saas_target_namespaces.py +10 -10
  111. reconcile/gql_definitions/common/saasherder_settings.py +5 -5
  112. reconcile/gql_definitions/common/slack_workspaces.py +5 -5
  113. reconcile/gql_definitions/common/smtp_client_settings.py +19 -19
  114. reconcile/gql_definitions/common/state_aws_account.py +7 -8
  115. reconcile/gql_definitions/common/users.py +5 -5
  116. reconcile/gql_definitions/common/users_with_paths.py +5 -5
  117. reconcile/gql_definitions/cost_report/app_names.py +5 -5
  118. reconcile/gql_definitions/cost_report/cost_namespaces.py +5 -5
  119. reconcile/gql_definitions/cost_report/settings.py +9 -9
  120. reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +43 -43
  121. reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +10 -10
  122. reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +5 -5
  123. reconcile/gql_definitions/email_sender/apps.py +5 -5
  124. reconcile/gql_definitions/email_sender/emails.py +8 -8
  125. reconcile/gql_definitions/email_sender/users.py +6 -6
  126. reconcile/gql_definitions/endpoints_discovery/apps.py +10 -10
  127. reconcile/gql_definitions/external_resources/aws_accounts.py +9 -9
  128. reconcile/gql_definitions/external_resources/external_resources_modules.py +23 -23
  129. reconcile/gql_definitions/external_resources/external_resources_namespaces.py +494 -410
  130. reconcile/gql_definitions/external_resources/external_resources_settings.py +28 -26
  131. reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +5 -5
  132. reconcile/gql_definitions/fleet_labeler/fleet_labels.py +40 -40
  133. reconcile/gql_definitions/fragments/aus_organization.py +5 -5
  134. reconcile/gql_definitions/fragments/aws_account_common.py +7 -5
  135. reconcile/gql_definitions/fragments/aws_account_managed.py +5 -5
  136. reconcile/gql_definitions/fragments/aws_account_sso.py +5 -5
  137. reconcile/gql_definitions/fragments/aws_infra_management_account.py +5 -5
  138. reconcile/gql_definitions/fragments/{aws_vpc_request_subnet.py → aws_organization.py} +12 -8
  139. reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
  140. reconcile/gql_definitions/fragments/aws_vpc_request.py +12 -5
  141. reconcile/gql_definitions/fragments/container_image_mirror.py +5 -5
  142. reconcile/gql_definitions/fragments/deploy_resources.py +5 -5
  143. reconcile/gql_definitions/fragments/disable.py +5 -5
  144. reconcile/gql_definitions/fragments/email_service.py +5 -5
  145. reconcile/gql_definitions/fragments/email_user.py +5 -5
  146. reconcile/gql_definitions/fragments/jumphost_common_fields.py +5 -5
  147. reconcile/gql_definitions/fragments/membership_source.py +5 -5
  148. reconcile/gql_definitions/fragments/minimal_ocm_organization.py +5 -5
  149. reconcile/gql_definitions/fragments/oc_connection_cluster.py +5 -5
  150. reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
  151. reconcile/gql_definitions/fragments/pipeline_provider_retention.py +5 -5
  152. reconcile/gql_definitions/fragments/prometheus_instance.py +5 -5
  153. reconcile/gql_definitions/fragments/resource_limits_requirements.py +5 -5
  154. reconcile/gql_definitions/fragments/resource_requests_requirements.py +5 -5
  155. reconcile/gql_definitions/fragments/resource_values.py +5 -5
  156. reconcile/gql_definitions/fragments/saas_slo_document.py +5 -5
  157. reconcile/gql_definitions/fragments/saas_target_namespace.py +5 -5
  158. reconcile/gql_definitions/fragments/serviceaccount_token.py +5 -5
  159. reconcile/gql_definitions/fragments/terraform_state.py +5 -5
  160. reconcile/gql_definitions/fragments/upgrade_policy.py +5 -5
  161. reconcile/gql_definitions/fragments/user.py +5 -5
  162. reconcile/gql_definitions/fragments/vault_secret.py +5 -5
  163. reconcile/gql_definitions/gcp/gcp_docker_repos.py +9 -9
  164. reconcile/gql_definitions/gcp/gcp_projects.py +9 -9
  165. reconcile/gql_definitions/gitlab_members/gitlab_instances.py +9 -9
  166. reconcile/gql_definitions/gitlab_members/permissions.py +9 -9
  167. reconcile/gql_definitions/glitchtip/glitchtip_instance.py +9 -9
  168. reconcile/gql_definitions/glitchtip/glitchtip_project.py +11 -11
  169. reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +9 -9
  170. reconcile/gql_definitions/integrations/integrations.py +48 -51
  171. reconcile/gql_definitions/introspection.json +3510 -1865
  172. reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +11 -11
  173. reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +10 -10
  174. reconcile/gql_definitions/jira/jira_servers.py +5 -5
  175. reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +14 -10
  176. reconcile/gql_definitions/jumphosts/jumphosts.py +13 -13
  177. reconcile/gql_definitions/ldap_groups/roles.py +5 -5
  178. reconcile/gql_definitions/ldap_groups/settings.py +9 -9
  179. reconcile/gql_definitions/maintenance/maintenances.py +5 -5
  180. reconcile/gql_definitions/membershipsources/roles.py +5 -5
  181. reconcile/gql_definitions/ocm_labels/clusters.py +18 -19
  182. reconcile/gql_definitions/ocm_labels/organizations.py +5 -5
  183. reconcile/gql_definitions/openshift_cluster_bots/clusters.py +22 -22
  184. reconcile/gql_definitions/openshift_groups/managed_groups.py +5 -5
  185. reconcile/gql_definitions/openshift_groups/managed_roles.py +6 -6
  186. reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +10 -10
  187. reconcile/gql_definitions/quay_membership/quay_membership.py +6 -6
  188. reconcile/gql_definitions/rhcs/certs.py +33 -87
  189. reconcile/gql_definitions/rhcs/openshift_resource_rhcs_cert.py +43 -0
  190. reconcile/gql_definitions/rhidp/organizations.py +18 -18
  191. reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +5 -5
  192. reconcile/gql_definitions/service_dependencies/service_dependencies.py +8 -8
  193. reconcile/gql_definitions/sharding/aws_accounts.py +10 -10
  194. reconcile/gql_definitions/sharding/ocm_organization.py +8 -8
  195. reconcile/gql_definitions/skupper_network/site_controller_template.py +5 -5
  196. reconcile/gql_definitions/skupper_network/skupper_networks.py +10 -10
  197. reconcile/gql_definitions/slack_usergroups/clusters.py +5 -5
  198. reconcile/gql_definitions/slack_usergroups/permissions.py +9 -9
  199. reconcile/gql_definitions/slack_usergroups/users.py +5 -5
  200. reconcile/gql_definitions/slo_documents/slo_documents.py +5 -5
  201. reconcile/gql_definitions/status_board/status_board.py +6 -7
  202. reconcile/gql_definitions/statuspage/statuspages.py +9 -9
  203. reconcile/gql_definitions/templating/template_collection.py +5 -5
  204. reconcile/gql_definitions/templating/templates.py +5 -5
  205. reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +6 -6
  206. reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +11 -11
  207. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +11 -11
  208. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +20 -25
  209. reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +6 -6
  210. reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +12 -12
  211. reconcile/gql_definitions/terraform_init/aws_accounts.py +23 -9
  212. reconcile/gql_definitions/terraform_repo/terraform_repo.py +9 -9
  213. reconcile/gql_definitions/terraform_resources/database_access_manager.py +5 -5
  214. reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +450 -402
  215. reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +23 -17
  216. reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +9 -9
  217. reconcile/gql_definitions/vault_instances/vault_instances.py +61 -61
  218. reconcile/gql_definitions/vault_policies/vault_policies.py +11 -11
  219. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +8 -8
  220. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +5 -5
  221. reconcile/integrations_manager.py +3 -3
  222. reconcile/jenkins_job_builder.py +1 -1
  223. reconcile/jenkins_worker_fleets.py +80 -11
  224. reconcile/jira_permissions_validator.py +237 -122
  225. reconcile/ldap_groups/integration.py +1 -1
  226. reconcile/ocm/types.py +35 -56
  227. reconcile/ocm_aws_infrastructure_access.py +1 -1
  228. reconcile/ocm_clusters.py +4 -4
  229. reconcile/ocm_labels/integration.py +3 -2
  230. reconcile/ocm_machine_pools.py +33 -27
  231. reconcile/openshift_base.py +122 -10
  232. reconcile/openshift_cluster_bots.py +5 -5
  233. reconcile/openshift_groups.py +5 -0
  234. reconcile/openshift_limitranges.py +1 -1
  235. reconcile/openshift_namespace_labels.py +1 -1
  236. reconcile/openshift_namespaces.py +97 -101
  237. reconcile/openshift_resources_base.py +10 -5
  238. reconcile/openshift_rhcs_certs.py +77 -40
  239. reconcile/openshift_rolebindings.py +230 -130
  240. reconcile/openshift_saas_deploy.py +6 -7
  241. reconcile/openshift_saas_deploy_change_tester.py +9 -7
  242. reconcile/openshift_saas_deploy_trigger_cleaner.py +3 -5
  243. reconcile/openshift_serviceaccount_tokens.py +8 -7
  244. reconcile/openshift_tekton_resources.py +1 -1
  245. reconcile/openshift_upgrade_watcher.py +4 -4
  246. reconcile/openshift_users.py +5 -3
  247. reconcile/oum/labelset.py +5 -3
  248. reconcile/oum/models.py +1 -4
  249. reconcile/oum/providers.py +1 -1
  250. reconcile/prometheus_rules_tester/integration.py +4 -4
  251. reconcile/quay_mirror.py +1 -1
  252. reconcile/queries.py +131 -0
  253. reconcile/requests_sender.py +8 -3
  254. reconcile/resource_scraper.py +1 -5
  255. reconcile/rhidp/common.py +3 -5
  256. reconcile/rhidp/sso_client/base.py +19 -10
  257. reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
  258. reconcile/saas_auto_promotions_manager/subscriber.py +4 -3
  259. reconcile/sendgrid_teammates.py +20 -9
  260. reconcile/skupper_network/integration.py +2 -2
  261. reconcile/slack_usergroups.py +35 -14
  262. reconcile/sql_query.py +1 -0
  263. reconcile/status.py +2 -2
  264. reconcile/status_board.py +6 -6
  265. reconcile/statuspage/atlassian.py +7 -7
  266. reconcile/statuspage/integrations/maintenances.py +4 -3
  267. reconcile/statuspage/page.py +4 -9
  268. reconcile/statuspage/status.py +5 -8
  269. reconcile/templates/rosa-classic-cluster-creation.sh.j2 +5 -1
  270. reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +4 -1
  271. reconcile/templating/lib/merge_request_manager.py +2 -2
  272. reconcile/templating/lib/rendering.py +3 -3
  273. reconcile/templating/renderer.py +12 -13
  274. reconcile/terraform_aws_route53.py +18 -8
  275. reconcile/terraform_cloudflare_dns.py +3 -3
  276. reconcile/terraform_cloudflare_resources.py +12 -13
  277. reconcile/terraform_cloudflare_users.py +3 -2
  278. reconcile/terraform_init/integration.py +187 -23
  279. reconcile/terraform_repo.py +16 -12
  280. reconcile/terraform_resources.py +18 -10
  281. reconcile/terraform_tgw_attachments.py +28 -20
  282. reconcile/terraform_users.py +27 -22
  283. reconcile/terraform_vpc_peerings.py +15 -3
  284. reconcile/terraform_vpc_resources/integration.py +23 -8
  285. reconcile/typed_queries/app_interface_roles.py +10 -0
  286. reconcile/typed_queries/aws_account_tags.py +41 -0
  287. reconcile/typed_queries/cost_report/app_names.py +1 -1
  288. reconcile/typed_queries/cost_report/cost_namespaces.py +2 -2
  289. reconcile/typed_queries/saas_files.py +13 -13
  290. reconcile/typed_queries/status_board.py +2 -2
  291. reconcile/unleash_feature_toggles/integration.py +4 -2
  292. reconcile/utils/acs/base.py +6 -3
  293. reconcile/utils/acs/policies.py +2 -2
  294. reconcile/utils/aggregated_list.py +4 -3
  295. reconcile/utils/aws_api.py +51 -20
  296. reconcile/utils/aws_api_typed/api.py +38 -9
  297. reconcile/utils/aws_api_typed/cloudformation.py +149 -0
  298. reconcile/utils/aws_api_typed/logs.py +73 -0
  299. reconcile/utils/aws_api_typed/organization.py +4 -2
  300. reconcile/utils/binary.py +7 -12
  301. reconcile/utils/datetime_util.py +67 -0
  302. reconcile/utils/deadmanssnitch_api.py +1 -1
  303. reconcile/utils/differ.py +2 -3
  304. reconcile/utils/early_exit_cache.py +11 -12
  305. reconcile/utils/expiration.py +7 -3
  306. reconcile/utils/external_resource_spec.py +24 -1
  307. reconcile/utils/filtering.py +1 -1
  308. reconcile/utils/gitlab_api.py +7 -5
  309. reconcile/utils/glitchtip/client.py +6 -2
  310. reconcile/utils/glitchtip/models.py +25 -28
  311. reconcile/utils/gpg.py +5 -3
  312. reconcile/utils/gql.py +4 -7
  313. reconcile/utils/helm.py +2 -1
  314. reconcile/utils/helpers.py +1 -1
  315. reconcile/utils/imap_client.py +1 -1
  316. reconcile/utils/instrumented_wrappers.py +1 -1
  317. reconcile/utils/internal_groups/client.py +2 -2
  318. reconcile/utils/internal_groups/models.py +8 -17
  319. reconcile/utils/jenkins_api.py +24 -1
  320. reconcile/utils/jinja2/utils.py +6 -8
  321. reconcile/utils/jira_client.py +82 -63
  322. reconcile/utils/jjb_client.py +78 -46
  323. reconcile/utils/jobcontroller/controller.py +2 -2
  324. reconcile/utils/jobcontroller/models.py +17 -1
  325. reconcile/utils/json.py +74 -0
  326. reconcile/utils/ldap_client.py +4 -3
  327. reconcile/utils/lean_terraform_client.py +3 -1
  328. reconcile/utils/membershipsources/app_interface_resolver.py +4 -2
  329. reconcile/utils/membershipsources/models.py +16 -23
  330. reconcile/utils/membershipsources/resolver.py +4 -2
  331. reconcile/utils/merge_request_manager/merge_request_manager.py +4 -4
  332. reconcile/utils/merge_request_manager/parser.py +6 -6
  333. reconcile/utils/metrics.py +5 -5
  334. reconcile/utils/models.py +304 -82
  335. reconcile/utils/mr/__init__.py +3 -1
  336. reconcile/utils/mr/app_interface_reporter.py +6 -3
  337. reconcile/utils/mr/aws_access.py +1 -1
  338. reconcile/utils/mr/base.py +7 -13
  339. reconcile/utils/mr/clusters_updates.py +4 -2
  340. reconcile/utils/mr/notificator.py +3 -3
  341. reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +4 -1
  342. reconcile/utils/mr/promote_qontract.py +28 -12
  343. reconcile/utils/mr/update_access_report_base.py +3 -4
  344. reconcile/utils/mr/user_maintenance.py +7 -6
  345. reconcile/utils/oc.py +445 -336
  346. reconcile/utils/oc_filters.py +3 -3
  347. reconcile/utils/ocm/addons.py +0 -1
  348. reconcile/utils/ocm/base.py +18 -21
  349. reconcile/utils/ocm/cluster_groups.py +1 -1
  350. reconcile/utils/ocm/identity_providers.py +2 -2
  351. reconcile/utils/ocm/labels.py +1 -1
  352. reconcile/utils/ocm/ocm.py +81 -71
  353. reconcile/utils/ocm/products.py +9 -3
  354. reconcile/utils/ocm/search_filters.py +3 -6
  355. reconcile/utils/ocm/service_log.py +4 -6
  356. reconcile/utils/ocm/sre_capability_labels.py +20 -13
  357. reconcile/utils/ocm_base_client.py +4 -4
  358. reconcile/utils/openshift_resource.py +83 -52
  359. reconcile/utils/openssl.py +2 -2
  360. reconcile/utils/output.py +3 -2
  361. reconcile/utils/pagerduty_api.py +10 -7
  362. reconcile/utils/promotion_state.py +6 -11
  363. reconcile/utils/raw_github_api.py +11 -8
  364. reconcile/utils/repo_owners.py +21 -29
  365. reconcile/utils/rhcsv2_certs.py +138 -35
  366. reconcile/utils/rosa/session.py +16 -0
  367. reconcile/utils/runtime/integration.py +2 -3
  368. reconcile/utils/runtime/meta.py +2 -1
  369. reconcile/utils/runtime/runner.py +2 -2
  370. reconcile/utils/saasherder/interfaces.py +13 -20
  371. reconcile/utils/saasherder/models.py +25 -21
  372. reconcile/utils/saasherder/saasherder.py +60 -32
  373. reconcile/utils/secret_reader.py +6 -6
  374. reconcile/utils/sharding.py +1 -1
  375. reconcile/utils/slack_api.py +26 -4
  376. reconcile/utils/sloth.py +224 -0
  377. reconcile/utils/sqs_gateway.py +16 -11
  378. reconcile/utils/state.py +2 -1
  379. reconcile/utils/structs.py +1 -1
  380. reconcile/utils/terraform_client.py +29 -26
  381. reconcile/utils/terrascript_aws_client.py +200 -116
  382. reconcile/utils/three_way_diff_strategy.py +1 -1
  383. reconcile/utils/unleash/server.py +2 -8
  384. reconcile/utils/vault.py +44 -41
  385. reconcile/utils/vcs.py +8 -8
  386. reconcile/vault_replication.py +119 -58
  387. tools/app_interface_reporter.py +4 -4
  388. tools/cli_commands/cost_report/cost_management_api.py +3 -3
  389. tools/cli_commands/cost_report/view.py +7 -6
  390. tools/cli_commands/erv2.py +1 -1
  391. tools/cli_commands/gpg_encrypt.py +4 -1
  392. tools/cli_commands/systems_and_tools.py +5 -1
  393. tools/qontract_cli.py +36 -21
  394. tools/template_validation.py +3 -1
  395. reconcile/gql_definitions/ocm_oidc_idp/__init__.py +0 -0
  396. reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
  397. reconcile/jenkins/__init__.py +0 -0
  398. reconcile/jenkins/types.py +0 -77
  399. {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/WHEEL +0 -0
  400. {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/entry_points.txt +0 -0
@@ -7,12 +7,7 @@ from enum import StrEnum
7
7
  from typing import Any
8
8
 
9
9
  import semver
10
- from pydantic import (
11
- BaseModel,
12
- ValidationError,
13
- root_validator,
14
- validator,
15
- )
10
+ from pydantic import BaseModel, ValidationError, field_validator, model_validator
16
11
 
17
12
  from reconcile.aws_version_sync.merge_request_manager.merge_request import (
18
13
  Renderer,
@@ -81,7 +76,7 @@ class SupportedResourceProvider(StrEnum):
81
76
  ELASTICACHE = "elasticache"
82
77
 
83
78
 
84
- class ExternalResource(BaseModel):
79
+ class ExternalResource(BaseModel, arbitrary_types_allowed=True):
85
80
  namespace_file: str | None = None
86
81
  provider: str = "aws"
87
82
  provisioner: ExternalResourceProvisioner
@@ -94,9 +89,6 @@ class ExternalResource(BaseModel):
94
89
  # used to map AWS cache name to resource_identifier
95
90
  redis_replication_group_id: str | None = None
96
91
 
97
- class Config:
98
- arbitrary_types_allowed = True
99
-
100
92
  @property
101
93
  def key(self) -> tuple:
102
94
  return (
@@ -104,10 +96,10 @@ class ExternalResource(BaseModel):
104
96
  self.provisioner.uid,
105
97
  self.resource_provider,
106
98
  self.resource_identifier,
107
- self.resource_engine,
108
99
  )
109
100
 
110
- @validator("resource_engine_version", pre=True)
101
+ @field_validator("resource_engine_version", mode="before")
102
+ @classmethod
111
103
  def parse_resource_engine_version(
112
104
  cls, v: str | semver.VersionInfo
113
105
  ) -> semver.VersionInfo:
@@ -115,7 +107,8 @@ class ExternalResource(BaseModel):
115
107
  return v
116
108
  return parse_semver(str(v), optional_minor_and_patch=True)
117
109
 
118
- @root_validator(pre=True)
110
+ @model_validator(mode="before")
111
+ @classmethod
119
112
  def set_resource_engine_version_format(cls, values: dict) -> dict:
120
113
  resource_engine_version, resource_engine_version_format = (
121
114
  str(values.get("resource_engine_version")),
@@ -220,6 +213,7 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
220
213
  clusters: Iterable[ClusterV1],
221
214
  timeout: int,
222
215
  elasticache_replication_group_id_to_identifier: ReplicationGroupIdToIdentifier,
216
+ supported_providers: Iterable[str],
223
217
  prom_get_func: Callable = prom_get,
224
218
  ) -> list[ExternalResource]:
225
219
  metrics: list[ExternalResource] = []
@@ -232,81 +226,123 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
232
226
  )
233
227
 
234
228
  # RDS resources
235
- try:
236
- rds_metrics = prom_get_func(
237
- url=cluster.prometheus_url,
238
- params={"query": "aws_resources_exporter_rds_engineversion"},
239
- token=token,
240
- timeout=timeout,
229
+ if SupportedResourceProvider.RDS in supported_providers:
230
+ metrics.extend(
231
+ self._fetch_rds_metrics(cluster, token, timeout, prom_get_func)
241
232
  )
242
233
 
243
- for m in rds_metrics:
244
- try:
245
- metrics.append(
246
- ExternalResource(
247
- provider="aws",
248
- provisioner=ExternalResourceProvisioner(
249
- uid=m["aws_account_id"]
250
- ),
251
- resource_provider=SupportedResourceProvider.RDS,
252
- resource_identifier=m["dbinstance_identifier"],
253
- resource_engine=m["engine"],
254
- resource_engine_version=m["engine_version"],
255
- )
256
- )
257
- except ValidationError:
258
- # don't try to parse AWS extended support version numbers
259
- # See https://aws.amazon.com/about-aws/whats-new/2025/04/amazon-rds-postgresql-extended-support-11-22-rds-20250220-12-22-rds-20250220/ for more info
260
- if (
261
- EXTENDED_SUPPORT_VERSION_INDICATOR
262
- not in m["engine_version"]
263
- ):
264
- raise
265
- except Exception as e:
266
- logging.error(
267
- f"Failed to parse RDS metric for {m['dbinstance_identifier']}: {e}"
268
- )
269
- except Exception as e:
234
+ # ElastiCache resources
235
+ if SupportedResourceProvider.ELASTICACHE in supported_providers:
236
+ metrics.extend(
237
+ self._fetch_elasticache_metrics(
238
+ cluster,
239
+ token,
240
+ timeout,
241
+ elasticache_replication_group_id_to_identifier,
242
+ prom_get_func,
243
+ )
244
+ )
245
+
246
+ return metrics
247
+
248
+ def _fetch_rds_metrics(
249
+ self,
250
+ cluster: ClusterV1,
251
+ token: str | None,
252
+ timeout: int,
253
+ prom_get_func: Callable,
254
+ ) -> list[ExternalResource]:
255
+ """Fetch RDS metrics from the AWS resource exporter."""
256
+ metrics: list[ExternalResource] = []
257
+ try:
258
+ rds_metrics = prom_get_func(
259
+ url=cluster.prometheus_url,
260
+ params={"query": "aws_resources_exporter_rds_engineversion"},
261
+ token=token,
262
+ timeout=timeout,
263
+ )
264
+ except Exception as e:
265
+ logging.error(
266
+ f"Failed to get 'aws_resources_exporter_rds_engineversion' metrics for cluster {cluster.name}: {e}"
267
+ )
268
+ return []
269
+
270
+ for m in rds_metrics:
271
+ try:
272
+ metrics.append(
273
+ ExternalResource(
274
+ provider="aws",
275
+ provisioner=ExternalResourceProvisioner(
276
+ uid=m["aws_account_id"]
277
+ ),
278
+ resource_provider=SupportedResourceProvider.RDS,
279
+ resource_identifier=m["dbinstance_identifier"],
280
+ resource_engine=m["engine"],
281
+ resource_engine_version=m["engine_version"],
282
+ )
283
+ )
284
+ except ValidationError as e:
285
+ if EXTENDED_SUPPORT_VERSION_INDICATOR in m["engine_version"]:
286
+ # don't try to parse AWS extended support version numbers
287
+ # See https://aws.amazon.com/about-aws/whats-new/2025/04/amazon-rds-postgresql-extended-support-11-22-rds-20250220-12-22-rds-20250220/ for more info
288
+ pass
289
+ else:
290
+ logging.error(
291
+ f"Failed to parse RDS metric for {m['dbinstance_identifier']}: {e}"
292
+ )
293
+ except KeyError as e:
270
294
  logging.error(
271
- f"Failed to get 'aws_resources_exporter_rds_engineversion' metrics for cluster {cluster.name}: {e}"
295
+ f"Failed to parse RDS metric for {m['dbinstance_identifier']}: {e}"
272
296
  )
297
+ return metrics
273
298
 
274
- # ElastiCache resources
299
+ def _fetch_elasticache_metrics(
300
+ self,
301
+ cluster: ClusterV1,
302
+ token: str | None,
303
+ timeout: int,
304
+ elasticache_replication_group_id_to_identifier: ReplicationGroupIdToIdentifier,
305
+ prom_get_func: Callable,
306
+ ) -> list[ExternalResource]:
307
+ """Fetch ElastiCache metrics from the AWS resource exporter."""
308
+ metrics: list[ExternalResource] = []
309
+ try:
310
+ elasticache_metrics = prom_get_func(
311
+ url=cluster.prometheus_url,
312
+ params={"query": "aws_resources_exporter_elasticache_redisversion"},
313
+ token=token,
314
+ timeout=timeout,
315
+ )
316
+ except Exception as e:
317
+ logging.error(
318
+ f"Failed to get 'aws_resources_exporter_elasticache_redisversion' metrics for cluster {cluster.name}: {e}"
319
+ )
320
+ return []
321
+
322
+ for m in elasticache_metrics:
275
323
  try:
276
- elasticache_metrics = prom_get_func(
277
- url=cluster.prometheus_url,
278
- params={"query": "aws_resources_exporter_elasticache_redisversion"},
279
- token=token,
280
- timeout=timeout,
324
+ metrics.append(
325
+ ExternalResource(
326
+ provider="aws",
327
+ provisioner=ExternalResourceProvisioner(
328
+ uid=m["aws_account_id"]
329
+ ),
330
+ resource_provider=SupportedResourceProvider.ELASTICACHE,
331
+ # replication_group_id != resource_identifier!
332
+ resource_identifier=elasticache_replication_group_id_to_identifier.get(
333
+ (
334
+ m["aws_account_id"],
335
+ m["replication_group_id"],
336
+ ),
337
+ m["replication_group_id"],
338
+ ),
339
+ resource_engine=m["engine"],
340
+ resource_engine_version=m["engine_version"],
341
+ )
281
342
  )
282
- for m in elasticache_metrics:
283
- try:
284
- metrics.append(
285
- ExternalResource(
286
- provider="aws",
287
- provisioner=ExternalResourceProvisioner(
288
- uid=m["aws_account_id"]
289
- ),
290
- resource_provider=SupportedResourceProvider.ELASTICACHE,
291
- # replication_group_id != resource_identifier!
292
- resource_identifier=elasticache_replication_group_id_to_identifier.get(
293
- (
294
- m["aws_account_id"],
295
- m["replication_group_id"],
296
- ),
297
- m["replication_group_id"],
298
- ),
299
- resource_engine=m["engine"],
300
- resource_engine_version=m["engine_version"],
301
- )
302
- )
303
- except Exception as e:
304
- logging.error(
305
- f"Failed to parse ElastiCache metrics for {m['replication_group_id']}: {e}"
306
- )
307
- except Exception as e:
343
+ except (ValidationError, KeyError) as e:
308
344
  logging.error(
309
- f"Failed to get 'aws_resources_exporter_elasticache_redisversion' metrics for cluster {cluster.name}: {e}"
345
+ f"Failed to parse ElastiCache metrics for {m['replication_group_id']}: {e}"
310
346
  )
311
347
 
312
348
  return metrics
@@ -353,8 +389,8 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
353
389
  resource.provider == SupportedResourceProvider.ELASTICACHE
354
390
  and str(values["engine_version"]).lower().endswith("x")
355
391
  ):
356
- # AWS ElastiCache Redis 6 could use a version like 6.x. Then, we don't need to manage it
357
- continue
392
+ # AWS ElastiCache Redis 6 could use a version like 6.x. Let's patch it to a fix version
393
+ values["engine_version"] = "6.2"
358
394
 
359
395
  if (
360
396
  resource.provider == SupportedResourceProvider.RDS
@@ -400,7 +436,9 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
400
436
  key=lambda r: r.key,
401
437
  equal=lambda external_resources_app_interface,
402
438
  external_resources_aws: external_resources_app_interface.resource_engine_version_string
403
- == external_resources_aws.resource_engine_version_string,
439
+ == external_resources_aws.resource_engine_version_string
440
+ and external_resources_app_interface.resource_engine
441
+ == external_resources_aws.resource_engine,
404
442
  )
405
443
  for diff_pair in diff.change.values():
406
444
  aws_resource = diff_pair.desired
@@ -408,6 +446,8 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
408
446
  if (
409
447
  aws_resource.resource_engine_version
410
448
  <= app_interface_resource.resource_engine_version
449
+ and aws_resource.resource_engine
450
+ == app_interface_resource.resource_engine
411
451
  ):
412
452
  # do not downgrade the version
413
453
  continue
@@ -422,7 +462,7 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
422
462
  provisioner_uid=app_interface_resource.provisioner.uid,
423
463
  resource_provider=app_interface_resource.resource_provider,
424
464
  resource_identifier=app_interface_resource.resource_identifier,
425
- resource_engine=app_interface_resource.resource_engine,
465
+ resource_engine=aws_resource.resource_engine,
426
466
  resource_engine_version=aws_resource.resource_engine_version_string,
427
467
  )
428
468
  )
@@ -475,6 +515,7 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
475
515
  for external_resource in external_resources_app_interface
476
516
  if external_resource.redis_replication_group_id
477
517
  },
518
+ supported_providers=self.params.supported_providers,
478
519
  )
479
520
 
480
521
  self.reconcile(
@@ -62,8 +62,8 @@ class QontractServerDatafileDiff(BaseModel):
62
62
 
63
63
  datafilepath: str
64
64
  datafileschema: str
65
- old: dict[str, Any] | None
66
- new: dict[str, Any] | None
65
+ old: dict[str, Any] | None = None
66
+ new: dict[str, Any] | None = None
67
67
 
68
68
  @property
69
69
  def old_datafilepath(self) -> str | None:
@@ -119,7 +119,7 @@ class QontractServerResourcefileDiffState(BaseModel):
119
119
  content: str
120
120
  resourcefileschema: str | None = Field(..., alias="$schema")
121
121
  sha256sum: str
122
- backrefs: list[QontractServerResourcefileBackref] | None
122
+ backrefs: list[QontractServerResourcefileBackref] | None = None
123
123
 
124
124
 
125
125
  class QontractServerResourcefileDiff(BaseModel):
@@ -155,7 +155,8 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
155
155
  changes = aggregate_resource_changes(
156
156
  bundle_changes=aggregate_file_moves(parse_bundle_changes(diff)),
157
157
  content_store={
158
- c.path: c.dict(by_alias=True) for c in namespaces + jenkins_configs
158
+ c.path: c.model_dump(by_alias=True)
159
+ for c in namespaces + jenkins_configs
159
160
  },
160
161
  supported_schemas={
161
162
  "/openshift/namespace-1.yml",
@@ -239,4 +240,4 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
239
240
  change_log.items, key=lambda i: i.merged_at, reverse=True
240
241
  )
241
242
  if not dry_run:
242
- integration_state.add(BUNDLE_DIFFS_OBJ, change_log.dict(), force=True)
243
+ integration_state.add(BUNDLE_DIFFS_OBJ, change_log.model_dump(), force=True)
@@ -140,7 +140,7 @@ def write_coverage_report_to_mr(
140
140
  approver_reachability = set()
141
141
  for d in change_decisions:
142
142
  approvers = [
143
- f"{cr.context} - {' '.join([f'@{a.org_username}' if a.tag_on_merge_requests else a.org_username for a in cr.approvers])}"
143
+ f"{cr.context} - {' '.join([f'@{a.org_username}' if (a.tag_on_merge_requests or len(cr.approvers) == 1) else a.org_username for a in cr.approvers])}"
144
144
  for cr in d.change_responsibles
145
145
  ]
146
146
  if d.coverable_by_fragment_decisions:
@@ -1,5 +1,4 @@
1
1
  import copy
2
- import json
3
2
  from dataclasses import dataclass
4
3
  from enum import Enum
5
4
  from functools import reduce
@@ -11,6 +10,7 @@ from deepdiff.helper import CannotCompare
11
10
  from deepdiff.model import DiffLevel
12
11
  from deepdiff.path import parse_path
13
12
 
13
+ from reconcile.utils.json import json_dumps
14
14
  from reconcile.utils.jsonpath import parse_jsonpath
15
15
 
16
16
 
@@ -75,7 +75,7 @@ class Diff:
75
75
  def _value_repr(self, value: Any | None) -> str | None:
76
76
  if value:
77
77
  if isinstance(value, dict | list):
78
- return json.dumps(value, indent=2)
78
+ return json_dumps(value, indent=2)
79
79
  return str(value)
80
80
  return value
81
81
 
@@ -251,8 +251,6 @@ def deepdiff_path_to_jsonpath(deep_diff_path: str) -> jsonpath_ng.JSONPath:
251
251
  case int():
252
252
  return jsonpath_ng.Index(element)
253
253
  case str():
254
- if "." in element:
255
- return jsonpath_ng.Fields(f"'{element}'")
256
254
  return jsonpath_ng.Fields(element)
257
255
 
258
256
  path_parts = [build_jsonpath_part(p) for p in parse_path(deep_diff_path)]
reconcile/checkpoint.py CHANGED
@@ -26,6 +26,7 @@ from jira import Issue
26
26
 
27
27
  from reconcile.utils.constants import PROJ_ROOT
28
28
  from reconcile.utils.jira_client import JiraClient
29
+ from reconcile.utils.secret_reader import SecretReaderBase
29
30
 
30
31
  DEFAULT_CHECKPOINT_LABELS = ("sre-checkpoint",)
31
32
 
@@ -61,7 +62,7 @@ def url_makes_sense(url: str) -> bool:
61
62
  return rs.status_code < HTTPStatus.NOT_FOUND
62
63
 
63
64
 
64
- def valid_owners(owners: Iterable[Mapping[str, str]]) -> bool:
65
+ def valid_owners(owners: Iterable[Mapping[str, str | None]]) -> bool:
65
66
  """Confirm whether all the owners have a name and a valid email address."""
66
67
  return all(
67
68
  o["name"]
@@ -118,8 +119,8 @@ def file_ticket(
118
119
  def report_invalid_metadata(
119
120
  app: Mapping[str, Any],
120
121
  path: str,
121
- board: Mapping[str, str | Mapping],
122
- settings: Mapping[str, Any],
122
+ board: Mapping[str, Any],
123
+ secret_reader: SecretReaderBase,
123
124
  parent: str,
124
125
  dry_run: bool = False,
125
126
  ) -> None:
@@ -150,7 +151,14 @@ def report_invalid_metadata(
150
151
  path=path,
151
152
  )
152
153
  else:
153
- jira = JiraClient(board, settings)
154
+ jira = JiraClient.create(
155
+ project_name=board["name"],
156
+ token=secret_reader.read_secret(board["server"]["token"]),
157
+ email=secret_reader.read_secret(board["server"]["email"])
158
+ if board["server"]["email"]
159
+ else None,
160
+ server_url=board["server"]["server_url"],
161
+ )
154
162
  do_cut = partial(
155
163
  file_ticket, # type: ignore
156
164
  jira=jira,