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
@@ -5,29 +5,38 @@ from infrahub.core.constants import RelationshipHierarchyDirection, Relationship
5
5
  from infrahub.core.constants.database import DatabaseEdgeType
6
6
  from infrahub.core.query.node import NodeGetHierarchyQuery
7
7
  from infrahub.core.query.relationship import RelationshipGetPeerQuery, RelationshipPeerData
8
- from infrahub.core.schema import ProfileSchema
8
+ from infrahub.core.schema import ProfileSchema, TemplateSchema
9
9
  from infrahub.database import InfrahubDatabase
10
+ from infrahub.log import get_logger
10
11
 
11
12
  from ..model.path import (
12
13
  CalculatedDiffs,
13
14
  EnrichedDiffRoot,
14
15
  )
16
+ from ..parent_node_adder import DiffParentNodeAdder, ParentNodeAddRequest
15
17
  from .interface import DiffEnricherInterface
16
18
 
19
+ log = get_logger()
20
+
17
21
 
18
22
  class DiffHierarchyEnricher(DiffEnricherInterface):
19
23
  """Add hierarchy and parent/component nodes to diff even if the higher-level nodes are unchanged"""
20
24
 
21
- def __init__(self, db: InfrahubDatabase):
25
+ def __init__(self, db: InfrahubDatabase, parent_adder: DiffParentNodeAdder):
22
26
  self.db = db
27
+ self.parent_adder = parent_adder
23
28
 
24
29
  async def enrich(
25
- self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs | None = None
30
+ self,
31
+ enriched_diff_root: EnrichedDiffRoot,
32
+ calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
26
33
  ) -> None:
27
34
  # A hierarchy can be defined in 2 ways
28
35
  # - A node has a relationship of kind parent
29
36
  # - A node is part of a hierarchy
30
37
 
38
+ log.info("Beginning hierarchical diff enrichment...")
39
+ self.parent_adder.initialize(enriched_diff_root=enriched_diff_root)
31
40
  node_rel_parent_map: dict[str, list[str]] = defaultdict(list)
32
41
  node_hierarchy_map: dict[str, list[str]] = defaultdict(list)
33
42
 
@@ -36,7 +45,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
36
45
  name=node.kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
37
46
  )
38
47
 
39
- if isinstance(schema_node, ProfileSchema):
48
+ if isinstance(schema_node, ProfileSchema | TemplateSchema):
40
49
  continue
41
50
 
42
51
  if schema_node.has_parent_relationship:
@@ -53,6 +62,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
53
62
 
54
63
  await self._enrich_nodes_with_parent(enriched_diff_root=enriched_diff_root, node_map=node_rel_parent_map)
55
64
  await self._enrich_hierarchical_nodes(enriched_diff_root=enriched_diff_root, node_map=node_hierarchy_map)
65
+ log.info("Hierarchical diff enrichment complete.")
56
66
 
