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
@@ -43,6 +43,6 @@ class Migration008(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 Migration009(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 Migration010(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
@@ -16,7 +16,7 @@ class Migration011Query01(Query):
16
16
  type: QueryType = QueryType.WRITE
17
17
  insert_return = False
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
  // get all the SchemaRelationship nodes for 'profiles' relationships
22
22
  MATCH (sr_to_delete:SchemaRelationship)-[HAS_ATTRIBUTE]->(:Attribute {name: "name"})-[HAS_VALUE]->(av:AttributeValue {value: "profiles"})
@@ -42,7 +42,7 @@ class Migration011(GraphMigration):
42
42
  queries: Sequence[type[Query]] = [Migration011Query01]
43
43
  minimum_version: int = 10
44
44
 
45
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
45
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
46
46
  result = MigrationResult()
47
47
 
48
48
  return result
@@ -54,8 +54,7 @@ class Migration012RenameTypeAttributeData(AttributeRenameQuery):
54
54
  branch_support=BranchSupportType.AGNOSTIC.value,
55
55
  )
56
56
 
57
- if "branch" in kwargs:
58
- del kwargs["branch"]
57
+ kwargs.pop("branch", None)
59
58
 
60
59
  super().__init__(new_attr=new_attr, previous_attr=previous_attr, branch=global_branch, **kwargs)
61
60
 
@@ -113,8 +112,7 @@ class Migration012AddLabelData(NodeDuplicateQuery):
113
112
  sync_with_git=False,
114
113
  )
115
114
 
116
- if "branch" in kwargs:
117
- del kwargs["branch"]
115
+ kwargs.pop("branch", None)
118
116
 
119
117
  super().__init__(new_node=new_node, previous_node=previous_node, branch=branch, **kwargs)
120
118
 
@@ -165,8 +163,7 @@ class Migration012RenameRelationshipAccountTokenData(RelationshipDuplicateQuery)
165
163
  dst_peer=InfrahubKind.ACCOUNTTOKEN,
166
164
  )
167
165
 
168
- if "branch" in kwargs:
169
- del kwargs["branch"]
166
+ kwargs.pop("branch", None)
170
167
 
171
168
  super().__init__(new_rel=new_rel, previous_rel=previous_rel, branch=global_branch, **kwargs)
172
169
 
@@ -189,8 +186,7 @@ class Migration012RenameRelationshipRefreshTokenData(RelationshipDuplicateQuery)
189
186
  dst_peer=InfrahubKind.REFRESHTOKEN,
190
187
  )
191
188
 
192
- if "branch" in kwargs:
193
- del kwargs["branch"]
189
+ kwargs.pop("branch", None)
194
190
 
195
191
  super().__init__(new_rel=new_rel, previous_rel=previous_rel, branch=global_branch, **kwargs)
196
192
 
@@ -213,8 +209,7 @@ class Migration012RenameRelationshipThreadData(RelationshipDuplicateQuery):
213
209
  dst_peer=InfrahubKind.THREAD,
214
210
  )
215
211
 
216
- if "branch" in kwargs:
217
- del kwargs["branch"]
212
+ kwargs.pop("branch", None)
218
213
 
219
214
  super().__init__(new_rel=new_rel, previous_rel=previous_rel, branch=global_branch, **kwargs)
220
215
 
@@ -237,8 +232,7 @@ class Migration012RenameRelationshipCommentData(RelationshipDuplicateQuery):
237
232
  dst_peer=InfrahubKind.COMMENT,
238
233
  )
239
234
 
240
- if "branch" in kwargs:
241
- del kwargs["branch"]
235
+ kwargs.pop("branch", None)
242
236
 
243
237
  super().__init__(new_rel=new_rel, previous_rel=previous_rel, branch=default_branch, **kwargs)
244
238
 
@@ -249,8 +243,7 @@ class Migration012DeleteOldElementsSchema(DeleteElementInSchemaQuery):
249
243
  insert_return = False
250
244
 
251
245
  def __init__(self, **kwargs: Any):
252
- if "branch" in kwargs:
253
- del kwargs["branch"]
246
+ kwargs.pop("branch", None)
254
247
 
