qontract-reconcile 0.10.2.dev349__py3-none-any.whl → 0.10.2.dev414__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 (356) hide show
  1. {qontract_reconcile-0.10.2.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/METADATA +12 -11
  2. {qontract_reconcile-0.10.2.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/RECORD +356 -350
  3. reconcile/acs_rbac.py +2 -2
  4. reconcile/aus/advanced_upgrade_service.py +15 -12
  5. reconcile/aus/base.py +26 -27
  6. reconcile/aus/cluster_version_data.py +15 -5
  7. reconcile/aus/models.py +1 -1
  8. reconcile/automated_actions/config/integration.py +15 -3
  9. reconcile/aws_account_manager/integration.py +8 -8
  10. reconcile/aws_account_manager/reconciler.py +3 -3
  11. reconcile/aws_ami_cleanup/integration.py +8 -12
  12. reconcile/aws_ami_share.py +69 -62
  13. reconcile/aws_cloudwatch_log_retention/integration.py +155 -126
  14. reconcile/aws_ecr_image_pull_secrets.py +2 -2
  15. reconcile/aws_iam_keys.py +7 -41
  16. reconcile/aws_saml_idp/integration.py +12 -4
  17. reconcile/aws_saml_roles/integration.py +32 -25
  18. reconcile/aws_version_sync/integration.py +6 -12
  19. reconcile/change_owners/bundle.py +3 -3
  20. reconcile/change_owners/change_log_tracking.py +3 -2
  21. reconcile/change_owners/change_owners.py +1 -1
  22. reconcile/change_owners/diff.py +2 -4
  23. reconcile/checkpoint.py +11 -3
  24. reconcile/cli.py +33 -8
  25. reconcile/dashdotdb_dora.py +5 -12
  26. reconcile/dashdotdb_slo.py +1 -1
  27. reconcile/database_access_manager.py +123 -117
  28. reconcile/dynatrace_token_provider/integration.py +1 -1
  29. reconcile/endpoints_discovery/integration.py +4 -1
  30. reconcile/endpoints_discovery/merge_request.py +1 -1
  31. reconcile/endpoints_discovery/merge_request_manager.py +9 -11
  32. reconcile/external_resources/factories.py +5 -12
  33. reconcile/external_resources/integration.py +1 -1
  34. reconcile/external_resources/manager.py +24 -10
  35. reconcile/external_resources/meta.py +0 -1
  36. reconcile/external_resources/metrics.py +1 -1
  37. reconcile/external_resources/model.py +13 -13
  38. reconcile/external_resources/reconciler.py +7 -4
  39. reconcile/external_resources/secrets_sync.py +6 -8
  40. reconcile/external_resources/state.py +60 -17
  41. reconcile/fleet_labeler/integration.py +1 -1
  42. reconcile/gabi_authorized_users.py +8 -5
  43. reconcile/gcp_image_mirror.py +2 -2
  44. reconcile/github_org.py +1 -1
  45. reconcile/github_owners.py +4 -0
  46. reconcile/gitlab_housekeeping.py +13 -15
  47. reconcile/gitlab_members.py +6 -12
  48. reconcile/gitlab_mr_sqs_consumer.py +2 -2
  49. reconcile/gitlab_owners.py +15 -11
  50. reconcile/gitlab_permissions.py +8 -12
  51. reconcile/glitchtip_project_alerts/integration.py +3 -1
  52. reconcile/gql_definitions/acs/acs_instances.py +5 -5
  53. reconcile/gql_definitions/acs/acs_policies.py +5 -5
  54. reconcile/gql_definitions/acs/acs_rbac.py +5 -5
  55. reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +5 -5
  56. reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +5 -5
  57. reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +5 -5
  58. reconcile/gql_definitions/app_sre_tekton_access_revalidation/roles.py +5 -5
  59. reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py +5 -5
  60. reconcile/gql_definitions/automated_actions/instance.py +46 -7
  61. reconcile/gql_definitions/aws_account_manager/aws_accounts.py +5 -5
  62. reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +15 -5
  63. reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +27 -66
  64. reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +15 -5
  65. reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +15 -5
  66. reconcile/gql_definitions/aws_saml_roles/roles.py +5 -5
  67. reconcile/gql_definitions/aws_version_sync/clusters.py +5 -5
  68. reconcile/gql_definitions/aws_version_sync/namespaces.py +5 -5
  69. reconcile/gql_definitions/change_owners/queries/change_types.py +5 -5
  70. reconcile/gql_definitions/change_owners/queries/self_service_roles.py +5 -5
  71. reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +5 -5
  72. reconcile/gql_definitions/common/alerting_services_settings.py +5 -5
  73. reconcile/gql_definitions/common/app_code_component_repos.py +5 -5
  74. reconcile/gql_definitions/common/app_interface_custom_messages.py +5 -5
  75. reconcile/gql_definitions/common/app_interface_dms_settings.py +5 -5
  76. reconcile/gql_definitions/common/app_interface_repo_settings.py +5 -5
  77. reconcile/gql_definitions/common/app_interface_roles.py +5 -5
  78. reconcile/gql_definitions/common/app_interface_state_settings.py +5 -5
  79. reconcile/gql_definitions/common/app_interface_vault_settings.py +5 -5
  80. reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +5 -5
  81. reconcile/gql_definitions/common/apps.py +5 -5
  82. reconcile/gql_definitions/common/aws_vpc_requests.py +15 -5
  83. reconcile/gql_definitions/common/aws_vpcs.py +5 -5
  84. reconcile/gql_definitions/common/clusters.py +7 -5
  85. reconcile/gql_definitions/common/clusters_minimal.py +5 -5
  86. reconcile/gql_definitions/common/clusters_with_dms.py +5 -5
  87. reconcile/gql_definitions/common/clusters_with_peering.py +5 -5
  88. reconcile/gql_definitions/common/github_orgs.py +5 -5
  89. reconcile/gql_definitions/common/jira_settings.py +5 -5
  90. reconcile/gql_definitions/common/jiralert_settings.py +5 -5
  91. reconcile/gql_definitions/common/ldap_settings.py +5 -5
  92. reconcile/gql_definitions/common/namespaces.py +5 -5
  93. reconcile/gql_definitions/common/namespaces_minimal.py +7 -5
  94. reconcile/gql_definitions/common/ocm_env_telemeter.py +5 -5
  95. reconcile/gql_definitions/common/ocm_environments.py +5 -5
  96. reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
  97. reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -5
  98. reconcile/gql_definitions/common/pipeline_providers.py +5 -5
  99. reconcile/gql_definitions/common/quay_instances.py +5 -5
  100. reconcile/gql_definitions/common/quay_orgs.py +5 -5
  101. reconcile/gql_definitions/common/reserved_networks.py +5 -5
  102. reconcile/gql_definitions/common/rhcs_provider_settings.py +5 -5
  103. reconcile/gql_definitions/common/saas_files.py +5 -5
  104. reconcile/gql_definitions/common/saas_target_namespaces.py +5 -5
  105. reconcile/gql_definitions/common/saasherder_settings.py +5 -5
  106. reconcile/gql_definitions/common/slack_workspaces.py +5 -5
  107. reconcile/gql_definitions/common/smtp_client_settings.py +5 -5
  108. reconcile/gql_definitions/common/state_aws_account.py +5 -5
  109. reconcile/gql_definitions/common/users.py +5 -5
  110. reconcile/gql_definitions/common/users_with_paths.py +5 -5
  111. reconcile/gql_definitions/cost_report/app_names.py +5 -5
  112. reconcile/gql_definitions/cost_report/cost_namespaces.py +5 -5
  113. reconcile/gql_definitions/cost_report/settings.py +5 -5
  114. reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +5 -5
  115. reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +5 -5
  116. reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +5 -5
  117. reconcile/gql_definitions/email_sender/apps.py +5 -5
  118. reconcile/gql_definitions/email_sender/emails.py +5 -5
  119. reconcile/gql_definitions/email_sender/users.py +5 -5
  120. reconcile/gql_definitions/endpoints_discovery/apps.py +5 -5
  121. reconcile/gql_definitions/external_resources/aws_accounts.py +5 -5
  122. reconcile/gql_definitions/external_resources/external_resources_modules.py +5 -5
  123. reconcile/gql_definitions/external_resources/external_resources_namespaces.py +89 -6
  124. reconcile/gql_definitions/external_resources/external_resources_settings.py +7 -5
  125. reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +5 -5
  126. reconcile/gql_definitions/fleet_labeler/fleet_labels.py +5 -5
  127. reconcile/gql_definitions/fragments/aus_organization.py +5 -5
  128. reconcile/gql_definitions/fragments/aws_account_common.py +7 -5
  129. reconcile/gql_definitions/fragments/aws_account_managed.py +5 -5
  130. reconcile/gql_definitions/fragments/aws_account_sso.py +5 -5
  131. reconcile/gql_definitions/fragments/aws_infra_management_account.py +5 -5
  132. reconcile/gql_definitions/fragments/aws_organization.py +33 -0
  133. reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
  134. reconcile/gql_definitions/fragments/aws_vpc_request.py +7 -5
  135. reconcile/gql_definitions/fragments/container_image_mirror.py +5 -5
  136. reconcile/gql_definitions/fragments/deploy_resources.py +5 -5
  137. reconcile/gql_definitions/fragments/disable.py +5 -5
  138. reconcile/gql_definitions/fragments/email_service.py +5 -5
  139. reconcile/gql_definitions/fragments/email_user.py +5 -5
  140. reconcile/gql_definitions/fragments/jumphost_common_fields.py +5 -5
  141. reconcile/gql_definitions/fragments/membership_source.py +5 -5
  142. reconcile/gql_definitions/fragments/minimal_ocm_organization.py +5 -5
  143. reconcile/gql_definitions/fragments/oc_connection_cluster.py +5 -5
  144. reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
  145. reconcile/gql_definitions/fragments/pipeline_provider_retention.py +5 -5
  146. reconcile/gql_definitions/fragments/prometheus_instance.py +5 -5
  147. reconcile/gql_definitions/fragments/resource_limits_requirements.py +5 -5
  148. reconcile/gql_definitions/fragments/resource_requests_requirements.py +5 -5
  149. reconcile/gql_definitions/fragments/resource_values.py +5 -5
  150. reconcile/gql_definitions/fragments/saas_slo_document.py +5 -5
  151. reconcile/gql_definitions/fragments/saas_target_namespace.py +5 -5
  152. reconcile/gql_definitions/fragments/serviceaccount_token.py +5 -5
  153. reconcile/gql_definitions/fragments/terraform_state.py +5 -5
  154. reconcile/gql_definitions/fragments/upgrade_policy.py +5 -5
  155. reconcile/gql_definitions/fragments/user.py +5 -5
  156. reconcile/gql_definitions/fragments/vault_secret.py +5 -5
  157. reconcile/gql_definitions/gcp/gcp_docker_repos.py +5 -5
  158. reconcile/gql_definitions/gcp/gcp_projects.py +5 -5
  159. reconcile/gql_definitions/gitlab_members/gitlab_instances.py +5 -5
  160. reconcile/gql_definitions/gitlab_members/permissions.py +5 -5
  161. reconcile/gql_definitions/glitchtip/glitchtip_instance.py +5 -5
  162. reconcile/gql_definitions/glitchtip/glitchtip_project.py +5 -5
  163. reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +5 -5
  164. reconcile/gql_definitions/integrations/integrations.py +5 -5
  165. reconcile/gql_definitions/introspection.json +2137 -1053
  166. reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +5 -5
  167. reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +5 -5
  168. reconcile/gql_definitions/jira/jira_servers.py +5 -5
  169. reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +9 -5
  170. reconcile/gql_definitions/jumphosts/jumphosts.py +5 -5
  171. reconcile/gql_definitions/ldap_groups/roles.py +5 -5
  172. reconcile/gql_definitions/ldap_groups/settings.py +5 -5
  173. reconcile/gql_definitions/maintenance/maintenances.py +5 -5
  174. reconcile/gql_definitions/membershipsources/roles.py +5 -5
  175. reconcile/gql_definitions/ocm_labels/clusters.py +5 -5
  176. reconcile/gql_definitions/ocm_labels/organizations.py +5 -5
  177. reconcile/gql_definitions/openshift_cluster_bots/clusters.py +5 -5
  178. reconcile/gql_definitions/openshift_groups/managed_groups.py +5 -5
  179. reconcile/gql_definitions/openshift_groups/managed_roles.py +5 -5
  180. reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +5 -5
  181. reconcile/gql_definitions/quay_membership/quay_membership.py +5 -5
  182. reconcile/gql_definitions/rhcs/certs.py +5 -5
  183. reconcile/gql_definitions/rhidp/organizations.py +5 -5
  184. reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +5 -5
  185. reconcile/gql_definitions/service_dependencies/service_dependencies.py +5 -5
  186. reconcile/gql_definitions/sharding/aws_accounts.py +5 -5
  187. reconcile/gql_definitions/sharding/ocm_organization.py +5 -5
  188. reconcile/gql_definitions/skupper_network/site_controller_template.py +5 -5
  189. reconcile/gql_definitions/skupper_network/skupper_networks.py +5 -5
  190. reconcile/gql_definitions/slack_usergroups/clusters.py +5 -5
  191. reconcile/gql_definitions/slack_usergroups/permissions.py +5 -5
  192. reconcile/gql_definitions/slack_usergroups/users.py +5 -5
  193. reconcile/gql_definitions/slo_documents/slo_documents.py +5 -5
  194. reconcile/gql_definitions/status_board/status_board.py +5 -5
  195. reconcile/gql_definitions/statuspage/statuspages.py +5 -5
  196. reconcile/gql_definitions/templating/template_collection.py +5 -5
  197. reconcile/gql_definitions/templating/templates.py +5 -5
  198. reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +5 -5
  199. reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +5 -5
  200. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +5 -5
  201. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +5 -5
  202. reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +5 -5
  203. reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +5 -5
  204. reconcile/gql_definitions/terraform_init/aws_accounts.py +19 -5
  205. reconcile/gql_definitions/terraform_repo/terraform_repo.py +5 -5
  206. reconcile/gql_definitions/terraform_resources/database_access_manager.py +5 -5
  207. reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +38 -6
  208. reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +15 -5
  209. reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +5 -5
  210. reconcile/gql_definitions/vault_instances/vault_instances.py +5 -5
  211. reconcile/gql_definitions/vault_policies/vault_policies.py +5 -5
  212. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +5 -5
  213. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +5 -5
  214. reconcile/integrations_manager.py +3 -3
  215. reconcile/jenkins_worker_fleets.py +10 -8
  216. reconcile/jira_permissions_validator.py +237 -122
  217. reconcile/ldap_groups/integration.py +1 -1
  218. reconcile/ocm/types.py +35 -56
  219. reconcile/ocm_aws_infrastructure_access.py +1 -1
  220. reconcile/ocm_clusters.py +4 -4
  221. reconcile/ocm_labels/integration.py +3 -2
  222. reconcile/ocm_machine_pools.py +23 -23
  223. reconcile/openshift_base.py +53 -2
  224. reconcile/openshift_cluster_bots.py +3 -2
  225. reconcile/openshift_namespace_labels.py +1 -1
  226. reconcile/openshift_namespaces.py +97 -101
  227. reconcile/openshift_resources_base.py +6 -2
  228. reconcile/openshift_rhcs_certs.py +5 -5
  229. reconcile/openshift_rolebindings.py +7 -11
  230. reconcile/openshift_saas_deploy.py +6 -7
  231. reconcile/openshift_saas_deploy_change_tester.py +9 -7
  232. reconcile/openshift_saas_deploy_trigger_cleaner.py +3 -5
  233. reconcile/openshift_serviceaccount_tokens.py +2 -2
  234. reconcile/openshift_upgrade_watcher.py +4 -4
  235. reconcile/oum/labelset.py +5 -3
  236. reconcile/oum/models.py +1 -4
  237. reconcile/prometheus_rules_tester/integration.py +3 -3
  238. reconcile/quay_mirror.py +1 -1
  239. reconcile/queries.py +131 -1
  240. reconcile/rhidp/common.py +3 -5
  241. reconcile/rhidp/sso_client/base.py +1 -1
  242. reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
  243. reconcile/saas_auto_promotions_manager/subscriber.py +4 -3
  244. reconcile/skupper_network/integration.py +2 -2
  245. reconcile/slack_usergroups.py +35 -14
  246. reconcile/sql_query.py +1 -0
  247. reconcile/status_board.py +6 -6
  248. reconcile/statuspage/atlassian.py +7 -7
  249. reconcile/statuspage/integrations/maintenances.py +4 -3
  250. reconcile/statuspage/page.py +4 -9
  251. reconcile/statuspage/status.py +5 -8
  252. reconcile/templates/rosa-classic-cluster-creation.sh.j2 +4 -0
  253. reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +3 -0
  254. reconcile/templating/lib/rendering.py +3 -3
  255. reconcile/templating/renderer.py +4 -3
  256. reconcile/terraform_aws_route53.py +7 -1
  257. reconcile/terraform_cloudflare_dns.py +3 -3
  258. reconcile/terraform_cloudflare_resources.py +5 -5
  259. reconcile/terraform_cloudflare_users.py +3 -2
  260. reconcile/terraform_init/integration.py +187 -23
  261. reconcile/terraform_repo.py +16 -12
  262. reconcile/terraform_resources.py +17 -7
  263. reconcile/terraform_tgw_attachments.py +27 -19
  264. reconcile/terraform_users.py +7 -0
  265. reconcile/terraform_vpc_peerings.py +14 -3
  266. reconcile/terraform_vpc_resources/integration.py +10 -1
  267. reconcile/typed_queries/aws_account_tags.py +41 -0
  268. reconcile/typed_queries/cost_report/app_names.py +1 -1
  269. reconcile/typed_queries/cost_report/cost_namespaces.py +2 -2
  270. reconcile/typed_queries/saas_files.py +13 -13
  271. reconcile/typed_queries/status_board.py +2 -2
  272. reconcile/unleash_feature_toggles/integration.py +4 -2
  273. reconcile/utils/acs/base.py +6 -3
  274. reconcile/utils/acs/policies.py +2 -2
  275. reconcile/utils/aggregated_list.py +4 -3
  276. reconcile/utils/aws_api.py +51 -54
  277. reconcile/utils/aws_api_typed/api.py +38 -9
  278. reconcile/utils/aws_api_typed/cloudformation.py +149 -0
  279. reconcile/utils/aws_api_typed/logs.py +73 -0
  280. reconcile/utils/aws_api_typed/organization.py +4 -2
  281. reconcile/utils/datetime_util.py +67 -0
  282. reconcile/utils/deadmanssnitch_api.py +1 -1
  283. reconcile/utils/differ.py +2 -3
  284. reconcile/utils/early_exit_cache.py +11 -12
  285. reconcile/utils/expiration.py +7 -3
  286. reconcile/utils/external_resource_spec.py +24 -1
  287. reconcile/utils/filtering.py +1 -1
  288. reconcile/utils/gitlab_api.py +7 -5
  289. reconcile/utils/glitchtip/client.py +6 -2
  290. reconcile/utils/glitchtip/models.py +25 -28
  291. reconcile/utils/gql.py +4 -7
  292. reconcile/utils/helm.py +2 -1
  293. reconcile/utils/helpers.py +1 -1
  294. reconcile/utils/instrumented_wrappers.py +1 -1
  295. reconcile/utils/internal_groups/client.py +2 -2
  296. reconcile/utils/internal_groups/models.py +8 -17
  297. reconcile/utils/jinja2/utils.py +6 -101
  298. reconcile/utils/jira_client.py +82 -63
  299. reconcile/utils/jjb_client.py +9 -12
  300. reconcile/utils/jobcontroller/controller.py +1 -1
  301. reconcile/utils/jobcontroller/models.py +17 -1
  302. reconcile/utils/json.py +70 -0
  303. reconcile/utils/membershipsources/app_interface_resolver.py +4 -2
  304. reconcile/utils/membershipsources/models.py +16 -23
  305. reconcile/utils/membershipsources/resolver.py +4 -2
  306. reconcile/utils/merge_request_manager/merge_request_manager.py +4 -4
  307. reconcile/utils/merge_request_manager/parser.py +6 -6
  308. reconcile/utils/metrics.py +5 -5
  309. reconcile/utils/models.py +304 -82
  310. reconcile/utils/mr/app_interface_reporter.py +2 -2
  311. reconcile/utils/mr/base.py +2 -2
  312. reconcile/utils/mr/notificator.py +3 -3
  313. reconcile/utils/mr/update_access_report_base.py +3 -4
  314. reconcile/utils/mr/user_maintenance.py +3 -2
  315. reconcile/utils/oc.py +118 -97
  316. reconcile/utils/oc_filters.py +3 -3
  317. reconcile/utils/ocm/addons.py +0 -1
  318. reconcile/utils/ocm/base.py +17 -20
  319. reconcile/utils/ocm/cluster_groups.py +1 -1
  320. reconcile/utils/ocm/identity_providers.py +2 -2
  321. reconcile/utils/ocm/labels.py +1 -1
  322. reconcile/utils/ocm/products.py +9 -3
  323. reconcile/utils/ocm/search_filters.py +3 -6
  324. reconcile/utils/ocm/service_log.py +4 -6
  325. reconcile/utils/ocm/sre_capability_labels.py +20 -13
  326. reconcile/utils/openshift_resource.py +10 -5
  327. reconcile/utils/output.py +3 -2
  328. reconcile/utils/pagerduty_api.py +10 -7
  329. reconcile/utils/promotion_state.py +6 -11
  330. reconcile/utils/raw_github_api.py +1 -1
  331. reconcile/utils/rhcsv2_certs.py +1 -4
  332. reconcile/utils/runtime/integration.py +2 -3
  333. reconcile/utils/runtime/runner.py +2 -2
  334. reconcile/utils/saasherder/interfaces.py +13 -20
  335. reconcile/utils/saasherder/models.py +25 -21
  336. reconcile/utils/saasherder/saasherder.py +35 -24
  337. reconcile/utils/slack_api.py +26 -4
  338. reconcile/utils/sloth.py +171 -2
  339. reconcile/utils/sqs_gateway.py +2 -1
  340. reconcile/utils/state.py +2 -1
  341. reconcile/utils/structs.py +1 -1
  342. reconcile/utils/terraform_client.py +5 -4
  343. reconcile/utils/terrascript_aws_client.py +171 -114
  344. reconcile/utils/unleash/server.py +2 -8
  345. reconcile/utils/vault.py +5 -12
  346. reconcile/utils/vcs.py +8 -8
  347. reconcile/vault_replication.py +107 -42
  348. tools/app_interface_reporter.py +4 -4
  349. tools/cli_commands/cost_report/cost_management_api.py +3 -3
  350. tools/cli_commands/cost_report/view.py +7 -6
  351. tools/cli_commands/erv2.py +3 -1
  352. tools/cli_commands/systems_and_tools.py +5 -1
  353. tools/qontract_cli.py +31 -18
  354. tools/template_validation.py +3 -1
  355. {qontract_reconcile-0.10.2.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/WHEEL +0 -0
  356. {qontract_reconcile-0.10.2.dev349.dist-info → qontract_reconcile-0.10.2.dev414.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,3 @@
1
- import json
2
1
  import logging
3
2
  import sys
4
3
  from collections.abc import (
@@ -7,10 +6,11 @@ from collections.abc import (
7
6
  )
8
7
  from typing import (
9
8
  Any,
9
+ Self,
10
10
  TypedDict,
11
11
  )
12
12
 
13
- from pydantic import BaseModel, root_validator, validator
13
+ from pydantic import BaseModel, field_validator, model_validator
14
14
 
15
15
  from reconcile.gql_definitions.aws_saml_roles.aws_accounts import (
16
16
  AWSAccountV1,
@@ -22,6 +22,7 @@ from reconcile.gql_definitions.aws_saml_roles.roles import (
22
22
  query as roles_query,
23
23
  )
24
24
  from reconcile.status import ExitCodes
25
+ from reconcile.typed_queries.external_resources import get_settings
25
26
  from reconcile.utils import gql
26
27
  from reconcile.utils.aws_api import AWSApi
27
28
  from reconcile.utils.aws_helper import unique_sso_aws_accounts
@@ -32,6 +33,7 @@ from reconcile.utils.extended_early_exit import (
32
33
  ExtendedEarlyExitRunnerResult,
33
34
  extended_early_exit_run,
34
35
  )
36
+ from reconcile.utils.json import json_dumps
35
37
  from reconcile.utils.runtime.integration import (
36
38
  PydanticRunParams,
37
39
  QontractReconcileIntegration,
@@ -58,7 +60,8 @@ class AwsSamlRolesIntegrationParams(PydanticRunParams):
58
60
  extended_early_exit_cache_ttl_seconds: int = 3600
59
61
  log_cached_log_output: bool = False
60
62
 
61
- @validator("max_session_duration_hours")
63
+ @field_validator("max_session_duration_hours")
64
+ @classmethod
62
65
  def max_session_duration_range(cls, v: str | int) -> int:
63
66
  if 1 <= int(v) <= 12:
64
67
  return int(v)
@@ -69,7 +72,8 @@ class CustomPolicy(BaseModel):
69
72
  name: str
70
73
  policy: dict[str, Any]
71
74
 
72
- @validator("name")
75
+ @field_validator("name")
76
+ @classmethod
73
77
  def name_size(cls, v: str) -> str:
74
78
  """Check the policy name size.
75
79
 
@@ -81,13 +85,14 @@ class CustomPolicy(BaseModel):
81
85
  )
82
86
  return v
83
87
 
84
- @validator("policy")
88
+ @field_validator("policy")
89
+ @classmethod
85
90
  def policy_size(cls, v: dict[str, Any]) -> dict[str, Any]:
86
91
  """Check the policy size.
87
92
 
88
93
  See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html
89
94
  """
90
- if len(json.dumps(v, separators=(",", ":"))) > 6144:
95
+ if len(json_dumps(v, compact=True)) > 6144:
91
96
  raise ValueError(
92
97
  f"The policy document '{v}' is too large. AWS policy documents must be 6144 characters or less (w/o white spaces)."
93
98
  )
@@ -104,7 +109,8 @@ class AwsRole(BaseModel):
104
109
  custom_policies: list[CustomPolicy]
105
110
  managed_policies: list[ManagedPolicy]
106
111
 
107
- @validator("name")
112
+ @field_validator("name")
113
+ @classmethod
108
114
  def name_size(cls, v: str) -> str:
109
115
  """Check the role name size.
110
116
 
@@ -116,29 +122,23 @@ class AwsRole(BaseModel):
116
122
  )
117
123
  return v
118
124
 
119
- @root_validator
120
- def validate_policies(cls, values: dict[str, Any]) -> dict[str, Any]:
125
+ @model_validator(mode="after")
126
+ def validate_policies(self) -> Self:
121
127
  """Check the policies.
122
128
 
123
129
  See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html
124
130
  """
125
- custom_policies = values.get("custom_policies", [])
126
- managed_policies = values.get("managed_policies", [])
127
- if len(custom_policies) + len(managed_policies) > 20:
131
+ if len(self.custom_policies) + len(self.managed_policies) > 20:
128
132
  raise ValueError(
129
- f"The role '{values['name']}' has too many policies. AWS roles can have at most 20 policies (via quota increase). Please consider consolidating the policies."
133
+ f"The role '{self.name}' has too many policies. AWS roles can have at most 20 policies (via quota increase). Please consider consolidating the policies."
130
134
  )
131
- cp_names = [cp.name for cp in custom_policies]
135
+ cp_names = [cp.name for cp in self.custom_policies]
132
136
  if len(set(cp_names)) != len(cp_names):
133
- raise ValueError(
134
- f"The role '{values['name']}' has duplicate custom policies."
135
- )
136
- mp_names = [mp.name for mp in managed_policies]
137
+ raise ValueError(f"The role '{self.name}' has duplicate custom policies.")
138
+ mp_names = [mp.name for mp in self.managed_policies]
137
139
  if len(set(mp_names)) != len(mp_names):
138
- raise ValueError(
139
- f"The role '{values['name']}' has duplicate managed policies."
140
- )
141
- return values
140
+ raise ValueError(f"The role '{self.name}' has duplicate managed policies.")
141
+ return self
142
142
 
143
143
 
144
144
  class RunnerParams(TypedDict):
@@ -163,7 +163,7 @@ class AwsSamlRolesIntegration(
163
163
  if not query_func:
164
164
  query_func = gql.get_api().query
165
165
  return {
166
- "roles": [c.dict() for c in self.get_roles(query_func)],
166
+ "roles": [c.model_dump() for c in self.get_roles(query_func)],
167
167
  }
168
168
 
169
169
  def get_aws_accounts(
@@ -251,15 +251,22 @@ class AwsSamlRolesIntegration(
251
251
  aws_accounts = self.get_aws_accounts(
252
252
  gql_api.query, account_name=self.params.account_name
253
253
  )
254
- aws_accounts_dict = [account.dict(by_alias=True) for account in aws_accounts]
254
+ aws_accounts_dict = [
255
+ account.model_dump(by_alias=True) for account in aws_accounts
256
+ ]
255
257
  aws_roles = self.get_roles(gql_api.query, account_name=self.params.account_name)
256
-
258
+ try:
259
+ default_tags = get_settings().default_tags
260
+ except ValueError:
261
+ # no external resources settings found
262
+ default_tags = None
257
263
  ts = TerrascriptClient(
258
264
  self.name.replace("-", "_"),
259
265
  "",
260
266
  self.params.thread_pool_size,
261
267
  aws_accounts_dict,
262
268
  secret_reader=self.secret_reader,
269
+ default_tags=default_tags,
263
270
  )
264
271
  self.populate_saml_iam_roles(ts, aws_roles)
265
272
  working_dirs = ts.dump(print_to_file=self.params.print_to_file)
@@ -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 (
@@ -106,7 +98,8 @@ class ExternalResource(BaseModel):
106
98
  self.resource_identifier,
107
99
  )
108
100
 
109
- @validator("resource_engine_version", pre=True)
101
+ @field_validator("resource_engine_version", mode="before")
102
+ @classmethod
110
103
  def parse_resource_engine_version(
111
104
  cls, v: str | semver.VersionInfo
112
105
  ) -> semver.VersionInfo:
@@ -114,7 +107,8 @@ class ExternalResource(BaseModel):
114
107
  return v
115
108
  return parse_semver(str(v), optional_minor_and_patch=True)
116
109
 
117
- @root_validator(pre=True)
110
+ @model_validator(mode="before")
111
+ @classmethod
118
112
  def set_resource_engine_version_format(cls, values: dict) -> dict:
119
113
  resource_engine_version, resource_engine_version_format = (
120
114
  str(values.get("resource_engine_version")),
@@ -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
 
@@ -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,
reconcile/cli.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # ruff: noqa: PLC0415 - `import` should be at the top-level of a file
2
2
  import faulthandler
3
- import json
4
3
  import logging
5
4
  import os
6
5
  import re
@@ -31,6 +30,7 @@ from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
31
30
  from reconcile.utils.exceptions import PrintToFileInGitRepositoryError
32
31
  from reconcile.utils.git import is_file_in_git_repo
33
32
  from reconcile.utils.gql import GqlApiSingleton
33
+ from reconcile.utils.json import json_dumps
34
34
  from reconcile.utils.promtool import PROMTOOL_VERSION, PROMTOOL_VERSION_REGEX
35
35
  from reconcile.utils.runtime.environment import init_env
36
36
  from reconcile.utils.runtime.integration import (
@@ -608,7 +608,7 @@ def run_class_integration(
608
608
  if dump_schemas_file:
609
609
  gqlapi = gql.get_api()
610
610
  with open(dump_schemas_file, "w", encoding="locale") as f:
611
- f.write(json.dumps(gqlapi.get_queried_schemas()))
611
+ f.write(json_dumps(gqlapi.get_queried_schemas()))
612
612
 
613
613
 
614
614
  @click.group()
@@ -1028,7 +1028,7 @@ def aws_account_manager(
1028
1028
  "--state-tmpl-resource",
1029
1029
  help="Resource name of the state template-collection template in the app-interface.",
1030
1030
  required=True,
1031
- default="/terraform-init/terraform-state.yml",
1031
+ default="/terraform-init/terraform-state.yml.j2",
1032
1032
  )
1033
1033
  @click.option(
1034
1034
  "--template-collection-root-path",
@@ -1036,12 +1036,26 @@ def aws_account_manager(
1036
1036
  required=True,
1037
1037
  default="data/templating/collections/terraform-init",
1038
1038
  )
1039
+ @click.option(
1040
+ "--cloudformation-template-resource",
1041
+ help="Resource name of the CloudFormation template to create the S3 bucket",
1042
+ required=True,
1043
+ default="/terraform-init/terraform-state-s3-bucket.yaml",
1044
+ )
1045
+ @click.option(
1046
+ "--cloudformation-import-template-resource",
1047
+ help="Resource name of the CloudFormation template to import existing S3 bucket",
1048
+ required=True,
1049
+ default="/terraform-init/terraform-state-s3-bucket-import.yaml",
1050
+ )
1039
1051
  @click.pass_context
1040
1052
  def terraform_init(
1041
1053
  ctx: click.Context,
1042
1054
  account_name: str | None,
1043
1055
  state_tmpl_resource: str,
1044
1056
  template_collection_root_path: str,
1057
+ cloudformation_template_resource: str,
1058
+ cloudformation_import_template_resource: str,
1045
1059
  ) -> None:
1046
1060
  from reconcile.terraform_init.integration import (
1047
1061
  TerraformInitIntegration,
@@ -1054,6 +1068,8 @@ def terraform_init(
1054
1068
  account_name=account_name,
1055
1069
  state_tmpl_resource=state_tmpl_resource,
1056
1070
  template_collection_root_path=template_collection_root_path,
1071
+ cloudformation_template_resource=cloudformation_template_resource,
1072
+ cloudformation_import_template_resource=cloudformation_import_template_resource,
1057
1073
  )
1058
1074
  ),
1059
1075
  ctx=ctx,
@@ -1135,9 +1151,17 @@ def jenkins_webhooks_cleaner(ctx: click.Context) -> None:
1135
1151
  "--jira-board-name", help="The Jira board to act on.", default=None, multiple=True
1136
1152
  )
1137
1153
  @click.option("--board-check-interval", help="Check interval in minutes", default=120)
1154
+ @click.option(
1155
+ "--use-cache/--no-use-cache",
1156
+ default=True,
1157
+ help="Use cached results for validation.",
1158
+ )
1138
1159
  @click.pass_context
1139
1160
  def jira_permissions_validator(
1140
- ctx: click.Context, jira_board_name: Iterable[str] | None, board_check_interval: int
1161
+ ctx: click.Context,
1162
+ jira_board_name: Iterable[str] | None,
1163
+ board_check_interval: int,
1164
+ use_cache: bool,
1141
1165
  ) -> None:
1142
1166
  import reconcile.jira_permissions_validator
1143
1167
 
@@ -1146,6 +1170,7 @@ def jira_permissions_validator(
1146
1170
  ctx,
1147
1171
  jira_board_name=jira_board_name,
1148
1172
  board_check_interval_sec=board_check_interval * 60,
1173
+ use_cache=use_cache,
1149
1174
  )
1150
1175
 
1151
1176
 
@@ -1270,14 +1295,14 @@ def aws_ami_cleanup(ctx: click.Context, thread_pool_size: int) -> None:
1270
1295
  run_integration(reconcile.aws_ami_cleanup.integration, ctx, thread_pool_size)
1271
1296
 
1272
1297
 
1273
- @integration.command(short_help="Set up retention period for Cloudwatch logs.")
1274
- @threaded()
1298
+ @integration.command(short_help="Set up retention period and tags for Cloudwatch logs.")
1275
1299
  @click.pass_context
1276
- def aws_cloudwatch_log_retention(ctx: click.Context, thread_pool_size: int) -> None:
1300
+ def aws_cloudwatch_log_retention(ctx: click.Context) -> None:
1277
1301
  import reconcile.aws_cloudwatch_log_retention.integration
1278
1302
 
1279
1303
  run_integration(
1280
- reconcile.aws_cloudwatch_log_retention.integration, ctx, thread_pool_size
1304
+ reconcile.aws_cloudwatch_log_retention.integration,
1305
+ ctx,
1281
1306
  )
1282
1307
 
1283
1308
 
@@ -4,7 +4,6 @@ from collections import defaultdict
4
4
  from collections.abc import Iterable, Mapping
5
5
  from dataclasses import dataclass
6
6
  from datetime import (
7
- UTC,
8
7
  datetime,
9
8
  timedelta,
10
9
  )
@@ -31,6 +30,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
31
30
  get_app_interface_vault_settings,
32
31
  )
33
32
  from reconcile.typed_queries.saas_files import get_saas_files
33
+ from reconcile.utils.datetime_util import ensure_utc, utc_now
34
34
  from reconcile.utils.github_api import GithubRepositoryApi
35
35
  from reconcile.utils.gitlab_api import GitLabApi
36
36
  from reconcile.utils.secret_reader import create_secret_reader
@@ -159,15 +159,8 @@ class Commit:
159
159
  date: datetime
160
160
 
161
161
  def lttc(self, finish_timestamp: datetime) -> int:
162
- commit_date_tzaware = self.date
163
- finish_timestamp_tzaware = finish_timestamp
164
-
165
- if commit_date_tzaware.tzinfo is None:
166
- commit_date_tzaware = commit_date_tzaware.replace(tzinfo=UTC)
167
-
168
- if finish_timestamp_tzaware.tzinfo is None:
169
- finish_timestamp_tzaware = finish_timestamp_tzaware.replace(tzinfo=UTC)
170
-
162
+ commit_date_tzaware = ensure_utc(self.date)
163
+ finish_timestamp_tzaware = ensure_utc(finish_timestamp)
171
164
  return int((finish_timestamp_tzaware - commit_date_tzaware).total_seconds())
172
165
 
173
166
 
@@ -277,7 +270,7 @@ class DashdotdbDORA(DashdotdbBase):
277
270
  # from the DB for a unique (app_name, env_name) multiple times.
278
271
  app_envs = {s.app_env for s in saastargets}
279
272
 
280
- since_default = datetime.now() - timedelta(days=90)
273
+ since_default = utc_now() - timedelta(days=90)
281
274
  app_env_since_list: list[tuple[AppEnv, datetime]] = threaded.run(
282
275
  func=functools.partial(self.get_latest_with_default, since_default),
283
276
  iterable=app_envs,
@@ -473,7 +466,7 @@ class DashdotdbDORA(DashdotdbBase):
473
466
  ]
474
467
 
475
468
  def _github_compare_commits(self, rc: RepoChanges, repo: str) -> list[Commit]:
476
- if not rc.repo_url:
469
+ if not rc.repo_url or not rc.ref_from or not rc.ref_to:
477
470
  return []
478
471
 
479
472
  return [
@@ -119,4 +119,4 @@ def run(
119
119
 
120
120
 
121
121
  def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
122
- return {doc.name: doc.dict() for doc in get_slo_documents()}
122
+ return {doc.name: doc.model_dump() for doc in get_slo_documents()}