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
reconcile/oum/labelset.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from collections import defaultdict
2
+ from typing import Annotated
2
3
 
3
4
  from pydantic import BaseModel
4
5
 
@@ -22,9 +23,10 @@ class _GroupMappingLabelset(BaseModel):
22
23
  the sre-capabilities.user-mgmt.$provider prefix.
23
24
  """
24
25
 
25
- authz_roles: dict[str, CSV] | None = sre_capability_labels.labelset_groupfield(
26
- group_prefix="authz."
27
- )
26
+ authz_roles: Annotated[
27
+ dict[str, CSV] | None,
28
+ sre_capability_labels.labelset_groupfield(group_prefix="authz."),
29
+ ]
28
30
 
29
31
 
30
32
  def build_cluster_config_from_labels(
reconcile/oum/models.py CHANGED
@@ -56,7 +56,7 @@ class ClusterUserManagementSpec(BaseModel):
56
56
  errors: list[ClusterError] = Field(default_factory=list)
57
57
 
58
58
 
59
- class ClusterRoleReconcileResult(BaseModel):
59
+ class ClusterRoleReconcileResult(BaseModel, arbitrary_types_allowed=True):
60
60
  """
61
61
  Holds the result of a cluster role reconciliation.
62
62
  """
@@ -64,6 +64,3 @@ class ClusterRoleReconcileResult(BaseModel):
64
64
  users_added: int = 0
65
65
  users_removed: int = 0
66
66
  error: Exception | None = None
67
-
68
- class Config:
69
- arbitrary_types_allowed = True
@@ -33,7 +33,7 @@ class LdapGroupMemberProvider(GroupMemberProvider):
33
33
  if len(group_ids) == 0:
34
34
  return {}
35
35
  with self.ldap_client as lc:
36
- groups_members_by_dn = lc.get_group_members(group_dn_mapping.keys())
36
+ groups_members_by_dn = lc.get_group_members(set(group_dn_mapping.keys()))
37
37
  return {
38
38
  group_dn_mapping[dn]: members
39
39
  for dn, members in groups_members_by_dn.items()
@@ -42,7 +42,7 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
42
42
  PROVIDERS = ["prometheus-rule"]
43
43
 
44
44
  NAMESPACE_NAME = "openshift-customer-monitoring"
45
- DEFAULT_PROMTOOL_VERSION = "2.55.1"
45
+ DEFAULT_PROMTOOL_VERSION = "3.2.1"
46
46
 
47
47
 
48
48
  class TestContent(BaseModel):
@@ -56,7 +56,7 @@ class Test(BaseModel):
56
56
  rule_path: str
57
57
  rule: dict
58
58
  rule_length: int
59
- tests: list[TestContent] | None
59
+ tests: list[TestContent] | None = None
60
60
  result: CommandExecutionResult | None = None
61
61
  promtool_version: str
62
62
 
@@ -76,7 +76,7 @@ def fetch_rule_and_tests(
76
76
  openshift_resource = orb.fetch_openshift_resource(
77
77
  resource=rule.resource,
78
78
  parent=rule.namespace,
79
- settings=vault_settings.dict(by_alias=True),
79
+ settings=vault_settings.model_dump(by_alias=True),
80
80
  )
81
81
 
82
82
  rule_body = openshift_resource.body
@@ -96,7 +96,7 @@ def fetch_rule_and_tests(
96
96
  test_raw_yaml = process_extracurlyjinja2_template(
97
97
  body=test_raw_yaml,
98
98
  vars=variables,
99
- settings=vault_settings.dict(by_alias=True),
99
+ settings=vault_settings.model_dump(by_alias=True),
100
100
  )
101
101
 
102
102
  test_yaml_spec = yaml.safe_load(test_raw_yaml)
reconcile/quay_mirror.py CHANGED
@@ -66,7 +66,7 @@ class QuayMirror:
66
66
  }
67
67
  """
68
68
 
