infrahub-server 1.1.6__py3-none-any.whl → 1.2.0b1__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 (407) 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} +5 -3
  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/models.py +1 -1
  16. infrahub/computed_attribute/tasks.py +64 -17
  17. infrahub/computed_attribute/triggers.py +90 -0
  18. infrahub/config.py +1 -1
  19. infrahub/context.py +39 -0
  20. infrahub/core/account.py +5 -8
  21. infrahub/core/attribute.py +54 -22
  22. infrahub/core/branch/models.py +4 -4
  23. infrahub/core/branch/tasks.py +137 -129
  24. infrahub/core/changelog/__init__.py +0 -0
  25. infrahub/core/changelog/diff.py +283 -0
  26. infrahub/core/changelog/models.py +499 -0
  27. infrahub/core/constants/__init__.py +43 -2
  28. infrahub/core/constants/infrahubkind.py +1 -0
  29. infrahub/core/constants/schema.py +2 -0
  30. infrahub/core/diff/combiner.py +12 -8
  31. infrahub/core/diff/coordinator.py +49 -70
  32. infrahub/core/diff/data_check_synchronizer.py +86 -7
  33. infrahub/core/diff/enricher/aggregated.py +3 -3
  34. infrahub/core/diff/enricher/cardinality_one.py +7 -7
  35. infrahub/core/diff/enricher/hierarchy.py +22 -7
  36. infrahub/core/diff/enricher/labels.py +19 -4
  37. infrahub/core/diff/enricher/path_identifier.py +7 -9
  38. infrahub/core/diff/enricher/summary_counts.py +3 -1
  39. infrahub/core/diff/merger/merger.py +8 -4
  40. infrahub/core/diff/model/path.py +76 -35
  41. infrahub/core/diff/parent_node_adder.py +78 -0
  42. infrahub/core/diff/payload_builder.py +13 -2
  43. infrahub/core/diff/query/all_conflicts.py +6 -3
  44. infrahub/core/diff/query/artifact.py +1 -1
  45. infrahub/core/diff/query/delete_query.py +1 -1
  46. infrahub/core/diff/query/diff_get.py +3 -2
  47. infrahub/core/diff/query/diff_summary.py +1 -1
  48. infrahub/core/diff/query/field_specifiers.py +3 -1
  49. infrahub/core/diff/query/field_summary.py +3 -2
  50. infrahub/core/diff/query/filters.py +14 -3
  51. infrahub/core/diff/query/get_conflict_query.py +1 -1
  52. infrahub/core/diff/query/has_conflicts_query.py +6 -3
  53. infrahub/core/diff/query/merge.py +3 -3
  54. infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
  55. infrahub/core/diff/query/roots_metadata.py +9 -2
  56. infrahub/core/diff/query/save.py +233 -142
  57. infrahub/core/diff/query/summary_counts_enricher.py +267 -0
  58. infrahub/core/diff/query/time_range_query.py +3 -2
  59. infrahub/core/diff/query/update_conflict_query.py +1 -1
  60. infrahub/core/diff/query_parser.py +49 -24
  61. infrahub/core/diff/repository/deserializer.py +32 -28
  62. infrahub/core/diff/repository/repository.py +215 -41
  63. infrahub/core/diff/tasks.py +13 -12
  64. infrahub/core/enums.py +1 -1
  65. infrahub/core/graph/__init__.py +1 -1
  66. infrahub/core/graph/index.py +3 -0
  67. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  68. infrahub/core/ipam/reconciler.py +1 -1
  69. infrahub/core/ipam/tasks.py +2 -3
  70. infrahub/core/manager.py +20 -15
  71. infrahub/core/merge.py +5 -2
  72. infrahub/core/migrations/graph/__init__.py +4 -0
  73. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  74. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  75. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  76. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  77. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  78. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  79. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  80. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  81. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  82. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  83. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  84. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  85. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  86. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  87. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  88. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  89. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
  90. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
  91. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
  92. infrahub/core/migrations/graph/m020_add_generate_template_attr.py +48 -0
  93. infrahub/core/migrations/query/attribute_add.py +1 -1
  94. infrahub/core/migrations/query/attribute_rename.py +1 -1
  95. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  96. infrahub/core/migrations/query/node_duplicate.py +39 -19
  97. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  98. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  99. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  100. infrahub/core/migrations/schema/node_remove.py +27 -13
  101. infrahub/core/migrations/schema/tasks.py +5 -5
  102. infrahub/core/migrations/shared.py +4 -4
  103. infrahub/core/models.py +7 -8
  104. infrahub/core/node/__init__.py +170 -46
  105. infrahub/core/node/base.py +1 -1
  106. infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
  107. infrahub/core/node/delete_validator.py +4 -4
  108. infrahub/core/node/ipam.py +13 -8
  109. infrahub/core/node/permissions.py +4 -0
  110. infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
  111. infrahub/core/node/standard.py +3 -5
  112. infrahub/core/property.py +1 -1
  113. infrahub/core/protocols.py +6 -0
  114. infrahub/core/protocols_base.py +4 -2
  115. infrahub/core/query/__init__.py +2 -5
  116. infrahub/core/query/attribute.py +9 -9
  117. infrahub/core/query/branch.py +5 -5
  118. infrahub/core/query/delete.py +1 -1
  119. infrahub/core/query/diff.py +45 -7
  120. infrahub/core/query/ipam.py +4 -4
  121. infrahub/core/query/node.py +19 -14
  122. infrahub/core/query/relationship.py +213 -26
  123. infrahub/core/query/resource_manager.py +13 -11
  124. infrahub/core/query/standard_node.py +6 -6
  125. infrahub/core/query/task.py +3 -3
  126. infrahub/core/query/task_log.py +1 -1
  127. infrahub/core/query/utils.py +5 -5
  128. infrahub/core/registry.py +0 -2
  129. infrahub/core/relationship/constraints/count.py +1 -1
  130. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  131. infrahub/core/relationship/model.py +76 -38
  132. infrahub/core/schema/__init__.py +6 -4
  133. infrahub/core/schema/attribute_schema.py +8 -0
  134. infrahub/core/schema/basenode_schema.py +13 -3
  135. infrahub/core/schema/definitions/core/__init__.py +153 -0
  136. infrahub/core/schema/definitions/core/account.py +168 -0
  137. infrahub/core/schema/definitions/core/artifact.py +127 -0
  138. infrahub/core/schema/definitions/core/builtin.py +21 -0
  139. infrahub/core/schema/definitions/core/check.py +60 -0
  140. infrahub/core/schema/definitions/core/generator.py +96 -0
  141. infrahub/core/schema/definitions/core/graphql_query.py +77 -0
  142. infrahub/core/schema/definitions/core/group.py +105 -0
  143. infrahub/core/schema/definitions/core/ipam.py +252 -0
  144. infrahub/core/schema/definitions/core/lineage.py +17 -0
  145. infrahub/core/schema/definitions/core/menu.py +46 -0
  146. infrahub/core/schema/definitions/core/permission.py +161 -0
  147. infrahub/core/schema/definitions/core/profile.py +29 -0
  148. infrahub/core/schema/definitions/core/propose_change.py +88 -0
  149. infrahub/core/schema/definitions/core/propose_change_comment.py +188 -0
  150. infrahub/core/schema/definitions/core/propose_change_validator.py +326 -0
  151. infrahub/core/schema/definitions/core/repository.py +280 -0
  152. infrahub/core/schema/definitions/core/resource_pool.py +180 -0
  153. infrahub/core/schema/definitions/core/template.py +12 -0
  154. infrahub/core/schema/definitions/core/transform.py +87 -0
  155. infrahub/core/schema/definitions/core/webhook.py +108 -0
  156. infrahub/core/schema/definitions/internal.py +16 -0
  157. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  158. infrahub/core/schema/generated/node_schema.py +5 -0
  159. infrahub/core/schema/generic_schema.py +5 -1
  160. infrahub/core/schema/manager.py +45 -42
  161. infrahub/core/schema/node_schema.py +4 -0
  162. infrahub/core/schema/profile_schema.py +4 -0
  163. infrahub/core/schema/relationship_schema.py +10 -2
  164. infrahub/core/schema/schema_branch.py +260 -16
  165. infrahub/core/schema/template_schema.py +36 -0
  166. infrahub/core/task/user_task.py +7 -5
  167. infrahub/core/timestamp.py +3 -3
  168. infrahub/core/utils.py +3 -2
  169. infrahub/core/validators/attribute/choices.py +1 -1
  170. infrahub/core/validators/attribute/enum.py +1 -1
  171. infrahub/core/validators/attribute/kind.py +1 -1
  172. infrahub/core/validators/attribute/length.py +1 -1
  173. infrahub/core/validators/attribute/optional.py +1 -1
  174. infrahub/core/validators/attribute/regex.py +1 -1
  175. infrahub/core/validators/attribute/unique.py +1 -1
  176. infrahub/core/validators/checks_runner.py +37 -0
  177. infrahub/core/validators/node/generate_profile.py +1 -1
  178. infrahub/core/validators/node/hierarchy.py +1 -1
  179. infrahub/core/validators/query.py +1 -1
  180. infrahub/core/validators/relationship/count.py +1 -1
  181. infrahub/core/validators/relationship/optional.py +1 -1
  182. infrahub/core/validators/relationship/peer.py +1 -1
  183. infrahub/core/validators/tasks.py +8 -6
  184. infrahub/core/validators/uniqueness/query.py +20 -17
  185. infrahub/database/__init__.py +16 -2
  186. infrahub/database/memgraph.py +1 -1
  187. infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
  188. infrahub/dependencies/builder/diff/combiner.py +1 -1
  189. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  190. infrahub/dependencies/builder/diff/coordinator.py +0 -2
  191. infrahub/dependencies/builder/diff/deserializer.py +4 -2
  192. infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
  193. infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
  194. infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
  195. infrahub/events/artifact_action.py +76 -0
  196. infrahub/events/branch_action.py +50 -21
  197. infrahub/events/group_action.py +117 -0
  198. infrahub/events/models.py +164 -51
  199. infrahub/events/node_action.py +70 -8
  200. infrahub/events/repository_action.py +8 -8
  201. infrahub/events/schema_action.py +21 -8
  202. infrahub/exceptions.py +9 -0
  203. infrahub/generators/models.py +1 -0
  204. infrahub/generators/tasks.py +34 -15
  205. infrahub/git/base.py +3 -5
  206. infrahub/git/constants.py +0 -1
  207. infrahub/git/integrator.py +60 -36
  208. infrahub/git/models.py +80 -1
  209. infrahub/git/repository.py +7 -8
  210. infrahub/git/tasks.py +432 -112
  211. infrahub/git_credential/helper.py +2 -3
  212. infrahub/graphql/analyzer.py +572 -11
  213. infrahub/graphql/app.py +34 -26
  214. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  215. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  216. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  217. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  218. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  219. infrahub/graphql/context.py +33 -0
  220. infrahub/graphql/enums.py +1 -1
  221. infrahub/graphql/initialization.py +5 -1
  222. infrahub/graphql/loaders/node.py +2 -2
  223. infrahub/graphql/manager.py +63 -63
  224. infrahub/graphql/mutations/account.py +20 -13
  225. infrahub/graphql/mutations/artifact_definition.py +16 -12
  226. infrahub/graphql/mutations/branch.py +86 -40
  227. infrahub/graphql/mutations/computed_attribute.py +24 -13
  228. infrahub/graphql/mutations/diff.py +54 -14
  229. infrahub/graphql/mutations/diff_conflict.py +14 -8
  230. infrahub/graphql/mutations/generator.py +83 -0
  231. infrahub/graphql/mutations/graphql_query.py +19 -11
  232. infrahub/graphql/mutations/ipam.py +25 -23
  233. infrahub/graphql/mutations/main.py +243 -50
  234. infrahub/graphql/mutations/menu.py +10 -10
  235. infrahub/graphql/mutations/proposed_change.py +36 -28
  236. infrahub/graphql/mutations/relationship.py +343 -104
  237. infrahub/graphql/mutations/repository.py +41 -35
  238. infrahub/graphql/mutations/resource_manager.py +26 -26
  239. infrahub/graphql/mutations/schema.py +66 -33
  240. infrahub/graphql/mutations/tasks.py +16 -10
  241. infrahub/graphql/parser.py +1 -1
  242. infrahub/graphql/permissions.py +3 -10
  243. infrahub/graphql/queries/account.py +22 -18
  244. infrahub/graphql/queries/branch.py +6 -4
  245. infrahub/graphql/queries/diff/tree.py +63 -52
  246. infrahub/graphql/queries/event.py +115 -0
  247. infrahub/graphql/queries/internal.py +3 -3
  248. infrahub/graphql/queries/ipam.py +23 -18
  249. infrahub/graphql/queries/relationship.py +11 -10
  250. infrahub/graphql/queries/resource_manager.py +43 -27
  251. infrahub/graphql/queries/search.py +9 -8
  252. infrahub/graphql/queries/status.py +12 -9
  253. infrahub/graphql/queries/task.py +11 -9
  254. infrahub/graphql/resolvers/resolver.py +69 -43
  255. infrahub/graphql/resolvers/single_relationship.py +16 -10
  256. infrahub/graphql/schema.py +4 -0
  257. infrahub/graphql/subscription/__init__.py +1 -1
  258. infrahub/graphql/subscription/events.py +1 -1
  259. infrahub/graphql/subscription/graphql_query.py +8 -8
  260. infrahub/graphql/types/branch.py +2 -2
  261. infrahub/graphql/types/common.py +6 -1
  262. infrahub/graphql/types/context.py +12 -0
  263. infrahub/graphql/types/enums.py +2 -0
  264. infrahub/graphql/types/event.py +158 -0
  265. infrahub/graphql/types/interface.py +2 -2
  266. infrahub/graphql/types/node.py +3 -3
  267. infrahub/graphql/types/permission.py +2 -2
  268. infrahub/graphql/types/relationship.py +3 -3
  269. infrahub/graphql/types/standard_node.py +9 -11
  270. infrahub/graphql/utils.py +28 -182
  271. infrahub/groups/tasks.py +2 -3
  272. infrahub/lock.py +21 -21
  273. infrahub/menu/generator.py +0 -1
  274. infrahub/menu/menu.py +116 -138
  275. infrahub/menu/models.py +4 -4
  276. infrahub/message_bus/__init__.py +11 -13
  277. infrahub/message_bus/messages/__init__.py +0 -14
  278. infrahub/message_bus/messages/check_generator_run.py +1 -3
  279. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  280. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  281. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  282. infrahub/message_bus/messages/send_echo_request.py +1 -1
  283. infrahub/message_bus/operations/__init__.py +4 -13
  284. infrahub/message_bus/operations/check/__init__.py +2 -2
  285. infrahub/message_bus/operations/check/generator.py +1 -3
  286. infrahub/message_bus/operations/event/branch.py +7 -3
  287. infrahub/message_bus/operations/event/schema.py +1 -1
  288. infrahub/message_bus/operations/event/worker.py +0 -3
  289. infrahub/message_bus/operations/finalize/validator.py +1 -1
  290. infrahub/message_bus/operations/git/file.py +2 -2
  291. infrahub/message_bus/operations/git/repository.py +1 -1
  292. infrahub/message_bus/operations/requests/__init__.py +0 -4
  293. infrahub/message_bus/operations/requests/generator_definition.py +2 -4
  294. infrahub/message_bus/operations/requests/proposed_change.py +37 -20
  295. infrahub/message_bus/operations/send/echo.py +1 -1
  296. infrahub/message_bus/types.py +1 -1
  297. infrahub/permissions/__init__.py +2 -1
  298. infrahub/permissions/globals.py +15 -0
  299. infrahub/permissions/types.py +26 -0
  300. infrahub/pools/prefix.py +29 -165
  301. infrahub/prefect_server/__init__.py +0 -0
  302. infrahub/prefect_server/app.py +18 -0
  303. infrahub/prefect_server/database.py +20 -0
  304. infrahub/prefect_server/events.py +28 -0
  305. infrahub/prefect_server/models.py +46 -0
  306. infrahub/proposed_change/models.py +18 -1
  307. infrahub/proposed_change/tasks.py +195 -53
  308. infrahub/pytest_plugin.py +4 -4
  309. infrahub/server.py +13 -12
  310. infrahub/services/__init__.py +148 -63
  311. infrahub/services/adapters/cache/__init__.py +11 -11
  312. infrahub/services/adapters/cache/nats.py +42 -25
  313. infrahub/services/adapters/cache/redis.py +3 -11
  314. infrahub/services/adapters/event/__init__.py +10 -18
  315. infrahub/services/adapters/http/__init__.py +0 -5
  316. infrahub/services/adapters/http/httpx.py +22 -15
  317. infrahub/services/adapters/message_bus/__init__.py +25 -8
  318. infrahub/services/adapters/message_bus/local.py +9 -7
  319. infrahub/services/adapters/message_bus/nats.py +14 -8
  320. infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
  321. infrahub/services/adapters/workflow/__init__.py +11 -8
  322. infrahub/services/adapters/workflow/local.py +27 -6
  323. infrahub/services/adapters/workflow/worker.py +23 -7
  324. infrahub/services/component.py +43 -40
  325. infrahub/services/protocols.py +7 -7
  326. infrahub/services/scheduler.py +30 -29
  327. infrahub/storage.py +2 -4
  328. infrahub/task_manager/constants.py +1 -1
  329. infrahub/task_manager/event.py +261 -0
  330. infrahub/task_manager/models.py +147 -3
  331. infrahub/task_manager/task.py +1 -1
  332. infrahub/tasks/artifact.py +19 -18
  333. infrahub/tasks/registry.py +1 -1
  334. infrahub/tasks/telemetry.py +13 -14
  335. infrahub/transformations/tasks.py +3 -5
  336. infrahub/trigger/__init__.py +0 -0
  337. infrahub/trigger/catalogue.py +16 -0
  338. infrahub/trigger/constants.py +9 -0
  339. infrahub/trigger/models.py +105 -0
  340. infrahub/trigger/tasks.py +91 -0
  341. infrahub/types.py +1 -1
  342. infrahub/utils.py +1 -1
  343. infrahub/webhook/constants.py +0 -2
  344. infrahub/webhook/models.py +161 -40
  345. infrahub/webhook/tasks.py +123 -202
  346. infrahub/webhook/triggers.py +27 -0
  347. infrahub/workers/infrahub_async.py +36 -25
  348. infrahub/workers/utils.py +63 -0
  349. infrahub/workflows/catalogue.py +71 -52
  350. infrahub/workflows/initialization.py +14 -8
  351. infrahub/workflows/models.py +28 -4
  352. infrahub/workflows/utils.py +1 -1
  353. infrahub_sdk/client.py +8 -0
  354. infrahub_sdk/ctl/branch.py +3 -2
  355. infrahub_sdk/ctl/check.py +3 -3
  356. infrahub_sdk/ctl/cli_commands.py +16 -11
  357. infrahub_sdk/ctl/exceptions.py +0 -6
  358. infrahub_sdk/ctl/exporter.py +1 -1
  359. infrahub_sdk/ctl/generator.py +5 -5
  360. infrahub_sdk/ctl/importer.py +3 -2
  361. infrahub_sdk/ctl/menu.py +1 -1
  362. infrahub_sdk/ctl/object.py +1 -1
  363. infrahub_sdk/ctl/repository.py +23 -15
  364. infrahub_sdk/ctl/schema.py +2 -2
  365. infrahub_sdk/ctl/utils.py +4 -19
  366. infrahub_sdk/ctl/validate.py +2 -1
  367. infrahub_sdk/exceptions.py +12 -0
  368. infrahub_sdk/generator.py +3 -0
  369. infrahub_sdk/node.py +4 -4
  370. infrahub_sdk/protocols.py +21 -8
  371. infrahub_sdk/schema/__init__.py +14 -2
  372. infrahub_sdk/schema/main.py +7 -0
  373. infrahub_sdk/task/__init__.py +1 -0
  374. infrahub_sdk/task/constants.py +3 -0
  375. infrahub_sdk/task/exceptions.py +25 -0
  376. infrahub_sdk/task/manager.py +545 -0
  377. infrahub_sdk/task/models.py +74 -0
  378. infrahub_sdk/timestamp.py +134 -33
  379. infrahub_sdk/utils.py +39 -1
  380. infrahub_sdk/yaml.py +2 -3
  381. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/METADATA +47 -12
  382. infrahub_server-1.2.0b1.dist-info/RECORD +725 -0
  383. infrahub_testcontainers/container.py +14 -6
  384. infrahub_testcontainers/docker-compose.test.yml +24 -5
  385. infrahub_testcontainers/haproxy.cfg +43 -0
  386. infrahub_testcontainers/helpers.py +85 -1
  387. infrahub/core/branch/constants.py +0 -2
  388. infrahub/core/schema/definitions/core.py +0 -2274
  389. infrahub/graphql/query.py +0 -52
  390. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  391. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  392. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  393. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  394. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  395. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  396. infrahub/message_bus/operations/check/repository.py +0 -293
  397. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  398. infrahub/message_bus/operations/requests/repository.py +0 -133
  399. infrahub/schema/constants.py +0 -1
  400. infrahub/schema/tasks.py +0 -76
  401. infrahub/services/adapters/database/__init__.py +0 -9
  402. infrahub_sdk/ctl/_file.py +0 -13
  403. infrahub_server-1.1.6.dist-info/RECORD +0 -681
  404. /infrahub/{schema → artifacts}/__init__.py +0 -0
  405. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/LICENSE.txt +0 -0
  406. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/WHEEL +0 -0
  407. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/entry_points.txt +0 -0
