infrahub-server 1.1.6__py3-none-any.whl → 1.2.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. infrahub/api/artifact.py +16 -4
  2. infrahub/api/dependencies.py +8 -0
  3. infrahub/api/oauth2.py +0 -1
  4. infrahub/api/oidc.py +0 -1
  5. infrahub/api/query.py +18 -7
  6. infrahub/api/schema.py +32 -6
  7. infrahub/api/transformation.py +12 -5
  8. infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +5 -3
  9. infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
  10. infrahub/cli/__init__.py +0 -2
  11. infrahub/cli/db.py +6 -7
  12. infrahub/cli/events.py +8 -3
  13. infrahub/cli/git_agent.py +9 -7
  14. infrahub/cli/tasks.py +4 -6
  15. infrahub/computed_attribute/models.py +1 -1
  16. infrahub/computed_attribute/tasks.py +64 -17
  17. infrahub/computed_attribute/triggers.py +90 -0
  18. infrahub/config.py +1 -1
  19. infrahub/context.py +39 -0
  20. infrahub/core/account.py +5 -8
  21. infrahub/core/attribute.py +54 -22
  22. infrahub/core/branch/models.py +4 -4
  23. infrahub/core/branch/tasks.py +137 -129
  24. infrahub/core/changelog/__init__.py +0 -0
  25. infrahub/core/changelog/diff.py +283 -0
  26. infrahub/core/changelog/models.py +499 -0
  27. infrahub/core/constants/__init__.py +43 -2
  28. infrahub/core/constants/infrahubkind.py +1 -0
  29. infrahub/core/constants/schema.py +2 -0
  30. infrahub/core/diff/combiner.py +12 -8
  31. infrahub/core/diff/coordinator.py +49 -70
  32. infrahub/core/diff/data_check_synchronizer.py +86 -7
  33. infrahub/core/diff/enricher/aggregated.py +3 -3
  34. infrahub/core/diff/enricher/cardinality_one.py +7 -7
  35. infrahub/core/diff/enricher/hierarchy.py +22 -7
  36. infrahub/core/diff/enricher/labels.py +19 -4
  37. infrahub/core/diff/enricher/path_identifier.py +7 -9
  38. infrahub/core/diff/enricher/summary_counts.py +3 -1
  39. infrahub/core/diff/merger/merger.py +8 -4
  40. infrahub/core/diff/model/path.py +76 -35
  41. infrahub/core/diff/parent_node_adder.py +78 -0
  42. infrahub/core/diff/payload_builder.py +13 -2
  43. infrahub/core/diff/query/all_conflicts.py +6 -3
  44. infrahub/core/diff/query/artifact.py +1 -1
  45. infrahub/core/diff/query/delete_query.py +1 -1
  46. infrahub/core/diff/query/diff_get.py +3 -2
  47. infrahub/core/diff/query/diff_summary.py +1 -1
  48. infrahub/core/diff/query/field_specifiers.py +3 -1
  49. infrahub/core/diff/query/field_summary.py +3 -2
  50. infrahub/core/diff/query/filters.py +14 -3
  51. infrahub/core/diff/query/get_conflict_query.py +1 -1
  52. infrahub/core/diff/query/has_conflicts_query.py +6 -3
  53. infrahub/core/diff/query/merge.py +3 -3
  54. infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
  55. infrahub/core/diff/query/roots_metadata.py +9 -2
  56. infrahub/core/diff/query/save.py +233 -142
  57. infrahub/core/diff/query/summary_counts_enricher.py +267 -0
  58. infrahub/core/diff/query/time_range_query.py +3 -2
  59. infrahub/core/diff/query/update_conflict_query.py +1 -1
  60. infrahub/core/diff/query_parser.py +49 -24
  61. infrahub/core/diff/repository/deserializer.py +32 -28
  62. infrahub/core/diff/repository/repository.py +215 -41
  63. infrahub/core/diff/tasks.py +13 -12
  64. infrahub/core/enums.py +1 -1
  65. infrahub/core/graph/__init__.py +1 -1
  66. infrahub/core/graph/index.py +3 -0
  67. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  68. infrahub/core/ipam/reconciler.py +1 -1
  69. infrahub/core/ipam/tasks.py +2 -3
  70. infrahub/core/manager.py +20 -15
  71. infrahub/core/merge.py +5 -2
  72. infrahub/core/migrations/graph/__init__.py +4 -0
  73. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  74. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  75. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  76. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  77. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  78. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  79. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  80. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  81. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  82. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  83. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  84. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  85. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  86. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  87. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  88. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  89. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
  90. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
  91. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
  92. infrahub/core/migrations/graph/m020_add_generate_template_attr.py +48 -0
  93. infrahub/core/migrations/query/attribute_add.py +1 -1
  94. infrahub/core/migrations/query/attribute_rename.py +1 -1
  95. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  96. infrahub/core/migrations/query/node_duplicate.py +39 -19
  97. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  98. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  99. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  100. infrahub/core/migrations/schema/node_remove.py +27 -13
  101. infrahub/core/migrations/schema/tasks.py +5 -5
  102. infrahub/core/migrations/shared.py +4 -4
  103. infrahub/core/models.py +7 -8
  104. infrahub/core/node/__init__.py +170 -46
  105. infrahub/core/node/base.py +1 -1
  106. infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
  107. infrahub/core/node/delete_validator.py +4 -4
  108. infrahub/core/node/ipam.py +13 -8
  109. infrahub/core/node/permissions.py +4 -0
  110. infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
  111. infrahub/core/node/standard.py +3 -5
  112. infrahub/core/property.py +1 -1
  113. infrahub/core/protocols.py +6 -0
  114. infrahub/core/protocols_base.py +4 -2
  115. infrahub/core/query/__init__.py +2 -5
  116. infrahub/core/query/attribute.py +9 -9
  117. infrahub/core/query/branch.py +5 -5
  118. infrahub/core/query/delete.py +1 -1
  119. infrahub/core/query/diff.py +45 -7
  120. infrahub/core/query/ipam.py +4 -4
  121. infrahub/core/query/node.py +19 -14
  122. infrahub/core/query/relationship.py +213 -26
  123. infrahub/core/query/resource_manager.py +13 -11
  124. infrahub/core/query/standard_node.py +6 -6
  125. infrahub/core/query/task.py +3 -3
  126. infrahub/core/query/task_log.py +1 -1
  127. infrahub/core/query/utils.py +5 -5
  128. infrahub/core/registry.py +0 -2
  129. infrahub/core/relationship/constraints/count.py +1 -1
  130. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  131. infrahub/core/relationship/model.py +76 -38
  132. infrahub/core/schema/__init__.py +6 -4
  133. infrahub/core/schema/attribute_schema.py +8 -0
  134. infrahub/core/schema/basenode_schema.py +13 -3
  135. infrahub/core/schema/definitions/core/__init__.py +153 -0
  136. infrahub/core/schema/definitions/core/account.py +168 -0
  137. infrahub/core/schema/definitions/core/artifact.py +127 -0
  138. infrahub/core/schema/definitions/core/builtin.py +21 -0
  139. infrahub/core/schema/definitions/core/check.py +60 -0
  140. infrahub/core/schema/definitions/core/generator.py +96 -0
  141. infrahub/core/schema/definitions/core/graphql_query.py +77 -0
  142. infrahub/core/schema/definitions/core/group.py +105 -0
  143. infrahub/core/schema/definitions/core/ipam.py +252 -0
  144. infrahub/core/schema/definitions/core/lineage.py +17 -0
  145. infrahub/core/schema/definitions/core/menu.py +46 -0
  146. infrahub/core/schema/definitions/core/permission.py +161 -0
  147. infrahub/core/schema/definitions/core/profile.py +29 -0
  148. infrahub/core/schema/definitions/core/propose_change.py +88 -0
  149. infrahub/core/schema/definitions/core/propose_change_comment.py +188 -0
  150. infrahub/core/schema/definitions/core/propose_change_validator.py +326 -0
  151. infrahub/core/schema/definitions/core/repository.py +280 -0
  152. infrahub/core/schema/definitions/core/resource_pool.py +180 -0
  153. infrahub/core/schema/definitions/core/template.py +12 -0
  154. infrahub/core/schema/definitions/core/transform.py +87 -0
  155. infrahub/core/schema/definitions/core/webhook.py +108 -0
  156. infrahub/core/schema/definitions/internal.py +16 -0
  157. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  158. infrahub/core/schema/generated/node_schema.py +5 -0
  159. infrahub/core/schema/generic_schema.py +5 -1
  160. infrahub/core/schema/manager.py +45 -42
  161. infrahub/core/schema/node_schema.py +4 -0
  162. infrahub/core/schema/profile_schema.py +4 -0
  163. infrahub/core/schema/relationship_schema.py +10 -2
  164. infrahub/core/schema/schema_branch.py +260 -16
  165. infrahub/core/schema/template_schema.py +36 -0
  166. infrahub/core/task/user_task.py +7 -5
  167. infrahub/core/timestamp.py +3 -3
  168. infrahub/core/utils.py +3 -2
  169. infrahub/core/validators/attribute/choices.py +1 -1
  170. infrahub/core/validators/attribute/enum.py +1 -1
  171. infrahub/core/validators/attribute/kind.py +1 -1
  172. infrahub/core/validators/attribute/length.py +1 -1
  173. infrahub/core/validators/attribute/optional.py +1 -1
  174. infrahub/core/validators/attribute/regex.py +1 -1
  175. infrahub/core/validators/attribute/unique.py +1 -1
  176. infrahub/core/validators/checks_runner.py +37 -0
  177. infrahub/core/validators/node/generate_profile.py +1 -1
  178. infrahub/core/validators/node/hierarchy.py +1 -1
  179. infrahub/core/validators/query.py +1 -1
  180. infrahub/core/validators/relationship/count.py +1 -1
  181. infrahub/core/validators/relationship/optional.py +1 -1
  182. infrahub/core/validators/relationship/peer.py +1 -1
  183. infrahub/core/validators/tasks.py +8 -6
  184. infrahub/core/validators/uniqueness/query.py +20 -17
  185. infrahub/database/__init__.py +16 -2
  186. infrahub/database/memgraph.py +1 -1
  187. infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
  188. infrahub/dependencies/builder/diff/combiner.py +1 -1
  189. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  190. infrahub/dependencies/builder/diff/coordinator.py +0 -2
  191. infrahub/dependencies/builder/diff/deserializer.py +4 -2
  192. infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
  193. infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
  194. infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
  195. infrahub/events/artifact_action.py +76 -0
  196. infrahub/events/branch_action.py +50 -21
  197. infrahub/events/group_action.py +117 -0
  198. infrahub/events/models.py +164 -51
  199. infrahub/events/node_action.py +70 -8
  200. infrahub/events/repository_action.py +8 -8
  201. infrahub/events/schema_action.py +21 -8
  202. infrahub/exceptions.py +9 -0
  203. infrahub/generators/models.py +1 -0
  204. infrahub/generators/tasks.py +34 -15
  205. infrahub/git/base.py +3 -5
  206. infrahub/git/constants.py +0 -1
  207. infrahub/git/integrator.py +60 -36
  208. infrahub/git/models.py +80 -1
  209. infrahub/git/repository.py +7 -8
  210. infrahub/git/tasks.py +432 -112
  211. infrahub/git_credential/helper.py +2 -3
  212. infrahub/graphql/analyzer.py +572 -11
  213. infrahub/graphql/app.py +34 -26
  214. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  215. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  216. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  217. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  218. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  219. infrahub/graphql/context.py +33 -0
  220. infrahub/graphql/enums.py +1 -1
  221. infrahub/graphql/initialization.py +5 -1
  222. infrahub/graphql/loaders/node.py +2 -2
  223. infrahub/graphql/manager.py +63 -63
  224. infrahub/graphql/mutations/account.py +20 -13
  225. infrahub/graphql/mutations/artifact_definition.py +16 -12
  226. infrahub/graphql/mutations/branch.py +86 -40
  227. infrahub/graphql/mutations/computed_attribute.py +24 -13
  228. infrahub/graphql/mutations/diff.py +54 -14
  229. infrahub/graphql/mutations/diff_conflict.py +14 -8
  230. infrahub/graphql/mutations/generator.py +83 -0
  231. infrahub/graphql/mutations/graphql_query.py +19 -11
  232. infrahub/graphql/mutations/ipam.py +25 -23
  233. infrahub/graphql/mutations/main.py +243 -50
  234. infrahub/graphql/mutations/menu.py +10 -10
  235. infrahub/graphql/mutations/proposed_change.py +36 -28
  236. infrahub/graphql/mutations/relationship.py +343 -104
  237. infrahub/graphql/mutations/repository.py +41 -35
  238. infrahub/graphql/mutations/resource_manager.py +26 -26
  239. infrahub/graphql/mutations/schema.py +66 -33
  240. infrahub/graphql/mutations/tasks.py +16 -10
  241. infrahub/graphql/parser.py +1 -1
  242. infrahub/graphql/permissions.py +3 -10
  243. infrahub/graphql/queries/account.py +22 -18
  244. infrahub/graphql/queries/branch.py +6 -4
  245. infrahub/graphql/queries/diff/tree.py +63 -52
  246. infrahub/graphql/queries/event.py +115 -0
  247. infrahub/graphql/queries/internal.py +3 -3
  248. infrahub/graphql/queries/ipam.py +23 -18
  249. infrahub/graphql/queries/relationship.py +11 -10
  250. infrahub/graphql/queries/resource_manager.py +43 -27
  251. infrahub/graphql/queries/search.py +9 -8
  252. infrahub/graphql/queries/status.py +12 -9
  253. infrahub/graphql/queries/task.py +11 -9
  254. infrahub/graphql/resolvers/resolver.py +69 -43
  255. infrahub/graphql/resolvers/single_relationship.py +16 -10
  256. infrahub/graphql/schema.py +4 -0
  257. infrahub/graphql/subscription/__init__.py +1 -1
  258. infrahub/graphql/subscription/events.py +1 -1
  259. infrahub/graphql/subscription/graphql_query.py +8 -8
  260. infrahub/graphql/types/branch.py +2 -2
  261. infrahub/graphql/types/common.py +6 -1
  262. infrahub/graphql/types/context.py +12 -0
  263. infrahub/graphql/types/enums.py +2 -0
  264. infrahub/graphql/types/event.py +158 -0
  265. infrahub/graphql/types/interface.py +2 -2
  266. infrahub/graphql/types/node.py +3 -3
  267. infrahub/graphql/types/permission.py +2 -2
  268. infrahub/graphql/types/relationship.py +3 -3
  269. infrahub/graphql/types/standard_node.py +9 -11
  270. infrahub/graphql/utils.py +28 -182
  271. infrahub/groups/tasks.py +2 -3
  272. infrahub/lock.py +21 -21
  273. infrahub/menu/generator.py +0 -1
  274. infrahub/menu/menu.py +116 -138
  275. infrahub/menu/models.py +4 -4
  276. infrahub/message_bus/__init__.py +11 -13
  277. infrahub/message_bus/messages/__init__.py +0 -14
  278. infrahub/message_bus/messages/check_generator_run.py +1 -3
  279. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  280. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  281. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  282. infrahub/message_bus/messages/send_echo_request.py +1 -1
  283. infrahub/message_bus/operations/__init__.py +4 -13
  284. infrahub/message_bus/operations/check/__init__.py +2 -2
  285. infrahub/message_bus/operations/check/generator.py +1 -3
  286. infrahub/message_bus/operations/event/branch.py +7 -3
  287. infrahub/message_bus/operations/event/schema.py +1 -1
  288. infrahub/message_bus/operations/event/worker.py +0 -3
  289. infrahub/message_bus/operations/finalize/validator.py +1 -1
  290. infrahub/message_bus/operations/git/file.py +2 -2
  291. infrahub/message_bus/operations/git/repository.py +1 -1
  292. infrahub/message_bus/operations/requests/__init__.py +0 -4
  293. infrahub/message_bus/operations/requests/generator_definition.py +2 -4
  294. infrahub/message_bus/operations/requests/proposed_change.py +37 -20
  295. infrahub/message_bus/operations/send/echo.py +1 -1
  296. infrahub/message_bus/types.py +1 -1
  297. infrahub/permissions/__init__.py +2 -1
  298. infrahub/permissions/globals.py +15 -0
  299. infrahub/permissions/types.py +26 -0
  300. infrahub/pools/prefix.py +29 -165
  301. infrahub/prefect_server/__init__.py +0 -0
  302. infrahub/prefect_server/app.py +18 -0
  303. infrahub/prefect_server/database.py +20 -0
  304. infrahub/prefect_server/events.py +28 -0
  305. infrahub/prefect_server/models.py +46 -0
  306. infrahub/proposed_change/models.py +18 -1
  307. infrahub/proposed_change/tasks.py +195 -53
  308. infrahub/pytest_plugin.py +4 -4
  309. infrahub/server.py +13 -12
  310. infrahub/services/__init__.py +148 -63
  311. infrahub/services/adapters/cache/__init__.py +11 -11
  312. infrahub/services/adapters/cache/nats.py +42 -25
  313. infrahub/services/adapters/cache/redis.py +3 -11
  314. infrahub/services/adapters/event/__init__.py +10 -18
  315. infrahub/services/adapters/http/__init__.py +0 -5
  316. infrahub/services/adapters/http/httpx.py +22 -15
  317. infrahub/services/adapters/message_bus/__init__.py +25 -8
  318. infrahub/services/adapters/message_bus/local.py +9 -7
  319. infrahub/services/adapters/message_bus/nats.py +14 -8
  320. infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
  321. infrahub/services/adapters/workflow/__init__.py +11 -8
  322. infrahub/services/adapters/workflow/local.py +27 -6
  323. infrahub/services/adapters/workflow/worker.py +23 -7
  324. infrahub/services/component.py +43 -40
  325. infrahub/services/protocols.py +7 -7
  326. infrahub/services/scheduler.py +30 -29
  327. infrahub/storage.py +2 -4
  328. infrahub/task_manager/constants.py +1 -1
  329. infrahub/task_manager/event.py +261 -0
  330. infrahub/task_manager/models.py +147 -3
  331. infrahub/task_manager/task.py +1 -1
  332. infrahub/tasks/artifact.py +19 -18
  333. infrahub/tasks/registry.py +1 -1
  334. infrahub/tasks/telemetry.py +13 -14
  335. infrahub/transformations/tasks.py +3 -5
  336. infrahub/trigger/__init__.py +0 -0
  337. infrahub/trigger/catalogue.py +16 -0
  338. infrahub/trigger/constants.py +9 -0
  339. infrahub/trigger/models.py +105 -0
  340. infrahub/trigger/tasks.py +91 -0
  341. infrahub/types.py +1 -1
  342. infrahub/utils.py +1 -1
  343. infrahub/webhook/constants.py +0 -2
  344. infrahub/webhook/models.py +161 -40
  345. infrahub/webhook/tasks.py +123 -202
  346. infrahub/webhook/triggers.py +27 -0
  347. infrahub/workers/infrahub_async.py +36 -25
  348. infrahub/workers/utils.py +63 -0
  349. infrahub/workflows/catalogue.py +71 -52
  350. infrahub/workflows/initialization.py +14 -8
  351. infrahub/workflows/models.py +28 -4
  352. infrahub/workflows/utils.py +1 -1
  353. infrahub_sdk/client.py +8 -0
  354. infrahub_sdk/ctl/branch.py +3 -2
  355. infrahub_sdk/ctl/check.py +3 -3
  356. infrahub_sdk/ctl/cli_commands.py +16 -11
  357. infrahub_sdk/ctl/exceptions.py +0 -6
  358. infrahub_sdk/ctl/exporter.py +1 -1
  359. infrahub_sdk/ctl/generator.py +5 -5
  360. infrahub_sdk/ctl/importer.py +3 -2
  361. infrahub_sdk/ctl/menu.py +1 -1
  362. infrahub_sdk/ctl/object.py +1 -1
  363. infrahub_sdk/ctl/repository.py +23 -15
  364. infrahub_sdk/ctl/schema.py +2 -2
  365. infrahub_sdk/ctl/utils.py +4 -19
  366. infrahub_sdk/ctl/validate.py +2 -1
  367. infrahub_sdk/exceptions.py +12 -0
  368. infrahub_sdk/generator.py +3 -0
  369. infrahub_sdk/node.py +4 -4
  370. infrahub_sdk/protocols.py +21 -8
  371. infrahub_sdk/schema/__init__.py +14 -2
  372. infrahub_sdk/schema/main.py +7 -0
  373. infrahub_sdk/task/__init__.py +1 -0
  374. infrahub_sdk/task/constants.py +3 -0
  375. infrahub_sdk/task/exceptions.py +25 -0
  376. infrahub_sdk/task/manager.py +545 -0
  377. infrahub_sdk/task/models.py +74 -0
  378. infrahub_sdk/timestamp.py +134 -33
  379. infrahub_sdk/utils.py +39 -1
  380. infrahub_sdk/yaml.py +2 -3
  381. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/METADATA +47 -12
  382. infrahub_server-1.2.0b1.dist-info/RECORD +725 -0
  383. infrahub_testcontainers/container.py +14 -6
  384. infrahub_testcontainers/docker-compose.test.yml +24 -5
  385. infrahub_testcontainers/haproxy.cfg +43 -0
  386. infrahub_testcontainers/helpers.py +85 -1
  387. infrahub/core/branch/constants.py +0 -2
  388. infrahub/core/schema/definitions/core.py +0 -2274
  389. infrahub/graphql/query.py +0 -52
  390. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  391. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  392. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  393. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  394. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  395. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  396. infrahub/message_bus/operations/check/repository.py +0 -293
  397. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  398. infrahub/message_bus/operations/requests/repository.py +0 -133
  399. infrahub/schema/constants.py +0 -1
  400. infrahub/schema/tasks.py +0 -76
  401. infrahub/services/adapters/database/__init__.py +0 -9
  402. infrahub_sdk/ctl/_file.py +0 -13
  403. infrahub_server-1.1.6.dist-info/RECORD +0 -681
  404. /infrahub/{schema → artifacts}/__init__.py +0 -0
  405. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/LICENSE.txt +0 -0
  406. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/WHEEL +0 -0
  407. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,37 @@