69
- response_cache: dict[tuple[str, str], Response] = {}
69
+ response_cache: dict[tuple[str, str | None], Response] = {}
70
70
 
71
71
  def __init__(
72
72
  self,
reconcile/queries.py CHANGED
@@ -477,6 +477,12 @@ AWS_ACCOUNTS_QUERY = """
477
477
  integrations
478
478
  }
479
479
  deleteKeys
480
+ organization {
481
+ payerAccount {
482
+ organizationAccountTags
483
+ }
484
+ tags
485
+ }
480
486
  {% if reset_passwords %}
481
487
  resetPasswords {
482
488
  user {
@@ -499,6 +505,12 @@ AWS_ACCOUNTS_QUERY = """
499
505
  name
500
506
  uid
501
507
  supportedDeploymentRegions
508
+ organization {
509
+ payerAccount {
510
+ organizationAccountTags
511
+ }
512
+ tags
513
+ }
502
514
  }
503
515
  ... on AWSAccountSharingOptionAMI_v1 {
504
516
  regex
@@ -606,6 +618,12 @@ awsInfrastructureManagementAccounts {
606
618
  version
607
619
  format
608
620
  }
621
+ organization {
622
+ payerAccount {
623
+ organizationAccountTags
624
+ }
625
+ tags
626
+ }
609
627
  }
610
628
  accessLevel
611
629
  default
@@ -636,6 +654,12 @@ awsInfrastructureAccess {
636
654
  version
637
655
  format
638
656
  }
657
+ organization {
658
+ payerAccount {
659
+ organizationAccountTags
660
+ }
661
+ tags
662
+ }
639
663
  }
640
664
  roles {
641
665
  users {
@@ -745,6 +769,12 @@ CLUSTERS_QUERY = """
745
769
  version
746
770
  format
747
771
  }
772
+ organization {
773
+ payerAccount {
774
+ organizationAccountTags
775
+ }
776
+ tags
777
+ }
748
778
  rosa {
749
779
  ocm_environments {
750
780
  ocm {
@@ -773,6 +803,7 @@ CLUSTERS_QUERY = """
773
803
  private
774
804
  provision_shard_id
775
805
  disable_user_workload_monitoring
806
+ fips
776
807
  }
777
808
  externalConfiguration {
778
809
  labels
@@ -829,6 +860,12 @@ CLUSTERS_QUERY = """
829
860
  version
830
861
  format
831
862
  }
863
+ organization {
864
+ payerAccount {
865
+ organizationAccountTags
866
+ }
867
+ tags
868
+ }
832
869
  }
833
870
  vpc_id
834
871
  cidr_block
@@ -847,6 +884,12 @@ CLUSTERS_QUERY = """
847
884
  version
848
885
  format
849
886
  }
887
+ organization {
888
+ payerAccount {
889
+ organizationAccountTags
890
+ }
891
+ tags
892
+ }
850
893
  }
851
894
  tags
852
895
  }
@@ -861,6 +904,12 @@ CLUSTERS_QUERY = """
861
904
  version
862
905
  format
863
906
  }
907
+ organization {
908
+ payerAccount {
909
+ organizationAccountTags
910
+ }
911
+ tags
912
+ }
864
913
  }
865
914
  tags
866
915
  cidrBlock
@@ -889,6 +938,12 @@ CLUSTERS_QUERY = """
889
938
  version
890
939
  format
891
940
  }
941
+ organization {
942
+ payerAccount {
943
+ organizationAccountTags
944
+ }
945
+ tags
946
+ }
892
947
  }
893
948
  }
894
949
  accessLevel
@@ -914,6 +969,12 @@ CLUSTERS_QUERY = """
914
969
  version
915
970
  format
916
971
  }
972
+ organization {
973
+ payerAccount {
974
+ organizationAccountTags
975
+ }
976
+ tags
977
+ }
917
978
  }
918
979
  }
919
980
  }
@@ -1067,6 +1128,12 @@ CLUSTER_PEERING_QUERY = """
1067
1128
  version