@@ -45,7 +45,7 @@ log = get_logger()
45
45
 
46
46
  class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
47
47
  @classmethod
48
- def __init_subclass_with_meta__(cls, schema: Optional[NodeSchema] = None, _meta=None, **options): # pylint: disable=arguments-differ
48
+ def __init_subclass_with_meta__(cls, schema: Optional[NodeSchema] = None, _meta=None, **options):
49
49
  # Make sure schema is a valid NodeSchema Node Class
50
50
  if not isinstance(schema, NodeSchema):
51
51
  raise ValueError(f"You need to pass a valid NodeSchema in '{cls.__name__}.Meta', received '{schema}'")
@@ -63,9 +63,9 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
63
63
  info: GraphQLResolveInfo,
64
64
  data: InputObjectType,
65
65
  branch: Branch,
66
- database: Optional[InfrahubDatabase] = None,
66
+ database: Optional[InfrahubDatabase] = None, # noqa: ARG003
67
67
  ):
68
- context: GraphqlContext = info.context
68
+ graphql_context: GraphqlContext = info.context
69
69
 
70
70
  cleanup_payload(data)
71
71
  # Create the object in the database
@@ -74,17 +74,17 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
74
74
 
75
75
  # First check the connectivity to the remote repository
76
76
  # If the connectivity is not good, we remove the repository to allow the user to add a new one