57
67
  async def _enrich_hierarchical_nodes(
58
68
  self,
@@ -63,6 +73,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
63
73
 
64
74
  # Retrieve the ID of all ancestors
65
75
  for kind, node_ids in node_map.items():
76
+ log.info(f"Beginning hierarchy enrichment for {kind} node, num_nodes={len(node_ids)}...")
66
77
  hierarchy_schema = self.db.schema.get(
67
78
  name=kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
68
79
  )
@@ -87,7 +98,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
87
98
 
88
99
  current_node = node
89
100
  for ancestor in ancestors:
90
- parent = enriched_diff_root.add_parent(
101
+ parent_request = ParentNodeAddRequest(
91
102
  node_id=current_node.uuid,
92
103
  parent_id=str(ancestor.uuid),
93
104
  parent_kind=ancestor.kind,
@@ -97,6 +108,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
97
108
  parent_rel_cardinality=parent_rel.cardinality,
98
109
  parent_rel_label=parent_rel.label or "",
99
110
  )
111
+ parent = self.parent_adder.add_parent(parent_request=parent_request)
100
112
 
101
113
  current_node = parent
102
114
 
@@ -114,6 +126,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
114
126
 
115
127
  # Query the UUID of the parent
116
128
  for kind, ids in node_map.items():
129
+ log.info(f"Beginning parent enrichment for {kind} node, num_nodes={len(ids)}...")
117
130
  schema_node = self.db.schema.get(name=kind, branch=enriched_diff_root.diff_branch_name, duplicate=False)
118
131
 
119
132
  parent_rel = [rel for rel in schema_node.relationships if rel.kind == RelationshipKind.PARENT][0]
@@ -138,15 +151,16 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
138
151
  # Check if the parent are already present
139
152
  # If parent is already in the list of node we need to add a relationship
140
153
  # If parent is not in the list of node, we need to add it
154
+ diff_node_map = enriched_diff_root.get_node_map(node_uuids=set(parent_peers.keys()))
141
155
  for node_id, peer_parent in parent_peers.items():
142
156
  # TODO check if we can optimize this part to avoid querying this multiple times
143
- node = enriched_diff_root.get_node(node_uuid=node_id)
157
+ node = diff_node_map[node_id]
144
158
  schema_node = self.db.schema.get(
145
159
  name=node.kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
146
160
  )
147
161
  parent_rel = [rel for rel in schema_node.relationships if rel.kind == RelationshipKind.PARENT][0]
148
162
 
149
- enriched_diff_root.add_parent(
163
+ parent_request = ParentNodeAddRequest(
150
164
  node_id=node.uuid,
151
165
  parent_id=str(peer_parent.peer_id),
152
166
  parent_kind=peer_parent.peer_kind,
@@ -156,6 +170,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
156
170
  parent_rel_cardinality=parent_rel.cardinality,
157
171
  parent_rel_label=parent_rel.label or "",
158
172
  )
173
+ self.parent_adder.add_parent(parent_request=parent_request)
159
174
 
160
175
  if node_parent_with_parent_map:
161
176
  await self._enrich_nodes_with_parent(
@@ -6,6 +6,7 @@ from infrahub.core.constants import DiffAction
6
6
  from infrahub.core.constants.database import DatabaseEdgeType
7
7
  from infrahub.core.query.node import NodeGetKindQuery
8
8
  from infrahub.database import InfrahubDatabase
9
+ from infrahub.log import get_logger
9
10
 
10
11
  from ..model.path import (
11
12
  CalculatedDiffs,
@@ -17,6 +18,8 @@ from ..model.path import (
17
18
  from ..payload_builder import get_display_labels
18
19
  from .interface import DiffEnricherInterface
19
20
 
21
+ log = get_logger()
22
+
20
23
  PROPERTY_TYPES_WITH_LABELS = {DatabaseEdgeType.IS_RELATED, DatabaseEdgeType.HAS_OWNER, DatabaseEdgeType.HAS_SOURCE}
21
24
 
22
25
 
@@ -191,9 +194,10 @@ class DiffLabelsEnricher(DiffEnricherInterface):
191
194
  async def enrich(
192
195
  self,
193
196
  enriched_diff_root: EnrichedDiffRoot,
194
- calculated_diffs: CalculatedDiffs | None = None,
197
+ calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
195
198
  conflicts_only: bool = False,
196
199
  ) -> None:
200
+ log.info("Beginning display labels diff enrichment...")
197
201
  self._base_branch_name = enriched_diff_root.base_branch_name
198
202
  self._diff_branch_name = enriched_diff_root.diff_branch_name
199
203
  self._conflicts_only = conflicts_only
@@ -214,3 +218,4 @@ class DiffLabelsEnricher(DiffEnricherInterface):
214
218
  ...
215
219
 
216
220
  self._update_relationship_labels(enriched_diff=enriched_diff_root)
221
+ log.info("Display labels diff enrichment complete.")
@@ -1,10 +1,13 @@
1
1
  from infrahub.core.constants import PathType
2
2
  from infrahub.core.path import DataPath
3
3
  from infrahub.database import InfrahubDatabase
4
+ from infrahub.log import get_logger
4
5
 
5
6
  from ..model.path import CalculatedDiffs, EnrichedDiffRoot
6
7
  from .interface import DiffEnricherInterface
7
8
 
9
+ log = get_logger()
10
+
8
11
 
9
12
  class DiffPathIdentifierEnricher(DiffEnricherInterface):
10
13
  """Add path identifiers to every element in the diff"""
@@ -19,7 +22,7 @@ class DiffPathIdentifierEnricher(DiffEnricherInterface):
19
22
  raise RuntimeError("diff_branch_name not set")
20
23
  return self._diff_branch_name
21
24
 
22
- async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None:
25
+ async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None: # noqa: ARG002
23
26
  self._diff_branch_name = enriched_diff_root.diff_branch_name
24
27
  for node in enriched_diff_root.nodes:
25
28
  node_path = DataPath(
@@ -62,3 +65,4 @@ class DiffPathIdentifierEnricher(DiffEnricherInterface):
62
65
  relationship_property_path = relationship_element_path.model_copy()
63
66
  relationship_property_path.property_name = relationship_property.property_type.value
64
67
  relationship_property.path_identifier = relationship_property_path.get_path(with_peer=False)
68
+ log.info("Path identifier diff enrichment complete.")
@@ -0,0 +1,107 @@
1
+ from collections import Counter
2
+ from typing import Iterable
3
+
4
+ from infrahub.core.constants import DiffAction
5
+
6
+ from ..model.path import (
7
+ BaseSummary,
8
+ CalculatedDiffs,
9
+ EnrichedDiffAttribute,
10
+ EnrichedDiffNode,
11
+ EnrichedDiffRelationship,
12
+ EnrichedDiffRoot,
13
+ EnrichedDiffSingleRelationship,
14
+ )
15
+ from .interface import DiffEnricherInterface
16
+
17
+
18
+ class DiffSummaryCountsEnricher(DiffEnricherInterface):
19
+ async def enrich(
20
+ self,
21
+ enriched_diff_root: EnrichedDiffRoot,
22
+ calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
23
+ ) -> None:
24
+ self._add_root_summaries(diff_root=enriched_diff_root)
25
+
26
+ def _add_summary(self, summary_node: BaseSummary, actions: Iterable[DiffAction]) -> None:
27
+ summary_count = Counter(actions)
28
+ summary_node.num_added = summary_count.get(DiffAction.ADDED, 0)
29
+ summary_node.num_updated = summary_count.get(DiffAction.UPDATED, 0)
30
+ summary_node.num_removed = summary_count.get(DiffAction.REMOVED, 0)
31
+
32
+ def _add_root_summaries(self, diff_root: EnrichedDiffRoot) -> None:
33
+ contains_conflict = False
34
+ num_conflicts = 0
35
+ for diff_node in diff_root.nodes:
36
+ contains_conflict |= self._add_node_summaries(diff_node=diff_node)
37
+ if diff_node.conflict or diff_node.contains_conflict:
38
+ num_conflicts += 1
39
+ self._add_summary(summary_node=diff_root, actions=(n.action for n in diff_root.nodes))
40
+ diff_root.contains_conflict = contains_conflict
41
+ diff_root.num_conflicts = num_conflicts
42
+ self._add_child_nodes_to_summaries(diff_root=diff_root)
43
+
44
+ def _add_node_summaries(self, diff_node: EnrichedDiffNode) -> bool:
45
+ contains_conflict = False
46
+ num_conflicts = 0
47
+ for diff_attr in diff_node.attributes:
48
+ contains_conflict |= self._add_attribute_summaries(diff_attribute=diff_attr)
49
+ if diff_attr.contains_conflict:
50
+ num_conflicts += 1
51
+ for diff_rel in diff_node.relationships:
52
+ contains_conflict |= self._add_relationship_summaries(diff_relationship=diff_rel)
53
+ if diff_rel.contains_conflict:
54
+ num_conflicts += 1
55
+ self._add_summary(
56
+ summary_node=diff_node, actions=(field.action for field in diff_node.relationships | diff_node.attributes)
57
+ )
58
+ diff_node.contains_conflict = contains_conflict
59
+ diff_node.num_conflicts = num_conflicts
60
+ return contains_conflict
61
+
62
+ def _add_attribute_summaries(self, diff_attribute: EnrichedDiffAttribute) -> bool:
63
+ contains_conflict = False
64
+ num_conflicts = 0
65
+ for diff_prop in diff_attribute.properties:
66
+ if diff_prop.conflict:
67
+ num_conflicts += 1
68
+ contains_conflict = True
69
+ self._add_summary(summary_node=diff_attribute, actions=(p.action for p in diff_attribute.properties))
70
+ diff_attribute.contains_conflict = contains_conflict
71
+ diff_attribute.num_conflicts = num_conflicts
72
+ return contains_conflict
73
+
74
+ def _add_relationship_summaries(self, diff_relationship: EnrichedDiffRelationship) -> bool:
75
+ contains_conflict = False
76
+ num_conflicts = 0
77
+ for diff_element in diff_relationship.relationships:
78
+ contains_conflict |= self._add_element_summaries(diff_element=diff_element)
79
+ if diff_element.conflict:
80
+ num_conflicts += 1
81
+ self._add_summary(summary_node=diff_relationship, actions=(e.action for e in diff_relationship.relationships))
82
+ diff_relationship.contains_conflict = contains_conflict
83
+ diff_relationship.num_conflicts = num_conflicts
84
+ return contains_conflict
85
+
86
+ def _add_element_summaries(self, diff_element: EnrichedDiffSingleRelationship) -> bool:
87
+ if diff_element.conflict is None:
88
+ contains_conflict = False
89
+ num_conflicts = 0
90
+ else:
91
+ contains_conflict = True
92
+ num_conflicts = 1
93
+ for diff_prop in diff_element.properties:
94
+ if diff_prop.conflict:
95
+ num_conflicts += 1
96
+ contains_conflict = True
97
+ self._add_summary(summary_node=diff_element, actions=(p.action for p in diff_element.properties))
98
+ diff_element.contains_conflict = contains_conflict
99
+ diff_element.num_conflicts = num_conflicts
100
+ return contains_conflict
101
+
102
+ def _add_child_nodes_to_summaries(self, diff_root: EnrichedDiffRoot) -> None:
103
+ for diff_node in diff_root.nodes:
104
+ for diff_rel in diff_node.relationships:
105
+ if not diff_rel.contains_conflict:
106
+ diff_rel.contains_conflict = any(n.contains_conflict for n in diff_rel.nodes)
107
+ diff_rel.num_conflicts += sum(bool(n.contains_conflict or n.conflict) for n in diff_rel.nodes)
@@ -9,6 +9,7 @@ from infrahub.log import get_logger
9
9
 
10
10
  if TYPE_CHECKING:
11
11
  from infrahub.core.branch import Branch
12
+ from infrahub.core.diff.model.path import EnrichedDiffRoot
12
13
  from infrahub.core.diff.repository.repository import DiffRepository
13
14
  from infrahub.core.timestamp import Timestamp
14
15
  from infrahub.database import InfrahubDatabase
@@ -33,7 +34,7 @@ class DiffMerger:
33
34
  self.diff_repository = diff_repository
34
35
  self.serializer = serializer
35
36
 
36
- async def merge_graph(self, at: Timestamp) -> None:
37
+ async def merge_graph(self, at: Timestamp) -> EnrichedDiffRoot:
37
38
  tracking_id = BranchTrackingId(name=self.source_branch.name)
38
39
  enriched_diffs = await self.diff_repository.get_roots_metadata(
39
40
  diff_branch_names=[self.source_branch.name],
@@ -77,6 +78,7 @@ class DiffMerger:
77
78
  self.source_branch.branched_from = at.to_string()
78
79
  await self.source_branch.save(db=self.db)
79
80
  registry.branch[self.source_branch.name] = self.source_branch
81
+ return enriched_diff
80
82
 
81
83
  async def rollback(self, at: Timestamp) -> None:
82
84
  rollback_query = await DiffMergeRollbackQuery.init(
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
20
20
  from neo4j.graph import Node as Neo4jNode
21
21
  from neo4j.graph import Path as Neo4jPath
22
22
  from neo4j.graph import Relationship as Neo4jRelationship
23
- from pendulum import Interval
23
+ from whenever import TimeDelta
24
24
 
25
25
  from infrahub.graphql.initialization import GraphqlContext
26
26
 
@@ -163,6 +163,10 @@ class EnrichedDiffAttribute(BaseSummary):
163
163
  def __hash__(self) -> int:
164
164
  return hash(self.name)
165
165
 
166
+ @property
167
+ def num_properties(self) -> int:
168
+ return len(self.properties)
169
+
166
170
  def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
167
171
  return {prop.path_identifier: prop.conflict for prop in self.properties if prop.conflict}
168
172
 
@@ -202,6 +206,10 @@ class EnrichedDiffSingleRelationship(BaseSummary):
202
206
  def __hash__(self) -> int:
203
207
  return hash(self.peer_id)
204
208
 
209
+ @property
210
+ def num_properties(self) -> int:
211
+ return len(self.properties)
212
+
205
213
  def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
206
214
  all_conflicts: dict[str, EnrichedDiffConflict] = {}
207
215
  if self.conflict:
@@ -248,6 +256,10 @@ class EnrichedDiffRelationship(BaseSummary):
248
256
  def __hash__(self) -> int:
249
257
  return hash(self.name)
250
258
 
259
+ @property
260
+ def num_properties(self) -> int:
261
+ return sum(r.num_properties for r in self.relationships)
262
+
251
263
  def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
252
264
  all_conflicts: dict[str, EnrichedDiffConflict] = {}
253
265
  for element in self.relationships:
@@ -308,6 +320,10 @@ class EnrichedDiffNode(BaseSummary):
308
320
  def __hash__(self) -> int:
309
321
  return hash(self.uuid)
310
322
 
323
+ @property
324
+ def num_properties(self) -> int:
325
+ return sum(a.num_properties for a in self.attributes) + sum(r.num_properties for r in self.relationships)
326
+
311
327
  def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
312
328
  all_conflicts: dict[str, EnrichedDiffConflict] = {}
313
329
  if self.conflict:
@@ -325,18 +341,18 @@ class EnrichedDiffNode(BaseSummary):
325
341
  rel.clear_conflicts()
326
342
  self.conflict = None
327
343
 
328
- def get_parent_info(self, context: GraphqlContext | None = None) -> ParentNodeInfo | None:
344
+ def get_parent_info(self, graphql_context: GraphqlContext | None = None) -> ParentNodeInfo | None:
329
345
  for r in self.relationships:
330
346
  for n in r.nodes:
331
347
  relationship_name: str = "undefined"
332
348
 
333
- if not context:
349
+ if not graphql_context:
334
350
  return ParentNodeInfo(node=n, relationship_name=relationship_name)
335
351
 
336
- node_schema = context.db.schema.get(name=self.kind)
352
+ node_schema = graphql_context.db.schema.get(name=self.kind)
337
353
  rel_schema = node_schema.get_relationship(name=r.name)
338
354
 
339
- parent_schema = context.db.schema.get(name=n.kind)
355
+ parent_schema = graphql_context.db.schema.get(name=n.kind)
340
356
  rels_parent = parent_schema.get_relationships_by_identifier(id=rel_schema.get_identifier())
341
357
 
342
358
  if rels_parent and len(rels_parent) == 1:
@@ -409,16 +425,16 @@ class EnrichedDiffRootMetadata(BaseSummary):
409
425
  from_time: Timestamp
410
426
  to_time: Timestamp
411
427
  uuid: str
412
- partner_uuid: str
413
428
  tracking_id: TrackingId
429
+ partner_uuid: str | None = field(default=None)
414
430
  exists_on_database: bool = field(default=False)
415
431
 
416
432
  def __hash__(self) -> int:
417
433
  return hash(self.uuid)
418
434
 
419
435
  @property
420
- def time_range(self) -> Interval:
421
- return self.to_time.obj - self.from_time.obj
436
+ def time_range(self) -> TimeDelta:
437
+ return self.to_time.get_obj() - self.from_time.get_obj()
422
438
 
423
439
  def update_metadata(
424
440
  self,
@@ -447,8 +463,8 @@ class EnrichedDiffRoot(EnrichedDiffRootMetadata):
447
463
  return hash(self.uuid)
448
464
 
449
465
  @property
450
- def time_range(self) -> Interval:
451
- return self.to_time.obj - self.from_time.obj
466
+ def time_range(self) -> TimeDelta:
467
+ return self.to_time.get_obj() - self.from_time.get_obj()
452
468
 
453
469
  def get_nodes_without_parents(self) -> set[EnrichedDiffNode]:
454
470
  nodes_with_parent_uuids = set()
@@ -470,6 +486,13 @@ class EnrichedDiffRoot(EnrichedDiffRootMetadata):
470
486
  except ValueError:
471
487
  return False
472
488
 
489
+ def get_node_map(self, node_uuids: set[str] | None = None) -> dict[str, EnrichedDiffNode]:
490
+ node_map = {}
491
+ for node in self.nodes:
492
+ if node_uuids is None or node.uuid in node_uuids:
493
+ node_map[node.uuid] = node
494
+ return node_map
495
+
473
496
  def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
474
497
  all_conflicts: dict[str, EnrichedDiffConflict] = {}
475
498
  for node in self.nodes:
@@ -692,7 +715,7 @@ class DiffRoot:
692
715
 
693
716
 
694
717
  @dataclass
695
- class DatabasePath: # pylint: disable=too-many-public-methods
718
+ class DatabasePath:
696
719
  root_node: Neo4jNode
697
720
  path_to_node: Neo4jRelationship
698
721
  node_node: Neo4jNode
@@ -0,0 +1,78 @@
1
+ from dataclasses import dataclass, field
2
+
3
+ from infrahub.core.constants import DiffAction, RelationshipCardinality
4
+
5
+ from .model.path import EnrichedDiffNode, EnrichedDiffRelationship, EnrichedDiffRoot
6
+
7
+
8
+ @dataclass
9
+ class ParentNodeAddRequest:
10
+ node_id: str
11
+ parent_id: str
12
+ parent_kind: str
13
+ parent_label: str
14
+ parent_rel_name: str
15
+ parent_rel_identifier: str
16
+ parent_rel_cardinality: RelationshipCardinality
17
+ parent_rel_label: str = field(default="")
18
+
19
+
20
+ class DiffParentNodeAdder:
21
+ def __init__(self) -> None:
22
+ self._diff_root: EnrichedDiffRoot | None = None
23
+ self._node_map: dict[str, EnrichedDiffNode] = {}
24
+
25
+ def initialize(self, enriched_diff_root: EnrichedDiffRoot) -> None:
26
+ self._diff_root = enriched_diff_root
27
+ self._node_map = enriched_diff_root.get_node_map()
28
+
29
+ def get_root(self) -> EnrichedDiffRoot:
30
+ if not self._diff_root:
31
+ raise RuntimeError("Must call initialize before using")
32
+ return self._diff_root
33
+
34
+ def get_node(self, node_uuid: str) -> EnrichedDiffNode:
35
+ return self._node_map[node_uuid]
36
+
37
+ def has_node(self, node_uuid: str) -> bool:
38
+ return node_uuid in self._node_map
39
+
40
+ def add_node(self, node: EnrichedDiffNode) -> None:
41
+ if node.uuid in self._node_map:
42
+ return
43
+ self._node_map[node.uuid] = node
44
+ self.get_root().nodes.add(node)
45
+
46
+ def add_parent(self, parent_request: ParentNodeAddRequest) -> EnrichedDiffNode:
47
+ if not self._diff_root:
48
+ raise RuntimeError("Must call initialize before using")
49
+ node = self.get_node(node_uuid=parent_request.node_id)
50
+ if not self.has_node(node_uuid=parent_request.parent_id):
51
+ parent = EnrichedDiffNode(
52
+ uuid=parent_request.parent_id,
53
+ kind=parent_request.parent_kind,
54
+ label=parent_request.parent_label,
55
+ action=DiffAction.UNCHANGED,
56
+ changed_at=None,
57
+ )
58
+ self.add_node(parent)
59
+ else:
60
+ parent = self.get_node(node_uuid=parent_request.parent_id)
61
+
62
+ try:
63
+ rel = node.get_relationship(name=parent_request.parent_rel_name)
64
+ rel.nodes.add(parent)
65
+ except ValueError:
66
+ node.relationships.add(
67
+ EnrichedDiffRelationship(
68
+ name=parent_request.parent_rel_name,
69
+ identifier=parent_request.parent_rel_identifier,
70
+ label=parent_request.parent_rel_label,
71
+ cardinality=parent_request.parent_rel_cardinality,
72
+ changed_at=None,
73
+ action=DiffAction.UNCHANGED,
74
+ nodes={parent},
75
+ )
76
+ )
77
+
78
+ return parent
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
+ from infrahub import config
5
6
  from infrahub.core.manager import NodeManager
6
7
  from infrahub.core.registry import registry
7
8
  from infrahub.exceptions import SchemaNotFoundError
@@ -26,8 +27,18 @@ async def get_display_labels_per_kind(
26
27
  if skip_missing_schema:
27
28
  return {}
28
29
  raise
29
- nodes = await NodeManager.get_many(ids=ids, fields=fields, db=db, branch=branch)
30
- return {node_id: await node.render_display_label(db=db) for node_id, node in nodes.items()}
30
+ display_label_map: dict[str, str] = {}
31
+ offset = 0
32
+ limit = config.SETTINGS.database.query_size_limit
33
+ while True:
34
+ limited_ids = ids[offset : offset + limit]
35
+ if not limited_ids:
36
+ break
37
+ node_map = await NodeManager.get_many(ids=limited_ids, fields=fields, db=db, branch=branch)
38
+ for node_id, node in node_map.items():
39
+ display_label_map[node_id] = await node.render_display_label(db=db)
40
+ offset += limit
41
+ return display_label_map
31
42
 
32
43
 
33
44
  async def get_display_labels(nodes: dict[str, dict[str, list[str]]], db: InfrahubDatabase) -> dict[str, dict[str, str]]:
@@ -24,7 +24,7 @@ class EnrichedDiffAllConflictsQuery(Query):
24
24
  if self.tracking_id is None and self.diff_id is None:
25
25
  raise RuntimeError("tracking_id or diff_id is required")
26
26
 
27
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
27
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
28
28
  self.params = {
29
29
  "diff_branch_name": self.diff_branch_name,
30
30
  "diff_id": self.diff_id,
@@ -22,7 +22,7 @@ class ArtifactDiffQuery(Query):
22
22
  self.target_rel_identifier = target_rel_identifier
23
23
  self.definition_rel_identifier = definition_rel_identifier
24
24
 
25
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
25
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
26
26
  source_branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
27
27
  self.params.update(branch_params)
28
28
 
@@ -13,7 +13,7 @@ class EnrichedDiffDeleteQuery(Query):
13
13
  super().__init__(**kwargs)
14
14
  self.enriched_diff_root_uuids = enriched_diff_root_uuids
15
15
 
16
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
16
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
17
17
  self.params = {"diff_root_uuids": self.enriched_diff_root_uuids}
18
18
  query = """
19
19
  MATCH (d_root:DiffRoot)
@@ -52,7 +52,7 @@ class EnrichedDiffGetQuery(Query):
52
52
  self.diff_ids = diff_ids
53
53
  self.filters = filters or EnrichedDiffQueryFilters()
54
54
 
55
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
55
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
56
56
  self.params = {
57
57
  "base_branch": self.base_branch_name,
58
58
  "diff_branches": self.diff_branch_names,
@@ -61,7 +61,7 @@ class DiffSummaryQuery(Query):
61
61
  self.to_time = to_time
62
62
  self.tracking_id = tracking_id
63
63
 
64
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
64
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
65
65
  if (self.from_time is None or self.to_time is None) and self.tracking_id is None:
66
66
  raise ValueError("DiffSummaryQuery requires from_time and to_time or tracking_id ")
67
67
  self.params = {
@@ -12,7 +12,7 @@ class EnrichedDiffFieldSpecifiersQuery(Query):
12
12
  super().__init__(**kwargs)
13
13
  self.diff_id = diff_id
14
14
 
15
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
15
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
16
16
  self.params["diff_id"] = self.diff_id
17
17
  query = """
18
18
  CALL {
@@ -27,7 +27,7 @@ class EnrichedDiffNodeFieldSummaryQuery(Query):
27
27
  self.tracking_id = tracking_id
28
28
  self.diff_id = diff_id
29
29
 
30
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
30
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
31
31
  if self.tracking_id is None and self.diff_id is None:
32
32
  raise RuntimeError("Either tacking_id or diff_id is required")
33
33
  self.params = {
@@ -16,8 +16,8 @@ class IncExclFilterOptions(BaseModel):
16
16
 
17
17
 
18
18
  class IncExclActionFilterOptions(BaseModel):
19
- includes: set[DiffAction] = Field(default_factory=list)
20
- excludes: set[DiffAction] = Field(default_factory=list)
19
+ includes: set[DiffAction] = Field(default_factory=set)
20
+ excludes: set[DiffAction] = Field(default_factory=set)
21
21
 
22
22
  @property
23
23
  def is_empty(self) -> bool:
@@ -14,7 +14,7 @@ class EnrichedDiffConflictQuery(Query):
14
14
  super().__init__(**kwargs)
15
15
  self.conflict_id = conflict_id
16
16
 
17
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
17
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
18
18
  self.params = {"conflict_id": self.conflict_id}
19
19
  query = "MATCH (conflict:DiffConflict {uuid: $conflict_id})"
20
20
  self.return_labels = ["conflict"]
@@ -25,7 +25,7 @@ class EnrichedDiffHasConflictQuery(Query):
25
25
  self.tracking_id = tracking_id
26
26
  self.diff_id = diff_id
27
27
 
28
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
28
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
29
29
  self.params = {
30
30
  "diff_branch_name": self.diff_branch_name,
31
31
  "tracking_id": self.tracking_id.serialize() if self.tracking_id else None,