1068
1129
  format
1069
1130
  }
1131
+ organization {
1132
+ payerAccount {
1133
+ organizationAccountTags
1134
+ }
1135
+ tags
1136
+ }
1070
1137
  }
1071
1138
  accessLevel
1072
1139
  default
@@ -1088,6 +1155,12 @@ CLUSTER_PEERING_QUERY = """
1088
1155
  version
1089
1156
  format
1090
1157
  }
1158
+ organization {
1159
+ payerAccount {
1160
+ organizationAccountTags
1161
+ }
1162
+ tags
1163
+ }
1091
1164
  }
1092
1165
  }
1093
1166
  }
@@ -1112,6 +1185,12 @@ CLUSTER_PEERING_QUERY = """
1112
1185
  version
1113
1186
  format
1114
1187
  }
1188
+ organization {
1189
+ payerAccount {
1190
+ organizationAccountTags
1191
+ }
1192
+ tags
1193
+ }
1115
1194
  }
1116
1195
  vpc_id
1117
1196
  cidr_block
@@ -1131,6 +1210,12 @@ CLUSTER_PEERING_QUERY = """
1131
1210
  version
1132
1211
  format
1133
1212
  }
1213
+ organization {
1214
+ payerAccount {
1215
+ organizationAccountTags
1216
+ }
1217
+ tags
1218
+ }
1134
1219
  }
1135
1220
  tags
1136
1221
  assumeRole
@@ -1146,6 +1231,12 @@ CLUSTER_PEERING_QUERY = """
1146
1231
  version
1147
1232
  format
1148
1233
  }
1234
+ organization {
1235
+ payerAccount {
1236
+ organizationAccountTags
1237
+ }
1238
+ tags
1239
+ }
1149
1240
  }
1150
1241
  tags
1151
1242
  cidrBlock
@@ -1175,6 +1266,12 @@ CLUSTER_PEERING_QUERY = """
1175
1266
  version
1176
1267
  format
1177
1268
  }
1269
+ organization {
1270
+ payerAccount {
1271
+ organizationAccountTags
1272
+ }
1273
+ tags
1274
+ }
1178
1275
  }
1179
1276
  }
1180
1277
  }
@@ -1190,6 +1287,12 @@ CLUSTER_PEERING_QUERY = """
1190
1287
  version
1191
1288
  format
1192
1289
  }
1290
+ organization {
1291
+ payerAccount {
1292
+ organizationAccountTags
1293
+ }
1294
+ tags
1295
+ }
1193
1296
  }
1194
1297
  accessLevel
1195
1298
  default
@@ -1216,6 +1319,12 @@ CLUSTER_PEERING_QUERY = """
1216
1319
  version
1217
1320
  format
1218
1321
  }
1322
+ organization {
1323
+ payerAccount {
1324
+ organizationAccountTags
1325
+ }
1326
+ tags
1327
+ }
1219
1328
  }
1220
1329
  }
1221
1330
  }
@@ -1231,6 +1340,12 @@ CLUSTER_PEERING_QUERY = """
1231
1340
  version
1232
1341
  format
1233
1342
  }
1343
+ organization {
1344
+ payerAccount {
1345
+ organizationAccountTags
1346
+ }
1347
+ tags
1348
+ }
1234
1349
  }
1235
1350
  }
1236
1351
  }
@@ -2230,6 +2345,12 @@ JIRA_BOARDS_QUICK_QUERY = """
2230
2345
  version
2231
2346
  format
2232
2347
  }
2348
+ email {
2349
+ path
2350
+ field
2351
+ version
2352
+ format
2353
+ }
2233
2354
  }
2234
2355
  }
2235
2356
  }
@@ -2336,6 +2457,12 @@ DNS_ZONES_QUERY = """
2336
2457
  version
2337
2458
  format
2338
2459
  }
2460
+ organization {
2461
+ payerAccount {
2462
+ organizationAccountTags
2463
+ }
2464
+ tags
2465
+ }
2339
2466
  }