77
- if context.service:
77
+ if graphql_context.service:
78
78
  message = messages.GitRepositoryConnectivity(
79
79
  repository_name=obj.name.value,
80
80
  repository_location=obj.location.value,
81
81
  )
82
- response = await context.service.message_bus.rpc(
82
+ response = await graphql_context.service.message_bus.rpc(
83
83
  message=message, response_class=GitRepositoryConnectivityResponse
84
84
  )
85
85
 
86
86
  if response.data.success is False:
87
- await obj.delete(db=context.db)
87
+ await obj.delete(db=graphql_context.db)
88
88
  raise ValidationError(response.data.message)
89
89
 
90
90
  # If we are in the default branch, we set the sync status to Active
@@ -93,13 +93,13 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
93
93
  obj.internal_status.value = RepositoryInternalStatus.ACTIVE.value
94
94
  else:
95
95
  obj.internal_status.value = RepositoryInternalStatus.STAGING.value
96
- await obj.save(db=context.db)
96
+ await obj.save(db=graphql_context.db)
97
97
 
98
98
  # Create the new repository in the filesystem.
99
99
  log.info("create_repository", name=obj.name.value)
100
100
  authenticated_user = None
101
- if context.account_session and context.account_session.authenticated:
102
- authenticated_user = context.account_session.account_id
101
+ if graphql_context.account_session and graphql_context.account_session.authenticated:
102
+ authenticated_user = graphql_context.account_session.account_id
103
103
  if obj.get_kind() == InfrahubKind.READONLYREPOSITORY:
104
104
  obj = cast(CoreReadOnlyRepository, obj)
105
105
  model = GitRepositoryAddReadOnly(
@@ -112,9 +112,11 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
112
112
  internal_status=obj.internal_status.value,
113
113
  created_by=authenticated_user,
114
114
  )
115
- if context.service:
116
- await context.service.workflow.submit_workflow(
117
- workflow=GIT_REPOSITORY_ADD_READ_ONLY, parameters={"model": model}
115
+ if graphql_context.service:
116
+ await graphql_context.service.workflow.submit_workflow(
117
+ workflow=GIT_REPOSITORY_ADD_READ_ONLY,
118
+ context=graphql_context.get_context(),
119
+ parameters={"model": model},
118
120
  )
119
121
 
120
122
  else:
@@ -130,9 +132,11 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
130
132
  created_by=authenticated_user,
131
133
  )
132
134
 
133
- if context.service:
134
- await context.service.workflow.submit_workflow(
135
- workflow=GIT_REPOSITORY_ADD, parameters={"model": git_repo_add_model}
135
+ if graphql_context.service:
136
+ await graphql_context.service.workflow.submit_workflow(
137
+ workflow=GIT_REPOSITORY_ADD,
138
+ context=graphql_context.get_context(),
139
+ parameters={"model": git_repo_add_model},
136
140
  )
137
141
 
138
142
  # TODO Validate that the creation of the repository went as expected
@@ -145,15 +149,15 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
145
149
  info: GraphQLResolveInfo,
146
150
  data: InputObjectType,
147
151
  branch: Branch,
148
- database: Optional[InfrahubDatabase] = None,
152
+ database: Optional[InfrahubDatabase] = None, # noqa: ARG003
149
153
  node: Optional[Node] = None,
150
154
  ):
151
- context: GraphqlContext = info.context
155
+ graphql_context: GraphqlContext = info.context
152
156
 
153
157
  cleanup_payload(data)
154
158
  if not node:
155
159
  node: CoreReadOnlyRepository | CoreRepository = await NodeManager.get_one_by_id_or_default_filter(
156
- db=context.db,
160
+ db=graphql_context.db,
157
161
  kind=cls._meta.schema.kind,
158
162
  id=data.get("id"),
159
163
  branch=branch,
@@ -161,7 +165,7 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
161
165
  include_source=True,
162
166
  )
163
167
  if node.get_kind() != InfrahubKind.READONLYREPOSITORY:
164
- return await super().mutate_update(info, data, branch, database=context.db, node=node)
168
+ return await super().mutate_update(info, data, branch, database=graphql_context.db, node=node)
165
169
 
166
170
  node = cast(CoreReadOnlyRepository, node)
167
171
  current_commit = node.commit.value
@@ -173,7 +177,7 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
173
177
  if data.ref and data.ref.value:
174
178
  new_ref = data.ref.value
175
179
 
176
- obj, result = await super().mutate_update(info, data, branch, database=context.db, node=node)
180
+ obj, result = await super().mutate_update(info, data, branch, database=graphql_context.db, node=node)
177
181
  obj = cast(CoreReadOnlyRepository, obj)
178
182
 
179
183
  send_update_message = (new_commit and new_commit != current_commit) or (new_ref and new_ref != current_ref)
@@ -196,9 +200,11 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
196
200
  infrahub_branch_name=branch.name,
197
201
  infrahub_branch_id=str(branch.get_uuid()),
198
202
  )
