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
@@ -85,7 +85,7 @@ def compile_skupper_sites(
85
85
  or skupper_network.site_controller_templates
86
86
  ):
87
87
  tmpl_vars = tmpl.variables or {}
88
- tmpl_vars["resource"] = {"namespace": ns.dict(by_alias=True)}
88
+ tmpl_vars["resource"] = {"namespace": ns.model_dump(by_alias=True)}
89
89
 
90
90
  site_controller_objects.append(
91
91
  load_site_controller_template(tmpl.path, tmpl_vars)
@@ -304,6 +304,6 @@ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
304
304
  skupper_networks = get_skupper_networks(gqlapi.query)
305
305
  return {
306
306
  "skupper_sites": [
307
- site.dict() for site in compile_skupper_sites(skupper_networks)
307
+ site.model_dump() for site in compile_skupper_sites(skupper_networks)
308
308
  ],
309
309
  }
@@ -3,18 +3,19 @@ import sys
3
3
  from collections.abc import (
4
4
  Callable,
5
5
  Iterable,
6
+ MutableMapping,
6
7
  Sequence,
7
8
  )
8
9
  from datetime import datetime
9
10
  from typing import (
10
11
  Any,
11
12
  TypedDict,
13
+ TypeVar,
12
14
  )
13
15
 
14
16
  from github.GithubException import UnknownObjectException
15
17
  from pydantic import BaseModel
16
- from pydantic.utils import deep_update
17
- from sretoolbox.utils import retry
18
+ from sretoolbox.utils import datatransformation, retry
18
19
 
19
20
  from reconcile import (
20
21
  openshift_users,
@@ -40,6 +41,7 @@ from reconcile.typed_queries.app_interface_vault_settings import (
40
41
  )
41
42
  from reconcile.typed_queries.pagerduty_instances import get_pagerduty_instances
42
43
  from reconcile.utils import gql
44
+ from reconcile.utils.datetime_util import ensure_utc, utc_now
43
45
  from reconcile.utils.disabled_integrations import integration_is_enabled
44
46
  from reconcile.utils.exceptions import (
45
47
  AppInterfaceSettingsError,
@@ -74,6 +76,26 @@ INTEGRATION_VERSION = "0.1.0"
74
76
 
75
77
  error_occurred = False
76
78
 
79
+ KeyType = TypeVar("KeyType")
80
+
81
+
82
+ def deep_update(
83
+ mapping: dict[KeyType, Any],
84
+ *updating_mappings: MutableMapping[KeyType, Any],
85
+ ) -> dict[KeyType, Any]:
86
+ updated_mapping = mapping.copy()
87
+ for updating_mapping in updating_mappings:
88
+ for k, v in updating_mapping.items():
89
+ if (
90
+ k in updated_mapping
91
+ and isinstance(updated_mapping[k], dict)
92
+ and isinstance(v, dict)
93
+ ):
94
+ updated_mapping[k] = deep_update(updated_mapping[k], v)
95
+ else:
96
+ updated_mapping[k] = v
97
+ return updated_mapping
98
+
77
99
 
78
100
  def get_git_api(url: str) -> GithubRepositoryApi | GitLabApi:
79
101
  """Return GitHub/GitLab API based on url."""
@@ -122,15 +144,12 @@ class State(BaseModel):
122
144
  SlackState = dict[str, dict[str, State]]
123
145
 
124
146
 
125
- class WorkspaceSpec(BaseModel):
147
+ class WorkspaceSpec(BaseModel, arbitrary_types_allowed=True):
126
148
  """Slack workspace spec."""
127
149
 
128
150
  slack: SlackApi
129
151
  managed_usergroups: list[str] = []
130
152
 
131
- class Config:
132
- arbitrary_types_allowed = True
133
-
134
153
 
135
154
  SlackMap = dict[str, WorkspaceSpec]
136
155
 
@@ -357,11 +376,11 @@ def get_slack_usernames_from_owners(
357
376
 
358
377
  def get_slack_usernames_from_schedule(schedule: Iterable[ScheduleEntryV1]) -> list[str]:
359
378
  """Return list of usernames from all schedules."""
360
- now = datetime.utcnow()
379
+ now = utc_now()
361
380
  all_slack_usernames: list[str] = []
362
381
  for entry in schedule:
363
- start = datetime.strptime(entry.start, DATE_FORMAT)
364
- end = datetime.strptime(entry.end, DATE_FORMAT)
382
+ start = ensure_utc(datetime.strptime(entry.start, DATE_FORMAT)) # noqa: DTZ007
383
+ end = ensure_utc(datetime.strptime(entry.end, DATE_FORMAT)) # noqa: DTZ007
365
384
  if start <= now <= end:
366
385
  all_slack_usernames.extend(get_slack_username(u) for u in entry.users)
367
386
  return all_slack_usernames
@@ -819,7 +838,9 @@ def run(
819
838
  desired_usergroup_name=usergroup_name,
820
839
  )
821
840
  # merge the two desired states recursively
822
- desired_state = deep_update(desired_state, desired_state_cluster_usergroups)
841
+ desired_state = datatransformation.deep_merge(
842
+ desired_state, desired_state_cluster_usergroups
843
+ )
823
844
 
824
845
  runner_params: RunnerParams = {
825
846
  "dry_run": dry_run,
@@ -891,10 +912,10 @@ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
891
912
  if role.tag_on_cluster_updates is not False
892
913
  ]
893
914
  return {
894
- "permissions": [p.dict() for p in get_permissions(gqlapi.query)],
915
+ "permissions": [p.model_dump() for p in get_permissions(gqlapi.query)],
895
916
  "pagerduty_instances": [
896
- p.dict() for p in get_pagerduty_instances(gqlapi.query)
917
+ p.model_dump() for p in get_pagerduty_instances(gqlapi.query)
897
918
  ],
898
- "users": [u.dict() for u in users],
899
- "clusters": [c.dict() for c in get_clusters(gqlapi.query)],
919
+ "users": [u.model_dump() for u in users],
920
+ "clusters": [c.model_dump() for c in get_clusters(gqlapi.query)],
900
921
  }
reconcile/sql_query.py CHANGED
@@ -229,6 +229,7 @@ def collect_queries(
229
229
  accounts=[],
230
230
  prefetch_resources_by_schemas=["/aws/rds-defaults-1.yml"],
231
231
  secret_reader=secret_reader,
232
+ default_tags=None,
232
233
  )
233
234
 
234
235
  for sql_query in sql_queries:
reconcile/status_board.py CHANGED
@@ -52,7 +52,7 @@ class AbstractStatusBoard(ABC, BaseModel):
52
52
  """Abstract class for upgrade policies
53
53
  Used to create and delete upgrade policies in OCM."""
54
54
 
55
- id: str | None
55
+ id: str | None = None
56
56
  name: str
57
57
  fullname: str
58
58
 
@@ -88,7 +88,7 @@ class AbstractStatusBoard(ABC, BaseModel):
88
88
 
89
89
 
90
90
  class Product(AbstractStatusBoard):
91
- applications: list["Application"] | None
91
+ applications: list["Application"] | None = None
92
92
 
93
93
  def create(self, ocm: OCMBaseClient) -> None:
94
94
  spec = self.to_ocm_spec()
@@ -121,7 +121,7 @@ class Product(AbstractStatusBoard):
121
121
 
122
122
  class Application(AbstractStatusBoard):
123
123
  product: Product
124
- services: list["Service"] | None
124
+ services: list["Service"] | None = None
125
125
 
126
126
  def create(self, ocm: OCMBaseClient) -> None:
127
127
  if self.product.id:
@@ -214,9 +214,9 @@ class Service(AbstractStatusBoard):
214
214
 
215
215
 
216
216
  # Resolve forward references after class definitions
217
- Product.update_forward_refs()
218
- Application.update_forward_refs()
219
- Service.update_forward_refs()
217
+ Product.model_rebuild()
218
+ Application.model_rebuild()
219
+ Service.model_rebuild()
220
220
 
221
221
 
222
222
  class UpdateNotSupportedError(Exception):
@@ -29,12 +29,12 @@ class AtlassianRawComponent(BaseModel):
29
29
 
30
30
  id: str
31
31
  name: str
32
- description: str | None
32
+ description: str | None = None
33
33
  position: int
34
34
  status: str
35
- automation_email: str | None
36
- group_id: str | None
37
- group: bool | None
35
+ automation_email: str | None = None
36
+ group_id: str | None = None
37
+ group: bool | None = None
38
38
 
39
39
 
40
40
  class AtlassianRawMaintenanceUpdate(BaseModel):
@@ -56,9 +56,9 @@ class AtlassianRawMaintenance(BaseModel):
56
56
  scheduled_until: str
57
57
  incident_updates: list[AtlassianRawMaintenanceUpdate]
58
58
  components: list[AtlassianRawComponent]
59
- auto_transition_deliver_notifications_at_end: bool | None
60
- auto_transition_deliver_notifications_at_start: bool | None
61
- scheduled_remind_prior: bool | None
59
+ auto_transition_deliver_notifications_at_end: bool | None = None
60
+ auto_transition_deliver_notifications_at_start: bool | None = None
61
+ scheduled_remind_prior: bool | None = None
62
62
 
63
63
 
64
64
  class AtlassianAPI:
@@ -1,12 +1,13 @@
1
1
  import logging
2
2
  import sys
3
- from datetime import UTC, datetime, timedelta
3
+ from datetime import datetime, timedelta
4
4
 
5
5
  from reconcile.slack_base import slackapi_from_queries
6
6
  from reconcile.statuspage.atlassian import AtlassianStatusPageProvider
7
7
  from reconcile.statuspage.integration import get_binding_state, get_status_pages
8
8
  from reconcile.statuspage.page import StatusMaintenance
9
9
  from reconcile.statuspage.state import S3ComponentBindingState
10
+ from reconcile.utils.datetime_util import utc_now
10
11
  from reconcile.utils.differ import diff_iterables
11
12
  from reconcile.utils.runtime.integration import (
12
13
  NoParams,
@@ -52,7 +53,7 @@ class StatusPageMaintenancesIntegration(QontractReconcileIntegration[NoParams]):
52
53
  desired_state: list[StatusMaintenance],
53
54
  binding_state: S3ComponentBindingState,
54
55
  ) -> None:
55
- now = datetime.now(UTC)
56
+ now = utc_now()
56
57
  slack = slackapi_from_queries(QONTRACT_INTEGRATION, init_usergroups=False)
57
58
  for m in desired_state:
58
59
  scheduled_start = m.schedule_start
@@ -68,7 +69,7 @@ class StatusPageMaintenancesIntegration(QontractReconcileIntegration[NoParams]):
68
69
  def run(self, dry_run: bool = False) -> None:
69
70
  binding_state = get_binding_state(self.name, self.secret_reader)
70
71
  pages = get_status_pages()
71
- now = datetime.now(UTC)
72
+ now = utc_now()
72
73
 
73
74
  error = False
74
75
  for p in pages:
@@ -19,19 +19,17 @@ from reconcile.statuspage.status import (
19
19
  PROVIDER_NAME = "statuspage"
20
20
 
21
21
 
22
- class StatusComponent(BaseModel):
22
+ class StatusComponent(BaseModel, arbitrary_types_allowed=True):
23
23
  """
24
24
  Represents a status page component from the desired state.
25
25
  """
26
26
 
27
27
  name: str
28
28
  display_name: str
29
- description: str | None
30
- group_name: str | None
29
+ description: str | None = None
30
+ group_name: str | None = None
31
+ # Status provider configs hold different ways for a component to determine its status
31
32
  status_provider_configs: list[StatusProvider]
32
- """
33
- Status provider configs hold different ways for a component to determine its status
34
- """
35
33
 
36
34
  def status_management_enabled(self) -> bool:
37
35
  """
@@ -49,9 +47,6 @@ class StatusComponent(BaseModel):
49
47
  return "operational"
50
48
  return None
51
49
 
52
- class Config:
53
- arbitrary_types_allowed = True
54
-
55
50
  def __eq__(self, other: object) -> bool:
56
51
  if not isinstance(other, StatusComponent):
57
52
  raise NotImplementedError("Cannot compare to non StatusComponent objects.")
@@ -2,18 +2,15 @@ from abc import (
2
2
  ABC,
3
3
  abstractmethod,
4
4
  )
5
- from datetime import (
6
- UTC,
7
- datetime,
8
- )
5
+ from datetime import datetime
9
6
 
10
- from dateutil.parser import isoparse
11
7
  from pydantic import BaseModel
12
8
 
13
9
  from reconcile.gql_definitions.statuspage.statuspages import (
14
10
  ManualStatusProviderV1,
15
11
  StatusProviderV1,
16
12
  )
13
+ from reconcile.utils.datetime_util import from_utc_iso_format, utc_now
17
14
 
18
15
  # This module defines the interface for status providers for components on status
19
16
  # pages. A status provider is responsible for determining the status of a component.
@@ -70,7 +67,7 @@ class ManualStatusProvider(StatusProvider, BaseModel):
70
67
  raise ValueError(
71
68
  "manual component status time window is invalid: end before start"
72
69
  )
73
- now = datetime.now(UTC)
70
+ now = utc_now()
74
71
  if self.start and now < self.start:
75
72
  return False
76
73
  return not (self.end and self.end < now)
@@ -84,8 +81,8 @@ def build_status_provider_config(
84
81
  provider specific implementation that provides the status resolution logic.
85
82
  """
86
83
  if isinstance(cfg, ManualStatusProviderV1):
87
- start = isoparse(cfg.manual.q_from) if cfg.manual.q_from else None
88
- end = isoparse(cfg.manual.until) if cfg.manual.until else None
84
+ start = from_utc_iso_format(cfg.manual.q_from) if cfg.manual.q_from else None
85
+ end = from_utc_iso_format(cfg.manual.until) if cfg.manual.until else None
89
86
  return ManualStatusProvider(
90
87
  component_status=cfg.manual.component_status,
91
88
  start=start,
@@ -55,4 +55,8 @@ rosa create cluster -y --cluster-name={{ cluster_name }} \
55
55
  {% if cluster.spec.provision_shard_id -%}
56
56
  --properties provision_shard_id:{{ cluster.spec.provision_shard_id }} \
57
57
  {% endif -%}
58
+ {% if cluster.spec.fips -%}
59
+ --fips \
60
+ {% endif -%}
58
61
  --channel-group {{ cluster.spec.channel }}
62
+
@@ -59,4 +59,7 @@ rosa create cluster --cluster-name={{ cluster_name }} \
59
59
  {% if cluster.spec.provision_shard_id -%}
60
60
  --properties provision_shard_id:{{ cluster.spec.provision_shard_id }} \
61
61
  {% endif -%}
62
+ {% if cluster.spec.fips -%}
63
+ --fips \
64
+ {% endif -%}
62
65
  --channel-group {{ cluster.spec.channel }}
@@ -18,7 +18,7 @@ from reconcile.utils.secret_reader import SecretReaderBase
18
18
 
19
19
  class TemplateData(BaseModel):
20
20
  variables: dict[str, Any]
21
- current: dict[str, Any] | None
21
+ current: dict[str, Any] | None = None
22
22
  current_with_explicit_start: bool | None = False
23
23
 
24
24
 
@@ -26,7 +26,7 @@ class TemplatePatch(Protocol):
26
26
  path: str
27
27
  identifier: str | None
28
28
 
29
- def dict(self) -> dict[str, str]: ...
29
+ def model_dump(self) -> dict[str, str]: ...
30
30
 
31
31
 
32
32
  class Template(Protocol):
@@ -36,7 +36,7 @@ class Template(Protocol):
36
36
  template: str
37
37
  overwrite: bool | None
38
38
 
39
- def dict(self) -> dict[str, str]: ...
39
+ def model_dump(self) -> dict[str, str]: ...
40
40
 
41
41
  @property
42
42
  def patch(self) -> TemplatePatch | None:
@@ -33,6 +33,7 @@ from reconcile.utils import gql
33
33
  from reconcile.utils.git import checkout, clone
34
34
  from reconcile.utils.gql import GqlApi
35
35
  from reconcile.utils.jinja2.utils import TemplateRenderOptions, process_jinja2_template
36
+ from reconcile.utils.json import json_dumps
36
37
  from reconcile.utils.ruamel import create_ruamel_instance
37
38
  from reconcile.utils.runtime.integration import (
38
39
  PydanticRunParams,
@@ -215,7 +216,7 @@ def unpack_static_variables(
215
216
  each: dict[str, Any],
216
217
  ) -> dict:
217
218
  return {
218
- k: json.loads(process_jinja2_template(body=json.dumps(v), vars={"each": each}))
219
+ k: json.loads(process_jinja2_template(body=json_dumps(v), vars={"each": each}))
219
220
  for k, v in (collection_variables.static or {}).items()
220
221
  }
221
222
 
@@ -238,8 +239,8 @@ def unpack_dynamic_variables(
238
239
 
239
240
  class TemplateRendererIntegrationParams(PydanticRunParams):
240
241
  clone_repo: bool = False
241
- app_interface_root_path: str | None
242
- template_collection_name: str | None
242
+ app_interface_root_path: str | None = None
243
+ template_collection_name: str | None = None
243
244
 
244
245
 
245
246
  def join_path(base: str, sub: str) -> str:
@@ -9,6 +9,7 @@ from typing import Any
9
9
 
10
10
  from reconcile import queries
11
11
  from reconcile.status import ExitCodes
12
+ from reconcile.typed_queries.external_resources import get_settings
12
13
  from reconcile.utils import dnsutils
13
14
  from reconcile.utils.aws_api import AWSApi
14
15
  from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
@@ -227,13 +228,18 @@ def run(
227
228
  f"No participating AWS accounts found, consider disabling this integration, account name: {account_name}"
228
229
  )
229
230
  return
230
-
231
+ try:
232
+ default_tags = get_settings().default_tags
233
+ except ValueError:
234
+ # no external resources settings found
235
+ default_tags = None
231
236
  ts = Terrascript(
232
237
  QONTRACT_INTEGRATION,
233
238
  "",
234
239
  thread_pool_size,
235
240
  participating_accounts,
236
241
  settings=settings,
242
+ default_tags=default_tags,
237
243
  )
238
244
 
239
245
  desired_state = build_desired_state(zones, all_accounts, settings)
@@ -155,7 +155,7 @@ class TerraformCloudflareDNSIntegration(
155
155
 
156
156
  accts_per_zone = []
157
157
  for zone in query_zones.zones or []:
158
- acct = zone.account.dict(by_alias=True)
158
+ acct = zone.account.model_dump(by_alias=True)
159
159
  acct["name"] = f"{zone.account.name}-{zone.identifier}"
160
160
  accts_per_zone.append(acct)
161
161
 
@@ -369,11 +369,11 @@ def cloudflare_dns_zone_to_external_resource(
369
369
  provision_provider=DEFAULT_PROVISIONER_PROVIDER,
370
370
  provisioner={"name": f"{zone.account.name}-{zone.identifier}"},
371
371
  namespace=DEFAULT_NAMESPACE,
372
- resource=zone.dict(by_alias=True, exclude=DEFAULT_EXCLUDE_KEY),
372
+ resource=zone.model_dump(by_alias=True, exclude=DEFAULT_EXCLUDE_KEY),
373
373
  )
374
374
  external_resource_spec.resource["provider"] = DEFAULT_PROVIDER
375
375
  external_resource_spec.resource["records"] = [
376
- record.dict(by_alias=True) for record in zone.records or []
376
+ record.model_dump(by_alias=True) for record in zone.records or []
377
377
  ]
378
378
  external_resource_specs.append(external_resource_spec)
379
379
  return external_resource_specs
@@ -168,7 +168,7 @@ def _build_oc_resources(
168
168
  internal=internal,
169
169
  )
170
170
 
171
- namespace_mapping = [ns.dict() for ns in cloudflare_namespaces]
171
+ namespace_mapping = [ns.model_dump() for ns in cloudflare_namespaces]
172
172
 
173
173
  state_specs = init_specs_to_fetch(
174
174
  ri, oc_map, namespaces=namespace_mapping, override_managed_types=["Secret"]
@@ -338,7 +338,7 @@ def run(
338
338
  )
339
339
 
340
340
  if not cloudflare_namespaces:
341
- logging.info("No cloudflare namespaces were detected, nothing to do.")
341
+ logging.debug("No cloudflare namespaces were detected, nothing to do.")
342
342
  sys.exit(ExitCodes.SUCCESS)
343
343
 
344
344
  # Build Cloudflare clients
@@ -351,7 +351,7 @@ def run(
351
351
  spec
352
352
  for namespace in query_resources.namespaces
353
353
  for spec in get_external_resource_specs(
354
- namespace.dict(by_alias=True), PROVIDER_CLOUDFLARE
354
+ namespace.model_dump(by_alias=True), PROVIDER_CLOUDFLARE
355
355
  )
356
356
  if not selected_account or spec.provisioner_name == selected_account
357
357
  ]
@@ -383,7 +383,7 @@ def run(
383
383
  QONTRACT_INTEGRATION_VERSION,
384
384
  QONTRACT_TF_PREFIX,
385
385
  [
386
- acct.dict(by_alias=True) # convert CloudflareAccountV1 to dict
386
+ acct.model_dump(by_alias=True) # convert CloudflareAccountV1 to dict
387
387
  for acct in query_accounts.accounts or []
388
388
  if acct.name in cf_clients.dump() # use only if it is a registered client
389
389
  ],
@@ -442,4 +442,4 @@ def _get_cloudflare_desired_state() -> tuple[
442
442
  def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
443
443
  desired_state = _get_cloudflare_desired_state()
444
444
 
445
- return {state.__repr_name__(): state.dict() for state in desired_state}
445
+ return {str(state): state.model_dump() for state in desired_state}
@@ -88,7 +88,7 @@ class TerraformCloudflareUsers(
88
88
  if not settings.settings:
89
89
  raise RuntimeError("App interface setting not defined")
90
90
 
91
- early_exit_desired_state = cloudflare_roles.dict()
91
+ early_exit_desired_state = cloudflare_roles.model_dump()
92
92
  early_exit_desired_state.update({
93
93
  CLOUDFLARE_EMAIL_DOMAIN_ALLOW_LIST_KEY: settings.settings
94
94
  })
@@ -149,7 +149,8 @@ class TerraformCloudflareUsers(
149
149
  }
150
150
 
151
151
  accounts = [
152
- acct.dict(by_alias=True) for _, acct in account_names_to_account.items()
152
+ acct.model_dump(by_alias=True)
153
+ for _, acct in account_names_to_account.items()
153
154
  ]
154
155
 
155
156
  self._run_terraform(