1
+ import asyncio
2
+ from typing import Any, Coroutine
3
+
4
+ from infrahub_sdk.node import InfrahubNode
5
+
6
+ from infrahub.core.constants import ValidatorConclusion, ValidatorState
7
+ from infrahub.core.timestamp import Timestamp
8
+
9
+
10
+ async def run_checks_and_update_validator(
11
+ checks: list[Coroutine[Any, None, ValidatorConclusion]], validator: InfrahubNode
12
+ ) -> None:
13
+ """
14
+ Execute a list of checks coroutines, and set validator fields accordingly.
15
+ Tasks are retrieved by completion order so as soon as we detect a failing check,
16
+ we set validator conclusion to failure.
17
+ """
18
+
19
+ # First set validator to in progress, then wait for results
20
+ validator.state.value = ValidatorState.IN_PROGRESS.value
21
+ validator.started_at.value = Timestamp().to_string()
22
+ validator.completed_at.value = ""
23
+ await validator.save()
24
+
25
+ for earliest_task in asyncio.as_completed(checks):
26
+ result = await earliest_task
27
+ if validator.conclusion.value != ValidatorConclusion.FAILURE.value and result == ValidatorConclusion.FAILURE:
28
+ validator.conclusion.value = ValidatorConclusion.FAILURE.value
29
+ await validator.save()
30
+ # Continue to iterate to wait for the end of all checks
31
+
32
+ validator.state.value = ValidatorState.COMPLETED.value
33
+ validator.completed_at.value = Timestamp().to_string()
34
+ if validator.conclusion.value != ValidatorConclusion.FAILURE.value:
35
+ validator.conclusion.value = ValidatorConclusion.SUCCESS.value
36
+
37
+ await validator.save()
@@ -28,7 +28,7 @@ class NodeGenerateProfileValidatorQuery(SchemaValidatorQuery):
28
28
  super().__init__(*args, **kwargs)