199
- if context.service:
200
- await context.service.workflow.submit_workflow(
201
- workflow=GIT_REPOSITORIES_PULL_READ_ONLY, parameters={"model": model}
203
+ if graphql_context.service:
204
+ await graphql_context.service.workflow.submit_workflow(
205
+ workflow=GIT_REPOSITORIES_PULL_READ_ONLY,
206
+ context=graphql_context.get_context(),
207
+ parameters={"model": model},
202
208
  )
203
209
  return obj, result
204
210
 
@@ -226,15 +232,15 @@ class ProcessRepository(Mutation):
226
232
  @classmethod
227
233
  async def mutate(
228
234
  cls,
229
- root: dict, # pylint: disable=unused-argument
235
+ root: dict, # noqa: ARG003
230
236
  info: GraphQLResolveInfo,
231
237
  data: IdentifierInput,
232
238
  ) -> dict[str, bool]:
233
- context: GraphqlContext = info.context
234
- branch = context.branch
239
+ graphql_context: GraphqlContext = info.context
240
+ branch = graphql_context.branch
235
241
  repository_id = str(data.id)
236
242
  repo: CoreReadOnlyRepository | CoreRepository = await NodeManager.get_one_by_id_or_default_filter(
237
- db=context.db,
243
+ db=graphql_context.db,
238
244
  kind=InfrahubKind.GENERICREPOSITORY,
239
245
  id=str(data.id),
240
246
  branch=branch,
@@ -247,8 +253,8 @@ class ProcessRepository(Mutation):
247
253
  commit=str(repo.commit.value),
248
254
  infrahub_branch_name=branch.name,
249
255
  )
250
- workflow = await context.active_service.workflow.submit_workflow(
251
- workflow=GIT_REPOSITORIES_IMPORT_OBJECTS, parameters={"model": model}
256
+ workflow = await graphql_context.active_service.workflow.submit_workflow(
257
+ workflow=GIT_REPOSITORIES_IMPORT_OBJECTS, context=graphql_context.get_context(), parameters={"model": model}
252
258
  )
253
259
  task = {"id": workflow.id}
254
260
  return cls(ok=True, task=task)
@@ -264,15 +270,15 @@ class ValidateRepositoryConnectivity(Mutation):
264
270
  @classmethod
265
271
  async def mutate(
266
272
  cls,
267
- root: dict, # pylint: disable=unused-argument
273
+ root: dict, # noqa: ARG003
268
274
  info: GraphQLResolveInfo,
269
275
  data: IdentifierInput,
270
276
  ) -> dict[str, Any]:
271
- context: GraphqlContext = info.context
272
- branch = context.branch
277
+ graphql_context: GraphqlContext = info.context
278
+ branch = graphql_context.branch
273
279
  repository_id = str(data.id)
274
280
  repo: CoreReadOnlyRepository | CoreRepository = await NodeManager.get_one_by_id_or_default_filter(
275
- db=context.db,
281
+ db=graphql_context.db,
276
282
  kind=InfrahubKind.GENERICREPOSITORY,
277
283
  id=repository_id,
278
284
  branch=branch,
@@ -282,8 +288,8 @@ class ValidateRepositoryConnectivity(Mutation):
282
288
  repository_name=str(repo.name.value),
283
289
  repository_location=str(repo.location.value),
284
290
  )
285
- if context.service:
286
- response = await context.service.message_bus.rpc(
291
+ if graphql_context.service:
292
+ response = await graphql_context.service.message_bus.rpc(
287
293
  message=message, response_class=GitRepositoryConnectivityResponse
288
294
  )
289
295
 
@@ -61,11 +61,11 @@ class IPPrefixPoolGetResource(Mutation):
61
61
  @classmethod
62
62
  async def mutate(
63
63
  cls,
64
- root: dict, # pylint: disable=unused-argument
64
+ root: dict, # noqa: ARG003
65
65
  info: GraphQLResolveInfo,
66
66
  data: InputObjectType,
67
67
  ) -> Self:
68
- context: GraphqlContext = info.context
68
+ graphql_context: GraphqlContext = info.context
69
69
 
70
70
  member_type = data.get("member_type", None)
71
71
  allowed_member_types = [t.value for t in PrefixMemberType]
@@ -73,15 +73,15 @@ class IPPrefixPoolGetResource(Mutation):
73
73
  raise QueryValidationError(f"Invalid member_type value, allowed values are {allowed_member_types}")
74
74
 
75
75
  obj: CoreIPPrefixPool = await registry.manager.find_object( # type: ignore[assignment]
76
- db=context.db,
76
+ db=graphql_context.db,
77
77
  kind=InfrahubKind.IPPREFIXPOOL,
78
78
  id=data.get("id"),
79
79
  hfid=data.get("hfid"),
80
- branch=context.branch,
80
+ branch=graphql_context.branch,
81
81
  )
82
82
  resource = await obj.get_resource(
83
- db=context.db,
84
- branch=context.branch,
83
+ db=graphql_context.db,
84
+ branch=graphql_context.branch,
85
85
  identifier=data.get("identifier", None),
86
86
  prefixlen=data.get("prefix_length", None),
87
87
  member_type=member_type,
@@ -95,8 +95,8 @@ class IPPrefixPoolGetResource(Mutation):
95
95
  "id": resource.id,
96
96
  "kind": resource.get_kind(),
97
97
  "identifier": data.get("identifier", None),
98
- "display_label": await resource.render_display_label(db=context.db),
99
- "branch": context.branch.name,
98
+ "display_label": await resource.render_display_label(db=graphql_context.db),
99
+ "branch": graphql_context.branch.name,
100
100
  },
101
101
  }
102
102
 
@@ -113,26 +113,26 @@ class IPAddressPoolGetResource(Mutation):
113
113
  @classmethod
114
114
  async def mutate(
115
115
  cls,
116
- root: dict, # pylint: disable=unused-argument
116
+ root: dict, # noqa: ARG003
117
117
  info: GraphQLResolveInfo,
118
118
  data: dict[str, Any],
119
119
  ) -> Self:
120
- context: GraphqlContext = info.context
120
+ graphql_context: GraphqlContext = info.context
121
121
 
122
122
  obj: CoreIPAddressPool = await registry.manager.find_object(
123
- db=context.db,
123
+ db=graphql_context.db,
124
124
  kind=InfrahubKind.IPADDRESSPOOL,
125
125
  id=data.get("id"),
126
126
  hfid=data.get("hfid"),
127
- branch=context.branch,
127
+ branch=graphql_context.branch,
128
128
  )
129
129
  resource = await obj.get_resource(
130
- db=context.db,
131
- branch=context.branch,
132
- identifier=data.get("identifier", None),
133
- prefixlen=data.get("prefix_length", None),
134
- address_type=data.get("address_type", None),
135
- data=data.get("data", None),
130
+ db=graphql_context.db,
131
+ branch=graphql_context.branch,
132
+ identifier=data.get("identifier"),
133
+ prefixlen=data.get("prefix_length"),
134
+ address_type=data.get("address_type"),
135
+ data=data.get("data"),
136
136
  )
137
137
 
138
138
  result = {
@@ -140,9 +140,9 @@ class IPAddressPoolGetResource(Mutation):
140
140
  "node": {
141
141
  "id": resource.id,
142
142
  "kind": resource.get_kind(),
143
- "identifier": data.get("identifier", None),
144
- "display_label": await resource.render_display_label(db=context.db),
145
- "branch": context.branch.name,
143
+ "identifier": data.get("identifier"),
144
+ "display_label": await resource.render_display_label(db=graphql_context.db),
145
+ "branch": graphql_context.branch.name,
146
146
  },
147
147
  }
148
148
 
@@ -151,7 +151,7 @@ class IPAddressPoolGetResource(Mutation):
151
151
 
152
152
  class InfrahubNumberPoolMutation(InfrahubMutationMixin, Mutation):
153
153
  @classmethod
154
- def __init_subclass_with_meta__( # pylint: disable=arguments-differ
154
+ def __init_subclass_with_meta__(
155
155
  cls,
156
156
  schema: NodeSchema | None = None,
157
157
  _meta: InfrahubMutationOptions | None = None,
@@ -174,7 +174,7 @@ class InfrahubNumberPoolMutation(InfrahubMutationMixin, Mutation):
174
174
  info: GraphQLResolveInfo,
175
175
  data: InputObjectType,
176
176
  branch: Branch,
177
- database: InfrahubDatabase | None = None,
177
+ database: InfrahubDatabase | None = None, # noqa: ARG003
178
178
  ) -> Any:
179
179
  try:
180
180
  pool_node = registry.get_node_schema(name=data["node"].value)
@@ -204,16 +204,16 @@ class InfrahubNumberPoolMutation(InfrahubMutationMixin, Mutation):
204
204
  info: GraphQLResolveInfo,
205
205
  data: InputObjectType,
206
206
  branch: Branch,
207
- database: InfrahubDatabase | None = None,
207
+ database: InfrahubDatabase | None = None, # noqa: ARG003
208
208
  node: Node | None = None,
209
209
  ) -> tuple[Node, Self]:
210
210
  if (data.get("node") and data.get("node").value) or (
211
211
  data.get("node_attribute") and data.get("node_attribute").value
212
212
  ):
213
213
  raise ValidationError(input_value="The fields 'node' or 'node_attribute' can't be changed.")
214
- context: GraphqlContext = info.context
214
+ graphql_context: GraphqlContext = info.context
215
215
 
216
- async with context.db.start_transaction() as dbt:
216
+ async with graphql_context.db.start_transaction() as dbt:
217
217
  number_pool, result = await super().mutate_update(
218
218
  info=info, data=data, branch=branch, database=dbt, node=node
219
219
  )
@@ -13,6 +13,8 @@ from infrahub.database import InfrahubDatabase, retry_db_transaction
13
13
  from infrahub.events import EventMeta
14
14
  from infrahub.events.schema_action import SchemaUpdatedEvent
15
15
  from infrahub.exceptions import ValidationError
16
+ from infrahub.graphql.context import apply_external_context
17
+ from infrahub.graphql.types.context import ContextInput
16
18
  from infrahub.log import get_log_data, get_logger
17
19
  from infrahub.worker import WORKER_IDENTITY
18
20
 
@@ -21,6 +23,7 @@ from ..types import DropdownFields
21
23
  if TYPE_CHECKING:
22
24
  from graphql import GraphQLResolveInfo
23
25
 
26
+ from infrahub.context import InfrahubContext
24
27
  from infrahub.core.branch import Branch
25
28
  from infrahub.services import InfrahubServices
26
29
 
@@ -50,6 +53,7 @@ class SchemaDropdownAddInput(SchemaDropdownRemoveInput):
50
53
  class SchemaDropdownAdd(Mutation):
51
54
  class Arguments:
52
55
  data = SchemaDropdownAddInput(required=True)
56
+ context = ContextInput(required=False)
53
57
 
54
58
  ok = Boolean()
55
59
  object = Field(DropdownFields)
@@ -58,13 +62,16 @@ class SchemaDropdownAdd(Mutation):
58
62
  @retry_db_transaction(name="schema_dropdown_add")
59
63
  async def mutate(
60
64
  cls,
61
- root: dict, # pylint: disable=unused-argument
65
+ root: dict, # noqa: ARG003
62
66
  info: GraphQLResolveInfo,
63
67
  data: SchemaDropdownAddInput,
68
+ context: ContextInput | None = None,
64
69
  ) -> Self:
65
- context: GraphqlContext = info.context
70
+ graphql_context: GraphqlContext = info.context
66
71
 
67
- kind = context.db.schema.get(name=str(data.kind), branch=context.branch.name)
72
+ await apply_external_context(graphql_context=graphql_context, context_input=context)
73
+
74
+ kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
68
75
  attribute = str(data.attribute)
69
76
  validate_kind_dropdown(kind=kind, attribute=attribute)
70
77
  dropdown = str(data.dropdown)
@@ -80,13 +87,14 @@ class SchemaDropdownAdd(Mutation):
80
87
 
81
88
  await update_registry(
82
89
  kind=kind,
83
- branch=context.branch,
84
- db=context.db,
85
- account_id=context.active_account_session.account_id,
86
- service=context.active_service,
90
+ branch=graphql_context.branch,
91
+ db=graphql_context.db,
92
+ account_id=graphql_context.active_account_session.account_id,
93
+ service=graphql_context.active_service,
94
+ context=graphql_context.get_context(),
87
95
  )
88
96
 
89
- kind = context.db.schema.get(name=str(data.kind), branch=context.branch.name)
97
+ kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
90
98
  attrib = kind.get_attribute(attribute)
91
99
  dropdown_entry = {}
92
100
  success = False
@@ -107,6 +115,7 @@ class SchemaDropdownAdd(Mutation):
107
115
  class SchemaDropdownRemove(Mutation):
108
116
  class Arguments:
109
117
  data = SchemaDropdownRemoveInput(required=True)
118
+ context = ContextInput(required=False)
110
119
 
111
120
  ok = Boolean()
112
121
 
@@ -114,19 +123,24 @@ class SchemaDropdownRemove(Mutation):
114
123
  @retry_db_transaction(name="schema_dropdown_remove")
115
124
  async def mutate(
116
125
  cls,
117
- root: dict, # pylint: disable=unused-argument
126
+ root: dict, # noqa: ARG003
118
127
  info: GraphQLResolveInfo,
119
128
  data: SchemaDropdownRemoveInput,
129
+ context: ContextInput | None = None,
120
130
  ) -> dict[str, bool]:
121
- context: GraphqlContext = info.context
131
+ graphql_context: GraphqlContext = info.context
122
132
 
123
- kind = context.db.schema.get(name=str(data.kind), branch=context.branch.name)
133
+ kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
134
+ await apply_external_context(graphql_context=graphql_context, context_input=context)
124
135
 
125
136
  attribute = str(data.attribute)
126
137
  validate_kind_dropdown(kind=kind, attribute=attribute)
127
138
  dropdown = str(data.dropdown)
128
139
  nodes_with_dropdown = await NodeManager.query(
129
- db=context.db, schema=kind.kind, filters={f"{attribute}__value": dropdown}, branch=context.branch
140
+ db=graphql_context.db,
141
+ schema=kind.kind,
142
+ filters={f"{attribute}__value": dropdown},
143
+ branch=graphql_context.branch,
130
144
  )
131
145
  if nodes_with_dropdown:
132
146
  raise ValidationError(f"There are still {kind.kind} objects using this dropdown")
@@ -143,10 +157,11 @@ class SchemaDropdownRemove(Mutation):
143
157
 
144
158
  await update_registry(
145
159
  kind=kind,
146
- branch=context.branch,
147
- db=context.db,
148
- account_id=context.active_account_session.account_id,
149
- service=context.active_service,
160
+ branch=graphql_context.branch,
161
+ db=graphql_context.db,
162
+ account_id=graphql_context.active_account_session.account_id,
163
+ service=graphql_context.active_service,
164
+ context=graphql_context.get_context(),
150
165
  )
151
166
 
152
167
  return {"ok": True}
@@ -155,6 +170,7 @@ class SchemaDropdownRemove(Mutation):
155
170
  class SchemaEnumAdd(Mutation):
156
171
  class Arguments:
157
172
  data = SchemaEnumInput(required=True)
173
+ context = ContextInput(required=False)
158
174
 
159
175
  ok = Boolean()
160
176
 
@@ -162,13 +178,15 @@ class SchemaEnumAdd(Mutation):
162
178
  @retry_db_transaction(name="schema_dropdown_add")
163
179
  async def mutate(
164
180
  cls,
165
- root: dict, # pylint: disable=unused-argument
181
+ root: dict, # noqa: ARG003
166
182
  info: GraphQLResolveInfo,
167
183
  data: SchemaEnumInput,
184
+ context: ContextInput | None = None,
168
185
  ) -> dict[str, bool]:
169
- context: GraphqlContext = info.context
186
+ graphql_context: GraphqlContext = info.context
170
187
 
171
- kind = context.db.schema.get(name=str(data.kind), branch=context.branch.name)
188
+ kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
189
+ await apply_external_context(graphql_context=graphql_context, context_input=context)
172
190
 
173
191
  attribute = str(data.attribute)
174
192
  enum = str(data.enum)
@@ -184,10 +202,11 @@ class SchemaEnumAdd(Mutation):
184
202
 
185
203
  await update_registry(
186
204
  kind=kind,
187
- branch=context.branch,
188
- db=context.db,
189
- account_id=context.active_account_session.account_id,
190
- service=context.active_service,
205
+ branch=graphql_context.branch,
206
+ db=graphql_context.db,
207
+ account_id=graphql_context.active_account_session.account_id,
208
+ service=graphql_context.active_service,
209
+ context=graphql_context.get_context(),
191
210
  )
192
211
 
193
212
  return {"ok": True}
@@ -196,6 +215,7 @@ class SchemaEnumAdd(Mutation):
196
215
  class SchemaEnumRemove(Mutation):
197
216
  class Arguments:
198
217
  data = SchemaEnumInput(required=True)
218
+ context = ContextInput(required=False)
199
219
 
200
220
  ok = Boolean()
201
221
 
@@ -203,19 +223,24 @@ class SchemaEnumRemove(Mutation):
203
223
  @retry_db_transaction(name="schema_enum_remove")
204
224
  async def mutate(
205
225
  cls,
206
- root: dict, # pylint: disable=unused-argument
226
+ root: dict, # noqa: ARG003
207
227
  info: GraphQLResolveInfo,
208
228
  data: SchemaEnumInput,
229
+ context: ContextInput | None = None,
209
230
  ) -> dict[str, bool]:
210
- context: GraphqlContext = info.context
231
+ graphql_context: GraphqlContext = info.context
211
232
 
212
- kind = context.db.schema.get(name=str(data.kind), branch=context.branch.name)
233
+ kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
234
+ await apply_external_context(graphql_context=graphql_context, context_input=context)
213
235
 
214
236
  attribute = str(data.attribute)
215
237
  enum = str(data.enum)
216
238
  validate_kind_enum(kind=kind, attribute=attribute)
217
239
  nodes_with_enum = await NodeManager.query(
218
- db=context.db, schema=kind.kind, filters={f"{attribute}__value": enum}, branch=context.branch
240
+ db=graphql_context.db,
241
+ schema=kind.kind,
242
+ filters={f"{attribute}__value": enum},
243
+ branch=graphql_context.branch,
219
244
  )
220
245
  if nodes_with_enum:
221
246
  raise ValidationError(f"There are still {kind.kind} objects using this enum")
@@ -232,10 +257,11 @@ class SchemaEnumRemove(Mutation):
232
257
 
233
258
  await update_registry(
234
259
  kind=kind,
235
- branch=context.branch,
236
- db=context.db,
237
- account_id=context.active_account_session.account_id,
238
- service=context.active_service,
260
+ branch=graphql_context.branch,
261
+ db=graphql_context.db,
262
+ account_id=graphql_context.active_account_session.account_id,
263
+ service=graphql_context.active_service,
264
+ context=graphql_context.get_context(),
239
265
  )
240
266
 
241
267
  return {"ok": True}
@@ -268,7 +294,12 @@ def validate_kind(kind: Union[GenericSchema, NodeSchema], attribute: str) -> Non
268
294
 
269
295
 
270
296
  async def update_registry(
271
- kind: NodeSchema, db: InfrahubDatabase, branch: Branch, account_id: str, service: InfrahubServices
297
+ kind: NodeSchema,
298
+ db: InfrahubDatabase,
299
+ branch: Branch,
300
+ account_id: str,
301
+ service: InfrahubServices,
302
+ context: InfrahubContext,
272
303
  ) -> None:
273
304
  async with lock.registry.global_schema_lock():
274
305
  branch_schema = registry.schema.get_schema_branch(name=branch.name)
@@ -296,12 +327,14 @@ async def update_registry(
296
327
  log_data = get_log_data()
297
328
  request_id = log_data.get("request_id", "")
298
329
  event = SchemaUpdatedEvent(
299
- branch=branch.name,
330
+ branch_name=branch.name,
300
331
  schema_hash=branch.active_schema_hash.main,
301
332
  meta=EventMeta(
302
333
  initiator_id=WORKER_IDENTITY,
303
334
  request_id=request_id,
304
335
  account_id=account_id,
336
+ branch=branch,
337
+ context=context,
305
338
  ),
306
339
  )
307
340
  await service.event.send(event=event)
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from prefect import flow
4
4
 
5
+ from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
5
6
  from infrahub.core import registry
6
7
  from infrahub.core.branch import Branch
7
8
  from infrahub.core.diff.coordinator import DiffCoordinator
@@ -13,15 +14,14 @@ from infrahub.core.validators.models.validate_migration import SchemaValidateMig
13
14
  from infrahub.core.validators.tasks import schema_validate_migrations
14
15
  from infrahub.dependencies.registry import get_component_registry
15
16
  from infrahub.exceptions import ValidationError
16
- from infrahub.services import services
17
+ from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
17
18
  from infrahub.workflows.catalogue import BRANCH_MERGE
18
- from infrahub.workflows.utils import add_branch_tag
19
+ from infrahub.workflows.utils import add_tags
19
20
 
20
21
 
21
22
  @flow(name="merge-branch-mutation", flow_run_name="Merge branch graphQL mutation")
22
- async def merge_branch_mutation(branch: str) -> None:
23
- service = services.service
24
- await add_branch_tag(branch_name=branch)
23
+ async def merge_branch_mutation(branch: str, context: InfrahubContext, service: InfrahubServices) -> None:
24
+ await add_tags(branches=[branch])
25
25
 
26
26
  async with service.database.start_session() as db:
27
27
  obj = await Branch.get_by_name(db=db, name=branch)
@@ -31,14 +31,17 @@ async def merge_branch_mutation(branch: str) -> None:
31
31
  diff_coordinator = await component_registry.get_component(DiffCoordinator, db=db, branch=obj)
32
32
  diff_repository = await component_registry.get_component(DiffRepository, db=db, branch=obj)
33
33
  diff_merger = await component_registry.get_component(DiffMerger, db=db, branch=obj)
34
- enriched_diff = await diff_coordinator.update_branch_diff_and_return(base_branch=base_branch, diff_branch=obj)
35
- if enriched_diff.get_all_conflicts():
34
+ enriched_diff_metadata = await diff_coordinator.update_branch_diff(base_branch=base_branch, diff_branch=obj)
35
+ async for _ in diff_repository.get_all_conflicts_for_diff(
36
+ diff_branch_name=enriched_diff_metadata.diff_branch_name, diff_id=enriched_diff_metadata.uuid
37
+ ):
38
+ # if there are any conflicts, raise the error
36
39
  raise ValidationError(
37
40
  f"Branch {obj.name} contains conflicts with the default branch."
38
41
  " Please create a Proposed Change to resolve the conflicts or manually update them before merging."
39
42
  )
40
43
  node_diff_field_summaries = await diff_repository.get_node_field_summaries(
41
- diff_branch_name=enriched_diff.diff_branch_name, diff_id=enriched_diff.uuid
44
+ diff_branch_name=enriched_diff_metadata.diff_branch_name, diff_id=enriched_diff_metadata.uuid
42
45
  )
43
46
 
44
47
  merger = BranchMerger(
@@ -57,10 +60,13 @@ async def merge_branch_mutation(branch: str) -> None:
57
60
 
58
61
  if constraints:
59
62
  responses = await schema_validate_migrations(
60
- message=SchemaValidateMigrationData(branch=obj, schema_branch=candidate_schema, constraints=constraints)
63
+ message=SchemaValidateMigrationData(
64
+ branch=obj, schema_branch=candidate_schema, constraints=constraints
65
+ ),
66
+ service=service,
61
67
  )
62
68
  error_messages = [violation.message for response in responses for violation in response.violations]
63
69
  if error_messages:
64
70
  raise ValidationError(",\n".join(error_messages))
65
71
 
66
- await service.workflow.execute_workflow(workflow=BRANCH_MERGE, parameters={"branch": obj.name})
72
+ await service.workflow.execute_workflow(workflow=BRANCH_MERGE, context=context, parameters={"branch": obj.name})
@@ -162,7 +162,7 @@ class GraphQLExtractor:
162
162
  FieldNode(
163
163
  kind="field",
164
164
  name=NameNode(kind="name", value=sub_node.key),
165
- selection_set=SelectionSetNode(selections=tuple([sub_node.node])),
165
+ selection_set=SelectionSetNode(selections=(sub_node.node,)),
166
166
  )
167
167
  )
168
168
  selection_set.selections = tuple(selections)