2340
2467
  vpc {
2341
2468
  vpc_id
@@ -2697,6 +2824,10 @@ APP_METADATA = """
2697
2824
  path
2698
2825
  field
2699
2826
  }
2827
+ email {
2828
+ path
2829
+ field
2830
+ }
2700
2831
  }
2701
2832
  }
2702
2833
  slackUserGroup {
@@ -1,6 +1,8 @@
1
1
  import logging
2
2
  import sys
3
+ from collections.abc import Callable, Mapping
3
4
  from subprocess import CalledProcessError
5
+ from typing import Any
4
6
 
5
7
  from reconcile import (
6
8
  queries,
@@ -44,7 +46,9 @@ Encrypted credentials:
44
46
  """
45
47
 
46
48
 
47
- def get_encrypted_credentials(credentials_name, user, settings):
49
+ def get_encrypted_credentials(
50
+ credentials_name: str, user: Mapping[str, Any], settings: Mapping[str, Any]
51
+ ) -> str | None:
48
52
  credentials_map = settings["credentials"]
49
53
  credentials_map_item = [c for c in credentials_map if c["name"] == credentials_name]
50
54
  if len(credentials_map_item) != 1:
@@ -59,7 +63,7 @@ def get_encrypted_credentials(credentials_name, user, settings):
59
63
 
60
64
 
61
65
  @defer
62
- def run(dry_run, defer=None):
66
+ def run(dry_run: bool, defer: Callable | None = None) -> None:
63
67
  settings = queries.get_app_interface_settings()
64
68
  vault_settings = get_app_interface_vault_settings()
65
69
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
@@ -76,7 +80,8 @@ def run(dry_run, defer=None):
76
80
  integration=QONTRACT_INTEGRATION,
77
81
  secret_reader=secret_reader,
78
82
  )
79
- defer(state.cleanup)
83
+ if defer:
84
+ defer(state.cleanup)
80
85
  credentials_requests = queries.get_credentials_requests()
81
86
 
82
87
  # validate no 2 requests have the same name
@@ -1,8 +1,5 @@
1
1
  import logging
2
2
  import sys
3
- from typing import (
4
- cast,
5
- )
6
3
 
7
4
  from reconcile.status import ExitCodes