29
29
  self.profile_kind = f"Profile{self.node_schema.kind}"
30
30
 
31
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
31
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
32
32
  branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at)
33
33
  self.params.update(branch_params)
34
34
 
@@ -31,7 +31,7 @@ class NodeHierarchyUpdateValidatorQuery(SchemaValidatorQuery):
31
31
  self.check_parent = check_parent
32
32
  super().__init__(**kwargs)
33
33
 
34
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
34
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
35
35
  if self.check_children and self.check_parent:
36
36
  raise RuntimeError("Cannot check children and parent at same time")
37
37
  if self.check_children:
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
14
14
  class NodeNotPresentValidatorQuery(SchemaValidatorQuery):
15
15
  name: str = "node_not_present_validator"
16
16
 
17
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
17
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
18
18
  branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
19
19
  self.params.update(branch_params)
20
20
 
@@ -30,7 +30,7 @@ class RelationshipCountUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
30
30
  self.max_count_override = max_count_override
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(), is_isolated=False)
35
35
  self.params.update(branch_params)
36
36
 
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
20
20
  class RelationshipOptionalUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
21
21
  name = "relationship_constraints_optional_validator"
22
22
 
23
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
23
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
24
24
  branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
25
25
  self.params.update(branch_params)
26
26
 
