qontract-reconcile 0.10.1rc879__py3-none-any.whl → 0.10.1rc894__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 (291) hide show
  1. {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/METADATA +1 -1
  2. {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/RECORD +291 -284
  3. reconcile/acs_rbac.py +1 -2
  4. reconcile/aus/advanced_upgrade_service.py +14 -14
  5. reconcile/aus/aus_label_source.py +1 -2
  6. reconcile/aus/base.py +23 -26
  7. reconcile/aus/cluster_version_data.py +4 -4
  8. reconcile/aus/models.py +2 -3
  9. reconcile/aus/version_gate_approver.py +2 -6
  10. reconcile/aus/version_gates/__init__.py +1 -3
  11. reconcile/aus/version_gates/sts_version_gate_handler.py +2 -3
  12. reconcile/aws_account_manager/integration.py +9 -14
  13. reconcile/aws_account_manager/reconciler.py +51 -1
  14. reconcile/aws_account_manager/utils.py +3 -0
  15. reconcile/aws_ami_cleanup/integration.py +3 -4
  16. reconcile/aws_iam_password_reset.py +2 -5
  17. reconcile/aws_version_sync/integration.py +2 -2
  18. reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
  19. reconcile/change_owners/approver.py +4 -5
  20. reconcile/change_owners/bundle.py +20 -22
  21. reconcile/change_owners/change_types.py +23 -24
  22. reconcile/change_owners/changes.py +13 -16
  23. reconcile/change_owners/decision.py +2 -5
  24. reconcile/change_owners/diff.py +11 -15
  25. reconcile/change_owners/self_service_roles.py +1 -2
  26. reconcile/change_owners/tester.py +7 -10
  27. reconcile/checkpoint.py +2 -5
  28. reconcile/cli.py +26 -12
  29. reconcile/closedbox_endpoint_monitoring_base.py +8 -11
  30. reconcile/cluster_deployment_mapper.py +2 -5
  31. reconcile/cna/assets/asset.py +4 -7
  32. reconcile/cna/assets/null.py +2 -5
  33. reconcile/cna/integration.py +2 -3
  34. reconcile/cna/state.py +2 -5
  35. reconcile/dashdotdb_base.py +8 -11
  36. reconcile/dashdotdb_cso.py +3 -6
  37. reconcile/dashdotdb_dora.py +10 -14
  38. reconcile/dashdotdb_dvo.py +10 -13
  39. reconcile/dashdotdb_slo.py +5 -8
  40. reconcile/database_access_manager.py +5 -6
  41. reconcile/dynatrace_token_provider/integration.py +3 -6
  42. reconcile/dynatrace_token_provider/integration_v2.py +20 -0
  43. reconcile/dynatrace_token_provider/meta.py +1 -0
  44. reconcile/external_resources/integration.py +1 -1
  45. reconcile/external_resources/manager.py +4 -4
  46. reconcile/external_resources/model.py +3 -3
  47. reconcile/external_resources/secrets_sync.py +5 -5
  48. reconcile/external_resources/state.py +5 -5
  49. reconcile/gabi_authorized_users.py +3 -6
  50. reconcile/gcr_mirror.py +1 -1
  51. reconcile/github_org.py +1 -3
  52. reconcile/github_repo_invites.py +2 -5
  53. reconcile/gitlab_housekeeping.py +7 -11
  54. reconcile/gitlab_labeler.py +1 -2
  55. reconcile/gitlab_members.py +2 -5
  56. reconcile/gitlab_permissions.py +1 -3
  57. reconcile/glitchtip/integration.py +5 -8
  58. reconcile/glitchtip_project_alerts/integration.py +57 -33
  59. reconcile/glitchtip_project_dsn/integration.py +8 -11
  60. reconcile/gql_definitions/aws_account_manager/aws_accounts.py +6 -0
  61. reconcile/gql_definitions/fragments/aws_account_managed.py +8 -0
  62. reconcile/gql_definitions/glitchtip/glitchtip_project.py +4 -4
  63. reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +27 -7
  64. reconcile/integrations_manager.py +5 -8
  65. reconcile/jenkins/types.py +5 -6
  66. reconcile/jenkins_job_builder.py +9 -12
  67. reconcile/jenkins_roles.py +1 -1
  68. reconcile/jira_watcher.py +2 -2
  69. reconcile/ldap_groups/integration.py +2 -5
  70. reconcile/ocm/types.py +21 -26
  71. reconcile/ocm_addons_upgrade_tests_trigger.py +3 -6
  72. reconcile/ocm_clusters.py +8 -8
  73. reconcile/ocm_internal_notifications/integration.py +1 -2
  74. reconcile/ocm_labels/integration.py +2 -5
  75. reconcile/ocm_machine_pools.py +11 -15
  76. reconcile/ocm_upgrade_scheduler_org_updater.py +2 -5
  77. reconcile/openshift_base.py +29 -30
  78. reconcile/openshift_groups.py +15 -20
  79. reconcile/openshift_namespace_labels.py +8 -14
  80. reconcile/openshift_namespaces.py +5 -8
  81. reconcile/openshift_network_policies.py +2 -4
  82. reconcile/openshift_resources_base.py +19 -29
  83. reconcile/openshift_saas_deploy.py +9 -10
  84. reconcile/openshift_saas_deploy_change_tester.py +7 -10
  85. reconcile/openshift_saas_deploy_trigger_base.py +4 -7
  86. reconcile/openshift_saas_deploy_trigger_cleaner.py +5 -8
  87. reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
  88. reconcile/openshift_saas_deploy_trigger_images.py +1 -2
  89. reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
  90. reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
  91. reconcile/openshift_tekton_resources.py +7 -11
  92. reconcile/openshift_upgrade_watcher.py +10 -13
  93. reconcile/openshift_users.py +8 -11
  94. reconcile/oum/base.py +3 -4
  95. reconcile/oum/labelset.py +1 -2
  96. reconcile/oum/metrics.py +2 -2
  97. reconcile/oum/models.py +1 -2
  98. reconcile/oum/standalone.py +2 -3
  99. reconcile/prometheus_rules_tester/integration.py +6 -9
  100. reconcile/quay_membership.py +1 -2
  101. reconcile/quay_mirror.py +12 -13
  102. reconcile/quay_mirror_org.py +10 -10
  103. reconcile/queries.py +4 -7
  104. reconcile/resource_scraper.py +3 -4
  105. reconcile/rhidp/common.py +2 -2
  106. reconcile/saas_auto_promotions_manager/integration.py +5 -6
  107. reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +1 -2
  108. reconcile/saas_auto_promotions_manager/publisher.py +5 -6
  109. reconcile/saas_auto_promotions_manager/subscriber.py +36 -15
  110. reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +8 -0
  111. reconcile/saas_file_validator.py +2 -5
  112. reconcile/signalfx_endpoint_monitoring.py +2 -5
  113. reconcile/skupper_network/integration.py +3 -6
  114. reconcile/skupper_network/models.py +3 -5
  115. reconcile/slack_base.py +4 -7
  116. reconcile/slack_usergroups.py +15 -17
  117. reconcile/sql_query.py +5 -9
  118. reconcile/status_board.py +4 -5
  119. reconcile/statuspage/atlassian.py +14 -15
  120. reconcile/statuspage/integrations/maintenances.py +3 -3
  121. reconcile/statuspage/page.py +8 -8
  122. reconcile/statuspage/state.py +4 -5
  123. reconcile/statuspage/status.py +7 -8
  124. reconcile/templating/lib/rendering.py +8 -8
  125. reconcile/templating/renderer.py +10 -11
  126. reconcile/templating/validator.py +4 -4
  127. reconcile/terraform_aws_route53.py +3 -6
  128. reconcile/terraform_cloudflare_dns.py +9 -12
  129. reconcile/terraform_cloudflare_resources.py +9 -11
  130. reconcile/terraform_cloudflare_users.py +8 -11
  131. reconcile/terraform_init/integration.py +2 -2
  132. reconcile/terraform_repo.py +11 -14
  133. reconcile/terraform_resources.py +20 -21
  134. reconcile/terraform_tgw_attachments.py +32 -36
  135. reconcile/terraform_users.py +6 -7
  136. reconcile/terraform_vpc_resources/integration.py +6 -6
  137. reconcile/test/conftest.py +7 -10
  138. reconcile/test/fixtures.py +1 -1
  139. reconcile/test/saas_auto_promotions_manager/conftest.py +3 -2
  140. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +2 -2
  141. reconcile/test/test_database_access_manager.py +3 -6
  142. reconcile/test/test_gitlab_labeler.py +2 -5
  143. reconcile/test/test_jump_host.py +5 -8
  144. reconcile/test/test_ocm_machine_pools.py +1 -4
  145. reconcile/test/test_openshift_base.py +3 -6
  146. reconcile/test/test_openshift_cluster_bots.py +5 -5
  147. reconcile/test/test_openshift_namespace_labels.py +2 -3
  148. reconcile/test/test_openshift_saas_deploy_trigger_cleaner.py +2 -2
  149. reconcile/test/test_saasherder.py +9 -12
  150. reconcile/test/test_slack_base.py +4 -6
  151. reconcile/test/test_status_board.py +4 -7
  152. reconcile/test/test_terraform_tgw_attachments.py +14 -20
  153. reconcile/typed_queries/alerting_services_settings.py +1 -2
  154. reconcile/typed_queries/app_interface_custom_messages.py +2 -3
  155. reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +1 -3
  156. reconcile/typed_queries/app_interface_repo_url.py +1 -2
  157. reconcile/typed_queries/app_interface_state_settings.py +1 -3
  158. reconcile/typed_queries/app_interface_vault_settings.py +1 -2
  159. reconcile/typed_queries/aws_vpc_requests.py +1 -3
  160. reconcile/typed_queries/aws_vpcs.py +1 -3
  161. reconcile/typed_queries/clusters.py +2 -4
  162. reconcile/typed_queries/clusters_minimal.py +1 -3
  163. reconcile/typed_queries/clusters_with_dms.py +1 -3
  164. reconcile/typed_queries/dynatrace_environments.py +14 -0
  165. reconcile/typed_queries/external_resources.py +3 -4
  166. reconcile/typed_queries/pagerduty_instances.py +1 -2
  167. reconcile/typed_queries/repos.py +2 -3
  168. reconcile/typed_queries/reserved_networks.py +1 -3
  169. reconcile/typed_queries/saas_files.py +49 -59
  170. reconcile/typed_queries/slo_documents.py +1 -3
  171. reconcile/typed_queries/status_board.py +3 -7
  172. reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
  173. reconcile/typed_queries/terraform_namespaces.py +1 -2
  174. reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +1 -3
  175. reconcile/utils/acs/base.py +2 -3
  176. reconcile/utils/acs/notifiers.py +3 -3
  177. reconcile/utils/acs/policies.py +3 -3
  178. reconcile/utils/aggregated_list.py +1 -1
  179. reconcile/utils/amtool.py +1 -2
  180. reconcile/utils/aws_api.py +28 -31
  181. reconcile/utils/aws_api_typed/account.py +23 -0
  182. reconcile/utils/aws_api_typed/api.py +20 -9
  183. reconcile/utils/binary.py +1 -3
  184. reconcile/utils/clusterhealth/providerbase.py +1 -2
  185. reconcile/utils/clusterhealth/telemeter.py +2 -2
  186. reconcile/utils/deadmanssnitch_api.py +1 -2
  187. reconcile/utils/disabled_integrations.py +4 -6
  188. reconcile/utils/environ.py +1 -1
  189. reconcile/utils/expiration.py +3 -7
  190. reconcile/utils/external_resource_spec.py +3 -4
  191. reconcile/utils/external_resources.py +4 -7
  192. reconcile/utils/filtering.py +1 -2
  193. reconcile/utils/git.py +3 -9
  194. reconcile/utils/git_secrets.py +5 -5
  195. reconcile/utils/github_api.py +5 -9
  196. reconcile/utils/gitlab_api.py +2 -3
  197. reconcile/utils/glitchtip/client.py +2 -4
  198. reconcile/utils/glitchtip/models.py +8 -11
  199. reconcile/utils/gql.py +26 -35
  200. reconcile/utils/grouping.py +1 -3
  201. reconcile/utils/imap_client.py +2 -5
  202. reconcile/utils/internal_groups/client.py +1 -2
  203. reconcile/utils/internal_groups/models.py +8 -9
  204. reconcile/utils/jenkins_api.py +4 -4
  205. reconcile/utils/jinja2/extensions.py +1 -1
  206. reconcile/utils/jinja2/filters.py +4 -4
  207. reconcile/utils/jinja2/utils.py +16 -16
  208. reconcile/utils/jira_client.py +10 -11
  209. reconcile/utils/jjb_client.py +14 -17
  210. reconcile/utils/jobcontroller/controller.py +5 -5
  211. reconcile/utils/jobcontroller/models.py +2 -2
  212. reconcile/utils/jsonpath.py +4 -5
  213. reconcile/utils/jump_host.py +7 -8
  214. reconcile/utils/keycloak.py +3 -7
  215. reconcile/utils/ldap_client.py +2 -3
  216. reconcile/utils/lean_terraform_client.py +13 -17
  217. reconcile/utils/membershipsources/app_interface_resolver.py +1 -1
  218. reconcile/utils/membershipsources/models.py +19 -22
  219. reconcile/utils/metrics.py +13 -15
  220. reconcile/utils/mr/base.py +7 -11
  221. reconcile/utils/mr/glitchtip_access_reporter.py +2 -2
  222. reconcile/utils/mr/notificator.py +1 -2
  223. reconcile/utils/oc.py +38 -38
  224. reconcile/utils/oc_connection_parameters.py +24 -25
  225. reconcile/utils/oc_filters.py +2 -3
  226. reconcile/utils/oc_map.py +9 -15
  227. reconcile/utils/ocm/addons.py +7 -10
  228. reconcile/utils/ocm/base.py +38 -39
  229. reconcile/utils/ocm/clusters.py +6 -9
  230. reconcile/utils/ocm/label_sources.py +1 -2
  231. reconcile/utils/ocm/labels.py +3 -6
  232. reconcile/utils/ocm/ocm.py +11 -14
  233. reconcile/utils/ocm/products.py +1 -3
  234. reconcile/utils/ocm/search_filters.py +16 -17
  235. reconcile/utils/ocm/service_log.py +2 -3
  236. reconcile/utils/ocm/sre_capability_labels.py +4 -8
  237. reconcile/utils/ocm/subscriptions.py +1 -3
  238. reconcile/utils/ocm/syncsets.py +2 -4
  239. reconcile/utils/ocm/upgrades.py +5 -9
  240. reconcile/utils/ocm_base_client.py +13 -16
  241. reconcile/utils/openshift_resource.py +5 -11
  242. reconcile/utils/output.py +2 -3
  243. reconcile/utils/pagerduty_api.py +4 -5
  244. reconcile/utils/prometheus.py +2 -2
  245. reconcile/utils/promotion_state.py +4 -5
  246. reconcile/utils/promtool.py +2 -8
  247. reconcile/utils/quay_api.py +12 -22
  248. reconcile/utils/raw_github_api.py +3 -5
  249. reconcile/utils/rosa/rosa_cli.py +6 -6
  250. reconcile/utils/rosa/session.py +6 -7
  251. reconcile/utils/runtime/desired_state_diff.py +3 -8
  252. reconcile/utils/runtime/environment.py +4 -7
  253. reconcile/utils/runtime/integration.py +4 -4
  254. reconcile/utils/runtime/meta.py +1 -2
  255. reconcile/utils/runtime/runner.py +7 -10
  256. reconcile/utils/runtime/sharding.py +22 -27
  257. reconcile/utils/saasherder/interfaces.py +63 -69
  258. reconcile/utils/saasherder/models.py +30 -35
  259. reconcile/utils/saasherder/saasherder.py +39 -54
  260. reconcile/utils/secret_reader.py +17 -19
  261. reconcile/utils/slack_api.py +15 -17
  262. reconcile/utils/smtp_client.py +1 -2
  263. reconcile/utils/sqs_gateway.py +1 -3
  264. reconcile/utils/state.py +1 -2
  265. reconcile/utils/terraform/config_client.py +4 -5
  266. reconcile/utils/terraform_client.py +12 -8
  267. reconcile/utils/terrascript/cloudflare_client.py +4 -10
  268. reconcile/utils/terrascript/cloudflare_resources.py +10 -13
  269. reconcile/utils/terrascript/models.py +2 -3
  270. reconcile/utils/terrascript/resources.py +1 -2
  271. reconcile/utils/terrascript_aws_client.py +50 -38
  272. reconcile/utils/unleash/client.py +4 -7
  273. reconcile/utils/unleash/server.py +2 -2
  274. reconcile/utils/vault.py +8 -11
  275. reconcile/utils/vaultsecretref.py +2 -3
  276. reconcile/utils/vcs.py +7 -8
  277. reconcile/vault_replication.py +4 -8
  278. reconcile/vpc_peerings_validator.py +4 -9
  279. release/version.py +6 -7
  280. tools/app_interface_reporter.py +2 -2
  281. tools/cli_commands/gpg_encrypt.py +3 -6
  282. tools/cli_commands/systems_and_tools.py +4 -7
  283. tools/qontract_cli.py +105 -17
  284. tools/saas_promotion_state/__init__.py +0 -0
  285. tools/saas_promotion_state/saas_promotion_state.py +105 -0
  286. tools/template_validation.py +1 -1
  287. tools/test/conftest.py +45 -6
  288. tools/test/test_saas_promotion_state.py +187 -0
  289. {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/WHEEL +0 -0
  290. {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/entry_points.txt +0 -0
  291. {qontract_reconcile-0.10.1rc879.dist-info → qontract_reconcile-0.10.1rc894.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,4 @@
1
- from typing import (
2
- Callable,
3
- Optional,
4
- )
1
+ from collections.abc import Callable
5
2
  from unittest.mock import call
6
3
 
7
4
  import pytest
@@ -19,9 +16,9 @@ from reconcile.utils.ocm_base_client import OCMBaseClient
19
16
 
20
17
 
21
18
  class StatusBoardStub(AbstractStatusBoard):
22
- created: Optional[bool] = False
23
- deleted: Optional[bool] = False
24
- summarized: Optional[bool] = False
19
+ created: bool | None = False
20
+ deleted: bool | None = False
21
+ summarized: bool | None = False
25
22
 
26
23
  def create(self, ocm: OCMBaseClient) -> None:
27
24
  self.created = True
@@ -3,10 +3,6 @@ from collections.abc import (
3
3
  Iterable,
4
4
  Mapping,
5
5
  )
6
- from typing import (
7
- Optional,
8
- Union,
9
- )
10
6
  from unittest.mock import create_autospec
11
7
 
12
8
  import pytest
@@ -162,10 +158,10 @@ def peering_connection_builder(
162
158
  name: str,
163
159
  provider: str,
164
160
  manage_routes: bool = False,
165
- account: Optional[ClusterPeeringConnectionAccountTGWV1_AWSAccountV1] = None,
166
- assume_role: Optional[str] = None,
167
- cidr_block: Optional[str] = None,
168
- delete: Optional[bool] = None,
161
+ account: ClusterPeeringConnectionAccountTGWV1_AWSAccountV1 | None = None,
162
+ assume_role: str | None = None,
163
+ cidr_block: str | None = None,
164
+ delete: bool | None = None,
169
165
  ) -> ClusterPeeringConnectionAccountTGWV1:
170
166
  return gql_class_factory(
171
167
  ClusterPeeringConnectionAccountTGWV1,
@@ -260,13 +256,11 @@ def peering_builder(
260
256
  ) -> Callable[..., ClusterPeeringV1]:
261
257
  def builder(
262
258
  connections: list[
263
- Union[
264
- ClusterPeeringConnectionAccountTGWV1,
265
- ClusterPeeringConnectionAccountV1,
266
- ClusterPeeringConnectionAccountVPCMeshV1,
267
- ClusterPeeringConnectionClusterRequesterV1,
268
- ClusterPeeringConnectionV1,
269
- ]
259
+ ClusterPeeringConnectionAccountTGWV1
260
+ | ClusterPeeringConnectionAccountV1
261
+ | ClusterPeeringConnectionAccountVPCMeshV1
262
+ | ClusterPeeringConnectionClusterRequesterV1
263
+ | ClusterPeeringConnectionV1
270
264
  ],
271
265
  ) -> ClusterPeeringV1:
272
266
  return gql_class_factory(
@@ -504,11 +498,11 @@ def build_expected_desired_state_item(
504
498
  def _setup_mocks(
505
499
  mocker: MockerFixture,
506
500
  vault_settings: AppInterfaceSettingsV1,
507
- clusters: Optional[Iterable[ClusterV1]] = None,
508
- accounts: Optional[Iterable[AWSAccountV1]] = None,
509
- vpc_details: Optional[Mapping] = None,
510
- tgws: Optional[Iterable] = None,
511
- assume_role: Optional[str] = None,
501
+ clusters: Iterable[ClusterV1] | None = None,
502
+ accounts: Iterable[AWSAccountV1] | None = None,
503
+ vpc_details: Mapping | None = None,
504
+ tgws: Iterable | None = None,
505
+ assume_role: str | None = None,
512
506
  feature_toggle_state: bool = True,
513
507
  ) -> dict:
514
508
  mocked_gql_api = create_autospec(GqlApi)
@@ -1,12 +1,11 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.alerting_services_settings import query
5
4
  from reconcile.utils import gql
6
5
  from reconcile.utils.exceptions import AppInterfaceSettingsError
7
6
 
8
7
 
9
- def get_alerting_services(query_func: Optional[Callable] = None) -> set[str]:
8
+ def get_alerting_services(query_func: Callable | None = None) -> set[str]:
10
9
  """Get alertingServices from app-interface settings"""
11
10
 
12
11
  if not query_func:
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.app_interface_custom_messages import (
5
4
  query,
@@ -9,8 +8,8 @@ from reconcile.utils import gql
9
8
 
10
9
  def get_app_interface_custom_message(
11
10
  desired_id: str,
12
- query_func: Optional[Callable] = None,
13
- ) -> Optional[str]:
11
+ query_func: Callable | None = None,
12
+ ) -> str | None:
14
13
  """Returns App Interface Custom Message by ID or None if not found"""
15
14
  if not query_func:
16
15
  query_func = gql.get_api().query
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.app_interface_dms_settings import (
4
2
  DeadMansSnitchSettingsV1,
5
3
  query,
@@ -10,7 +8,7 @@ from reconcile.utils.gql import GqlApi
10
8
 
11
9
 
12
10
  def get_deadmanssnitch_settings(
13
- gql_api: Optional[GqlApi] = None,
11
+ gql_api: GqlApi | None = None,
14
12
  ) -> DeadMansSnitchSettingsV1:
15
13
  api = gql_api if gql_api else gql.get_api()
16
14
  data = query(query_func=api.query)
@@ -1,12 +1,11 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.app_interface_repo_settings import query
5
4
  from reconcile.utils import gql
6
5
  from reconcile.utils.exceptions import AppInterfaceSettingsError
7
6
 
8
7
 
9
- def get_app_interface_repo_url(query_func: Optional[Callable] = None) -> str:
8
+ def get_app_interface_repo_url(query_func: Callable | None = None) -> str:
10
9
  if not query_func:
11
10
  gqlapi = gql.get_api()
12
11
  query_func = gqlapi.query
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.app_interface_state_settings import (
4
2
  AppInterfaceStateConfigurationV1,
5
3
  query,
@@ -7,7 +5,7 @@ from reconcile.gql_definitions.common.app_interface_state_settings import (
7
5
  from reconcile.utils import gql
8
6
 
9
7
 
10
- def get_app_interface_state_settings() -> Optional[AppInterfaceStateConfigurationV1]:
8
+ def get_app_interface_state_settings() -> AppInterfaceStateConfigurationV1 | None:
11
9
  """Returns App Interface Settings"""
12
10
  gqlapi = gql.get_api()
13
11
  data = query(gqlapi.query)
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.app_interface_vault_settings import (
5
4
  AppInterfaceSettingsV1,
@@ -10,7 +9,7 @@ from reconcile.utils.exceptions import AppInterfaceSettingsError
10
9
 
11
10
 
12
11
  def get_app_interface_vault_settings(
13
- query_func: Optional[Callable] = None,
12
+ query_func: Callable | None = None,
14
13
  ) -> AppInterfaceSettingsV1:
15
14
  """Returns App Interface Settings and raises err if none are found"""
16
15
  if not query_func:
@@ -1,11 +1,9 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.aws_vpc_requests import VPCRequest, query
4
2
  from reconcile.utils import gql
5
3
  from reconcile.utils.gql import GqlApi
6
4
 
7
5
 
8
- def get_aws_vpc_requests(gql_api: Optional[GqlApi] = None) -> list[VPCRequest]:
6
+ def get_aws_vpc_requests(gql_api: GqlApi | None = None) -> list[VPCRequest]:
9
7
  api = gql_api if gql_api else gql.get_api()
10
8
  data = query(query_func=api.query)
11
9
  return list(data.vpc_requests or [])
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.aws_vpcs import (
4
2
  AWSVPC,
5
3
  query,
@@ -8,7 +6,7 @@ from reconcile.utils import gql
8
6
  from reconcile.utils.gql import GqlApi
9
7
 
10
8
 
11
- def get_aws_vpcs(gql_api: Optional[GqlApi] = None) -> list[AWSVPC]:
9
+ def get_aws_vpcs(gql_api: GqlApi | None = None) -> list[AWSVPC]:
12
10
  api = gql_api if gql_api else gql.get_api()
13
11
  data = query(query_func=api.query)
14
12
  return list(data.vpcs or [])
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.clusters import (
4
2
  ClusterV1,
5
3
  query,
@@ -9,8 +7,8 @@ from reconcile.utils.gql import GqlApi
9
7
 
10
8
 
11
9
  def get_clusters(
12
- gql_api: Optional[GqlApi] = None,
13
- name: Optional[str] = None,
10
+ gql_api: GqlApi | None = None,
11
+ name: str | None = None,
14
12
  ) -> list[ClusterV1]:
15
13
  variables = {}
16
14
  if name:
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.clusters_minimal import (
4
2
  ClusterV1,
5
3
  query,
@@ -9,7 +7,7 @@ from reconcile.utils.gql import GqlApi
9
7
 
10
8
 
11
9
  def get_clusters_minimal(
12
- gql_api: Optional[GqlApi] = None, name: Optional[str] = None
10
+ gql_api: GqlApi | None = None, name: str | None = None
13
11
  ) -> list[ClusterV1]:
14
12
  variables = {}
15
13
  if name:
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.clusters_with_dms import (
4
2
  ClusterV1,
5
3
  query,
@@ -9,7 +7,7 @@ from reconcile.utils.gql import GqlApi
9
7
 
10
8
 
11
9
  def get_clusters_with_dms(
12
- gql_api: Optional[GqlApi] = None,
10
+ gql_api: GqlApi | None = None,
13
11
  ) -> list[ClusterV1]:
14
12
  # get the clusters containing the filed enableDeadMansSnitch
15
13
  variable = {"filter": {"enableDeadMansSnitch": {"ne": None}}}
@@ -0,0 +1,14 @@
1
+ from reconcile.gql_definitions.dynatrace_token_provider.dynatrace_bootstrap_tokens import (
2
+ DynatraceEnvironmentV1,
3
+ query,
4
+ )
5
+ from reconcile.utils import gql
6
+ from reconcile.utils.gql import GqlApi
7
+
8
+
9
+ def get_dynatrace_environments(
10
+ api: GqlApi | None = None,
11
+ ) -> list[DynatraceEnvironmentV1]:
12
+ api = api if api else gql.get_api()
13
+ data = query(api.query)
14
+ return list(data.environments or [])
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.external_resources.external_resources_modules import (
5
4
  ExternalResourcesModuleV1,
@@ -22,7 +21,7 @@ from reconcile.gql_definitions.external_resources.external_resources_settings im
22
21
  from reconcile.utils import gql
23
22
 
24
23
 
25
- def get_namespaces(query_func: Optional[Callable] = None) -> list[NamespaceV1]:
24
+ def get_namespaces(query_func: Callable | None = None) -> list[NamespaceV1]:
26
25
  if not query_func:
27
26
  query_func = gql.get_api().query
28
27
  data = query_namespaces(query_func=query_func)
@@ -30,7 +29,7 @@ def get_namespaces(query_func: Optional[Callable] = None) -> list[NamespaceV1]:
30
29
 
31
30
 
32
31
  def get_settings(
33
- query_func: Optional[Callable] = None,
32
+ query_func: Callable | None = None,
34
33
  ) -> list[ExternalResourcesSettingsV1]:
35
34
  if not query_func:
36
35
  query_func = gql.get_api().query
@@ -39,7 +38,7 @@ def get_settings(
39
38
 
40
39
 
41
40
  def get_modules(
42
- query_func: Optional[Callable] = None,
41
+ query_func: Callable | None = None,
43
42
  ) -> list[ExternalResourcesModuleV1]:
44
43
  if not query_func:
45
44
  query_func = gql.get_api().query
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.pagerduty_instances import (
5
4
  PagerDutyInstanceV1,
@@ -9,7 +8,7 @@ from reconcile.utils import gql
9
8
 
10
9
 
11
10
  def get_pagerduty_instances(
12
- query_func: Optional[Callable],
11
+ query_func: Callable | None,
13
12
  ) -> list[PagerDutyInstanceV1]:
14
13
  """Return all pagerduty instances from app-interface."""
15
14
  if not query_func:
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.app_code_component_repos import (
5
4
  AppCodeComponentsV1,
@@ -10,7 +9,7 @@ from reconcile.utils import gql
10
9
 
11
10
  def get_code_components(
12
11
  server: str = "",
13
- query_func: Optional[Callable] = None,
12
+ query_func: Callable | None = None,
14
13
  ) -> list[AppCodeComponentsV1]:
15
14
  if not query_func:
16
15
  query_func = gql.get_api().query
@@ -24,7 +23,7 @@ def get_code_components(
24
23
 
25
24
  def get_repos(
26
25
  server: str = "",
27
- query_func: Optional[Callable] = None,
26
+ query_func: Callable | None = None,
28
27
  ) -> list[str]:
29
28
  code_components = get_code_components(server=server, query_func=query_func)
30
29
  return [c.url for c in code_components]
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.common.reserved_networks import (
4
2
  NetworkV1,
5
3
  query,
@@ -8,7 +6,7 @@ from reconcile.utils import gql
8
6
  from reconcile.utils.gql import GqlApi
9
7
 
10
8
 
11
- def get_networks(gql_api: Optional[GqlApi] = None) -> list[NetworkV1]:
9
+ def get_networks(gql_api: GqlApi | None = None) -> list[NetworkV1]:
12
10
  api = gql_api if gql_api else gql.get_api()
13
11
  data = query(query_func=api.query)
14
12
  return list(data.networks or [])
@@ -2,11 +2,7 @@ import hashlib
2
2
  import json
3
3
  from collections.abc import Callable
4
4
  from threading import Lock
5
- from typing import (
6
- Any,
7
- Optional,
8
- Union,
9
- )
5
+ from typing import Any
10
6
 
11
7
  from jsonpath_ng.exceptions import JsonPathParserError
12
8
  from pydantic import (
@@ -55,24 +51,22 @@ from reconcile.utils.jsonpath import parse_jsonpath
55
51
 
56
52
 
57
53
  class SaasResourceTemplateTarget(ConfiguredBaseModel):
58
- path: Optional[str] = Field(..., alias="path")
59
- name: Optional[str] = Field(..., alias="name")
54
+ path: str | None = Field(..., alias="path")
55
+ name: str | None = Field(..., alias="name")
60
56
  # the namespace must be required to fulfill the saas file schema (utils.saasherder.interface.SaasFile)
61
57
  namespace: SaasTargetNamespace = Field(..., alias="namespace")
62
58
  ref: str = Field(..., alias="ref")
63
- promotion: Optional[SaasResourceTemplateTargetPromotionV1] = Field(
59
+ promotion: SaasResourceTemplateTargetPromotionV1 | None = Field(
64
60
  ..., alias="promotion"
65
61
  )
66
- parameters: Optional[Json] = Field(..., alias="parameters")
67
- secret_parameters: Optional[
68
- list[SaasResourceTemplateTargetV2_SaasSecretParametersV1]
69
- ] = Field(..., alias="secretParameters")
70
- upstream: Optional[SaasResourceTemplateTargetUpstreamV1] = Field(
71
- ..., alias="upstream"
72
- )
73
- image: Optional[SaasResourceTemplateTargetImageV1] = Field(..., alias="image")
74
- disable: Optional[bool] = Field(..., alias="disable")
75
- delete: Optional[bool] = Field(..., alias="delete")
62
+ parameters: Json | None = Field(..., alias="parameters")
63
+ secret_parameters: (
64
+ list[SaasResourceTemplateTargetV2_SaasSecretParametersV1] | None
65
+ ) = Field(..., alias="secretParameters")
66
+ upstream: SaasResourceTemplateTargetUpstreamV1 | None = Field(..., alias="upstream")
67
+ image: SaasResourceTemplateTargetImageV1 | None = Field(..., alias="image")
68
+ disable: bool | None = Field(..., alias="disable")
69
+ delete: bool | None = Field(..., alias="delete")
76
70
 
77
71
  def uid(
78
72
  self, parent_saas_file_name: str, parent_resource_template_name: str
@@ -92,10 +86,10 @@ class SaasResourceTemplate(ConfiguredBaseModel):
92
86
  name: str = Field(..., alias="name")
93
87
  url: str = Field(..., alias="url")
94
88
  path: str = Field(..., alias="path")
95
- provider: Optional[str] = Field(..., alias="provider")
96
- hash_length: Optional[int] = Field(..., alias="hash_length")
97
- parameters: Optional[Json] = Field(..., alias="parameters")
98
- secret_parameters: Optional[list[SaasResourceTemplateV2_SaasSecretParametersV1]] = (
89
+ provider: str | None = Field(..., alias="provider")
90
+ hash_length: int | None = Field(..., alias="hash_length")
91
+ parameters: Json | None = Field(..., alias="parameters")
92
+ secret_parameters: list[SaasResourceTemplateV2_SaasSecretParametersV1] | None = (
99
93
  Field(..., alias="secretParameters")
100
94
  )
101
95
  targets: list[SaasResourceTemplateTarget] = Field(..., alias="targets")
@@ -104,53 +98,49 @@ class SaasResourceTemplate(ConfiguredBaseModel):
104
98
  class SaasFile(ConfiguredBaseModel):
105
99
  path: str = Field(..., alias="path")
106
100
  name: str = Field(..., alias="name")
107
- labels: Optional[Json] = Field(..., alias="labels")
101
+ labels: Json | None = Field(..., alias="labels")
108
102
  app: AppV1 = Field(..., alias="app")
109
- pipelines_provider: Union[PipelinesProviderTektonV1, PipelinesProviderV1] = Field(
103
+ pipelines_provider: PipelinesProviderTektonV1 | PipelinesProviderV1 = Field(
110
104
  ..., alias="pipelinesProvider"
111
105
  )
112
- deploy_resources: Optional[DeployResourcesV1] = Field(..., alias="deployResources")
113
- slack: Optional[SlackOutputV1] = Field(..., alias="slack")
106
+ deploy_resources: DeployResourcesV1 | None = Field(..., alias="deployResources")
107
+ slack: SlackOutputV1 | None = Field(..., alias="slack")
114
108
  managed_resource_types: list[str] = Field(..., alias="managedResourceTypes")
115
- takeover: Optional[bool] = Field(..., alias="takeover")
116
- deprecated: Optional[bool] = Field(..., alias="deprecated")
117
- compare: Optional[bool] = Field(..., alias="compare")
118
- timeout: Optional[str] = Field(..., alias="timeout")
119
- skip_successful_deploy_notifications: Optional[bool] = Field(
109
+ takeover: bool | None = Field(..., alias="takeover")
110
+ deprecated: bool | None = Field(..., alias="deprecated")
111
+ compare: bool | None = Field(..., alias="compare")
112
+ timeout: str | None = Field(..., alias="timeout")
113
+ skip_successful_deploy_notifications: bool | None = Field(
120
114
  ..., alias="skipSuccessfulDeployNotifications"
121
115
  )
122
- publish_job_logs: Optional[bool] = Field(..., alias="publishJobLogs")
123
- cluster_admin: Optional[bool] = Field(..., alias="clusterAdmin")
116
+ publish_job_logs: bool | None = Field(..., alias="publishJobLogs")
117
+ cluster_admin: bool | None = Field(..., alias="clusterAdmin")
124
118
  image_patterns: list[str] = Field(..., alias="imagePatterns")
125
- allowed_secret_parameter_paths: Optional[list[str]] = Field(
119
+ allowed_secret_parameter_paths: list[str] | None = Field(
126
120
  ..., alias="allowedSecretParameterPaths"
127
121
  )
128
- use_channel_in_image_tag: Optional[bool] = Field(
129
- ..., alias="use_channel_in_image_tag"
130
- )
131
- authentication: Optional[SaasFileAuthenticationV1] = Field(
132
- ..., alias="authentication"
133
- )
134
- parameters: Optional[Json] = Field(..., alias="parameters")
135
- secret_parameters: Optional[list[SaasSecretParametersV1]] = Field(
122
+ use_channel_in_image_tag: bool | None = Field(..., alias="use_channel_in_image_tag")
123
+ authentication: SaasFileAuthenticationV1 | None = Field(..., alias="authentication")
124
+ parameters: Json | None = Field(..., alias="parameters")
125
+ secret_parameters: list[SaasSecretParametersV1] | None = Field(
136
126
  ..., alias="secretParameters"
137
127
  )
138
- validate_targets_in_app: Optional[bool] = Field(..., alias="validateTargetsInApp")
139
- managed_resource_names: Optional[list[ManagedResourceNamesV1]] = Field(
128
+ validate_targets_in_app: bool | None = Field(..., alias="validateTargetsInApp")
129
+ managed_resource_names: list[ManagedResourceNamesV1] | None = Field(
140
130
  ..., alias="managedResourceNames"
141
131
  )
142
132
  resource_templates: list[SaasResourceTemplate] = Field(
143
133
  ..., alias="resourceTemplates"
144
134
  )
145
- self_service_roles: Optional[list[RoleV1]] = Field(..., alias="selfServiceRoles")
135
+ self_service_roles: list[RoleV1] | None = Field(..., alias="selfServiceRoles")
146
136
 
147
137
 
148
138
  class SaasFileList:
149
139
  def __init__(
150
140
  self,
151
- name: Optional[str] = None,
152
- query_func: Optional[Callable] = None,
153
- namespaces: Optional[list[SaasTargetNamespace]] = None,
141
+ name: str | None = None,
142
+ query_func: Callable | None = None,
143
+ namespaces: list[SaasTargetNamespace] | None = None,
154
144
  ) -> None:
155
145
  # query_func and namespaces are optional args mostly used in tests
156
146
  if not query_func:
@@ -170,7 +160,7 @@ class SaasFileList:
170
160
  self.saas_files = self._resolve_namespace_selectors()
171
161
 
172
162
  def _init_caches(self) -> None:
173
- self._namespaces_as_dict_cache: Optional[dict[str, list[Any]]] = None
163
+ self._namespaces_as_dict_cache: dict[str, list[Any]] | None = None
174
164
  self._namespaces_as_dict_lock = Lock()
175
165
  self._matching_namespaces_cache: dict[str, Any] = {}
176
166
  self._matching_namespaces_lock = Lock()
@@ -272,9 +262,9 @@ class SaasFileList:
272
262
 
273
263
  def where(
274
264
  self,
275
- name: Optional[str] = None,
276
- env_name: Optional[str] = None,
277
- app_name: Optional[str] = None,
265
+ name: str | None = None,
266
+ env_name: str | None = None,
267
+ app_name: str | None = None,
278
268
  ) -> list[SaasFile]:
279
269
  if name is None and env_name is None and app_name is None:
280
270
  return self.saas_files
@@ -325,12 +315,12 @@ def export_model(model: BaseModel) -> dict[str, Any]:
325
315
 
326
316
 
327
317
  def get_saas_files(
328
- name: Optional[str] = None,
329
- env_name: Optional[str] = None,
330
- app_name: Optional[str] = None,
331
- query_func: Optional[Callable] = None,
332
- namespaces: Optional[list[SaasTargetNamespace]] = None,
333
- saas_file_list: Optional[SaasFileList] = None,
318
+ name: str | None = None,
319
+ env_name: str | None = None,
320
+ app_name: str | None = None,
321
+ query_func: Callable | None = None,
322
+ namespaces: list[SaasTargetNamespace] | None = None,
323
+ saas_file_list: SaasFileList | None = None,
334
324
  ) -> list[SaasFile]:
335
325
  if not saas_file_list:
336
326
  saas_file_list = SaasFileList(
@@ -340,7 +330,7 @@ def get_saas_files(
340
330
 
341
331
 
342
332
  def get_saasherder_settings(
343
- query_func: Optional[Callable] = None,
333
+ query_func: Callable | None = None,
344
334
  ) -> AppInterfaceSettingsV1:
345
335
  if not query_func:
346
336
  query_func = gql.get_api().query
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.slo_documents.slo_documents import (
4
2
  SLODocumentV1,
5
3
  query,
@@ -8,7 +6,7 @@ from reconcile.utils import gql
8
6
  from reconcile.utils.gql import GqlApi
9
7
 
10
8
 
11
- def get_slo_documents(gql_api: Optional[GqlApi] = None) -> list[SLODocumentV1]:
9
+ def get_slo_documents(gql_api: GqlApi | None = None) -> list[SLODocumentV1]:
12
10
  api = gql_api if gql_api else gql.get_api()
13
11
  data = query(query_func=api.query)
14
12
  return data.slo_document_v1 or []
@@ -1,9 +1,5 @@
1
- from typing import (
2
- Any,
3
- Callable,
4
- Iterable,
5
- Optional,
6
- )
1
+ from collections.abc import Callable, Iterable
2
+ from typing import Any
7
3
 
8
4
  from jsonpath_ng.ext import parser
9
5
 
@@ -16,7 +12,7 @@ from reconcile.utils import gql
16
12
 
17
13
 
18
14
  def get_status_board(
19
- query_func: Optional[Callable] = None,
15
+ query_func: Callable | None = None,
20
16
  ) -> list[StatusBoardV1]:
21
17
  if not query_func:
22
18
  query_func = gql.get_api().query
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.common.pipeline_providers import (
5
4
  PipelinesProviderTektonV1,
@@ -9,7 +8,7 @@ from reconcile.utils import gql
9
8
 
10
9
 
11
10
  def get_tekton_pipeline_providers(
12
- query_func: Optional[Callable] = None,
11
+ query_func: Callable | None = None,
13
12
  ) -> list[PipelinesProviderTektonV1]:
14
13
  if not query_func:
15
14
  query_func = gql.get_api().query
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Callable
2
- from typing import Optional
3
2
 
4
3
  from reconcile.gql_definitions.terraform_resources.terraform_resources_namespaces import (
5
4
  NamespaceV1,
@@ -8,7 +7,7 @@ from reconcile.gql_definitions.terraform_resources.terraform_resources_namespace
8
7
  from reconcile.utils import gql
9
8
 
10
9
 
11
- def get_namespaces(query_func: Optional[Callable] = None) -> list[NamespaceV1]:
10
+ def get_namespaces(query_func: Callable | None = None) -> list[NamespaceV1]:
12
11
  if not query_func:
13
12
  query_func = gql.get_api().query
14
13
  data = query(query_func=query_func)
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from reconcile.gql_definitions.terraform_tgw_attachments.aws_accounts import (
4
2
  AWSAccountV1,
5
3
  query,
@@ -9,7 +7,7 @@ from reconcile.utils.gql import GqlApi
9
7
 
10
8
  def get_aws_accounts(
11
9
  gql_api: GqlApi,
12
- name: Optional[str] = None,
10
+ name: str | None = None,
13
11
  ) -> list[AWSAccountV1]:
14
12
  variables = {
15
13
  "name": name,
@@ -2,7 +2,6 @@ import logging
2
2
  from collections.abc import Callable
3
3
  from typing import (
4
4
  Any,
5
- Optional,
6
5
  Self,
7
6
  )
8
7
 
@@ -55,7 +54,7 @@ class AcsBaseApi(BaseModel):
55
54
  )
56
55
 
57
56
  def generic_request(
58
- self, path: str, verb: str, json: Optional[Any] = None
57
+ self, path: str, verb: str, json: Any | None = None
59
58
  ) -> requests.Response:
60
59
  url = f"{self.url}{path}"
61
60
  headers = {
@@ -77,6 +76,6 @@ class AcsBaseApi(BaseModel):
77
76
  return response
78
77
 
79
78
  def generic_request_json(
80
- self, path: str, verb: str, json: Optional[Any] = None
79
+ self, path: str, verb: str, json: Any | None = None
81
80
  ) -> Any:
82
81
  return self.generic_request(path, verb, json=json).json()