255
248
  super().__init__(
256
249
  element_names=["name", "password", "label", "description", "type", "role", "tokens"],
@@ -267,8 +260,7 @@ class Migration012UpdateDisplayLabels(SchemaAttributeUpdateQuery):
267
260
  insert_return = False
268
261
 
269
262
  def __init__(self, **kwargs: Any):
270
- if "branch" in kwargs:
271
- del kwargs["branch"]
263
+ kwargs.pop("branch", None)
272
264
 
273
265
  super().__init__(
274
266
  attribute_name="display_labels",
@@ -285,8 +277,7 @@ class Migration012UpdateOrderBy(SchemaAttributeUpdateQuery):
285
277
  insert_return = False
286
278
 
287
279
  def __init__(self, **kwargs: Any):
288
- if "branch" in kwargs:
289
- del kwargs["branch"]
280
+ kwargs.pop("branch", None)
290
281
 
291
282
  super().__init__(
292
283
  attribute_name="order_by",
@@ -303,8 +294,7 @@ class Migration012UpdateDefaultFilter(SchemaAttributeUpdateQuery):
303
294
  insert_return = False
304
295
 
305
296
  def __init__(self, **kwargs: Any):
306
- if "branch" in kwargs:
307
- del kwargs["branch"]
297
+ kwargs.pop("branch", None)
308
298
 
309
299
  super().__init__(
310
300
  attribute_name="default_filter",
@@ -321,8 +311,7 @@ class Migration012UpdateHFID(SchemaAttributeUpdateQuery):
321
311
  insert_return = False
322
312
 
323
313
  def __init__(self, **kwargs: Any):
324
- if "branch" in kwargs:
325
- del kwargs["branch"]
314
+ kwargs.pop("branch", None)
326
315
 
327
316
  super().__init__(
328
317
  attribute_name="human_friendly_id",
@@ -350,7 +339,7 @@ class Migration012(GraphMigration):
350
339
  ]
351
340
  minimum_version: int = 11
352
341
 
353
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
342
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
354
343
  result = MigrationResult()
355
344
 
356
345
  return result
@@ -36,7 +36,7 @@ class Migration013ConvertCoreRepositoryWithCred(Query):
36
36
  name = "migration_013_convert_repository_with_cred"
37
37
  type = QueryType.WRITE
38
38
 
39
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
39
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
40
40
  at = Timestamp()
41
41
  filters, params = at.get_query_filter_path()
42
42
 
@@ -172,7 +172,7 @@ class Migration013ConvertCoreRepositoryWithoutCred(Query):
172
172
  name = "migration_013_convert_repository_without_cred"
173
173
  type = QueryType.WRITE
174
174
 
175
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
175
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
176
176
  at = Timestamp()
177
177
  filters, params = at.get_query_filter_path()
178
178
 
@@ -237,8 +237,7 @@ class Migration013DeleteUsernamePasswordGenericSchema(DeleteElementInSchemaQuery
237
237
  insert_return = False
238
238
 
239
239
  def __init__(self, **kwargs: Any):
240
- if "branch" in kwargs:
241
- del kwargs["branch"]
240
+ kwargs.pop("branch", None)
242
241
 
243
242
  super().__init__(
244
243
  element_names=["username", "password"],
@@ -255,8 +254,7 @@ class Migration013DeleteUsernamePasswordReadWriteSchema(DeleteElementInSchemaQue
255
254
  insert_return = False
256
255
 
257
256
  def __init__(self, **kwargs: Any):
258
- if "branch" in kwargs:
259
- del kwargs["branch"]
257
+ kwargs.pop("branch", None)
260
258
 
261
259
  super().__init__(
262
260
  element_names=["username", "password"],
@@ -273,8 +271,7 @@ class Migration013DeleteUsernamePasswordReadOnlySchema(DeleteElementInSchemaQuer
273
271
  insert_return = False
274
272
 
275
273
  def __init__(self, **kwargs: Any):
276
- if "branch" in kwargs:
277
- del kwargs["branch"]
274
+ kwargs.pop("branch", None)
278
275
 
279
276
  super().__init__(
280
277
  element_names=["username", "password"],
@@ -289,8 +286,7 @@ class Migration013AddInternalStatusData(AttributeAddQuery):
289
286
  type = QueryType.WRITE
290
287
 
291
288
  def __init__(self, **kwargs: Any):
292
- if "branch" in kwargs:
293
- del kwargs["branch"]
289
+ kwargs.pop("branch", None)
294
290
 
295
291
  super().__init__(
296
292
  node_kind="CoreGenericRepository",
@@ -315,7 +311,7 @@ class Migration013(GraphMigration):
315
311
  ]
316
312
  minimum_version: int = 12
317
313
 
318
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
314
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
319
315
  result = MigrationResult()
320
316
 
321
317
  return result
@@ -33,12 +33,12 @@ class Migration014(GraphMigration):
33
33
  try:
34
34
  ts.manager.index.init(nodes=[INDEX_TO_DELETE], rels=[])
35
35
  await ts.manager.index.drop()
36
- except Exception as exc: # pylint: disable=broad-exception-caught
36
+ except Exception as exc:
37
37
  result.errors.append(str(exc))
38
38
  return result
39
39
 
40
40
  return result
41
41
 
42
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
42
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
43
43
  result = MigrationResult()
44
44
  return result
@@ -20,7 +20,7 @@ class Migration015(ArbitraryMigration):
20
20
  name: str = "015_diff_format_update"
21
21
  minimum_version: int = 14
22
22
 
23
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
23
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
24
24
  result = MigrationResult()
25
25
 
26
26
  return result
@@ -20,7 +20,7 @@ class Migration016(ArbitraryMigration):
20
20
  name: str = "016_diff_delete_bug_fix_update"
21
21
  minimum_version: int = 15
22
22
 
23
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
23
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
24
24
  result = MigrationResult()
25
25
 
26
26
  return result
@@ -22,7 +22,7 @@ class Migration017(InternalSchemaMigration):
22
22
  minimum_version: int = 16
23
23
  migrations: Sequence[SchemaMigration] = []
24
24
 
25
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
25
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
26
26
  result = MigrationResult()
27
27
 
28
28
  return result
@@ -26,7 +26,7 @@ class Migration018(InternalSchemaMigration):
26
26
  minimum_version: int = 17
27
27
  migrations: Sequence[SchemaMigration] = []
28
28
 
29
- async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult:
29
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
30
30
  result = MigrationResult()
31
31
 
32
32
  return result
@@ -52,7 +52,7 @@ class Migration018(InternalSchemaMigration):
52
52
 
53
53
  for schema_kind in schema_branch.node_names + schema_branch.generic_names:
54
54
  schema = schema_branch.get(name=schema_kind, duplicate=False)
55
- if not isinstance(schema, (NodeSchema, GenericSchema)):
55
+ if not isinstance(schema, NodeSchema | GenericSchema):
56
56
  continue
57
57
 
58
58
  schema_constraint_path_groups = schema.get_unique_constraint_schema_attribute_paths(
@@ -0,0 +1,256 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any, Sequence
4
+
5
+ from infrahub.core.migrations.shared import GraphMigration, MigrationResult
6
+ from infrahub.log import get_logger
7
+
8
+ from ...constants import GLOBAL_BRANCH_NAME, BranchSupportType
9
+ from ...query import Query, QueryType
10
+
11
+ if TYPE_CHECKING:
12
+ from infrahub.database import InfrahubDatabase
13
+
14
+ log = get_logger()
15
+
16
+
17
+ class FixBranchAwareEdgesQuery(Query):
18
+ name = "replace_global_edges"
19
+ type = QueryType.WRITE
20
+ insert_return = False
21
+
22
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
23
+ """
24
+ Between a Node and a Relationship, if Relationship.branch_support=aware, replace any global edge
25
+ to the branch of a non-global edge leaving out of the Relationship node. Note that there can't
26
+ be multiple non-global branches on these edges, as a dedicated Relationship node would exist for that.
27
+ """
28
+
29
+ query = """
30
+ MATCH (node:Node)-[global_edge:IS_RELATED {branch: $global_branch}]-(rel:Relationship)
31
+ WHERE rel.branch_support=$branch_aware
32
+ MATCH (rel)-[non_global_edge:IS_RELATED]-(node_2: Node)
33
+ WHERE non_global_edge.branch <> $global_branch
34
+ SET global_edge.branch = non_global_edge.branch
35
+ """
36
+
37
+ params = {
38
+ "global_branch": GLOBAL_BRANCH_NAME,
39
+ "branch_aware": BranchSupportType.AWARE.value,
40
+ "branch_agnostic": BranchSupportType.AGNOSTIC.value,
41
+ }
42
+
43
+ self.params.update(params)
44
+ self.add_to_query(query)
45
+
46
+
47
+ class SetMissingToTimeQuery(Query):
48
+ name = "set_missing_to_time"
49
+ type = QueryType.WRITE
50
+ insert_return = False
51
+
52
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
53
+ """
54
+ If both a deleted edge and an active edge with no time exist between 2 nodes on the same branch,
55
+ set `to` time of active edge using `from` time of the deleted one. This would typically happen after having
56
+ replaced a deleted edge on global branch by correct branch with above query.
57
+ """
58
+
59
+ query = """
60
+ MATCH (node:Node)-[deleted_edge:IS_RELATED {status: "deleted"}]-(rel:Relationship)
61
+ MATCH (rel)-[active_edge:IS_RELATED {status: "active"}]-(node)
62
+ WHERE active_edge.to IS NULL AND deleted_edge.branch = active_edge.branch
63
+ SET active_edge.to = deleted_edge.from
64
+ """
65
+
66
+ self.add_to_query(query)
67
+
68
+
69
+ class DeleteNodesRelsQuery(Query):
70
+ name = "delete_relationships_of_deleted_nodes"
71
+ type = QueryType.WRITE
72
+ insert_return = False
73
+
74
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
75
+ """
76
+ Some nodes may have been incorrectly deleted, typically, while these nodes edges connected to Root
77
+ are correctly deleted, edges connected to other `Node` through a `Relationship` node may still be active.
78
+ Following query correctly deletes these edges by both setting correct to time and creating corresponding deleted edge.
79
+ """
80
+
81
+ query = """
82
+ MATCH (deleted_node: Node)-[deleted_edge:IS_PART_OF {status: "deleted"}]->(:Root)
83
+ MATCH (deleted_node)-[:IS_RELATED]-(rel:Relationship)
84
+
85
+ // exclude nodes having been deleted through migration. find those with same uuid and exclude the one with earlier
86
+ // timestamp on active branch
87
+ WHERE NOT EXISTS {
88
+ MATCH (deleted_node)-[e1:IS_RELATED]-(rel)-[e2:IS_RELATED]-(other_node)
89
+ WITH deleted_node, other_node, MIN(e1.from) AS min_e1_from, MIN(e2.from) AS min_e2_from
90
+ WHERE deleted_node <> other_node AND deleted_node.uuid = other_node.uuid AND min_e1_from < min_e2_from
91
+ }
92
+
93
+ // Note that if an AWARE node has been deleted on a branch and relationship is AGNOSTIC, we do not "delete" this relationship
94
+ // right now as this aware node might exist on another branch.
95
+
96
+ // Set to time if there is an active edge:
97
+ // - on deleted edge branch
98
+ // - or on any branch and deleted node is agnostic
99
+ // - or deleted node is aware and rel is agnostic
100
+ CALL {
101
+ WITH rel, deleted_edge
102
+ OPTIONAL MATCH (rel)-[peer_active_edge {status: "active"}]-(peer_1)
103
+ WHERE (peer_active_edge.branch = deleted_edge.branch OR (rel.branch_support <> $branch_agnostic AND deleted_edge.branch = $global_branch))
104
+ AND peer_active_edge.to IS NULL
105
+ SET peer_active_edge.to = deleted_edge.from
106
+ }
107
+
108
+ // Get distinct rel nodes linked to a deleted node, with the time at which we should delete rel edges.
109
+ // Take the MAX time so if it does not take the deleted time of a node deleted through a duplication migration.
110
+ WITH DISTINCT rel,
111
+ deleted_edge.branch AS deleted_edge_branch,
112
+ deleted_edge.branch_level AS branch_level,
113
+ MAX(deleted_edge.from) as deleted_time,
114
+ deleted_node.branch_support as deleted_node_branch_support
115
+
116
+
117
+ // No need to check deleted edge branch because
118
+ // If deleted_node has different branch support type (agnostic/aware) than rel type,
119
+ // there might already be a deleted edge that we would not match if we filter on deleted_edge_branch.
120
+ // If both are aware, it still works, as we would have one Relationship node for each branch on which this relationship exists.
121
+ MATCH (rel)-[]-(peer_2)
122
+ WHERE NOT exists((rel)-[{status: "deleted"}]-(peer_2))
123
+
124
+
125
+ // If res is agnostic and delete node is agnostic, we should delete on global branch
126
+ // If rel is aware and deleted node is aware, we should use deleted edge branch
127
+ // If rel is aware and delete node is agnostic, we need to create deleted edges for every distinct branch on which this relationship exists.
128
+ WITH DISTINCT
129
+ CASE
130
+ // Branch on which `deleted` edge should be created depends on rel.branch_support.
131
+ WHEN rel.branch_support = $branch_agnostic
132
+ THEN CASE
133
+ WHEN deleted_node_branch_support = $branch_agnostic THEN [$global_branch]
134
+ ELSE []
135
+ END
136
+ ELSE
137
+ CASE
138
+ WHEN deleted_node_branch_support = $branch_agnostic
139
+ THEN COLLECT {
140
+ WITH rel
141
+ MATCH (rel)-[active_edge {status: "active"}]-(peer_2)
142
+ RETURN DISTINCT active_edge.branch
143
+ }
144
+ ELSE
145
+ CASE
146
+ // if no active edge on this branch exists it means this relationship node is dedicated for another branch
147
+ WHEN exists((rel)-[{status: "active", branch: deleted_edge_branch}]-(peer_2)) THEN [deleted_edge_branch]
148
+ ELSE []
149
+ END
150
+ END
151
+ END AS branches,
152
+ branch_level,
153
+ deleted_time,
154
+ peer_2,
155
+ rel
156
+
157
+ UNWIND branches as branch
158
+
159
+ // Then creates `deleted` edge.
160
+ // Below CALL subqueries are called once for each rel-peer_2 pair for which we want to create a deleted edge.
161
+ // Note that with current infrahub relationships edges design, only one of this CALL should be matched per pair.
162
+
163
+ CALL {
164
+ WITH rel, peer_2, branch, branch_level, deleted_time
165
+ MATCH (rel)-[:IS_RELATED]->(peer_2)
166
+ MERGE (rel)-[:IS_RELATED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
167
+ }
168
+
169
+ CALL {
170
+ WITH rel, peer_2, branch, branch_level, deleted_time
171
+ MATCH (rel)-[:IS_PROTECTED]->(peer_2)
172
+ MERGE (rel)-[:IS_PROTECTED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
173
+ }
174
+
175
+ CALL {
176
+ WITH rel, peer_2, branch, branch_level, deleted_time
177
+ MATCH (rel)-[:IS_VISIBLE]->(peer_2)
178
+ MERGE (rel)-[:IS_VISIBLE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
179
+ }
180
+
181
+ CALL {
182
+ WITH rel, peer_2, branch, branch_level, deleted_time
183
+ MATCH (rel)-[:HAS_OWNER]->(peer_2)
184
+ MERGE (rel)-[:HAS_OWNER {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
185
+ }
186
+
187
+ CALL {
188
+ WITH rel, peer_2, branch, branch_level, deleted_time
189
+ MATCH (rel)-[:HAS_SOURCE]->(peer_2)
190
+ MERGE (rel)-[:HAS_SOURCE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
191
+ }
192
+
193
+ CALL {
194
+ WITH rel, peer_2, branch, branch_level, deleted_time
195
+ MATCH (rel)<-[:IS_RELATED]-(peer_2)
196
+ MERGE (rel)<-[:IS_RELATED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
197
+ }
198
+
199
+ CALL {
200
+ WITH rel, peer_2, branch, branch_level, deleted_time
201
+ MATCH (rel)<-[:IS_PROTECTED]-(peer_2)
202
+ MERGE (rel)<-[:IS_PROTECTED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
203
+ }
204
+
205
+ CALL {
206
+ WITH rel, peer_2, branch, branch_level, deleted_time
207
+ MATCH (rel)<-[:IS_VISIBLE]-(peer_2)
208
+ MERGE (rel)<-[:IS_VISIBLE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
209
+ }
210
+
211
+ CALL {
212
+ WITH rel, peer_2, branch, branch_level, deleted_time
213
+ MATCH (rel)<-[:HAS_OWNER]-(peer_2)
214
+ MERGE (rel)<-[:HAS_OWNER {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
215
+ }
216
+
217
+ CALL {
218
+ WITH rel, peer_2, branch, branch_level, deleted_time
219
+ MATCH (rel)<-[:HAS_SOURCE]-(peer_2)
220
+ MERGE (rel)<-[:HAS_SOURCE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
221
+ }
222
+ """
223
+
224
+ params = {
225
+ "global_branch": GLOBAL_BRANCH_NAME,
226
+ "branch_aware": BranchSupportType.AWARE.value,
227
+ "branch_agnostic": BranchSupportType.AGNOSTIC.value,
228
+ }
229
+
230
+ self.params.update(params)
231
+ self.add_to_query(query)
232
+
233
+
234
+ class Migration019(GraphMigration):
235
+ """
236
+ Fix corrupted state introduced by Migration012 when duplicating a CoreAccount (branch Aware)
237
+ being part of a CoreStandardGroup (branch Agnostic). Database is corrupted at multiple points:
238
+ - Old CoreAccount node <> group_member node `active` edge has no `to` time (possibly because of #5590).
239
+ - Old CoreAccount node <> group_member node `deleted` edge is on `$global_branch` branch instead of `main`.
240
+ - New CoreAccount node <> group_member node `active` edge is on `$global_branch` branch instead of `main`.
241
+
242
+ Also, users having deleted corresponding CoreStandardGroup will also have the following data corruption,
243
+ as deletion did not happen correctly due to above issues:
244
+ - Both CoreAccount <> group_member and CoreStandardGroup <> group_member edges
245
+ have not been deleted (ie status is `active` without `to` time and no additional `deleted` edge).
246
+
247
+ This migration fixes all above issues to have consistent edges, and fixes IFC-1204.
248
+ """
249
+
250
+ name: str = "019_fix_edges_state"
251
+ minimum_version: int = 18
252
+ queries: Sequence[type[Query]] = [FixBranchAwareEdgesQuery, SetMissingToTimeQuery, DeleteNodesRelsQuery]
253
+
254
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
255
+ result = MigrationResult()
256
+ return result
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from typing_extensions import Self
6
+
7
+ from infrahub.core.constants import SchemaPathType
8
+ from infrahub.core.migrations.shared import MigrationResult
9
+ from infrahub.core.path import SchemaPath
10
+
11
+ from ..schema.node_attribute_add import NodeAttributeAddMigration
12
+ from ..shared import InternalSchemaMigration
13
+
14
+ if TYPE_CHECKING:
15
+ from infrahub.database import InfrahubDatabase
16
+
17
+
18
+ class Migration020(InternalSchemaMigration):
19
+ name: str = "020_add_generate_template_attr"
20
+ minimum_version: int = 19
21
+
22
+ @classmethod
23
+ def init(cls, **kwargs: dict[str, Any]) -> Self:
24
+ internal_schema = cls.get_internal_schema()
25
+ schema_node = internal_schema.get_node(name="SchemaNode")
26
+ schema_generic = internal_schema.get_node(name="SchemaGeneric")
27
+
28
+ migrations = [
29
+ NodeAttributeAddMigration(
30
+ new_node_schema=schema_node,
31
+ previous_node_schema=schema_node,
32
+ schema_path=SchemaPath(
33
+ schema_kind="SchemaNode", path_type=SchemaPathType.ATTRIBUTE, field_name="generate_template"
34
+ ),
35
+ ),
36
+ NodeAttributeAddMigration(
37
+ new_node_schema=schema_generic,
38
+ previous_node_schema=schema_generic,
39
+ schema_path=SchemaPath(
40
+ schema_kind="SchemaNode", path_type=SchemaPathType.ATTRIBUTE, field_name="generate_template"
41
+ ),
42
+ ),
43
+ ]
44
+ return cls(migrations=migrations, **kwargs) # type: ignore[arg-type]
45
+
46
+ async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
47
+ result = MigrationResult()
48
+ return result
@@ -30,7 +30,7 @@ class AttributeAddQuery(Query):
30
30
 
31
31
  super().__init__(**kwargs)
32
32
 
33
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
33
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
34
34
  branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
35
35
  self.params.update(branch_params)
36
36
 
@@ -86,7 +86,7 @@ class AttributeRenameQuery(Query):
86
86
  subquery.append("RETURN peer_node as p2")
87
87
  return "\n".join(subquery)
88
88
 
89
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
89
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
90
90
  branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
91
91
  self.params.update(branch_params)
92
92
 
@@ -90,7 +90,7 @@ class DeleteElementInSchemaQuery(Query):
90
90
  sub_query_in = "\nUNION\n".join(sub_queries_in)
91
91
  return sub_query_in
92
92
 
93
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
93
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
94
94
  branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
95
95
  self.params.update(branch_params)
96
96