@@ -21,7 +21,7 @@ if TYPE_CHECKING:
21
21
  class RelationshipPeerUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
22
22
  name = "relationship_constraints_peer_validator"
23
23
 
24
- async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
24
+ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
25
25
  peer_schema = db.schema.get(name=self.relationship_schema.peer, branch=self.branch)
26
26
  allowed_peer_kinds = [peer_schema.kind]
27
27
  if isinstance(peer_schema, GenericSchema):
@@ -13,14 +13,16 @@ from infrahub.core.validators.model import (
13
13
  SchemaConstraintValidatorRequest,
14
14
  )
15
15
  from infrahub.dependencies.registry import get_component_registry
16
- from infrahub.services import services
16
+ from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
17
17
  from infrahub.workflows.utils import add_tags
18
18
 
19
19
  from .models.validate_migration import SchemaValidateMigrationData, SchemaValidatorPathResponseData
20
20
 
21
21
 
22
22
  @flow(name="schema_validate_migrations", flow_run_name="Validate schema migrations", persist_result=True)
23
- async def schema_validate_migrations(message: SchemaValidateMigrationData) -> list[SchemaValidatorPathResponseData]:
23
+ async def schema_validate_migrations(
24
+ message: SchemaValidateMigrationData, service: InfrahubServices
25
+ ) -> list[SchemaValidatorPathResponseData]:
24
26
  batch = InfrahubBatch(return_exceptions=True)
