infrahub-server 1.1.6__py3-none-any.whl → 1.2.0rc0__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 (346) hide show
  1. infrahub/api/artifact.py +16 -4
  2. infrahub/api/dependencies.py +8 -0
  3. infrahub/api/oauth2.py +0 -1
  4. infrahub/api/oidc.py +0 -1
  5. infrahub/api/query.py +18 -7
  6. infrahub/api/schema.py +32 -6
  7. infrahub/api/transformation.py +12 -5
  8. infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +2 -4
  9. infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
  10. infrahub/cli/__init__.py +0 -2
  11. infrahub/cli/db.py +6 -7
  12. infrahub/cli/events.py +8 -3
  13. infrahub/cli/git_agent.py +9 -7
  14. infrahub/cli/tasks.py +4 -6
  15. infrahub/computed_attribute/tasks.py +63 -17
  16. infrahub/computed_attribute/triggers.py +90 -0
  17. infrahub/config.py +1 -1
  18. infrahub/context.py +39 -0
  19. infrahub/core/account.py +5 -8
  20. infrahub/core/attribute.py +53 -21
  21. infrahub/core/branch/models.py +4 -4
  22. infrahub/core/branch/tasks.py +89 -130
  23. infrahub/core/changelog/__init__.py +0 -0
  24. infrahub/core/changelog/diff.py +232 -0
  25. infrahub/core/changelog/models.py +488 -0
  26. infrahub/core/constants/__init__.py +19 -2
  27. infrahub/core/constants/infrahubkind.py +1 -0
  28. infrahub/core/diff/combiner.py +12 -8
  29. infrahub/core/diff/coordinator.py +49 -70
  30. infrahub/core/diff/data_check_synchronizer.py +86 -7
  31. infrahub/core/diff/enricher/aggregated.py +3 -3
  32. infrahub/core/diff/enricher/cardinality_one.py +2 -7
  33. infrahub/core/diff/enricher/hierarchy.py +5 -3
  34. infrahub/core/diff/enricher/labels.py +14 -4
  35. infrahub/core/diff/enricher/path_identifier.py +3 -9
  36. infrahub/core/diff/enricher/summary_counts.py +3 -1
  37. infrahub/core/diff/merger/merger.py +8 -4
  38. infrahub/core/diff/model/path.py +47 -29
  39. infrahub/core/diff/query/all_conflicts.py +6 -3
  40. infrahub/core/diff/query/artifact.py +1 -1
  41. infrahub/core/diff/query/delete_query.py +1 -1
  42. infrahub/core/diff/query/diff_get.py +3 -2
  43. infrahub/core/diff/query/diff_summary.py +1 -1
  44. infrahub/core/diff/query/field_specifiers.py +3 -1
  45. infrahub/core/diff/query/field_summary.py +3 -2
  46. infrahub/core/diff/query/filters.py +12 -1
  47. infrahub/core/diff/query/get_conflict_query.py +1 -1
  48. infrahub/core/diff/query/has_conflicts_query.py +6 -3
  49. infrahub/core/diff/query/merge.py +3 -3
  50. infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
  51. infrahub/core/diff/query/roots_metadata.py +9 -2
  52. infrahub/core/diff/query/save.py +151 -66
  53. infrahub/core/diff/query/summary_counts_enricher.py +220 -0
  54. infrahub/core/diff/query/time_range_query.py +3 -2
  55. infrahub/core/diff/query/update_conflict_query.py +1 -1
  56. infrahub/core/diff/query_parser.py +49 -24
  57. infrahub/core/diff/repository/deserializer.py +24 -25
  58. infrahub/core/diff/repository/repository.py +76 -20
  59. infrahub/core/diff/tasks.py +9 -8
  60. infrahub/core/enums.py +1 -1
  61. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  62. infrahub/core/ipam/reconciler.py +1 -1
  63. infrahub/core/ipam/tasks.py +2 -3
  64. infrahub/core/manager.py +18 -13
  65. infrahub/core/merge.py +5 -2
  66. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  67. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  68. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  69. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  70. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  71. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  72. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  73. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  74. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  75. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  76. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  77. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  78. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  79. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  80. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  81. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  82. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
  83. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
  84. infrahub/core/migrations/query/attribute_add.py +1 -1
  85. infrahub/core/migrations/query/attribute_rename.py +1 -1
  86. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  87. infrahub/core/migrations/query/node_duplicate.py +1 -1
  88. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  89. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  90. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  91. infrahub/core/migrations/schema/node_remove.py +1 -1
  92. infrahub/core/migrations/schema/tasks.py +5 -5
  93. infrahub/core/migrations/shared.py +4 -4
  94. infrahub/core/models.py +7 -8
  95. infrahub/core/node/__init__.py +161 -40
  96. infrahub/core/node/base.py +1 -1
  97. infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
  98. infrahub/core/node/delete_validator.py +4 -4
  99. infrahub/core/node/ipam.py +13 -8
  100. infrahub/core/node/permissions.py +4 -0
  101. infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
  102. infrahub/core/node/standard.py +3 -5
  103. infrahub/core/property.py +1 -1
  104. infrahub/core/protocols.py +4 -0
  105. infrahub/core/protocols_base.py +4 -2
  106. infrahub/core/query/__init__.py +2 -5
  107. infrahub/core/query/attribute.py +9 -9
  108. infrahub/core/query/branch.py +5 -5
  109. infrahub/core/query/delete.py +1 -1
  110. infrahub/core/query/diff.py +45 -7
  111. infrahub/core/query/ipam.py +4 -4
  112. infrahub/core/query/node.py +19 -14
  113. infrahub/core/query/relationship.py +10 -11
  114. infrahub/core/query/resource_manager.py +13 -11
  115. infrahub/core/query/standard_node.py +6 -6
  116. infrahub/core/query/task.py +3 -3
  117. infrahub/core/query/task_log.py +1 -1
  118. infrahub/core/query/utils.py +5 -5
  119. infrahub/core/registry.py +0 -2
  120. infrahub/core/relationship/constraints/count.py +1 -1
  121. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  122. infrahub/core/relationship/model.py +66 -26
  123. infrahub/core/schema/__init__.py +6 -4
  124. infrahub/core/schema/basenode_schema.py +1 -3
  125. infrahub/core/schema/definitions/core.py +14 -2
  126. infrahub/core/schema/definitions/internal.py +16 -0
  127. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  128. infrahub/core/schema/generated/node_schema.py +5 -0
  129. infrahub/core/schema/generic_schema.py +5 -1
  130. infrahub/core/schema/manager.py +45 -42
  131. infrahub/core/schema/node_schema.py +4 -0
  132. infrahub/core/schema/profile_schema.py +4 -0
  133. infrahub/core/schema/relationship_schema.py +2 -2
  134. infrahub/core/schema/schema_branch.py +248 -14
  135. infrahub/core/schema/template_schema.py +36 -0
  136. infrahub/core/task/user_task.py +7 -5
  137. infrahub/core/timestamp.py +1 -1
  138. infrahub/core/utils.py +3 -2
  139. infrahub/core/validators/attribute/choices.py +1 -1
  140. infrahub/core/validators/attribute/enum.py +1 -1
  141. infrahub/core/validators/attribute/kind.py +1 -1
  142. infrahub/core/validators/attribute/length.py +1 -1
  143. infrahub/core/validators/attribute/optional.py +1 -1
  144. infrahub/core/validators/attribute/regex.py +1 -1
  145. infrahub/core/validators/attribute/unique.py +1 -1
  146. infrahub/core/validators/checks_runner.py +37 -0
  147. infrahub/core/validators/node/generate_profile.py +1 -1
  148. infrahub/core/validators/node/hierarchy.py +1 -1
  149. infrahub/core/validators/query.py +1 -1
  150. infrahub/core/validators/relationship/count.py +1 -1
  151. infrahub/core/validators/relationship/optional.py +1 -1
  152. infrahub/core/validators/relationship/peer.py +1 -1
  153. infrahub/core/validators/tasks.py +8 -6
  154. infrahub/core/validators/uniqueness/query.py +20 -17
  155. infrahub/database/__init__.py +15 -2
  156. infrahub/database/memgraph.py +1 -1
  157. infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
  158. infrahub/dependencies/builder/diff/combiner.py +1 -1
  159. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  160. infrahub/dependencies/builder/diff/coordinator.py +0 -2
  161. infrahub/dependencies/builder/diff/deserializer.py +1 -1
  162. infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
  163. infrahub/events/branch_action.py +47 -21
  164. infrahub/events/group_action.py +73 -0
  165. infrahub/events/models.py +159 -51
  166. infrahub/events/node_action.py +74 -8
  167. infrahub/events/repository_action.py +8 -8
  168. infrahub/events/schema_action.py +21 -8
  169. infrahub/generators/tasks.py +12 -13
  170. infrahub/git/base.py +3 -5
  171. infrahub/git/constants.py +0 -1
  172. infrahub/git/integrator.py +36 -35
  173. infrahub/git/repository.py +7 -8
  174. infrahub/git/tasks.py +43 -107
  175. infrahub/git_credential/helper.py +2 -3
  176. infrahub/graphql/analyzer.py +572 -11
  177. infrahub/graphql/app.py +34 -26
  178. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  179. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  180. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  181. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  182. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  183. infrahub/graphql/enums.py +1 -1
  184. infrahub/graphql/initialization.py +5 -1
  185. infrahub/graphql/loaders/node.py +2 -2
  186. infrahub/graphql/manager.py +59 -54
  187. infrahub/graphql/mutations/account.py +20 -13
  188. infrahub/graphql/mutations/artifact_definition.py +16 -12
  189. infrahub/graphql/mutations/branch.py +61 -40
  190. infrahub/graphql/mutations/computed_attribute.py +19 -13
  191. infrahub/graphql/mutations/diff.py +37 -9
  192. infrahub/graphql/mutations/diff_conflict.py +9 -8
  193. infrahub/graphql/mutations/graphql_query.py +19 -11
  194. infrahub/graphql/mutations/ipam.py +21 -19
  195. infrahub/graphql/mutations/main.py +197 -44
  196. infrahub/graphql/mutations/menu.py +8 -8
  197. infrahub/graphql/mutations/proposed_change.py +36 -28
  198. infrahub/graphql/mutations/relationship.py +302 -105
  199. infrahub/graphql/mutations/repository.py +41 -35
  200. infrahub/graphql/mutations/resource_manager.py +26 -26
  201. infrahub/graphql/mutations/schema.py +51 -33
  202. infrahub/graphql/mutations/tasks.py +16 -10
  203. infrahub/graphql/parser.py +1 -1
  204. infrahub/graphql/permissions.py +6 -4
  205. infrahub/graphql/queries/account.py +22 -18
  206. infrahub/graphql/queries/branch.py +6 -4
  207. infrahub/graphql/queries/diff/tree.py +48 -42
  208. infrahub/graphql/queries/event.py +112 -0
  209. infrahub/graphql/queries/internal.py +3 -3
  210. infrahub/graphql/queries/ipam.py +23 -18
  211. infrahub/graphql/queries/relationship.py +11 -10
  212. infrahub/graphql/queries/resource_manager.py +43 -27
  213. infrahub/graphql/queries/search.py +9 -8
  214. infrahub/graphql/queries/status.py +12 -9
  215. infrahub/graphql/queries/task.py +11 -9
  216. infrahub/graphql/resolvers/resolver.py +69 -43
  217. infrahub/graphql/resolvers/single_relationship.py +16 -10
  218. infrahub/graphql/schema.py +2 -0
  219. infrahub/graphql/subscription/__init__.py +1 -1
  220. infrahub/graphql/subscription/events.py +1 -1
  221. infrahub/graphql/subscription/graphql_query.py +8 -8
  222. infrahub/graphql/types/branch.py +2 -2
  223. infrahub/graphql/types/common.py +6 -1
  224. infrahub/graphql/types/enums.py +2 -0
  225. infrahub/graphql/types/event.py +100 -0
  226. infrahub/graphql/types/interface.py +2 -2
  227. infrahub/graphql/types/node.py +3 -3
  228. infrahub/graphql/types/permission.py +2 -2
  229. infrahub/graphql/types/relationship.py +3 -3
  230. infrahub/graphql/types/standard_node.py +9 -11
  231. infrahub/graphql/utils.py +28 -182
  232. infrahub/groups/tasks.py +2 -3
  233. infrahub/lock.py +1 -1
  234. infrahub/menu/constants.py +1 -0
  235. infrahub/menu/generator.py +14 -3
  236. infrahub/menu/menu.py +116 -127
  237. infrahub/menu/models.py +4 -4
  238. infrahub/message_bus/messages/__init__.py +0 -4
  239. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  240. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  241. infrahub/message_bus/operations/__init__.py +3 -5
  242. infrahub/message_bus/operations/check/__init__.py +2 -2
  243. infrahub/message_bus/operations/check/generator.py +1 -3
  244. infrahub/message_bus/operations/check/repository.py +1 -1
  245. infrahub/message_bus/operations/event/branch.py +7 -3
  246. infrahub/message_bus/operations/event/schema.py +1 -1
  247. infrahub/message_bus/operations/finalize/validator.py +1 -1
  248. infrahub/message_bus/operations/git/file.py +2 -2
  249. infrahub/message_bus/operations/git/repository.py +1 -1
  250. infrahub/message_bus/operations/requests/__init__.py +0 -2
  251. infrahub/message_bus/operations/requests/generator_definition.py +1 -1
  252. infrahub/message_bus/operations/requests/proposed_change.py +26 -11
  253. infrahub/message_bus/operations/requests/repository.py +2 -2
  254. infrahub/message_bus/operations/send/echo.py +1 -1
  255. infrahub/message_bus/types.py +1 -1
  256. infrahub/permissions/__init__.py +2 -1
  257. infrahub/permissions/types.py +26 -0
  258. infrahub/pools/prefix.py +29 -165
  259. infrahub/prefect_server/__init__.py +0 -0
  260. infrahub/prefect_server/app.py +18 -0
  261. infrahub/prefect_server/database.py +20 -0
  262. infrahub/prefect_server/events.py +28 -0
  263. infrahub/prefect_server/models.py +46 -0
  264. infrahub/proposed_change/models.py +15 -1
  265. infrahub/proposed_change/tasks.py +173 -35
  266. infrahub/pytest_plugin.py +4 -4
  267. infrahub/server.py +12 -11
  268. infrahub/services/__init__.py +147 -62
  269. infrahub/services/adapters/cache/__init__.py +7 -5
  270. infrahub/services/adapters/cache/nats.py +40 -22
  271. infrahub/services/adapters/cache/redis.py +0 -4
  272. infrahub/services/adapters/event/__init__.py +10 -18
  273. infrahub/services/adapters/http/__init__.py +0 -5
  274. infrahub/services/adapters/http/httpx.py +22 -15
  275. infrahub/services/adapters/message_bus/__init__.py +23 -6
  276. infrahub/services/adapters/message_bus/local.py +8 -6
  277. infrahub/services/adapters/message_bus/nats.py +12 -6
  278. infrahub/services/adapters/message_bus/rabbitmq.py +22 -9
  279. infrahub/services/adapters/workflow/__init__.py +11 -8
  280. infrahub/services/adapters/workflow/local.py +28 -7
  281. infrahub/services/adapters/workflow/worker.py +23 -7
  282. infrahub/services/component.py +38 -35
  283. infrahub/services/scheduler.py +32 -29
  284. infrahub/storage.py +2 -4
  285. infrahub/task_manager/constants.py +1 -1
  286. infrahub/task_manager/event.py +182 -0
  287. infrahub/task_manager/models.py +125 -1
  288. infrahub/task_manager/task.py +1 -1
  289. infrahub/tasks/artifact.py +14 -16
  290. infrahub/tasks/registry.py +1 -1
  291. infrahub/tasks/telemetry.py +13 -14
  292. infrahub/transformations/tasks.py +3 -5
  293. infrahub/trigger/__init__.py +0 -0
  294. infrahub/trigger/catalogue.py +15 -0
  295. infrahub/trigger/constants.py +9 -0
  296. infrahub/trigger/models.py +69 -0
  297. infrahub/trigger/tasks.py +85 -0
  298. infrahub/types.py +1 -1
  299. infrahub/utils.py +1 -1
  300. infrahub/webhook/constants.py +0 -2
  301. infrahub/webhook/models.py +8 -2
  302. infrahub/webhook/tasks.py +20 -73
  303. infrahub/webhook/triggers.py +20 -0
  304. infrahub/workers/infrahub_async.py +36 -25
  305. infrahub/workers/utils.py +63 -0
  306. infrahub/workflows/catalogue.py +13 -37
  307. infrahub/workflows/initialization.py +6 -8
  308. infrahub/workflows/models.py +3 -5
  309. infrahub/workflows/utils.py +1 -1
  310. infrahub_sdk/ctl/check.py +3 -3
  311. infrahub_sdk/ctl/cli_commands.py +11 -10
  312. infrahub_sdk/ctl/exceptions.py +0 -6
  313. infrahub_sdk/ctl/exporter.py +1 -1
  314. infrahub_sdk/ctl/generator.py +5 -5
  315. infrahub_sdk/ctl/importer.py +3 -2
  316. infrahub_sdk/ctl/menu.py +1 -1
  317. infrahub_sdk/ctl/object.py +1 -1
  318. infrahub_sdk/ctl/repository.py +23 -15
  319. infrahub_sdk/ctl/schema.py +2 -2
  320. infrahub_sdk/ctl/utils.py +4 -3
  321. infrahub_sdk/ctl/validate.py +2 -1
  322. infrahub_sdk/exceptions.py +6 -0
  323. infrahub_sdk/generator.py +3 -0
  324. infrahub_sdk/node.py +2 -2
  325. infrahub_sdk/schema/__init__.py +14 -2
  326. infrahub_sdk/schema/main.py +7 -0
  327. infrahub_sdk/utils.py +11 -1
  328. infrahub_sdk/yaml.py +2 -3
  329. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/METADATA +46 -12
  330. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/RECORD +338 -321
  331. infrahub_testcontainers/container.py +14 -6
  332. infrahub_testcontainers/docker-compose.test.yml +24 -5
  333. infrahub_testcontainers/haproxy.cfg +43 -0
  334. infrahub_testcontainers/helpers.py +85 -1
  335. infrahub/core/branch/constants.py +0 -2
  336. infrahub/graphql/query.py +0 -52
  337. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  338. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  339. infrahub/schema/constants.py +0 -1
  340. infrahub/schema/tasks.py +0 -76
  341. infrahub/services/adapters/database/__init__.py +0 -9
  342. infrahub_sdk/ctl/_file.py +0 -13
  343. /infrahub/{schema → artifacts}/__init__.py +0 -0
  344. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/LICENSE.txt +0 -0
  345. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/WHEEL +0 -0
  346. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/entry_points.txt +0 -0
