infrahub-server 1.1.7__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 (399) 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 +50 -21
  22. infrahub/core/branch/models.py +4 -4
  23. infrahub/core/branch/tasks.py +130 -125
  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 +1 -1
  31. infrahub/core/diff/enricher/cardinality_one.py +6 -1
  32. infrahub/core/diff/enricher/hierarchy.py +22 -7
  33. infrahub/core/diff/enricher/labels.py +6 -1
  34. infrahub/core/diff/enricher/path_identifier.py +5 -1
  35. infrahub/core/diff/enricher/summary_counts.py +107 -0
  36. infrahub/core/diff/merger/merger.py +3 -1
  37. infrahub/core/diff/model/path.py +34 -11
  38. infrahub/core/diff/parent_node_adder.py +78 -0
  39. infrahub/core/diff/payload_builder.py +13 -2
  40. infrahub/core/diff/query/all_conflicts.py +1 -1
  41. infrahub/core/diff/query/artifact.py +1 -1
  42. infrahub/core/diff/query/delete_query.py +1 -1
  43. infrahub/core/diff/query/diff_get.py +1 -1
  44. infrahub/core/diff/query/diff_summary.py +1 -1
  45. infrahub/core/diff/query/field_specifiers.py +1 -1
  46. infrahub/core/diff/query/field_summary.py +1 -1
  47. infrahub/core/diff/query/filters.py +2 -2
  48. infrahub/core/diff/query/get_conflict_query.py +1 -1
  49. infrahub/core/diff/query/has_conflicts_query.py +1 -1
  50. infrahub/core/diff/query/merge.py +3 -3
  51. infrahub/core/diff/query/merge_tracking_id.py +1 -1
  52. infrahub/core/diff/query/roots_metadata.py +1 -1
  53. infrahub/core/diff/query/save.py +191 -185
  54. infrahub/core/diff/query/summary_counts_enricher.py +52 -5
  55. infrahub/core/diff/query/time_range_query.py +1 -1
  56. infrahub/core/diff/query/update_conflict_query.py +1 -1
  57. infrahub/core/diff/repository/deserializer.py +9 -4
  58. infrahub/core/diff/repository/repository.py +156 -38
  59. infrahub/core/diff/tasks.py +13 -12
  60. infrahub/core/enums.py +1 -1
  61. infrahub/core/graph/__init__.py +1 -1
  62. infrahub/core/graph/index.py +3 -0
  63. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  64. infrahub/core/ipam/reconciler.py +1 -1
  65. infrahub/core/ipam/tasks.py +2 -3
  66. infrahub/core/manager.py +20 -15
  67. infrahub/core/merge.py +5 -2
  68. infrahub/core/migrations/graph/__init__.py +4 -0
  69. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  70. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  71. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  72. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  73. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  74. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  75. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  76. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  77. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  78. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  79. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  80. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  81. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  82. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  83. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  84. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  85. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
  86. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
  87. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
  88. infrahub/core/migrations/graph/m020_add_generate_template_attr.py +48 -0
  89. infrahub/core/migrations/query/attribute_add.py +1 -1
  90. infrahub/core/migrations/query/attribute_rename.py +1 -1
  91. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  92. infrahub/core/migrations/query/node_duplicate.py +39 -19
  93. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  94. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  95. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  96. infrahub/core/migrations/schema/node_remove.py +27 -13
  97. infrahub/core/migrations/schema/tasks.py +5 -5
  98. infrahub/core/migrations/shared.py +4 -4
  99. infrahub/core/models.py +7 -8
  100. infrahub/core/node/__init__.py +164 -45
  101. infrahub/core/node/base.py +1 -1
  102. infrahub/core/node/delete_validator.py +4 -4
  103. infrahub/core/node/ipam.py +7 -7
  104. infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
  105. infrahub/core/node/standard.py +3 -5
  106. infrahub/core/property.py +1 -1
  107. infrahub/core/protocols.py +6 -0
  108. infrahub/core/protocols_base.py +4 -2
  109. infrahub/core/query/__init__.py +2 -5
  110. infrahub/core/query/attribute.py +9 -9
  111. infrahub/core/query/branch.py +5 -5
  112. infrahub/core/query/delete.py +1 -1
  113. infrahub/core/query/diff.py +4 -4
  114. infrahub/core/query/ipam.py +4 -4
  115. infrahub/core/query/node.py +11 -12
  116. infrahub/core/query/relationship.py +211 -25
  117. infrahub/core/query/resource_manager.py +10 -10
  118. infrahub/core/query/standard_node.py +6 -6
  119. infrahub/core/query/task.py +3 -3
  120. infrahub/core/query/task_log.py +1 -1
  121. infrahub/core/query/utils.py +5 -5
  122. infrahub/core/registry.py +0 -2
  123. infrahub/core/relationship/constraints/count.py +1 -1
  124. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  125. infrahub/core/relationship/model.py +76 -38
  126. infrahub/core/schema/__init__.py +6 -4
  127. infrahub/core/schema/attribute_schema.py +8 -0
  128. infrahub/core/schema/basenode_schema.py +13 -3
  129. infrahub/core/schema/definitions/core/__init__.py +153 -0
  130. infrahub/core/schema/definitions/core/account.py +168 -0
  131. infrahub/core/schema/definitions/core/artifact.py +127 -0
  132. infrahub/core/schema/definitions/core/builtin.py +21 -0
  133. infrahub/core/schema/definitions/core/check.py +60 -0
  134. infrahub/core/schema/definitions/core/generator.py +96 -0
  135. infrahub/core/schema/definitions/core/graphql_query.py +77 -0
  136. infrahub/core/schema/definitions/core/group.py +105 -0
  137. infrahub/core/schema/definitions/core/ipam.py +252 -0
  138. infrahub/core/schema/definitions/core/lineage.py +17 -0
  139. infrahub/core/schema/definitions/core/menu.py +46 -0
  140. infrahub/core/schema/definitions/core/permission.py +161 -0
  141. infrahub/core/schema/definitions/core/profile.py +29 -0
  142. infrahub/core/schema/definitions/core/propose_change.py +88 -0
  143. infrahub/core/schema/definitions/core/propose_change_comment.py +188 -0
  144. infrahub/core/schema/definitions/core/propose_change_validator.py +326 -0
  145. infrahub/core/schema/definitions/core/repository.py +280 -0
  146. infrahub/core/schema/definitions/core/resource_pool.py +180 -0
  147. infrahub/core/schema/definitions/core/template.py +12 -0
  148. infrahub/core/schema/definitions/core/transform.py +87 -0
  149. infrahub/core/schema/definitions/core/webhook.py +108 -0
  150. infrahub/core/schema/definitions/internal.py +16 -0
  151. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  152. infrahub/core/schema/generated/node_schema.py +5 -0
  153. infrahub/core/schema/generic_schema.py +5 -1
  154. infrahub/core/schema/manager.py +45 -42
  155. infrahub/core/schema/node_schema.py +4 -0
  156. infrahub/core/schema/profile_schema.py +4 -0
  157. infrahub/core/schema/relationship_schema.py +10 -2
  158. infrahub/core/schema/schema_branch.py +260 -16
  159. infrahub/core/schema/template_schema.py +36 -0
  160. infrahub/core/task/user_task.py +7 -5
  161. infrahub/core/timestamp.py +3 -3
  162. infrahub/core/utils.py +2 -2
  163. infrahub/core/validators/attribute/choices.py +1 -1
  164. infrahub/core/validators/attribute/enum.py +1 -1
  165. infrahub/core/validators/attribute/kind.py +1 -1
  166. infrahub/core/validators/attribute/length.py +1 -1
  167. infrahub/core/validators/attribute/optional.py +1 -1
  168. infrahub/core/validators/attribute/regex.py +1 -1
  169. infrahub/core/validators/attribute/unique.py +1 -1
  170. infrahub/core/validators/checks_runner.py +37 -0
  171. infrahub/core/validators/node/generate_profile.py +1 -1
  172. infrahub/core/validators/node/hierarchy.py +1 -1
  173. infrahub/core/validators/query.py +1 -1
  174. infrahub/core/validators/relationship/count.py +1 -1
  175. infrahub/core/validators/relationship/optional.py +1 -1
  176. infrahub/core/validators/relationship/peer.py +1 -1
  177. infrahub/core/validators/tasks.py +8 -6
  178. infrahub/core/validators/uniqueness/query.py +1 -1
  179. infrahub/database/__init__.py +3 -2
  180. infrahub/database/memgraph.py +1 -1
  181. infrahub/dependencies/builder/diff/combiner.py +1 -1
  182. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  183. infrahub/dependencies/builder/diff/deserializer.py +4 -2
  184. infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
  185. infrahub/dependencies/builder/diff/enricher/summary_counts.py +8 -0
  186. infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
  187. infrahub/events/artifact_action.py +76 -0
  188. infrahub/events/branch_action.py +50 -21
  189. infrahub/events/group_action.py +117 -0
  190. infrahub/events/models.py +164 -51
  191. infrahub/events/node_action.py +70 -8
  192. infrahub/events/repository_action.py +8 -8
  193. infrahub/events/schema_action.py +21 -8
  194. infrahub/exceptions.py +9 -0
  195. infrahub/generators/models.py +1 -0
  196. infrahub/generators/tasks.py +34 -15
  197. infrahub/git/base.py +3 -5
  198. infrahub/git/constants.py +0 -1
  199. infrahub/git/integrator.py +60 -36
  200. infrahub/git/models.py +80 -1
  201. infrahub/git/repository.py +7 -8
  202. infrahub/git/tasks.py +432 -112
  203. infrahub/git_credential/helper.py +2 -3
  204. infrahub/graphql/analyzer.py +572 -11
  205. infrahub/graphql/app.py +34 -26
  206. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  207. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  208. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  209. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  210. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  211. infrahub/graphql/context.py +33 -0
  212. infrahub/graphql/enums.py +1 -1
  213. infrahub/graphql/initialization.py +5 -1
  214. infrahub/graphql/loaders/node.py +2 -2
  215. infrahub/graphql/manager.py +63 -63
  216. infrahub/graphql/mutations/account.py +20 -13
  217. infrahub/graphql/mutations/artifact_definition.py +16 -12
  218. infrahub/graphql/mutations/branch.py +86 -40
  219. infrahub/graphql/mutations/computed_attribute.py +24 -15
  220. infrahub/graphql/mutations/diff.py +33 -17
  221. infrahub/graphql/mutations/diff_conflict.py +14 -8
  222. infrahub/graphql/mutations/generator.py +83 -0
  223. infrahub/graphql/mutations/graphql_query.py +19 -11
  224. infrahub/graphql/mutations/ipam.py +25 -23
  225. infrahub/graphql/mutations/main.py +233 -45
  226. infrahub/graphql/mutations/menu.py +10 -10
  227. infrahub/graphql/mutations/proposed_change.py +36 -28
  228. infrahub/graphql/mutations/relationship.py +341 -130
  229. infrahub/graphql/mutations/repository.py +41 -35
  230. infrahub/graphql/mutations/resource_manager.py +26 -26
  231. infrahub/graphql/mutations/schema.py +66 -33
  232. infrahub/graphql/mutations/tasks.py +10 -7
  233. infrahub/graphql/parser.py +1 -1
  234. infrahub/graphql/permissions.py +3 -10
  235. infrahub/graphql/queries/account.py +22 -18
  236. infrahub/graphql/queries/branch.py +6 -4
  237. infrahub/graphql/queries/diff/tree.py +63 -52
  238. infrahub/graphql/queries/event.py +115 -0
  239. infrahub/graphql/queries/internal.py +3 -3
  240. infrahub/graphql/queries/ipam.py +23 -18
  241. infrahub/graphql/queries/relationship.py +11 -10
  242. infrahub/graphql/queries/resource_manager.py +37 -25
  243. infrahub/graphql/queries/search.py +9 -8
  244. infrahub/graphql/queries/status.py +12 -9
  245. infrahub/graphql/queries/task.py +11 -9
  246. infrahub/graphql/resolvers/resolver.py +69 -43
  247. infrahub/graphql/resolvers/single_relationship.py +16 -10
  248. infrahub/graphql/schema.py +4 -0
  249. infrahub/graphql/subscription/__init__.py +1 -1
  250. infrahub/graphql/subscription/events.py +1 -1
  251. infrahub/graphql/subscription/graphql_query.py +8 -8
  252. infrahub/graphql/types/branch.py +2 -2
  253. infrahub/graphql/types/common.py +6 -1
  254. infrahub/graphql/types/context.py +12 -0
  255. infrahub/graphql/types/enums.py +2 -0
  256. infrahub/graphql/types/event.py +158 -0
  257. infrahub/graphql/types/interface.py +2 -2
  258. infrahub/graphql/types/node.py +3 -3
  259. infrahub/graphql/types/permission.py +2 -2
  260. infrahub/graphql/types/relationship.py +3 -3
  261. infrahub/graphql/types/standard_node.py +9 -11
  262. infrahub/graphql/utils.py +28 -182
  263. infrahub/groups/tasks.py +2 -3
  264. infrahub/lock.py +21 -21
  265. infrahub/menu/generator.py +0 -1
  266. infrahub/menu/menu.py +116 -138
  267. infrahub/menu/models.py +4 -4
  268. infrahub/message_bus/__init__.py +11 -13
  269. infrahub/message_bus/messages/__init__.py +0 -14
  270. infrahub/message_bus/messages/check_generator_run.py +1 -3
  271. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  272. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  273. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  274. infrahub/message_bus/messages/send_echo_request.py +1 -1
  275. infrahub/message_bus/operations/__init__.py +4 -13
  276. infrahub/message_bus/operations/check/__init__.py +2 -2
  277. infrahub/message_bus/operations/check/generator.py +1 -3
  278. infrahub/message_bus/operations/event/branch.py +7 -3
  279. infrahub/message_bus/operations/event/schema.py +1 -1
  280. infrahub/message_bus/operations/event/worker.py +0 -3
  281. infrahub/message_bus/operations/finalize/validator.py +1 -1
  282. infrahub/message_bus/operations/git/file.py +2 -2
  283. infrahub/message_bus/operations/git/repository.py +1 -1
  284. infrahub/message_bus/operations/requests/__init__.py +0 -4
  285. infrahub/message_bus/operations/requests/generator_definition.py +2 -4
  286. infrahub/message_bus/operations/requests/proposed_change.py +37 -20
  287. infrahub/message_bus/operations/send/echo.py +1 -1
  288. infrahub/message_bus/types.py +1 -1
  289. infrahub/permissions/globals.py +15 -0
  290. infrahub/pools/prefix.py +29 -165
  291. infrahub/prefect_server/__init__.py +0 -0
  292. infrahub/prefect_server/app.py +18 -0
  293. infrahub/prefect_server/database.py +20 -0
  294. infrahub/prefect_server/events.py +28 -0
  295. infrahub/prefect_server/models.py +46 -0
  296. infrahub/proposed_change/models.py +18 -1
  297. infrahub/proposed_change/tasks.py +195 -53
  298. infrahub/pytest_plugin.py +4 -4
  299. infrahub/server.py +13 -12
  300. infrahub/services/__init__.py +148 -63
  301. infrahub/services/adapters/cache/__init__.py +11 -11
  302. infrahub/services/adapters/cache/nats.py +42 -25
  303. infrahub/services/adapters/cache/redis.py +3 -11
  304. infrahub/services/adapters/event/__init__.py +10 -18
  305. infrahub/services/adapters/http/__init__.py +0 -5
  306. infrahub/services/adapters/http/httpx.py +22 -15
  307. infrahub/services/adapters/message_bus/__init__.py +25 -8
  308. infrahub/services/adapters/message_bus/local.py +9 -7
  309. infrahub/services/adapters/message_bus/nats.py +14 -8
  310. infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
  311. infrahub/services/adapters/workflow/__init__.py +11 -8
  312. infrahub/services/adapters/workflow/local.py +27 -6
  313. infrahub/services/adapters/workflow/worker.py +23 -7
  314. infrahub/services/component.py +43 -40
  315. infrahub/services/protocols.py +7 -7
  316. infrahub/services/scheduler.py +30 -29
  317. infrahub/storage.py +2 -4
  318. infrahub/task_manager/constants.py +1 -1
  319. infrahub/task_manager/event.py +261 -0
  320. infrahub/task_manager/models.py +147 -3
  321. infrahub/task_manager/task.py +1 -1
  322. infrahub/tasks/artifact.py +19 -18
  323. infrahub/tasks/registry.py +1 -1
  324. infrahub/tasks/telemetry.py +13 -14
  325. infrahub/transformations/tasks.py +3 -5
  326. infrahub/trigger/__init__.py +0 -0
  327. infrahub/trigger/catalogue.py +16 -0
  328. infrahub/trigger/constants.py +9 -0
  329. infrahub/trigger/models.py +105 -0
  330. infrahub/trigger/tasks.py +91 -0
  331. infrahub/types.py +1 -1
  332. infrahub/utils.py +1 -1
  333. infrahub/webhook/constants.py +0 -2
  334. infrahub/webhook/models.py +161 -40
  335. infrahub/webhook/tasks.py +123 -202
  336. infrahub/webhook/triggers.py +27 -0
  337. infrahub/workers/infrahub_async.py +36 -25
  338. infrahub/workers/utils.py +63 -0
  339. infrahub/workflows/catalogue.py +71 -52
  340. infrahub/workflows/initialization.py +14 -8
  341. infrahub/workflows/models.py +28 -4
  342. infrahub/workflows/utils.py +1 -1
  343. infrahub_sdk/batch.py +2 -2
  344. infrahub_sdk/client.py +8 -0
  345. infrahub_sdk/config.py +1 -1
  346. infrahub_sdk/ctl/branch.py +3 -2
  347. infrahub_sdk/ctl/check.py +4 -4
  348. infrahub_sdk/ctl/cli_commands.py +16 -11
  349. infrahub_sdk/ctl/exceptions.py +0 -6
  350. infrahub_sdk/ctl/exporter.py +1 -1
  351. infrahub_sdk/ctl/generator.py +5 -5
  352. infrahub_sdk/ctl/importer.py +3 -2
  353. infrahub_sdk/ctl/menu.py +1 -1
  354. infrahub_sdk/ctl/object.py +1 -1
  355. infrahub_sdk/ctl/repository.py +23 -15
  356. infrahub_sdk/ctl/schema.py +2 -2
  357. infrahub_sdk/ctl/utils.py +6 -21
  358. infrahub_sdk/ctl/validate.py +2 -1
  359. infrahub_sdk/data.py +1 -1
  360. infrahub_sdk/exceptions.py +12 -0
  361. infrahub_sdk/generator.py +3 -0
  362. infrahub_sdk/node.py +5 -8
  363. infrahub_sdk/protocols.py +20 -8
  364. infrahub_sdk/schema/__init__.py +14 -5
  365. infrahub_sdk/schema/main.py +7 -0
  366. infrahub_sdk/task/__init__.py +1 -0
  367. infrahub_sdk/task/constants.py +3 -0
  368. infrahub_sdk/task/exceptions.py +25 -0
  369. infrahub_sdk/task/manager.py +545 -0
  370. infrahub_sdk/task/models.py +74 -0
  371. infrahub_sdk/testing/docker.py +30 -0
  372. infrahub_sdk/timestamp.py +134 -33
  373. infrahub_sdk/transfer/exporter/json.py +1 -1
  374. infrahub_sdk/utils.py +39 -1
  375. infrahub_sdk/yaml.py +2 -3
  376. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/METADATA +7 -6
  377. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/RECORD +383 -339
  378. infrahub_testcontainers/container.py +2 -3
  379. infrahub_testcontainers/docker-compose.test.yml +2 -2
  380. infrahub/core/branch/constants.py +0 -2
  381. infrahub/core/schema/definitions/core.py +0 -2274
  382. infrahub/graphql/query.py +0 -52
  383. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  384. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  385. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  386. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  387. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  388. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  389. infrahub/message_bus/operations/check/repository.py +0 -293
  390. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  391. infrahub/message_bus/operations/requests/repository.py +0 -133
  392. infrahub/schema/constants.py +0 -1
  393. infrahub/schema/tasks.py +0 -76
  394. infrahub/services/adapters/database/__init__.py +0 -9
  395. infrahub_sdk/ctl/_file.py +0 -13
  396. /infrahub/{schema → artifacts}/__init__.py +0 -0
  397. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/LICENSE.txt +0 -0
  398. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/WHEEL +0 -0
  399. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/entry_points.txt +0 -0