8
5
  from reconcile.typed_queries.app_interface_vault_settings import (
@@ -14,7 +11,6 @@ from reconcile.utils.oc_map import init_oc_map_from_clusters
14
11
  from reconcile.utils.secret_reader import create_secret_reader
15
12
  from reconcile.utils.vault import (
16
13
  VaultClient,
17
- _VaultClient,
18
14
  )
19
15
 
20
16
  QONTRACT_INTEGRATION = "resource-scraper"
@@ -63,7 +59,7 @@ def run(
63
59
  results.append(item)
64
60
 
65
61
  if not dry_run:
66
- vault_client = cast("_VaultClient", VaultClient())
62
+ vault_client = VaultClient.get_instance()
67
63
  for item in results:
68
64
  secret = {
69
65
  "path": f"{vault_output_path}/{QONTRACT_INTEGRATION}/{item['cluster']}/{namespace_name}/{item['name']}",
reconcile/rhidp/common.py CHANGED
@@ -7,10 +7,7 @@ from enum import StrEnum
7
7
  from typing import Any
8
8
  from urllib.parse import urlparse
9
9
 
10
- from pydantic import (
11
- BaseModel,
12
- root_validator,
13
- )
10
+ from pydantic import BaseModel, model_validator
14
11
 
15
12
  from reconcile.gql_definitions.common.ocm_environments import (
16
13
  query as ocm_environment_query,
@@ -63,7 +60,8 @@ class ClusterAuth(BaseModel):
63
60
  issuer: str
64
61
  status: str
65
62
 
66
- @root_validator
63
+ @model_validator(mode="before")
64
+ @classmethod
67
65
  def name_no_spaces(
68
66
  cls, values: MutableMapping[str, Any]
69
67
  ) -> MutableMapping[str, Any]:
@@ -1,3 +1,4 @@
1
+ import http
1
2
  import logging
2
3
  from collections.abc import (
3
4
  Iterable,
@@ -10,6 +11,7 @@ from urllib.parse import (
10
11
  )
11
12
 
12
13
  import jwt
14
+ from requests import HTTPError
13
15
 
14
16
  from reconcile.rhidp.common import (
15
17
  Cluster,
@@ -138,7 +140,7 @@ def fetch_current_state(
138
140
  secret_reader: VaultSecretReader, vault_input_path: str
139
141
  ) -> list[str]:
140
142
  """Fetch all existing SSO client IDs from vault."""
141
- return secret_reader.vault_client.list(vault_input_path) # type: ignore[attr-defined] # mypy doesn't recognize the VaultClient.__new__ method
143
+ return secret_reader.vault_client.list(vault_input_path)
142
144
 
143
145
 
144
146
  def fetch_desired_state(
@@ -234,10 +236,10 @@ def create_sso_client(
234
236
  vault_secret_id=sso_client_id,
235
237
  )
236
238
 
237
- secret_reader.vault_client.write( # type: ignore[attr-defined] # mypy doesn't recognize the VaultClient.__new__ method
239
+ secret_reader.vault_client.write(
238
240
  secret={
239
241
  "path": secret.path,
240
- "data": sso_client.dict(),
242
+ "data": sso_client.model_dump(),
241
243
  },
242
244
  decode_base64=False,
243
245
  )
@@ -256,11 +258,18 @@ def delete_sso_client(
256
258
  )
257
259
  sso_client = SSOClient(**secret_reader.read_all_secret(secret=secret))
258
260
  keycloak_api = keycloak_map.get(sso_client.issuer)
259
- keycloak_api.delete_client(
260
- registration_client_uri=sso_client.registration_client_uri,
261
- registration_access_token=sso_client.registration_access_token,
262
- )
261
+ try:
262
+ keycloak_api.delete_client(
263
+ registration_client_uri=sso_client.registration_client_uri,
264
+ registration_access_token=sso_client.registration_access_token,
265
+ )
266
+ except HTTPError as e:
267
+ if e.response.status_code != http.HTTPStatus.UNAUTHORIZED:
268
+ logging.error(f"Failed to delete SSO client {sso_client_id}: {e}")
269
+ raise
270
+ # something went wrong with the registration token, maybe it expired
271
+ logging.error(
272
+ f"Failed to delete SSO client {sso_client_id} due to unauthorized error: {e}. Continuing to delete the vault secret."
273
+ )
263
274
 
264
- secret_reader.vault_client.delete( # type: ignore[attr-defined] # mypy doesn't recognize the VaultClient.__new__ method
265
- path=secret.path
266
- )
275
+ secret_reader.vault_client.delete(path=secret.path)
@@ -177,7 +177,7 @@ def is_namespace_addressed_by_selector(
177
177
  # json representation of namespace to filter on
178
178
  # remove all the None values to simplify the jsonpath expressions
179
179
  namespace_as_dict = {
180
- "namespace": [namespace.dict(by_alias=True, exclude_none=True)]
180
+ "namespace": [namespace.model_dump(by_alias=True, exclude_none=True)]
181
181
  }
182
182
 
183
183
  do_include = any(
@@ -2,7 +2,7 @@ import hashlib
2
2
  import logging
3
3
  from collections.abc import Iterable
4
4
  from dataclasses import dataclass
5
- from datetime import UTC, datetime, timedelta
5
+ from datetime import timedelta
6
6
 
7
7
  from croniter import croniter
8
8
 
@@ -13,6 +13,7 @@ from reconcile.saas_auto_promotions_manager.publisher import (
13
13
  DeploymentInfo,
14
14
  Publisher,
15
15
  )
16
+ from reconcile.utils.datetime_util import utc_now
16
17
  from reconcile.utils.slo_document_manager import SLODocumentManager
17
18
 
18
19
  CONTENT_HASH_LENGTH = 32
@@ -113,7 +114,7 @@ class Subscriber:
113
114
  We accumulate the time a ref is running on all publishers for this subscriber.
114
115
  We compare that accumulated time with the soak_days setting of the subscriber.
115
116
  """
116
- now = datetime.now(UTC)
117
+ now = utc_now()
117
118
  delta = timedelta(days=0)
118
119
  for channel in self.channels:
119
120
  for publisher in channel.publishers:
@@ -136,7 +137,7 @@ class Subscriber:
136
137
  self.schedule,
137
138
  )
138
139
  return False
139
- return croniter.match(self.schedule, datetime.now(UTC), day_or=False)
140
+ return croniter.match(self.schedule, utc_now(), day_or=False)
140
141
 
141
142
  def _compute_desired_ref(self) -> None:
142
143
  """
@@ -1,5 +1,7 @@
1
1
  import logging
2
2
  import sys
3
+ from collections.abc import Iterable, Mapping
4
+ from typing import Any
3
5
 
4
6
  import sendgrid
5
7
  from sretoolbox.utils import retry
@@ -17,18 +19,22 @@ class SendGridAPIError(Exception):
17
19
 
18
20
 
19
21
  class Teammate:
20
- def __init__(self, email, pending_token=None, username=None):
22
+ def __init__(
23
+ self, email: str, pending_token: str | None = None, username: str | None = None
24
+ ) -> None:
21
25
  self.email = email
22
- self.username = username or email.split("@")[0]
26
+ self.username = username or email.split("@", maxsplit=1)[0]
23
27
  self.pending_token = pending_token
24
28
 
25
29
  @property
26
- def pending(self):
30
+ def pending(self) -> bool:
27
31
  return bool(self.pending_token)
28
32
 
29
33
 
30
- def fetch_desired_state(users):
31
- desired_state = {}
34
+ def fetch_desired_state(
35
+ users: Iterable[Mapping[str, Any]],
36
+ ) -> dict[str, list[Teammate]]:
37
+ desired_state: dict[str, list[Teammate]] = {}
32
38
  for user in users:
33
39
  roles = user.get("roles") or []
34
40
  for role in roles:
@@ -42,7 +48,7 @@ def fetch_desired_state(users):
42
48
 
43
49
 
44
50
  @retry()
45
- def fetch_current_state(sg_client):
51
+ def fetch_current_state(sg_client: sendgrid.SendGridAPIClient) -> list[Teammate]:
46
52
  state = []
47
53
  limit = 100
48
54
 
@@ -79,7 +85,7 @@ def fetch_current_state(sg_client):
79
85
  return state
80
86
 
81
87
 
82
- def raise_if_error(response):
88
+ def raise_if_error(response: Any) -> None:
83
89
  """
84
90
  Raises an SendGridAPIError if the request has returned an error
85
91
  """
@@ -87,7 +93,12 @@ def raise_if_error(response):
87
93
  raise SendGridAPIError(response.body.decode("utf-8"))
88
94
 
89
95
 
90
- def act(dry_run, sg_client, desired_state, current_state):
96
+ def act(
97
+ dry_run: bool,
98
+ sg_client: sendgrid.SendGridAPIClient,
99
+ desired_state: Iterable[Teammate],
100
+ current_state: Iterable[Teammate],
101
+ ) -> bool:
91
102
  """
92
103
  Reconciles current state with desired state.
93
104
 
@@ -145,7 +156,7 @@ def act(dry_run, sg_client, desired_state, current_state):
145
156
  return error
146
157
 
147
158
 
148
- def run(dry_run):
159
+ def run(dry_run: bool) -> None:
149
160
  settings = queries.get_app_interface_settings()
150
161
  secret_reader = SecretReader(settings=settings)
151
162
 
@@ -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
  }