25
27
  log = get_run_logger()
26
28
  await add_tags(branches=[message.branch.name])
@@ -33,7 +35,7 @@ async def schema_validate_migrations(message: SchemaValidateMigrationData) -> li
33
35
  # NOTE this task is a good candidate to add a progress bar
34
36
  for constraint in message.constraints:
35
37
  schema = message.schema_branch.get(name=constraint.path.schema_kind)
36
- if not isinstance(schema, (GenericSchema, NodeSchema)):
38
+ if not isinstance(schema, GenericSchema | NodeSchema):
37
39
  continue
38
40
  batch.add(
39
41
  task=schema_path_validate,
@@ -41,13 +43,14 @@ async def schema_validate_migrations(message: SchemaValidateMigrationData) -> li
41
43
  constraint_name=constraint.constraint_name,
42
44
  node_schema=schema,
43
45
  schema_path=constraint.path,
46
+ service=service,
44
47
  )
45
48
 
46
49
  results = [result async for _, result in batch.execute()]
47
50
  return results
48
51
 
49
52
 
50
- @task(
53
+ @task( # type: ignore[arg-type]
51
54
  name="schema-path-validate",
52
55
  task_run_name="Validate schema path {constraint_name} in {branch.name}",
53
56
  description="Validate if a given migration is compatible with the existing data",
@@ -59,9 +62,8 @@ async def schema_path_validate(
59
62
  constraint_name: str,
60
63
  node_schema: NodeSchema | GenericSchema,
61
64
  schema_path: SchemaPath,
65
+ service: InfrahubServices,
62
66
  ) -> SchemaValidatorPathResponseData:
63
- service = services.service
64
-
65
67
  async with service.database.start_session() as db:
66
68
  constraint_request = SchemaConstraintValidatorRequest(
67
69
  branch=branch,
@@ -30,7 +30,7 @@ class NodeUniqueAttributeConstraintQuery(Query):
30
30
  def get_context(self) -> dict[str, str]:
31
31
  return {"kind": self.query_request.kind}
32
32
 
33
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
33
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
34
34
  branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
35
35
  self.params.update(branch_params)
36
36
  from_times = db.render_list_comprehension(items="relationships(potential_path)", item_name="from")
@@ -56,6 +56,7 @@ class NodeUniqueAttributeConstraintQuery(Query):
56
56
  relationship_names = set()
57
57
  relationship_attr_paths = []
58
58
  relationship_only_attr_paths = []
59
+ relationship_only_attr_values = []
59
60
  relationship_attr_paths_with_value = []
60
61
  for rel_path in self.query_request.relationship_attribute_paths:
61
62
  relationship_names.add(rel_path.identifier)
@@ -67,6 +68,8 @@ class NodeUniqueAttributeConstraintQuery(Query):
67
68
  relationship_attr_paths.append((rel_path.identifier, rel_path.attribute_name))
68
69
  else:
69
70
  relationship_only_attr_paths.append(rel_path.identifier)
71
+ if rel_path.value:
72
+ relationship_only_attr_values.append(rel_path.value)
70
73
 
71
74
  if (
72
75
  not attr_paths
@@ -89,34 +92,37 @@ class NodeUniqueAttributeConstraintQuery(Query):
89
92
  "relationship_attr_paths": relationship_attr_paths,
90
93
  "relationship_attr_paths_with_value": relationship_attr_paths_with_value,
91
94
  "relationship_only_attr_paths": relationship_only_attr_paths,
95
+ "relationship_only_attr_values": relationship_only_attr_values,
92
96
  "min_count_required": self.min_count_required,
93
97
  }
94
98
  )
95
99
 
96
100
  attr_paths_subquery = """
97
- WITH start_node
98
- MATCH attr_path = (start_node)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[r:HAS_VALUE]->(attr_value:AttributeValue)
101
+ MATCH attr_path = (start_node:%(node_kind)s)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[r:HAS_VALUE]->(attr_value:AttributeValue)
99
102
  WHERE attr.name in $attribute_names
100
103
  AND ([attr.name, type(r)] in $attr_paths
101
104
  OR [attr.name, type(r), attr_value.value] in $attr_paths_with_value)
102
- RETURN attr_path as potential_path, NULL as rel_identifier, attr.name as potential_attr, attr_value.value as potential_attr_value
103
- """
105
+ RETURN start_node, attr_path as potential_path, NULL as rel_identifier, attr.name as potential_attr, attr_value.value as potential_attr_value
106
+ """ % {"node_kind": self.query_request.kind}
104
107
 
105
108
  relationship_attr_paths_with_value_subquery = """
106
- WITH start_node
107
- MATCH rel_path = (start_node)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)-[:HAS_ATTRIBUTE]->(rel_attr:Attribute)-[:HAS_VALUE]->(rel_attr_value:AttributeValue)
109
+ MATCH rel_path = (start_node:%(node_kind)s)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)-[:HAS_ATTRIBUTE]->(rel_attr:Attribute)-[:HAS_VALUE]->(rel_attr_value:AttributeValue)
108
110
  WHERE relationship_node.name in $relationship_names
109
111
  AND ([relationship_node.name, rel_attr.name] in $relationship_attr_paths
110
112
  OR [relationship_node.name, rel_attr.name, rel_attr_value.value] in $relationship_attr_paths_with_value)