@@ -1,10 +1,15 @@
1
1
  from collections import defaultdict
2
2
  from typing import AsyncGenerator, Generator, Iterable
3
3
 
4
+ from neo4j.exceptions import TransientError
5
+
4
6
  from infrahub import config
5
7
  from infrahub.core import registry
6
8
  from infrahub.core.diff.query.field_summary import EnrichedDiffNodeFieldSummaryQuery
7
- from infrahub.core.diff.query.summary_counts_enricher import DiffSummaryCountsEnricherQuery
9
+ from infrahub.core.diff.query.summary_counts_enricher import (
10
+ DiffFieldsSummaryCountsEnricherQuery,
11
+ DiffNodesSummaryCountsEnricherQuery,
12
+ )
8
13
  from infrahub.core.query.diff import DiffCountChanges
9
14
  from infrahub.core.timestamp import Timestamp
10
15
  from infrahub.database import InfrahubDatabase, retry_db_transaction
@@ -14,6 +19,7 @@ from infrahub.log import get_logger
14
19
  from ..model.path import (
15
20
  ConflictSelection,
16
21
  EnrichedDiffConflict,
22
+ EnrichedDiffNode,
17
23
  EnrichedDiffRoot,
18
24
  EnrichedDiffRootMetadata,
19
25
  EnrichedDiffs,
@@ -42,11 +48,10 @@ log = get_logger()
42
48
 
43
49
 
44
50
  class DiffRepository:
45
- MAX_SAVE_BATCH_SIZE: int = 100
46
-
47
- def __init__(self, db: InfrahubDatabase, deserializer: EnrichedDiffDeserializer):
51
+ def __init__(self, db: InfrahubDatabase, deserializer: EnrichedDiffDeserializer, max_save_batch_size: int = 1000):
48
52
  self.db = db
49
53
  self.deserializer = deserializer
54
+ self.max_save_batch_size = max_save_batch_size
50
55
 
51
56
  async def _run_get_diff_query(
52
57
  self,
@@ -154,18 +159,23 @@ class DiffRepository:
154
159
  diff_branch_names=[base_branch_name],
155
160
  max_depth=max_depth,
156
161
  batch_size_limit=batch_size_limit,
157
- diff_ids=[d.partner_uuid for d in diffs_by_uuid.values()],
162
+ diff_ids=[d.partner_uuid for d in diffs_by_uuid.values() if d.partner_uuid],
158
163
  )
159
164
  diffs_by_uuid.update({bbr.uuid: bbr for bbr in base_branch_roots})
160
- return [
161
- EnrichedDiffs(
162
- base_branch_name=base_branch_name,
163
- diff_branch_name=diff_branch_name,
164
- base_branch_diff=diffs_by_uuid[dbr.partner_uuid],
165
- diff_branch_diff=dbr,
165
+ diff_pairs = []
166
+ for dbr in diff_branch_roots:
167
+ if dbr.partner_uuid is None:
168
+ continue
169
+ base_branch_diff = diffs_by_uuid[dbr.partner_uuid]
170
+ diff_pairs.append(
171
+ EnrichedDiffs(
172
+ base_branch_name=base_branch_name,
173
+ diff_branch_name=diff_branch_name,
174
+ base_branch_diff=base_branch_diff,
175
+ diff_branch_diff=dbr,
176
+ )
166
177
  )
167
- for dbr in diff_branch_roots
168
- ]
178
+ return diff_pairs
169
179
 
170
180
  async def hydrate_diff_pair(
171
181
  self,
@@ -225,43 +235,111 @@ class DiffRepository:
225
235
  ) -> Generator[list[EnrichedNodeCreateRequest], None, None]:
226
236
  node_requests = []
227
237
  for diff_root in (enriched_diffs.base_branch_diff, enriched_diffs.diff_branch_diff):
238
+ size_count = 0
228
239
  for node in diff_root.nodes:
229
- node_requests.append(EnrichedNodeCreateRequest(node=node, root_uuid=diff_root.uuid))
230
- if len(node_requests) == self.MAX_SAVE_BATCH_SIZE:
240
+ node_size_count = node.num_properties
241
+ if size_count + node_size_count < self.max_save_batch_size:
242
+ node_requests.append(EnrichedNodeCreateRequest(node=node, root_uuid=diff_root.uuid))
243
+ size_count += node_size_count
244
+ else:
245
+ log.info(f"Num nodes in batch: {len(node_requests)}, num properties in batch: {size_count}")
231
246
  yield node_requests
232
- node_requests = []
247
+ size_count = node_size_count
248
+ node_requests = [EnrichedNodeCreateRequest(node=node, root_uuid=diff_root.uuid)]
233
249
  if node_requests:
250
+ log.info(f"Num nodes in batch: {len(node_requests)}, num properties in batch: {size_count}")
234
251
  yield node_requests
235
252
 
236
- @retry_db_transaction(name="enriched_diff_save")
237
- async def save(self, enriched_diffs: EnrichedDiffs | EnrichedDiffsMetadata, do_summary_counts: bool = True) -> None:
253
+ @retry_db_transaction(name="enriched_diff_metadata_save")
254
+ async def _save_root_metadata(self, enriched_diffs: EnrichedDiffsMetadata) -> None:
238
255
  log.info("Updating diff metadata...")
239
256
  root_query = await EnrichedDiffRootsUpsertQuery.init(db=self.db, enriched_diffs=enriched_diffs)
240
257
  await root_query.execute(db=self.db)
241
258
  log.info("Diff metadata updated.")
259
+
260
+ async def _save_node_batch(self, node_create_batch: list[EnrichedNodeCreateRequest]) -> None:
261
+ node_query = await EnrichedNodeBatchCreateQuery.init(db=self.db, node_create_batch=node_create_batch)
262
+ try:
263
+ await node_query.execute(db=self.db)
264
+ except TransientError as exc:
265
+ if not exc.code or "OutOfMemoryError".lower() not in str(exc.code).lower():
266
+ raise
267
+ log.exception("Database memory error during save. Trying smaller transactions")
268
+ for node_request in node_create_batch:
269
+ log.info(
270
+ f"Updating node {node_request.node.uuid}, num_properties={node_request.node.num_properties}..."
271
+ )
272
+ single_node_query = await EnrichedNodeBatchCreateQuery.init(
273
+ db=self.db, node_create_batch=[node_request]
274
+ )
275
+ await single_node_query.execute(db=self.db)
276
+
277
+ @retry_db_transaction(name="enriched_diff_hierarchy_update")
278
+ async def _run_hierarchy_links_update_query(self, diff_root_uuid: str, diff_nodes: list[EnrichedDiffNode]) -> None:
279
+ log.info(f"Updating diff hierarchy links, num_nodes={len(diff_nodes)}")
280
+ link_query = await EnrichedNodesLinkQuery.init(db=self.db, diff_root_uuid=diff_root_uuid, diff_nodes=diff_nodes)
281
+ await link_query.execute(db=self.db)
282
+
283
+ async def _update_hierarchy_links(self, enriched_diffs: EnrichedDiffs) -> None:
284
+ for diff_root in (enriched_diffs.base_branch_diff, enriched_diffs.diff_branch_diff):
285
+ nodes_to_update = []
286
+ for node in diff_root.nodes:
287
+ if any(r.nodes for r in node.relationships):
288
+ nodes_to_update.append(node)
289
+ if len(nodes_to_update) >= config.SETTINGS.database.query_size_limit:
290
+ await self._run_hierarchy_links_update_query(
291
+ diff_root_uuid=diff_root.uuid, diff_nodes=nodes_to_update
292
+ )
293
+ nodes_to_update = []
294
+ if nodes_to_update:
295
+ await self._run_hierarchy_links_update_query(diff_root_uuid=diff_root.uuid, diff_nodes=nodes_to_update)
296
+
297
+ async def _update_summary_counts(self, diff_root: EnrichedDiffRoot) -> None:
298
+ max_nodes_limit = config.SETTINGS.database.query_size_limit
299
+ num_nodes = len(diff_root.nodes)
300
+ if diff_root.exists_on_database and num_nodes < max_nodes_limit:
301
+ await self.add_summary_counts(
302
+ diff_branch_name=diff_root.diff_branch_name,
303
+ diff_id=diff_root.uuid,
304
+ node_uuids=None,
305
+ )
306
+ return
307
+ node_uuids: list[str] = []
308
+ for diff_node in diff_root.nodes:
309
+ node_uuids.append(diff_node.uuid)
310
+ if len(node_uuids) >= max_nodes_limit:
311
+ await self.add_summary_counts(
312
+ diff_branch_name=diff_root.diff_branch_name,
313
+ diff_id=diff_root.uuid,
314
+ node_uuids=node_uuids,
315
+ )
316
+ node_uuids = []
317
+ if node_uuids:
318
+ await self.add_summary_counts(
319
+ diff_branch_name=diff_root.diff_branch_name,
320
+ diff_id=diff_root.uuid,
321
+ node_uuids=node_uuids,
322
+ )
323
+
324
+ async def save(self, enriched_diffs: EnrichedDiffs | EnrichedDiffsMetadata, do_summary_counts: bool = True) -> None:
325
+ # metadata-only update
242
326
  if not isinstance(enriched_diffs, EnrichedDiffs):
327
+ await self._save_root_metadata(enriched_diffs=enriched_diffs)
243
328
  return
244
- num_nodes = len(enriched_diffs.base_branch_diff.nodes) + len(enriched_diffs.diff_branch_diff.nodes)
245
- log.info(f"Saving diff (num_nodes={num_nodes})...")
329
+
330
+ count_nodes_remaining = len(enriched_diffs.base_branch_diff.nodes) + len(enriched_diffs.diff_branch_diff.nodes)
331
+ log.info(f"Saving diff (num_nodes={count_nodes_remaining})...")
246
332
  for batch_num, node_create_batch in enumerate(
247
333
  self._get_node_create_request_batch(enriched_diffs=enriched_diffs)
248
334
  ):
249
335
  log.info(f"Saving node batch #{batch_num}...")
250
- node_query = await EnrichedNodeBatchCreateQuery.init(db=self.db, node_create_batch=node_create_batch)
251
- await node_query.execute(db=self.db)
252
- log.info(f"Batch #{batch_num} saved")
253
- link_query = await EnrichedNodesLinkQuery.init(db=self.db, enriched_diffs=enriched_diffs)
254
- await link_query.execute(db=self.db)
255
- log.info("Diff saved.")
336
+ await self._save_node_batch(node_create_batch=node_create_batch)
337
+ count_nodes_remaining -= len(node_create_batch)
338
+ log.info(f"Batch saved. {count_nodes_remaining=}")
339
+ await self._update_hierarchy_links(enriched_diffs=enriched_diffs)
256
340
  if do_summary_counts:
257
- node_uuids: list[str] | None = None
258
- if enriched_diffs.diff_branch_diff.exists_on_database:
259
- node_uuids = list(enriched_diffs.branch_node_uuids)
260
- await self.add_summary_counts(
261
- diff_branch_name=enriched_diffs.diff_branch_name,
262
- diff_id=enriched_diffs.diff_branch_diff.uuid,
263
- node_uuids=node_uuids,
264
- )
341
+ await self._update_summary_counts(diff_root=enriched_diffs.diff_branch_diff)
342
+ await self._save_root_metadata(enriched_diffs=enriched_diffs)
265
343
 
266
344
  async def summary(
267
345
  self,
@@ -325,7 +403,7 @@ class DiffRepository:
325
403
  roots_by_id = {root.uuid: root for root in empty_roots}
326
404
  pairs: list[EnrichedDiffsMetadata] = []
327
405
  for branch_root in empty_roots:
328
- if branch_root.base_branch_name == branch_root.diff_branch_name:
406
+ if branch_root.base_branch_name == branch_root.diff_branch_name or branch_root.partner_uuid is None:
329
407
  continue
330
408
  base_root = roots_by_id[branch_root.partner_uuid]
331
409
  pairs.append(
@@ -446,8 +524,48 @@ class DiffRepository:
446
524
  diff_id: str | None = None,
447
525
  node_uuids: list[str] | None = None,
448
526
  ) -> None:
449
- log.info("Updating summary counts...")
450
- query = await DiffSummaryCountsEnricherQuery.init(
527
+ await self._add_field_summary_counts(
528
+ diff_branch_name=diff_branch_name,
529
+ tracking_id=tracking_id,
530
+ diff_id=diff_id,
531
+ node_uuids=node_uuids,
532
+ )
533
+ await self._add_node_summary_counts(
534
+ diff_branch_name=diff_branch_name,
535
+ tracking_id=tracking_id,
536
+ diff_id=diff_id,
537
+ node_uuids=node_uuids,
538
+ )
539
+
540
+ @retry_db_transaction(name="enriched_diff_field_summary_counts")
541
+ async def _add_field_summary_counts(
542
+ self,
543
+ diff_branch_name: str,
544
+ tracking_id: TrackingId | None = None,
545
+ diff_id: str | None = None,
546
+ node_uuids: list[str] | None = None,
547
+ ) -> None:
548
+ log.info("Updating field summary counts...")
549
+ query = await DiffFieldsSummaryCountsEnricherQuery.init(
550
+ db=self.db,
551
+ diff_branch_name=diff_branch_name,
552
+ tracking_id=tracking_id,
553
+ diff_id=diff_id,
554
+ node_uuids=node_uuids,
555
+ )
556
+ await query.execute(db=self.db)
557
+ log.info("Field summary counts updated.")
558
+
559
+ @retry_db_transaction(name="enriched_diff_node_summary_counts")
560
+ async def _add_node_summary_counts(
561
+ self,
562
+ diff_branch_name: str,
563
+ tracking_id: TrackingId | None = None,
564
+ diff_id: str | None = None,
565
+ node_uuids: list[str] | None = None,
566
+ ) -> None:
567
+ log.info("Updating node summary counts...")
568
+ query = await DiffNodesSummaryCountsEnricherQuery.init(
451
569
  db=self.db,
452
570
  diff_branch_name=diff_branch_name,
453
571
  tracking_id=tracking_id,
@@ -455,4 +573,4 @@ class DiffRepository:
455
573
  node_uuids=node_uuids,
456
574
  )
457
575
  await query.execute(db=self.db)
458
- log.info("Summary counts updated...")
576
+ log.info("node summary counts updated.")
@@ -1,22 +1,24 @@
1
+ from __future__ import annotations
2
+
1
3
  from prefect import flow
2
4
 
5
+ from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
3
6
  from infrahub.core import registry
4
7
  from infrahub.core.diff.coordinator import DiffCoordinator
5
- from infrahub.core.diff.models import RequestDiffUpdate
8
+ from infrahub.core.diff.models import RequestDiffUpdate # noqa: TC001 needed for prefect flow
6
9
  from infrahub.core.diff.repository.repository import DiffRepository
7
10
  from infrahub.dependencies.registry import get_component_registry
8
11
  from infrahub.log import get_logger
9
- from infrahub.services import services
12
+ from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
10
13
  from infrahub.workflows.catalogue import DIFF_REFRESH
11
- from infrahub.workflows.utils import add_branch_tag
14
+ from infrahub.workflows.utils import add_tags
12
15
 
13
16
  log = get_logger()
14
17
 
15
18
 
16
19
  @flow(name="diff-update", flow_run_name="Update diff for branch {model.branch_name}")
17
- async def update_diff(model: RequestDiffUpdate) -> None:
18
- service = services.service
19
- await add_branch_tag(branch_name=model.branch_name)
20
+ async def update_diff(model: RequestDiffUpdate, service: InfrahubServices) -> None:
21
+ await add_tags(branches=[model.branch_name])
20
22
 
21
23
  async with service.database.start_session() as db:
22
24
  component_registry = get_component_registry()
@@ -35,9 +37,8 @@ async def update_diff(model: RequestDiffUpdate) -> None:
35
37
 
36
38
 
37
39
  @flow(name="diff-refresh", flow_run_name="Recreate diff for branch {branch_name}")
38
- async def refresh_diff(branch_name: str, diff_id: str) -> None:
39
- service = services.service
40
- await add_branch_tag(branch_name=branch_name)
40
+ async def refresh_diff(branch_name: str, diff_id: str, service: InfrahubServices) -> None:
41
+ await add_tags(branches=[branch_name])
41
42
 
42
43
  async with service.database.start_session() as db:
43
44
  component_registry = get_component_registry()
@@ -49,9 +50,8 @@ async def refresh_diff(branch_name: str, diff_id: str) -> None:
49
50
 
50
51
 
51
52
  @flow(name="diff-refresh-all", flow_run_name="Recreate all diffs for branch {branch_name}")
52
- async def refresh_diff_all(branch_name: str) -> None:
53
- service = services.service
54
- await add_branch_tag(branch_name=branch_name)
53
+ async def refresh_diff_all(branch_name: str, context: InfrahubContext, service: InfrahubServices) -> None:
54
+ await add_tags(branches=[branch_name])
55
55
 
56
56
  async with service.database.start_session() as db:
57
57
  component_registry = get_component_registry()
@@ -63,5 +63,6 @@ async def refresh_diff_all(branch_name: str) -> None:
63
63
  if diff_root.base_branch_name != diff_root.diff_branch_name:
64
64
  await service.workflow.submit_workflow(
65
65
  workflow=DIFF_REFRESH,
66
+ context=context,
66
67
  parameters={"branch_name": diff_root.diff_branch_name, "diff_id": diff_root.uuid},
67
68
  )
infrahub/core/enums.py CHANGED
@@ -2,7 +2,7 @@ import enum
2
2
  import re
3
3
  from typing import Any
4
4
 
5
- ENUM_NAME_REGEX = re.compile("[_a-zA-Z0-9]+")
5
+ ENUM_NAME_REGEX = re.compile(r"[_a-zA-Z0-9]+")
6
6
 
7
7
 
8
8
  def generate_python_enum(name: str, options: list[Any]) -> type[enum.Enum]:
@@ -1 +1 @@
1
- GRAPH_VERSION = 18
1
+ GRAPH_VERSION = 20
@@ -12,6 +12,9 @@ node_indexes: list[IndexItem] = [
12
12
  IndexItem(name="attr_iphost_bin", label="AttributeIPHost", properties=["binary_address"], type=IndexType.RANGE),
13
13
  IndexItem(name="rel_uuid", label="Relationship", properties=["uuid"], type=IndexType.RANGE),
14
14
  IndexItem(name="rel_identifier", label="Relationship", properties=["name"], type=IndexType.RANGE),
15
+ # diff indices
16
+ IndexItem(name="diff_uuid", label="DiffRoot", properties=["uuid"], type=IndexType.TEXT),
17
+ IndexItem(name="diff_node_uuid", label="DiffNode", properties=["uuid"], type=IndexType.TEXT),
15
18
  ]
16
19
 
17
20
  rel_indexes: list[IndexItem] = [
@@ -17,7 +17,7 @@ class ObjectConflictValidatorRecorder:
17
17
  self.validator_label = validator_label
18
18
  self.check_schema_kind = check_schema_kind
19
19
 
20
- async def record_conflicts(self, proposed_change_id: str, conflicts: Sequence[ObjectConflict]) -> list[Node]: # pylint: disable=too-many-branches
20
+ async def record_conflicts(self, proposed_change_id: str, conflicts: Sequence[ObjectConflict]) -> list[Node]:
21
21
  try:
22
22
  proposed_change = await NodeManager.get_one_by_id_or_default_filter(
23
23
  id=proposed_change_id, kind=InfrahubKind.PROPOSEDCHANGE, db=self.db
@@ -104,7 +104,7 @@ class IpamReconciler:
104
104
  ip_node_uuid = query.get_ip_node_uuid()
105
105
  if not ip_node_uuid:
106
106
  node_type = InfrahubKind.IPPREFIX
107
- if isinstance(ip_value, (ipaddress.IPv6Interface, ipaddress.IPv4Interface)):
107
+ if isinstance(ip_value, ipaddress.IPv6Interface | ipaddress.IPv4Interface):
108
108
  node_type = InfrahubKind.IPADDRESS
109
109
  raise NodeNotFoundError(node_type=node_type, identifier=str(ip_value))
110
110
  current_parent_uuid = query.get_current_parent_uuid()
@@ -5,7 +5,7 @@ from prefect import flow
5
5
 
6
6
  from infrahub.core import registry
7
7
  from infrahub.core.ipam.reconciler import IpamReconciler
8
- from infrahub.services import services
8
+ from infrahub.services import InfrahubServices
9
9
  from infrahub.workflows.utils import add_branch_tag
10
10
 
11
11
  from .model import IpamNodeDetails
@@ -20,8 +20,7 @@ if TYPE_CHECKING:
20
20
  description="Ensure the IPAM Tree is up to date",
21
21
  persist_result=False,
22
22
  )
23
- async def ipam_reconciliation(branch: str, ipam_node_details: list[IpamNodeDetails]) -> None:
24
- service = services.service
23
+ async def ipam_reconciliation(branch: str, ipam_node_details: list[IpamNodeDetails], service: InfrahubServices) -> None:
25
24
  async with service.database.start_session() as db:
26
25
  branch_obj = await registry.get_branch(db=db, branch=branch)
27
26
 
infrahub/core/manager.py CHANGED
@@ -23,7 +23,14 @@ from infrahub.core.query.node import (
23
23
  from infrahub.core.query.relationship import RelationshipGetPeerQuery
24
24
  from infrahub.core.registry import registry
25
25
  from infrahub.core.relationship import Relationship, RelationshipManager
26
- from infrahub.core.schema import GenericSchema, MainSchemaTypes, NodeSchema, ProfileSchema, RelationshipSchema
26
+ from infrahub.core.schema import (
27
+ GenericSchema,
28
+ MainSchemaTypes,
29
+ NodeSchema,
30
+ ProfileSchema,
31
+ RelationshipSchema,
32
+ TemplateSchema,
33
+ )
27
34
  from infrahub.core.timestamp import Timestamp
28
35
  from infrahub.exceptions import NodeNotFoundError, ProcessingError, SchemaNotFoundError
29
36
  from infrahub.graphql.models import OrderModel
@@ -35,8 +42,6 @@ if TYPE_CHECKING:
35
42
 
36
43
  SchemaProtocol = TypeVar("SchemaProtocol")
37
44
 
38
- # pylint: disable=redefined-builtin,too-many-lines
39
-
40
45
 
41
46
  def identify_node_class(node: NodeToProcess) -> type[Node]:
42
47
  """Identify the proper class to use to create the NodeObject.
@@ -61,7 +66,7 @@ def get_schema(
61
66
  ) -> MainSchemaTypes:
62
67
  if isinstance(node_schema, str):
63
68
  return db.schema.get(name=node_schema, branch=branch.name)
64
- if hasattr(node_schema, "_is_runtime_protocol") and getattr(node_schema, "_is_runtime_protocol"):
69
+ if hasattr(node_schema, "_is_runtime_protocol") and node_schema._is_runtime_protocol:
65
70
  return db.schema.get(name=node_schema.__name__, branch=branch.name)
66
71
  if not isinstance(node_schema, (MainSchemaTypes)):
67
72
  raise ValueError(f"Invalid schema provided {node_schema}")
@@ -129,7 +134,7 @@ class NodeManager:
129
134
  async def query(
130
135
  cls,
131
136
  db: InfrahubDatabase,
132
- schema: Union[NodeSchema, GenericSchema, ProfileSchema, str],
137
+ schema: Union[NodeSchema, GenericSchema, ProfileSchema, TemplateSchema, str],
133
138
  filters: dict | None = ...,
134
139
  fields: dict | None = ...,
135
140
  offset: int | None = ...,
@@ -267,11 +272,11 @@ class NodeManager:
267
272
  async def count(
268
273
  cls,
269
274
  db: InfrahubDatabase,
270
- schema: Union[type[SchemaProtocol], NodeSchema, GenericSchema, ProfileSchema, str],
275
+ schema: Union[type[SchemaProtocol], NodeSchema, GenericSchema, ProfileSchema, TemplateSchema, str],
271
276
  filters: Optional[dict] = None,
272
277
  at: Optional[Union[Timestamp, str]] = None,
273
278
  branch: Optional[Union[Branch, str]] = None,
274
- account=None, # pylint: disable=unused-argument
279
+ account=None, # noqa: ARG003
275
280
  partial_match: bool = False,
276
281
  branch_agnostic: bool = False,
277
282
  ) -> int:
@@ -446,7 +451,7 @@ class NodeManager:
446
451
  limit: Optional[int] = None,
447
452
  at: Optional[Union[Timestamp, str]] = None,
448
453
  branch: Optional[Union[Branch, str]] = None,
449
- ) -> dict[str, Any]:
454
+ ) -> dict[str, Node]:
450
455
  branch = await registry.get_branch(branch=branch, db=db)
451
456
  at = Timestamp(at)
452
457
 
@@ -489,7 +494,7 @@ class NodeManager:
489
494
  kind: type[SchemaProtocol],
490
495
  at: Timestamp | str | None = ...,
491
496
  branch: Branch | str | None = ...,
492
- id: str | None = ..., # pylint: disable=redefined-builtin
497
+ id: str | None = ...,
493
498
  hfid: list[str] | None = ...,
494
499
  ) -> SchemaProtocol: ...
495
500
 
@@ -501,7 +506,7 @@ class NodeManager:
501
506
  kind: str,
502
507
  at: Timestamp | str | None = ...,
503
508
  branch: Branch | str | None = ...,
504
- id: str | None = ..., # pylint: disable=redefined-builtin
509
+ id: str | None = ...,
505
510
  hfid: list[str] | None = ...,
506
511
  ) -> Any: ...
507
512
 
@@ -512,7 +517,7 @@ class NodeManager:
512
517
  kind: type[SchemaProtocol] | str,
513
518
  at: Timestamp | str | None = None,
514
519
  branch: Branch | str | None = None,
515
- id: str | None = None, # pylint: disable=redefined-builtin
520
+ id: str | None = None,
516
521
  hfid: list[str] | None = None,
517
522
  ) -> Any:
518
523
  if not id and not hfid:
@@ -802,7 +807,7 @@ class NodeManager:
802
807
  raise NodeNotFoundError(branch_name=branch.name, node_type=kind_str, identifier=hfid_str)
803
808
 
804
809
  filters = {}
805
- for key, item in zip(node_schema.human_friendly_id, hfid):
810
+ for key, item in zip(node_schema.human_friendly_id, hfid, strict=False):
806
811
  path = node_schema.parse_schema_path(path=key, schema=registry.schema.get_schema_branch(name=branch.name))
807
812
 
808
813
  if path.is_type_relationship:
@@ -1007,7 +1012,7 @@ class NodeManager:
1007
1012
  cls,
1008
1013
  id: str,
1009
1014
  db: InfrahubDatabase,
1010
- kind: Literal[None] = ...,
1015
+ kind: None = ...,
1011
1016
  raise_on_error: bool = ...,
1012
1017
  fields: dict | None = ...,
1013
1018
  at: Timestamp | str | None = ...,
@@ -1148,7 +1153,7 @@ class NodeManager:
1148
1153
 
1149
1154
  nodes: dict[str, Node] = {}
1150
1155
 
1151
- for node_id in ids: # pylint: disable=too-many-nested-blocks
1156
+ for node_id in ids:
1152
1157
  if node_id not in nodes_info_by_id:
1153
1158
  continue
1154
1159
 
@@ -1310,7 +1315,7 @@ class NodeManager:
1310
1315
  nodes: list[Node],
1311
1316
  branch: Optional[Union[Branch, str]] = None,
1312
1317
  at: Optional[Union[Timestamp, str]] = None,
1313
- ) -> list[Any]:
1318
+ ) -> list[Node]:
1314
1319
  """Returns list of deleted nodes because of cascading deletes"""
1315
1320
  branch = await registry.get_branch(branch=branch, db=db)
1316
1321
  node_delete_validator = NodeDeleteValidator(db=db, branch=branch)
infrahub/core/merge.py CHANGED
@@ -19,6 +19,7 @@ if TYPE_CHECKING:
19
19
  from infrahub.core.branch import Branch
20
20
  from infrahub.core.diff.coordinator import DiffCoordinator
21
21
  from infrahub.core.diff.merger.merger import DiffMerger
22
+ from infrahub.core.diff.model.path import EnrichedDiffRoot
22
23
  from infrahub.core.diff.repository.repository import DiffRepository
23
24
  from infrahub.core.models import SchemaUpdateConstraintInfo, SchemaUpdateMigrationInfo
24
25
  from infrahub.core.schema.manager import SchemaDiff
@@ -26,6 +27,7 @@ if TYPE_CHECKING:
26
27
  from infrahub.database import InfrahubDatabase
27
28
  from infrahub.services import InfrahubServices
28
29
 
30
+
29
31
  log = get_logger()
30
32
 
31
33
 
@@ -172,7 +174,7 @@ class BranchMerger:
172
174
  async def merge(
173
175
  self,
174
176
  at: Optional[Union[str, Timestamp]] = None,
175
- ) -> None:
177
+ ) -> EnrichedDiffRoot:
176
178
  """Merge the current branch into main."""
177
179
  if self.source_branch.name == registry.default_branch:
178
180
  raise ValidationError(f"Unable to merge the branch '{self.source_branch.name}' into itself")
@@ -198,8 +200,9 @@ class BranchMerger:
198
200
  # TODO need to find a way to properly communicate back to the user any issue that could come up during the merge
199
201
  # From the Graph or From the repositories
200
202
  self._merge_at = Timestamp(at)
201
- await self.diff_merger.merge_graph(at=self._merge_at)
203
+ branch_diff = await self.diff_merger.merge_graph(at=self._merge_at)
202
204
  await self.merge_repositories()
205
+ return branch_diff
203
206
 
204
207
  async def rollback(self) -> None:
205
208
  await self.diff_merger.rollback(at=self._merge_at)
@@ -20,6 +20,8 @@ from .m015_diff_format_update import Migration015
20
20
  from .m016_diff_delete_bug_fix import Migration016
21
21
  from .m017_add_core_profile import Migration017
22
22
  from .m018_uniqueness_nulls import Migration018
23
+ from .m019_restore_rels_to_time import Migration019
24
+ from .m020_add_generate_template_attr import Migration020
23
25
 
24
26
  if TYPE_CHECKING:
25
27
  from infrahub.core.root import Root
@@ -45,6 +47,8 @@ MIGRATIONS: list[type[Union[GraphMigration, InternalSchemaMigration, ArbitraryMi
45
47
  Migration016,
46
48
  Migration017,
47
49
  Migration018,
50
+ Migration019,
51
+ Migration020,
48
52
  ]
49
53
 
50
54
 
@@ -16,7 +16,7 @@ class Migration001Query01(Query):
16
16
  name = "migration_001_01"
17
17
  type: QueryType = QueryType.WRITE
18
18
 
19
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
19
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
20
20
  query = """
21
21
  MATCH (root:Root)
22
22
  SET root.graph_version = 1
@@ -15,7 +15,7 @@ class Migration002Query01(Query):
15
15
  name = "migration_002_01"
16
16
  type: QueryType = QueryType.WRITE
17
17
 
18
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
18
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
19
19
  query = """
20
20
  MATCH (a:AttributeValue)
21
21
  WHERE a.is_default IS NULL
@@ -30,7 +30,7 @@ class Migration002(GraphMigration):
30
30
  queries: Sequence[type[Query]] = [Migration002Query01]
31
31
  minimum_version: int = 1
32
32
 
33
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
33
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
34
34
  result = MigrationResult()
35
35
 
36
36
  return result
@@ -16,7 +16,7 @@ class Migration003Query01(Query):
16
16
  name = "migration_003_01"
17
17
  type: QueryType = QueryType.WRITE
18
18
 
19
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
19
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
20
20
  at = Timestamp()
21
21
  filters, params = at.get_query_filter_path()
22
22
 
@@ -49,7 +49,7 @@ class Migration003(GraphMigration):
49
49
  queries: Sequence[type[Query]] = [Migration003Query01]
50
50
  minimum_version: int = 2
51
51
 
52
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
52
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
53
53
  result = MigrationResult()
54
54
 
55
55
  return result
@@ -43,6 +43,6 @@ class Migration004(InternalSchemaMigration):
43
43
  ]
44
44
  return cls(migrations=migrations, **kwargs) # type: ignore[arg-type]
45
45
 
46
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
46
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
47
47
  result = MigrationResult()
48
48
  return result
@@ -35,6 +35,6 @@ class Migration005(InternalSchemaMigration):
35
35
  ]
36
36
  return cls(migrations=migrations, **kwargs) # type: ignore[arg-type]
37
37
 
38
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
38
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
39
39
  result = MigrationResult()
40
40
  return result
@@ -35,6 +35,6 @@ class Migration006(InternalSchemaMigration):
35
35
  ]
36
36
  return cls(migrations=migrations, **kwargs) # type: ignore[arg-type]
37
37
 
38
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
38
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
39
39
  result = MigrationResult()
40
40
  return result
@@ -43,6 +43,6 @@ class Migration007(InternalSchemaMigration):
43
43
  ]
44
44
  return cls(migrations=migrations, **kwargs) # type: ignore[arg-type]
45
45
 
46
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
46
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
47
47
  result = MigrationResult()
48
48
  return result