@@ -28,8 +28,6 @@ if TYPE_CHECKING:
28
28
  from ..initialization import GraphqlContext
29
29
 
30
30
 
31
- # pylint: disable=unused-argument
32
-
33
31
  log = get_logger()
34
32
 
35
33
 
@@ -57,28 +55,30 @@ class BranchCreate(Mutation):
57
55
  @trace.get_tracer(__name__).start_as_current_span("branch_create")
58
56
  async def mutate(
59
57
  cls,
60
- root: dict,
58
+ root: dict, # noqa: ARG003
61
59
  info: GraphQLResolveInfo,
62
60
  data: BranchCreateInput,
63
61
  background_execution: bool = False,
64
62
  wait_until_completion: bool = True,
65
63
  ) -> Self:
66
- context: GraphqlContext = info.context
64
+ graphql_context: GraphqlContext = info.context
67
65
  task: dict | None = None
68
66
 
69
67
  model = BranchCreateModel(**data)
70
68
 
71
69
  if background_execution or not wait_until_completion:
72
- workflow = await context.active_service.workflow.submit_workflow(
73
- workflow=BRANCH_CREATE, parameters={"model": model}
70
+ workflow = await graphql_context.active_service.workflow.submit_workflow(
71
+ workflow=BRANCH_CREATE, context=graphql_context.get_context(), parameters={"model": model}
74
72
  )
75
73
  task = {"id": workflow.id}
76
74
  return cls(ok=True, task=task)
77
75
 
78
- await context.active_service.workflow.execute_workflow(workflow=BRANCH_CREATE, parameters={"model": model})
76
+ await graphql_context.active_service.workflow.execute_workflow(
77
+ workflow=BRANCH_CREATE, context=graphql_context.get_context(), parameters={"model": model}
78
+ )
79
79
 
80
80
  # Retrieve created branch
81
- obj = await Branch.get_by_name(db=context.db, name=model.name)
81
+ obj = await Branch.get_by_name(db=graphql_context.db, name=model.name)
82
82
  fields = await extract_fields(info.field_nodes[0].selection_set)
83
83
  return cls(object=await obj.to_graphql(fields=fields.get("object", {})), ok=True, task=task)
84
84
 
@@ -103,19 +103,23 @@ class BranchDelete(Mutation):
103
103
 
104
104
  @classmethod
105
105
  async def mutate(
106
- cls, root: dict, info: GraphQLResolveInfo, data: BranchNameInput, wait_until_completion: bool = True
106
+ cls,
107
+ root: dict, # noqa: ARG003
108
+ info: GraphQLResolveInfo,
109
+ data: BranchNameInput,
110
+ wait_until_completion: bool = True,
107
111
  ) -> Self:
108
- context: GraphqlContext = info.context
109
- obj = await Branch.get_by_name(db=context.db, name=str(data.name))
112
+ graphql_context: GraphqlContext = info.context
113
+ obj = await Branch.get_by_name(db=graphql_context.db, name=str(data.name))
110
114
 
111
115
  if wait_until_completion:
112
- await context.active_service.workflow.execute_workflow(
113
- workflow=BRANCH_DELETE, parameters={"branch": obj.name}
116
+ await graphql_context.active_service.workflow.execute_workflow(
117
+ workflow=BRANCH_DELETE, context=graphql_context.get_context(), parameters={"branch": obj.name}
114
118
  )
115
119
  return cls(ok=True)
116
120
 
117
- workflow = await context.active_service.workflow.submit_workflow(
118
- workflow=BRANCH_DELETE, parameters={"branch": obj.name}
121
+ workflow = await graphql_context.active_service.workflow.submit_workflow(
122
+ workflow=BRANCH_DELETE, context=graphql_context.get_context(), parameters={"branch": obj.name}
119
123
  )
120
124
  return cls(ok=True, task={"id": str(workflow.id)})
121
125
 
@@ -128,17 +132,17 @@ class BranchUpdate(Mutation):
128
132
 
129
133
  @classmethod
130
134
  @retry_db_transaction(name="branch_update")
131
- async def mutate(cls, root: dict, info: GraphQLResolveInfo, data: BranchNameInput) -> Self:
132
- context: GraphqlContext = info.context
135
+ async def mutate(cls, root: dict, info: GraphQLResolveInfo, data: BranchNameInput) -> Self: # noqa: ARG003
136
+ graphql_context: GraphqlContext = info.context
133
137
 
134
- obj = await Branch.get_by_name(db=context.db, name=data["name"])
138
+ obj = await Branch.get_by_name(db=graphql_context.db, name=data["name"])
135
139
 
136
140
  to_extract = ["description"]
137
141
  for field_name in to_extract:
138
142
  if field_name in data and data.get(field_name) is not None:
139
143
  setattr(obj, field_name, data[field_name])
140
144
 
141
- async with context.db.start_transaction() as db:
145
+ async with graphql_context.db.start_transaction() as db:
142
146
  await obj.save(db=db)
143
147
 
144
148
  return cls(ok=True)
@@ -155,23 +159,27 @@ class BranchRebase(Mutation):
155
159
 
156
160
  @classmethod
157
161
  async def mutate(
158
- cls, root: dict, info: GraphQLResolveInfo, data: BranchNameInput, wait_until_completion: bool = True
162
+ cls,
163
+ root: dict, # noqa: ARG003
164
+ info: GraphQLResolveInfo,
165
+ data: BranchNameInput,
166
+ wait_until_completion: bool = True,
159
167
  ) -> Self:
160
- context: GraphqlContext = info.context
168
+ graphql_context: GraphqlContext = info.context
161
169
 
162
- obj = await Branch.get_by_name(db=context.db, name=str(data.name))
170
+ obj = await Branch.get_by_name(db=graphql_context.db, name=str(data.name))
163
171
  task: dict | None = None
164
172
 
165
173
  if wait_until_completion:
166
- await context.active_service.workflow.execute_workflow(
167
- workflow=BRANCH_REBASE, parameters={"branch": obj.name}
174
+ await graphql_context.active_service.workflow.execute_workflow(
175
+ workflow=BRANCH_REBASE, context=graphql_context.get_context(), parameters={"branch": obj.name}
168
176
  )
169
177
 
170
178
  # Pull the latest information about the branch from the database directly
171
- obj = await Branch.get_by_name(db=context.db, name=str(data.name))
179
+ obj = await Branch.get_by_name(db=graphql_context.db, name=str(data.name))
172
180
  else:
173
- workflow = await context.active_service.workflow.submit_workflow(
174
- workflow=BRANCH_REBASE, parameters={"branch": obj.name}
181
+ workflow = await graphql_context.active_service.workflow.submit_workflow(
182
+ workflow=BRANCH_REBASE, context=graphql_context.get_context(), parameters={"branch": obj.name}
175
183
  )
176
184
  task = {"id": workflow.id}
177
185
 
@@ -193,21 +201,25 @@ class BranchValidate(Mutation):
193
201
  @classmethod
194
202
  @retry_db_transaction(name="branch_validate")
195
203
  async def mutate(
196
- cls, root: dict, info: GraphQLResolveInfo, data: BranchNameInput, wait_until_completion: bool = True
204
+ cls,
205
+ root: dict, # noqa: ARG003
206
+ info: GraphQLResolveInfo,
207
+ data: BranchNameInput,
208
+ wait_until_completion: bool = True,
197
209
  ) -> Self:
198
- context: GraphqlContext = info.context
210
+ graphql_context: GraphqlContext = info.context
199
211
 
200
- obj = await Branch.get_by_name(db=context.db, name=str(data.name))
212
+ obj = await Branch.get_by_name(db=graphql_context.db, name=str(data.name))
201
213
  task: dict | None = None
202
214
  ok = True
203
215
 
204
216
  if wait_until_completion:
205
- await context.active_service.workflow.execute_workflow(
206
- workflow=BRANCH_VALIDATE, parameters={"branch": obj.name}
217
+ await graphql_context.active_service.workflow.execute_workflow(
218
+ workflow=BRANCH_VALIDATE, context=graphql_context.get_context(), parameters={"branch": obj.name}
207
219
  )
208
220
  else:
209
- workflow = await context.active_service.workflow.submit_workflow(
210
- workflow=BRANCH_VALIDATE, parameters={"branch": obj.name}
221
+ workflow = await graphql_context.active_service.workflow.submit_workflow(
222
+ workflow=BRANCH_VALIDATE, context=graphql_context.get_context(), parameters={"branch": obj.name}
211
223
  )
212
224
  task = {"id": workflow.id}
213
225
 
@@ -227,23 +239,32 @@ class BranchMerge(Mutation):
227
239
 
228
240
  @classmethod
229
241
  async def mutate(
230
- cls, root: dict, info: GraphQLResolveInfo, data: BranchNameInput, wait_until_completion: bool = True
242
+ cls,
243
+ root: dict, # noqa: ARG003
244
+ info: GraphQLResolveInfo,
245
+ data: BranchNameInput,
246
+ wait_until_completion: bool = True,
231
247
  ) -> Self:
232
248
  branch_name = data["name"]
233
249
  task: dict | None = None
250
+ graphql_context: GraphqlContext = info.context
234
251
 
235
252
  if wait_until_completion:
236
- await info.context.active_service.workflow.execute_workflow(
237
- workflow=BRANCH_MERGE_MUTATION, parameters={"branch": branch_name}
253
+ await graphql_context.active_service.workflow.execute_workflow(
254
+ workflow=BRANCH_MERGE_MUTATION,
255
+ context=graphql_context.get_context(),
256
+ parameters={"branch": branch_name},
238
257
  )
239
258
  else:
240
- workflow = await info.context.active_service.workflow.submit_workflow(
241
- workflow=BRANCH_MERGE_MUTATION, parameters={"branch": branch_name}
259
+ workflow = await graphql_context.active_service.workflow.submit_workflow(
260
+ workflow=BRANCH_MERGE_MUTATION,
261
+ context=graphql_context.get_context(),
262
+ parameters={"branch": branch_name},
242
263
  )
243
264
  task = {"id": workflow.id}
244
265
 
245
266
  # Pull the latest information about the branch from the database directly
246
- obj = await Branch.get_by_name(db=info.context.db, name=branch_name)
267
+ obj = await Branch.get_by_name(db=graphql_context.db, name=branch_name)
247
268
 
248
269
  fields = await extract_fields(info.field_nodes[0].selection_set)
249
270
  ok = True
@@ -9,7 +9,8 @@ from infrahub.core.constants import ComputedAttributeKind, MutationAction, Permi
9
9
  from infrahub.core.manager import NodeManager
10
10
  from infrahub.core.registry import registry
11
11
  from infrahub.database import retry_db_transaction
12
- from infrahub.events import EventMeta, NodeMutatedEvent
12
+ from infrahub.events import EventMeta
13
+ from infrahub.events.node_action import NodeMutatedEvent
13
14
  from infrahub.exceptions import NodeNotFoundError, ValidationError
14
15
  from infrahub.log import get_log_data
15
16
  from infrahub.worker import WORKER_IDENTITY
@@ -41,8 +42,10 @@ class UpdateComputedAttribute(Mutation):
41
42
  info: GraphQLResolveInfo,
42
43
  data: InfrahubComputedAttributeUpdateInput,
43
44
  ) -> UpdateComputedAttribute:
44
- context: GraphqlContext = info.context
45
- node_schema = registry.schema.get_node_schema(name=str(data.kind), branch=context.branch.name, duplicate=False)
45
+ graphql_context: GraphqlContext = info.context
46
+ node_schema = registry.schema.get_node_schema(
47
+ name=str(data.kind), branch=graphql_context.branch.name, duplicate=False
48
+ )
46
49
  target_attribute = node_schema.get_attribute(name=str(data.attribute))
47
50
  if (
48
51
  not target_attribute.computed_attribute
@@ -50,20 +53,20 @@ class UpdateComputedAttribute(Mutation):
50
53
  ):
51
54
  raise ValidationError(input_value=f"{node_schema.kind}.{target_attribute.name} is not a computed attribute")
52
55
 
53
- context.active_permissions.raise_for_permission(
56
+ graphql_context.active_permissions.raise_for_permission(
54
57
  permission=ObjectPermission(
55
58
  namespace=node_schema.namespace,
56
59
  name=node_schema.name,
57
60
  action=PermissionAction.UPDATE.value,
58
61
  decision=PermissionDecision.ALLOW_DEFAULT.value
59
- if context.branch.name == registry.default_branch
62
+ if graphql_context.branch.name == registry.default_branch
60
63
  else PermissionDecision.ALLOW_OTHER.value,
61
64
  )
62
65
  )
63
66
 
64
67
  if not (
65
68
  target_node := await NodeManager.get_one(
66
- db=context.db, kind=node_schema.kind, id=str(data.id), branch=context.branch
69
+ db=graphql_context.db, kind=node_schema.kind, id=str(data.id), branch=graphql_context.branch
67
70
  )
68
71
  ):
69
72
  raise NodeNotFoundError(
@@ -81,24 +84,27 @@ class UpdateComputedAttribute(Mutation):
81
84
  )
82
85
  if attribute_field.value != str(data.value):
83
86
  attribute_field.value = str(data.value)
84
- async with context.db.start_transaction() as dbt:
87
+ async with graphql_context.db.start_transaction() as dbt:
85
88
  await target_node.save(db=dbt, fields=[str(data.attribute)])
86
89
 
87
90
  log_data = get_log_data()
88
91
  request_id = log_data.get("request_id", "")
89
92
 
90
- graphql_payload = await target_node.to_graphql(db=context.db, filter_sensitive=True)
91
-
92
93
  event = NodeMutatedEvent(
93
- branch=context.branch.name,
94
94
  kind=node_schema.kind,
95
95
  node_id=target_node.get_id(),
96
- data=graphql_payload,
96
+ data=target_node.node_changelog.model_dump(),
97
97
  fields=[str(data.attribute)],
98
98
  action=MutationAction.UPDATED,
99
- meta=EventMeta(initiator_id=WORKER_IDENTITY, request_id=request_id),
99
+ meta=EventMeta(
100
+ context=graphql_context.get_context(),
101
+ initiator_id=WORKER_IDENTITY,
102
+ request_id=request_id,
103
+ account_id=graphql_context.active_account_session.account_id,
104
+ branch=graphql_context.branch,
105
+ ),
100
106
  )
101
- await context.active_service.event.send(event=event)
107
+ await graphql_context.active_service.event.send(event=event)
102
108
 
103
109
  result: dict[str, Any] = {"ok": True}
104
110
 
@@ -5,9 +5,13 @@ from graphql import GraphQLResolveInfo
5
5
 
6
6
  from infrahub.core import registry
7
7
  from infrahub.core.diff.coordinator import DiffCoordinator
8
+ from infrahub.core.diff.model.path import NameTrackingId
8
9
  from infrahub.core.diff.models import RequestDiffUpdate
10
+ from infrahub.core.diff.repository.repository import DiffRepository
11
+ from infrahub.core.timestamp import Timestamp
9
12
  from infrahub.database import retry_db_transaction
10
13
  from infrahub.dependencies.registry import get_component_registry
14
+ from infrahub.exceptions import ValidationError
11
15
  from infrahub.workflows.catalogue import DIFF_UPDATE
12
16
 
13
17
  if TYPE_CHECKING:
@@ -32,21 +36,43 @@ class DiffUpdateMutation(Mutation):
32
36
  @retry_db_transaction(name="diff_update")
33
37
  async def mutate(
34
38
  cls,
35
- root: dict, # pylint: disable=unused-argument
39
+ root: dict, # noqa: ARG003
36
40
  info: GraphQLResolveInfo,
37
41
  data: DiffUpdateInput,
38
42
  ) -> dict[str, bool]:
39
- context: GraphqlContext = info.context
43
+ graphql_context: GraphqlContext = info.context
40
44
 
41
45
  from_timestamp_str = DateTime.serialize(data.from_time) if data.from_time else None
42
46
  to_timestamp_str = DateTime.serialize(data.to_time) if data.to_time else None
43
- if data.wait_for_completion is True:
44
- component_registry = get_component_registry()
45
- base_branch = await registry.get_branch(db=context.db, branch=registry.default_branch)
46
- diff_branch = await registry.get_branch(db=context.db, branch=data.branch)
47
+ if (data.from_time or data.to_time) and not data.name:
48
+ raise ValidationError("diff with specified time range requires a name")
49
+
50
+ component_registry = get_component_registry()
51
+ base_branch = await registry.get_branch(db=graphql_context.db, branch=registry.default_branch)
52
+ diff_branch = await registry.get_branch(db=graphql_context.db, branch=data.branch)
53
+ diff_repository = await component_registry.get_component(
54
+ DiffRepository, db=graphql_context.db, branch=diff_branch
55
+ )
47
56
 
57
+ tracking_id = NameTrackingId(name=data.name)
58
+ existing_diffs_metatdatas = await diff_repository.get_roots_metadata(
59
+ diff_branch_names=[diff_branch.name], base_branch_names=[base_branch.name], tracking_id=tracking_id
60
+ )
61
+ if existing_diffs_metatdatas:
62
+ metadata = existing_diffs_metatdatas[0]
63
+ from_time = Timestamp(from_timestamp_str) if from_timestamp_str else None
64
+ to_time = Timestamp(to_timestamp_str) if to_timestamp_str else None
65
+ branched_from_timestamp = Timestamp(diff_branch.get_branched_from())
66
+ if from_time and from_time > metadata.from_time:
67
+ raise ValidationError(f"from_time must be null or less than or equal to {metadata.from_time}")
68
+ if from_time and from_time < branched_from_timestamp:
69
+ raise ValidationError(f"from_time must be null or greater than or equal to {branched_from_timestamp}")
70
+ if to_time and to_time < metadata.to_time:
71
+ raise ValidationError(f"to_time must be null or greater than or equal to {metadata.to_time}")
72
+
73
+ if data.wait_for_completion is True:
48
74
  diff_coordinator = await component_registry.get_component(
49
- DiffCoordinator, db=context.db, branch=diff_branch
75
+ DiffCoordinator, db=graphql_context.db, branch=diff_branch
50
76
  )
51
77
  await diff_coordinator.run_update(
52
78
  base_branch=base_branch,
@@ -64,7 +90,9 @@ class DiffUpdateMutation(Mutation):
64
90
  from_time=from_timestamp_str,
65
91
  to_time=to_timestamp_str,
66
92
  )
67
- if context.service:
68
- await context.service.workflow.submit_workflow(workflow=DIFF_UPDATE, parameters={"model": model})
93
+ if graphql_context.service:
94
+ await graphql_context.service.workflow.submit_workflow(
95
+ workflow=DIFF_UPDATE, context=graphql_context.get_context(), parameters={"model": model}
96
+ )
69
97
 
70
98
  return {"ok": True}
@@ -19,9 +19,6 @@ if TYPE_CHECKING:
19
19
  from ..initialization import GraphqlContext
20
20
 
21
21
 
22
- # pylint: disable=unused-argument
23
-
24
-
25
22
  class ResolveDiffConflictInput(InputObjectType):
26
23
  conflict_id = InputField(String(required=True), description="ID of the diff conflict to resolve")
27
24
  selected_branch = InputField(
@@ -39,14 +36,16 @@ class ResolveDiffConflict(Mutation):
39
36
  @retry_db_transaction(name="resolve_diff_conflict")
40
37
  async def mutate(
41
38
  cls,
42
- root: dict,
39
+ root: dict, # noqa: ARG003
43
40
  info: GraphQLResolveInfo,
44
41
  data: ResolveDiffConflictInput,
45
42
  ) -> ResolveDiffConflict:
46
- context: GraphqlContext = info.context
43
+ graphql_context: GraphqlContext = info.context
47
44
 
48
45
  component_registry = get_component_registry()
49
- diff_repo = await component_registry.get_component(DiffRepository, db=context.db, branch=context.branch)
46
+ diff_repo = await component_registry.get_component(
47
+ DiffRepository, db=graphql_context.db, branch=graphql_context.branch
48
+ )
50
49
 
51
50
  selection = ConflictSelection(data.selected_branch.value) if data.selected_branch else None
52
51
  conflict = await diff_repo.get_conflict_by_id(conflict_id=data.conflict_id)
@@ -55,7 +54,9 @@ class ResolveDiffConflict(Mutation):
55
54
  await diff_repo.update_conflict_by_id(conflict_id=data.conflict_id, selection=selection)
56
55
 
57
56
  core_data_checks = await NodeManager.query(
58
- db=context.db, schema=InfrahubKind.DATACHECK, filters={"enriched_conflict_id__value": data.conflict_id}
57
+ db=graphql_context.db,
58
+ schema=InfrahubKind.DATACHECK,
59
+ filters={"enriched_conflict_id__value": data.conflict_id},
59
60
  )
60
61
  if not core_data_checks:
61
62
  return cls(ok=True)
@@ -67,5 +68,5 @@ class ResolveDiffConflict(Mutation):
67
68
  keep_branch = None
68
69
  for cdc in core_data_checks:
69
70
  cdc.keep_branch.value = keep_branch
70
- await cdc.save(db=context.db)
71
+ await cdc.save(db=graphql_context.db)
71
72
  return cls(ok=True)
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
19
19
 
20
20
  class InfrahubGraphQLQueryMutation(InfrahubMutationMixin, Mutation):
21
21
  @classmethod
22
- def __init_subclass_with_meta__( # pylint: disable=arguments-differ
22
+ def __init_subclass_with_meta__(
23
23
  cls, schema: NodeSchema, _meta: Optional[Any] = None, **options: dict[str, Any]
24
24
  ) -> None:
25
25
  # Make sure schema is a valid NodeSchema Node Class
@@ -34,20 +34,24 @@ class InfrahubGraphQLQueryMutation(InfrahubMutationMixin, Mutation):
34
34
 
35
35
  @classmethod
36
36
  async def extract_query_info(
37
- cls, info: GraphQLResolveInfo, data: InputObjectType, branch: Branch
37
+ cls, info: GraphQLResolveInfo, data: InputObjectType, branch: Branch, db: InfrahubDatabase
38
38
  ) -> dict[str, Any]:
39
39
  query_value = data.get("query", {}).get("value", None)
40
40
  if query_value is None:
41
41
  return {}
42
42
 
43
43
  query_info = {}
44
- analyzer = InfrahubGraphQLQueryAnalyzer(query=query_value, schema=info.schema, branch=branch)
44
+ schema_branch = db.schema.get_schema_branch(name=branch.name)
45
+
46
+ analyzer = InfrahubGraphQLQueryAnalyzer(
47
+ query=query_value, schema=info.schema, branch=branch, schema_branch=schema_branch
48
+ )
45
49
 
46
50
  valid, errors = analyzer.is_valid
47
51
  if not valid:
48
52
  raise ValueError(f"Query is not valid, {str(errors)}")
49
53
 
50
- query_info["models"] = {"value": sorted(list(await analyzer.get_models_in_use(types=info.context.types)))}
54
+ query_info["models"] = {"value": analyzer.query_report.impacted_models}
51
55
  query_info["depth"] = {"value": await analyzer.calculate_depth()}
52
56
  query_info["height"] = {"value": await analyzer.calculate_height()}
53
57
  query_info["operations"] = {
@@ -63,11 +67,13 @@ class InfrahubGraphQLQueryMutation(InfrahubMutationMixin, Mutation):
63
67
  info: GraphQLResolveInfo,
64
68
  data: InputObjectType,
65
69
  branch: Branch,
66
- database: Optional[InfrahubDatabase] = None,
70
+ database: Optional[InfrahubDatabase] = None, # noqa: ARG003
67
71
  ) -> tuple[Node, Self]:
68
- context: GraphqlContext = info.context
72
+ graphql_context: GraphqlContext = info.context
69
73
 
70
- data.update(await cls.extract_query_info(info=info, data=data, branch=context.branch))
74
+ data.update(
75
+ await cls.extract_query_info(info=info, data=data, branch=graphql_context.branch, db=graphql_context.db)
76
+ )
71
77
 
72
78
  obj, result = await super().mutate_create(info=info, data=data, branch=branch)
73
79
 
@@ -79,12 +85,14 @@ class InfrahubGraphQLQueryMutation(InfrahubMutationMixin, Mutation):
79
85
  info: GraphQLResolveInfo,
80
86
  data: InputObjectType,
81
87
  branch: Branch,
82
- database: Optional[InfrahubDatabase] = None,
83
- node: Optional[Node] = None,
88
+ database: Optional[InfrahubDatabase] = None, # noqa: ARG003
89
+ node: Optional[Node] = None, # noqa: ARG003
84
90
  ) -> tuple[Node, Self]:
85
- context: GraphqlContext = info.context
91
+ graphql_context: GraphqlContext = info.context
86
92
 
87
- data.update(await cls.extract_query_info(info=info, data=data, branch=context.branch))
93
+ data.update(
94
+ await cls.extract_query_info(info=info, data=data, branch=graphql_context.branch, db=graphql_context.db)
95
+ )
88
96
 
89
97
  obj, result = await super().mutate_update(info=info, data=data, branch=branch)
90
98
 
@@ -53,7 +53,7 @@ async def validate_namespace(
53
53
 
54
54
  class InfrahubIPNamespaceMutation(InfrahubMutationMixin, Mutation):
55
55
  @classmethod
56
- def __init_subclass_with_meta__( # pylint: disable=arguments-differ
56
+ def __init_subclass_with_meta__(
57
57
  cls,
58
58
  schema: NodeSchema,
59
59
  _meta: Optional[Any] = None,
@@ -84,7 +84,7 @@ class InfrahubIPNamespaceMutation(InfrahubMutationMixin, Mutation):
84
84
 
85
85
  class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
86
86
  @classmethod
87
- def __init_subclass_with_meta__( # pylint: disable=arguments-differ
87
+ def __init_subclass_with_meta__(
88
88
  cls,
89
89
  schema: NodeSchema,
90
90
  _meta: Optional[Any] = None,
@@ -132,8 +132,8 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
132
132
  branch: Branch,
133
133
  database: Optional[InfrahubDatabase] = None,
134
134
  ) -> tuple[Node, Self]:
135
- context: GraphqlContext = info.context
136
- db = database or context.db
135
+ graphql_context: GraphqlContext = info.context
136
+ db = database or graphql_context.db
137
137
  ip_address = ipaddress.ip_interface(data["address"]["value"])
138
138
  namespace_id = await validate_namespace(db=db, branch=branch, data=data)
139
139
 
@@ -179,8 +179,8 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
179
179
  database: Optional[InfrahubDatabase] = None,
180
180
  node: Optional[Node] = None,
181
181
  ) -> tuple[Node, Self]:
182
- context: GraphqlContext = info.context
183
- db = database or context.db
182
+ graphql_context: GraphqlContext = info.context
183
+ db = database or graphql_context.db
184
184
 
185
185
  address = node or await NodeManager.get_one_by_id_or_default_filter(
186
186
  db=db,
@@ -219,8 +219,8 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
219
219
  node_getters: list[MutationNodeGetterInterface],
220
220
  database: Optional[InfrahubDatabase] = None,
221
221
  ) -> tuple[Node, Self, bool]:
222
- context: GraphqlContext = info.context
223
- db = database or context.db
222
+ graphql_context: GraphqlContext = info.context
223
+ db = database or graphql_context.db
224
224
 
225
225
  await validate_namespace(db=db, branch=branch, data=data)
226
226
  prefix, result, created = await super().mutate_upsert(
@@ -241,7 +241,7 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
241
241
 
242
242
  class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
243
243
  @classmethod
244
- def __init_subclass_with_meta__( # pylint: disable=arguments-differ
244
+ def __init_subclass_with_meta__(
245
245
  cls,
246
246
  schema: NodeSchema,
247
247
  _meta: Optional[Any] = None,
@@ -286,8 +286,8 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
286
286
  branch: Branch,
287
287
  database: Optional[InfrahubDatabase] = None,
288
288
  ) -> tuple[Node, Self]:
289
- context: GraphqlContext = info.context
290
- db = database or context.db
289
+ graphql_context: GraphqlContext = info.context
290
+ db = database or graphql_context.db
291
291
  namespace_id = await validate_namespace(db=db, branch=branch, data=data)
292
292
 
293
293
  async with db.start_transaction() as dbt:
@@ -330,8 +330,8 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
330
330
  database: Optional[InfrahubDatabase] = None,
331
331
  node: Optional[Node] = None,
332
332
  ) -> tuple[Node, Self]:
333
- context: GraphqlContext = info.context
334
- db = database or context.db
333
+ graphql_context: GraphqlContext = info.context
334
+ db = database or graphql_context.db
335
335
 
336
336
  prefix = node or await NodeManager.get_one_by_id_or_default_filter(
337
337
  db=db,
@@ -369,8 +369,8 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
369
369
  node_getters: list[MutationNodeGetterInterface],
370
370
  database: Optional[InfrahubDatabase] = None,
371
371
  ):
372
- context: GraphqlContext = info.context
373
- db = database or context.db
372
+ graphql_context: GraphqlContext = info.context
373
+ db = database or graphql_context.db
374
374
 
375
375
  await validate_namespace(db=db, branch=branch, data=data)
376
376
  prefix, result, created = await super().mutate_upsert(
@@ -403,17 +403,19 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
403
403
  data: InputObjectType,
404
404
  branch: Branch,
405
405
  ) -> tuple[Node, Self]:
406
- context: GraphqlContext = info.context
407
- db = context.db
406
+ graphql_context: GraphqlContext = info.context
407
+ db = graphql_context.db
408
408
 
409
- prefix = await NodeManager.get_one(data.get("id"), context.db, branch=branch, prefetch_relationships=True)
409
+ prefix = await NodeManager.get_one(
410
+ data.get("id"), graphql_context.db, branch=branch, prefetch_relationships=True
411
+ )
410
412
  if not prefix:
411
413
  raise NodeNotFoundError(branch, cls._meta.schema.kind, data.get("id"))
412
414
 
413
415
  namespace_rels = await prefix.ip_namespace.get_relationships(db=db)
414
416
  namespace_id = namespace_rels[0].peer_id
415
417
  try:
416
- async with context.db.start_transaction() as dbt:
418
+ async with graphql_context.db.start_transaction() as dbt:
417
419
  if lock_name := cls._get_lock_name(namespace_id, branch):
418
420
  async with InfrahubMultiLock(lock_registry=lock.registry, locks=[lock_name]):
419
421
  reconciled_prefix = await cls._reconcile_prefix(