111
- RETURN rel_path as potential_path, relationship_node.name as rel_identifier, rel_attr.name as potential_attr, rel_attr_value.value as potential_attr_value
112
- """
113
+ RETURN start_node, rel_path as potential_path, relationship_node.name as rel_identifier, rel_attr.name as potential_attr, rel_attr_value.value as potential_attr_value
114
+ """ % {"node_kind": self.query_request.kind}
113
115
 
114
116
  relationship_only_attr_paths_subquery = """
115
- WITH start_node
116
- MATCH rel_path = (start_node)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)
117
- WHERE relationship_node.name in $relationship_only_attr_paths
118
- RETURN rel_path as potential_path, relationship_node.name as rel_identifier, "id" as potential_attr, related_n.uuid as potential_attr_value
119
- """
117
+ MATCH rel_path = (start_node:%(node_kind)s)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)
118
+ WHERE %(rel_node_filter)s relationship_node.name in $relationship_only_attr_paths
119
+ RETURN start_node, rel_path as potential_path, relationship_node.name as rel_identifier, "id" as potential_attr, related_n.uuid as potential_attr_value
120
+ """ % {
121
+ "node_kind": self.query_request.kind,
122
+ "rel_node_filter": "related_n.uuid IN $relationship_only_attr_values AND "
123
+ if relationship_only_attr_values
124
+ else "",
125
+ }
120
126
 
121
127
  select_subqueries = []
122
128
  if attr_paths or attr_paths_with_value:
@@ -130,8 +136,6 @@ class NodeUniqueAttributeConstraintQuery(Query):
130
136
 
131
137
  # ruff: noqa: E501
132
138
  query = """
133
- // group by node
134
- MATCH (start_node:%(node_kind)s)
135
139
  // get attributes for node and its relationships
136
140
  CALL {
137
141
  %(select_subqueries_str)s
@@ -201,7 +205,6 @@ class NodeUniqueAttributeConstraintQuery(Query):
201
205
  attr_value,
202
206
  relationship_identifier
203
207
  """ % {
204
- "node_kind": self.query_request.kind,
205
208
  "select_subqueries_str": select_subqueries_str,
206
209
  "branch_filter": branch_filter,
207
210
  "from_times": from_times,
@@ -173,6 +173,19 @@ class InfrahubDatabase:
173
173
  elif self.db_type == DatabaseType.MEMGRAPH:
174
174
  self.manager = DatabaseManagerMemgraph(db=self)
175
175
 
176
+ def __del__(self) -> None:
177
+ if not self._session or not self._is_session_local or self._session.closed():
178
+ return
179
+
180
+ try:
181
+ loop = asyncio.get_running_loop()
182
+ except RuntimeError:
183
+ loop = None
184
+ if loop and loop.is_running():
185
+ loop.create_task(self._session.close())
186
+ else:
187
+ asyncio.run(self._session.close())
188
+
176
189
  @property
177
190
  def is_session(self) -> bool:
178
191
  if self._mode == InfrahubDatabaseMode.SESSION:
@@ -307,7 +320,7 @@ class InfrahubDatabase:
307
320
  params: dict[str, Any] | None = None,
308
321
  name: str = "undefined",
309
322
  context: dict[str, str] | None = None,
310
- type: QueryType | None = None, # pylint: disable=redefined-builtin
323
+ type: QueryType | None = None,
311
324
  ) -> list[Record]:
312
325
  results, _ = await self.execute_query_with_metadata(
313
326
  query=query, params=params, name=name, context=context, type=type
@@ -320,7 +333,7 @@ class InfrahubDatabase:
320
333
  params: dict[str, Any] | None = None,
321
334
  name: str = "undefined",
322
335
  context: dict[str, str] | None = None,
323
- type: QueryType | None = None, # pylint: disable=redefined-builtin
336
+ type: QueryType | None = None,
324
337
  ) -> tuple[list[Record], dict[str, Any]]:
325
338
  with trace.get_tracer(__name__).start_as_current_span("execute_db_query_with_metadata") as span:
326
339
  span.set_attribute("query", query)
@@ -501,6 +514,7 @@ def retry_db_transaction(
501
514
  if exc.code != "Neo.ClientError.Statement.EntityNotFound":
502
515
  raise exc
503
516
  retry_time: float = random.randrange(100, 500) / 1000
517
+ log.exception("Retry handler caught database error")
504
518
  log.info(
505
519
  f"Retrying database transaction, attempt {attempt}/{config.SETTINGS.database.retry_limit}",
506
520
  retry_time=retry_time,
@@ -21,7 +21,7 @@ class IndexNodeMemgraph(IndexItem):
21
21
 
22
22
 
23
23
  class IndexManagerMemgraph(IndexManagerBase):
24
- def init(self, nodes: list[IndexItem], rels: list[IndexItem]) -> None:
24
+ def init(self, nodes: list[IndexItem], rels: list[IndexItem]) -> None: # noqa: ARG002
25
25
  self.nodes = [IndexNodeMemgraph(**item.model_dump()) for item in nodes]
26
26
  self.initialized = True
27
27
 
@@ -2,7 +2,6 @@ from infrahub.core.constraint.node.runner import NodeConstraintRunner
2
2
  from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
3
3
 
4
4
  from ..node.grouped_uniqueness import NodeGroupedUniquenessConstraintDependency
5
- from ..node.uniqueness import NodeAttributeUniquenessConstraintDependency
6
5
  from ..relationship_manager.count import RelationshipCountConstraintDependency
7
6
  from ..relationship_manager.peer_kind import RelationshipPeerKindConstraintDependency
8
7
  from ..relationship_manager.profiles_kind import RelationshipProfilesKindConstraintDependency
@@ -15,7 +14,6 @@ class NodeConstraintRunnerDependency(DependencyBuilder[NodeConstraintRunner]):
15
14
  db=context.db,
16
15
  branch=context.branch,
17
16
  node_constraints=[
18
- NodeAttributeUniquenessConstraintDependency.build(context=context),
19
17
  NodeGroupedUniquenessConstraintDependency.build(context=context),
20
18
  ],
21
19
  relationship_manager_constraints=[
@@ -4,5 +4,5 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
4
4
 
5
5
  class DiffCombinerDependency(DependencyBuilder[DiffCombiner]):
6
6
  @classmethod
7
- def build(cls, context: DependencyBuilderContext) -> DiffCombiner:
7
+ def build(cls, context: DependencyBuilderContext) -> DiffCombiner: # noqa: ARG003
8
8
  return DiffCombiner()
@@ -4,5 +4,5 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
4
4
 
5
5
  class DiffConflictsEnricherDependency(DependencyBuilder[ConflictsEnricher]):
6
6
  @classmethod
7
- def build(cls, context: DependencyBuilderContext) -> ConflictsEnricher:
7
+ def build(cls, context: DependencyBuilderContext) -> ConflictsEnricher: # noqa: ARG003
8
8
  return ConflictsEnricher()
@@ -8,7 +8,6 @@ from .conflicts_enricher import DiffConflictsEnricherDependency
8
8
  from .data_check_synchronizer import DiffDataCheckSynchronizerDependency
9
9
  from .enricher.aggregated import DiffAggregatedEnricherDependency
10
10
  from .enricher.labels import DiffLabelsEnricherDependency
11
- from .enricher.summary_counts import DiffSummaryCountsEnricherDependency
12
11
  from .repository import DiffRepositoryDependency
13
12
 
14
13
 
@@ -22,7 +21,6 @@ class DiffCoordinatorDependency(DependencyBuilder[DiffCoordinator]):
22
21
  diff_enricher=DiffAggregatedEnricherDependency.build(context=context),
23
22
  conflicts_enricher=DiffConflictsEnricherDependency.build(context=context),
24
23
  labels_enricher=DiffLabelsEnricherDependency.build(context=context),
25
- summary_counts_enricher=DiffSummaryCountsEnricherDependency.build(context=context),
26
24
  data_check_synchronizer=DiffDataCheckSynchronizerDependency.build(context=context),
27
25
  conflict_transferer=DiffConflictTransfererDependency.build(context=context),
28
26
  )
@@ -1,8 +1,10 @@
1
1
  from infrahub.core.diff.repository.deserializer import EnrichedDiffDeserializer
2
2
  from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
3
3
 
4
+ from .parent_node_adder import DiffParentNodeAdderDependency
5
+
4
6
 
5
7
  class DiffDeserializerDependency(DependencyBuilder[EnrichedDiffDeserializer]):
6
8
  @classmethod
7
- def build(cls, context: DependencyBuilderContext) -> EnrichedDiffDeserializer:
8
- return EnrichedDiffDeserializer()
9
+ def build(cls, context: DependencyBuilderContext) -> EnrichedDiffDeserializer: # noqa: ARG003
10
+ return EnrichedDiffDeserializer(parent_adder=DiffParentNodeAdderDependency.build(context=context))
@@ -1,8 +1,10 @@
1
1
  from infrahub.core.diff.enricher.hierarchy import DiffHierarchyEnricher
2
2
  from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
3
3
 
4
+ from ..parent_node_adder import DiffParentNodeAdderDependency
5
+
4
6
 
5
7
  class DiffHierarchyEnricherDependency(DependencyBuilder[DiffHierarchyEnricher]):
6
8
  @classmethod
7
9
  def build(cls, context: DependencyBuilderContext) -> DiffHierarchyEnricher:
8
- return DiffHierarchyEnricher(db=context.db)
10
+ return DiffHierarchyEnricher(db=context.db, parent_adder=DiffParentNodeAdderDependency.build(context=context))
@@ -4,5 +4,5 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
4
4
 
5
5
  class DiffSummaryCountsEnricherDependency(DependencyBuilder[DiffSummaryCountsEnricher]):
6
6
  @classmethod
7
- def build(cls, context: DependencyBuilderContext) -> DiffSummaryCountsEnricher:
7
+ def build(cls, context: DependencyBuilderContext) -> DiffSummaryCountsEnricher: # noqa: ARG003
8
8
  return DiffSummaryCountsEnricher()
@@ -0,0 +1,8 @@
1
+ from infrahub.core.diff.parent_node_adder import DiffParentNodeAdder
2
+ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
3
+
4
+
5
+ class DiffParentNodeAdderDependency(DependencyBuilder[DiffParentNodeAdder]):
6
+ @classmethod
7
+ def build(cls, context: DependencyBuilderContext) -> DiffParentNodeAdder: # noqa: ARG003
8
+ return DiffParentNodeAdder()
@@ -0,0 +1,76 @@
1
+ from typing import Any
2
+
3
+ from pydantic import Field, computed_field
4
+
5
+ from infrahub.message_bus import InfrahubMessage
6
+
7
+ from .constants import EVENT_NAMESPACE
8
+ from .models import InfrahubEvent
9
+
10
+
11
+ class ArtifactEvent(InfrahubEvent):
12
+ """Event generated when an artifact has been created or updated."""
13
+
14
+ node_id: str = Field(..., description="The ID of the artifact")
15
+ artifact_definition_id: str = Field(..., description="The ID of the artifact definition")
16
+ target_id: str = Field(..., description="The ID of the target of the artifact")
17
+ target_kind: str = Field(..., description="The kind of the target of the artifact")
18
+ checksum: str = Field(..., description="The current checksum of the artifact")
19
+ checksum_previous: str | None = Field(default=None, description="The previous checksum of the artifact")
20
+ storage_id: str = Field(..., description="The current storage id of the artifact")
21
+ storage_id_previous: str | None = Field(default=None, description="The previous storage id of the artifact")
22
+ created: bool = Field(..., description="Indicates if the artifact was created with this event or already existed")
23
+
24
+ def get_related(self) -> list[dict[str, str]]:
25
+ related = super().get_related()
26
+ related.append(
27
+ {
28
+ "prefect.resource.id": self.target_id,
29
+ "prefect.resource.role": "infrahub.related.node",
30
+ "infrahub.node.kind": self.target_kind,
31
+ }
32
+ )
33
+ related.append(
34
+ {
35
+ "prefect.resource.id": self.target_id,
36
+ "prefect.resource.role": "infrahub.artifact",
37
+ "infrahub.artifact.checksum": self.checksum,
38
+ "infrahub.artifact.checksum_previous": self.checksum_previous or "",
39
+ "infrahub.artifact.storage_id": self.storage_id,
40
+ "infrahub.artifact.storage_id_previous": self.storage_id_previous or "",
41
+ "infrahub.artifact.artifact_definition_id": self.artifact_definition_id,
42
+ }
43
+ )
44
+
45
+ return related
46
+
47
+ def get_resource(self) -> dict[str, str]:
48
+ return {
49
+ "prefect.resource.id": self.node_id,
50
+ "infrahub.node.kind": "CoreArtifact",
51
+ "infrahub.node.id": self.node_id,
52
+ "infrahub.branch.name": self.meta.context.branch.name,
53
+ }
54
+
55
+ def get_payload(self) -> dict[str, Any]:
56
+ return {
57
+ "node_id": self.node_id,
58
+ "artifact_definition_id": self.artifact_definition_id,
59
+ "target_id": self.target_id,
60
+ "target_kind": self.target_kind,
61
+ "checksum": self.checksum,
62
+ "checksum_previous": self.checksum_previous,
63
+ "storage_id": self.storage_id,
64
+ "storage_id_previous": self.storage_id_previous,
65
+ }
66
+
67
+ def get_messages(self) -> list[InfrahubMessage]:
68
+ return []
69
+
70
+ @computed_field
71
+ def event_name(self) -> str:
72
+ match self.created:
73
+ case True:
74
+ return f"{EVENT_NAMESPACE}.artifact.created"
75
+ case False:
76
+ return f"{EVENT_NAMESPACE}.artifact.updated"
@@ -1,26 +1,25 @@
1
- from pydantic import Field
1
+ from pydantic import Field, computed_field
2
2
 
3
3
  from infrahub.message_bus import InfrahubMessage
4
4
  from infrahub.message_bus.messages.refresh_registry_branches import RefreshRegistryBranches
5
5
  from infrahub.message_bus.messages.refresh_registry_rebasedbranch import RefreshRegistryRebasedBranch
6
6
 
7
- from .models import InfrahubBranchEvent
7
+ from .constants import EVENT_NAMESPACE
8
+ from .models import InfrahubEvent
8
9
 
9
10
 
10
- class BranchDeleteEvent(InfrahubBranchEvent):
11
+ class BranchDeletedEvent(InfrahubEvent):
11
12
  """Event generated when a branch has been deleted"""
12
13
 
14
+ branch_name: str = Field(..., description="The name of the branch")
13
15
  branch_id: str = Field(..., description="The ID of the mutated node")
14
16
  sync_with_git: bool = Field(..., description="Indicates if the branch was extended to Git")
15
17
 
16
- def get_name(self) -> str:
17
- return f"{self.get_event_namespace()}.branch.deleted"
18
-
19
18
  def get_resource(self) -> dict[str, str]:
20
19
  return {
21
- "prefect.resource.id": f"infrahub.branch.{self.branch}",
20
+ "prefect.resource.id": f"infrahub.branch.{self.branch_name}",
22
21
  "infrahub.branch.id": self.branch_id,
23
- "infrahub.branch.name": self.branch,
22
+ "infrahub.branch.name": self.branch_name,
24
23
  }
25
24
 
26
25
  def get_messages(self) -> list[InfrahubMessage]:
@@ -35,21 +34,23 @@ class BranchDeleteEvent(InfrahubBranchEvent):
35
34
  ]
36
35
  return events
37
36
 
37
+ @computed_field
38
+ def event_name(self) -> str:
39
+ return f"{EVENT_NAMESPACE}.branch.deleted"
40
+
38
41
 
39
- class BranchCreateEvent(InfrahubBranchEvent):
42
+ class BranchCreatedEvent(InfrahubEvent):
40
43
  """Event generated when a branch has been created"""
41
44
 
42
- branch_id: str = Field(..., description="The ID of the mutated node")
45
+ branch_name: str = Field(..., description="The name of the branch")
46
+ branch_id: str = Field(..., description="The ID of the branch")
43
47
  sync_with_git: bool = Field(..., description="Indicates if the branch was extended to Git")
44
48
 
45
- def get_name(self) -> str:
46
- return f"{self.get_event_namespace()}.branch.created"
47
-
48
49
  def get_resource(self) -> dict[str, str]:
49
50
  return {
50
- "prefect.resource.id": f"infrahub.branch.{self.branch}",
51
+ "prefect.resource.id": f"infrahub.branch.{self.branch_name}",
51
52
  "infrahub.branch.id": self.branch_id,
52
- "infrahub.branch.name": self.branch,
53
+ "infrahub.branch.name": self.branch_name,
53
54
  }
54
55
 
55
56
  def get_messages(self) -> list[InfrahubMessage]:
@@ -64,19 +65,43 @@ class BranchCreateEvent(InfrahubBranchEvent):
64
65
  ]
65
66
  return events
66
67
 
68
+ @computed_field
69
+ def event_name(self) -> str:
70
+ return f"{EVENT_NAMESPACE}.branch.created"
71
+
72
+
73
+ class BranchMergedEvent(InfrahubEvent):
74
+ """Event generated when a branch has been merged"""
75
+
76
+ branch_name: str = Field(..., description="The name of the branch")
77
+ branch_id: str = Field(..., description="The ID of the branch")
78
+
79
+ def get_resource(self) -> dict[str, str]:
80
+ return {
81
+ "prefect.resource.id": f"infrahub.branch.{self.branch_name}",
82
+ "infrahub.branch.id": self.branch_id,
83
+ "infrahub.branch.name": self.branch_name,
84
+ }
85
+
86
+ def get_messages(self) -> list[InfrahubMessage]:
87
+ return []
67
88
 
68
- class BranchRebaseEvent(InfrahubBranchEvent):
89
+ @computed_field
90
+ def event_name(self) -> str:
91
+ return f"{EVENT_NAMESPACE}.branch.merged"
92
+
93
+
94
+ class BranchRebasedEvent(InfrahubEvent):
69
95
  """Event generated when a branch has been rebased"""
70
96
 
71
97
  branch_id: str = Field(..., description="The ID of the mutated node")
72
-
73
- def get_name(self) -> str:
74
- return f"{self.get_event_namespace()}.branch.rebased"
98
+ branch_name: str = Field(..., description="The name of the branch")
75
99
 
76
100
  def get_resource(self) -> dict[str, str]:
77
101
  return {
78
- "prefect.resource.id": f"infrahub.branch.{self.branch}",
102
+ "prefect.resource.id": f"infrahub.branch.{self.branch_name}",
79
103
  "infrahub.branch.id": self.branch_id,
104
+ "infrahub.branch.name": self.branch_name,
80
105
  }
81
106
 
82
107
  def get_messages(self) -> list[InfrahubMessage]:
@@ -85,6 +110,10 @@ class BranchRebaseEvent(InfrahubBranchEvent):
85
110
  # branch=self.branch,
86
111
  # meta=self.get_message_meta(),
87
112
  # ),
88
- RefreshRegistryRebasedBranch(branch=self.branch),
113
+ RefreshRegistryRebasedBranch(branch=self.branch_name),
89
114
  ]
90
115
  return events
116
+
117
+ @computed_field
118
+ def event_name(self) -> str:
119
+ return f"{EVENT_NAMESPACE}.branch.rebased"