infrahub-server 1.1.9__py3-none-any.whl → 1.2.0__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 (467) hide show
  1. infrahub/api/artifact.py +16 -4
  2. infrahub/api/dependencies.py +14 -6
  3. infrahub/api/diff/validation_models.py +7 -7
  4. infrahub/api/oauth2.py +0 -1
  5. infrahub/api/oidc.py +0 -1
  6. infrahub/api/query.py +18 -7
  7. infrahub/api/schema.py +33 -7
  8. infrahub/api/transformation.py +12 -5
  9. infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +6 -6
  10. infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +27 -28
  11. infrahub/cli/__init__.py +12 -10
  12. infrahub/cli/constants.py +3 -0
  13. infrahub/cli/db.py +166 -185
  14. infrahub/cli/events.py +8 -3
  15. infrahub/cli/git_agent.py +9 -7
  16. infrahub/cli/tasks.py +4 -6
  17. infrahub/cli/upgrade.py +146 -0
  18. infrahub/computed_attribute/gather.py +174 -0
  19. infrahub/computed_attribute/models.py +202 -11
  20. infrahub/computed_attribute/tasks.py +103 -421
  21. infrahub/computed_attribute/triggers.py +56 -0
  22. infrahub/config.py +33 -33
  23. infrahub/context.py +53 -0
  24. infrahub/core/account.py +9 -12
  25. infrahub/core/attribute.py +104 -75
  26. infrahub/core/branch/models.py +4 -4
  27. infrahub/core/branch/tasks.py +133 -125
  28. infrahub/core/changelog/__init__.py +0 -0
  29. infrahub/core/changelog/diff.py +291 -0
  30. infrahub/core/changelog/models.py +662 -0
  31. infrahub/core/constants/__init__.py +47 -2
  32. infrahub/core/constants/infrahubkind.py +3 -0
  33. infrahub/core/constants/schema.py +2 -0
  34. infrahub/core/constraint/node/runner.py +2 -2
  35. infrahub/core/diff/branch_differ.py +10 -10
  36. infrahub/core/diff/combiner.py +1 -1
  37. infrahub/core/diff/enricher/cardinality_one.py +1 -1
  38. infrahub/core/diff/enricher/hierarchy.py +5 -3
  39. infrahub/core/diff/enricher/labels.py +1 -1
  40. infrahub/core/diff/enricher/path_identifier.py +1 -2
  41. infrahub/core/diff/enricher/summary_counts.py +107 -0
  42. infrahub/core/diff/ipam_diff_parser.py +4 -5
  43. infrahub/core/diff/merger/merger.py +3 -1
  44. infrahub/core/diff/model/diff.py +27 -27
  45. infrahub/core/diff/model/path.py +13 -13
  46. infrahub/core/diff/query/all_conflicts.py +1 -1
  47. infrahub/core/diff/query/artifact.py +1 -1
  48. infrahub/core/diff/query/delete_query.py +1 -1
  49. infrahub/core/diff/query/diff_get.py +1 -1
  50. infrahub/core/diff/query/diff_summary.py +1 -1
  51. infrahub/core/diff/query/field_specifiers.py +1 -1
  52. infrahub/core/diff/query/field_summary.py +1 -1
  53. infrahub/core/diff/query/filters.py +2 -2
  54. infrahub/core/diff/query/get_conflict_query.py +1 -1
  55. infrahub/core/diff/query/has_conflicts_query.py +1 -1
  56. infrahub/core/diff/query/merge.py +3 -3
  57. infrahub/core/diff/query/merge_tracking_id.py +1 -1
  58. infrahub/core/diff/query/roots_metadata.py +1 -1
  59. infrahub/core/diff/query/save.py +3 -3
  60. infrahub/core/diff/query/summary_counts_enricher.py +2 -2
  61. infrahub/core/diff/query/time_range_query.py +1 -1
  62. infrahub/core/diff/query/update_conflict_query.py +1 -1
  63. infrahub/core/diff/query_parser.py +4 -4
  64. infrahub/core/diff/repository/deserializer.py +1 -1
  65. infrahub/core/diff/tasks.py +9 -8
  66. infrahub/core/enums.py +1 -1
  67. infrahub/core/initialization.py +1 -10
  68. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  69. infrahub/core/ipam/constants.py +3 -4
  70. infrahub/core/ipam/reconciler.py +13 -13
  71. infrahub/core/ipam/tasks.py +2 -3
  72. infrahub/core/ipam/utilization.py +10 -13
  73. infrahub/core/manager.py +52 -47
  74. infrahub/core/merge.py +12 -9
  75. infrahub/core/migrations/__init__.py +1 -3
  76. infrahub/core/migrations/graph/__init__.py +5 -3
  77. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  78. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  79. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  80. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  81. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  82. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  83. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  84. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  85. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  86. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  87. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  88. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  89. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  90. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  91. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  92. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  93. infrahub/core/migrations/graph/m017_add_core_profile.py +2 -6
  94. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +3 -3
  95. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +4 -4
  96. infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -3
  97. infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +2 -2
  98. infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
  99. infrahub/core/migrations/query/attribute_add.py +3 -3
  100. infrahub/core/migrations/query/attribute_rename.py +1 -1
  101. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  102. infrahub/core/migrations/query/node_duplicate.py +1 -1
  103. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  104. infrahub/core/migrations/query/schema_attribute_update.py +3 -3
  105. infrahub/core/migrations/schema/models.py +19 -4
  106. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  107. infrahub/core/migrations/schema/node_remove.py +1 -1
  108. infrahub/core/migrations/schema/tasks.py +7 -7
  109. infrahub/core/migrations/shared.py +10 -12
  110. infrahub/core/models.py +13 -14
  111. infrahub/core/node/__init__.py +172 -57
  112. infrahub/core/node/base.py +3 -5
  113. infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
  114. infrahub/core/node/constraints/grouped_uniqueness.py +5 -5
  115. infrahub/core/node/constraints/interface.py +1 -2
  116. infrahub/core/node/delete_validator.py +7 -9
  117. infrahub/core/node/ipam.py +10 -10
  118. infrahub/core/node/permissions.py +7 -7
  119. infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
  120. infrahub/core/node/resource_manager/ip_prefix_pool.py +14 -11
  121. infrahub/core/node/resource_manager/number_pool.py +3 -3
  122. infrahub/core/node/standard.py +3 -5
  123. infrahub/core/path.py +12 -12
  124. infrahub/core/property.py +12 -12
  125. infrahub/core/protocols.py +11 -0
  126. infrahub/core/protocols_base.py +25 -23
  127. infrahub/core/query/__init__.py +35 -38
  128. infrahub/core/query/attribute.py +13 -13
  129. infrahub/core/query/branch.py +5 -5
  130. infrahub/core/query/delete.py +1 -1
  131. infrahub/core/query/diff.py +7 -7
  132. infrahub/core/query/ipam.py +4 -4
  133. infrahub/core/query/node.py +23 -24
  134. infrahub/core/query/relationship.py +143 -46
  135. infrahub/core/query/resource_manager.py +10 -10
  136. infrahub/core/query/standard_node.py +9 -9
  137. infrahub/core/query/subquery.py +9 -9
  138. infrahub/core/query/task.py +3 -3
  139. infrahub/core/query/task_log.py +1 -1
  140. infrahub/core/query/utils.py +5 -5
  141. infrahub/core/registry.py +13 -17
  142. infrahub/core/relationship/constraints/count.py +4 -5
  143. infrahub/core/relationship/constraints/peer_kind.py +4 -5
  144. infrahub/core/relationship/constraints/profiles_kind.py +2 -2
  145. infrahub/core/relationship/model.py +103 -67
  146. infrahub/core/schema/__init__.py +6 -4
  147. infrahub/core/schema/attribute_schema.py +16 -8
  148. infrahub/core/schema/basenode_schema.py +38 -26
  149. infrahub/core/schema/computed_attribute.py +3 -3
  150. infrahub/core/schema/definitions/core/__init__.py +147 -0
  151. infrahub/core/schema/definitions/core/account.py +171 -0
  152. infrahub/core/schema/definitions/core/artifact.py +136 -0
  153. infrahub/core/schema/definitions/core/builtin.py +24 -0
  154. infrahub/core/schema/definitions/core/check.py +68 -0
  155. infrahub/core/schema/definitions/core/core.py +17 -0
  156. infrahub/core/schema/definitions/core/generator.py +100 -0
  157. infrahub/core/schema/definitions/core/graphql_query.py +79 -0
  158. infrahub/core/schema/definitions/core/group.py +108 -0
  159. infrahub/core/schema/definitions/core/ipam.py +193 -0
  160. infrahub/core/schema/definitions/core/lineage.py +19 -0
  161. infrahub/core/schema/definitions/core/menu.py +48 -0
  162. infrahub/core/schema/definitions/core/permission.py +163 -0
  163. infrahub/core/schema/definitions/core/profile.py +18 -0
  164. infrahub/core/schema/definitions/core/propose_change.py +97 -0
  165. infrahub/core/schema/definitions/core/propose_change_comment.py +193 -0
  166. infrahub/core/schema/definitions/core/propose_change_validator.py +328 -0
  167. infrahub/core/schema/definitions/core/repository.py +286 -0
  168. infrahub/core/schema/definitions/core/resource_pool.py +170 -0
  169. infrahub/core/schema/definitions/core/template.py +27 -0
  170. infrahub/core/schema/definitions/core/transform.py +96 -0
  171. infrahub/core/schema/definitions/core/webhook.py +134 -0
  172. infrahub/core/schema/definitions/internal.py +32 -16
  173. infrahub/core/schema/dropdown.py +3 -4
  174. infrahub/core/schema/generated/attribute_schema.py +15 -18
  175. infrahub/core/schema/generated/base_node_schema.py +12 -14
  176. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  177. infrahub/core/schema/generated/node_schema.py +8 -5
  178. infrahub/core/schema/generated/relationship_schema.py +9 -11
  179. infrahub/core/schema/generic_schema.py +6 -2
  180. infrahub/core/schema/manager.py +46 -43
  181. infrahub/core/schema/node_schema.py +6 -2
  182. infrahub/core/schema/profile_schema.py +4 -0
  183. infrahub/core/schema/relationship_schema.py +15 -7
  184. infrahub/core/schema/schema_branch.py +423 -89
  185. infrahub/core/schema/schema_branch_computed.py +41 -4
  186. infrahub/core/schema/template_schema.py +36 -0
  187. infrahub/core/task/task.py +3 -3
  188. infrahub/core/task/user_task.py +21 -19
  189. infrahub/core/timestamp.py +3 -3
  190. infrahub/core/utils.py +12 -12
  191. infrahub/core/validators/__init__.py +1 -3
  192. infrahub/core/validators/aggregated_checker.py +2 -2
  193. infrahub/core/validators/attribute/choices.py +3 -3
  194. infrahub/core/validators/attribute/enum.py +3 -3
  195. infrahub/core/validators/attribute/kind.py +3 -3
  196. infrahub/core/validators/attribute/length.py +3 -3
  197. infrahub/core/validators/attribute/optional.py +3 -3
  198. infrahub/core/validators/attribute/regex.py +3 -3
  199. infrahub/core/validators/attribute/unique.py +3 -3
  200. infrahub/core/validators/checks_runner.py +60 -0
  201. infrahub/core/validators/determiner.py +1 -3
  202. infrahub/core/validators/model.py +1 -3
  203. infrahub/core/validators/models/validate_migration.py +17 -4
  204. infrahub/core/validators/node/attribute.py +2 -2
  205. infrahub/core/validators/node/generate_profile.py +3 -3
  206. infrahub/core/validators/node/hierarchy.py +3 -3
  207. infrahub/core/validators/node/inherit_from.py +2 -2
  208. infrahub/core/validators/node/relationship.py +2 -2
  209. infrahub/core/validators/query.py +1 -1
  210. infrahub/core/validators/relationship/count.py +5 -5
  211. infrahub/core/validators/relationship/optional.py +3 -3
  212. infrahub/core/validators/relationship/peer.py +3 -3
  213. infrahub/core/validators/shared.py +2 -2
  214. infrahub/core/validators/tasks.py +8 -6
  215. infrahub/core/validators/uniqueness/checker.py +5 -6
  216. infrahub/core/validators/uniqueness/index.py +2 -2
  217. infrahub/core/validators/uniqueness/model.py +11 -11
  218. infrahub/core/validators/uniqueness/query.py +1 -1
  219. infrahub/database/__init__.py +19 -23
  220. infrahub/database/memgraph.py +1 -1
  221. infrahub/dependencies/builder/diff/combiner.py +1 -1
  222. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  223. infrahub/dependencies/builder/diff/deserializer.py +1 -1
  224. infrahub/dependencies/builder/diff/enricher/summary_counts.py +8 -0
  225. infrahub/dependencies/builder/diff/parent_node_adder.py +1 -1
  226. infrahub/dependencies/component/registry.py +2 -2
  227. infrahub/events/__init__.py +25 -2
  228. infrahub/events/artifact_action.py +64 -0
  229. infrahub/events/branch_action.py +57 -20
  230. infrahub/events/generator.py +71 -0
  231. infrahub/events/group_action.py +103 -0
  232. infrahub/events/models.py +160 -53
  233. infrahub/events/node_action.py +140 -23
  234. infrahub/events/repository_action.py +7 -20
  235. infrahub/events/schema_action.py +18 -10
  236. infrahub/events/utils.py +16 -0
  237. infrahub/events/validator_action.py +55 -0
  238. infrahub/exceptions.py +12 -3
  239. infrahub/generators/models.py +2 -3
  240. infrahub/generators/tasks.py +34 -15
  241. infrahub/git/base.py +10 -12
  242. infrahub/git/constants.py +0 -1
  243. infrahub/git/integrator.py +82 -57
  244. infrahub/git/models.py +101 -9
  245. infrahub/git/repository.py +9 -10
  246. infrahub/git/tasks.py +450 -112
  247. infrahub/git/utils.py +48 -0
  248. infrahub/git/worktree.py +1 -2
  249. infrahub/git_credential/askpass.py +1 -2
  250. infrahub/git_credential/helper.py +2 -3
  251. infrahub/graphql/analyzer.py +572 -11
  252. infrahub/graphql/app.py +47 -41
  253. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  254. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  255. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  256. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  257. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  258. infrahub/graphql/context.py +39 -0
  259. infrahub/graphql/enums.py +1 -1
  260. infrahub/graphql/initialization.py +5 -1
  261. infrahub/graphql/loaders/node.py +1 -1
  262. infrahub/graphql/loaders/shared.py +1 -1
  263. infrahub/graphql/manager.py +75 -72
  264. infrahub/graphql/mutations/account.py +20 -13
  265. infrahub/graphql/mutations/artifact_definition.py +18 -14
  266. infrahub/graphql/mutations/branch.py +86 -40
  267. infrahub/graphql/mutations/computed_attribute.py +26 -18
  268. infrahub/graphql/mutations/diff.py +17 -8
  269. infrahub/graphql/mutations/diff_conflict.py +14 -8
  270. infrahub/graphql/mutations/generator.py +83 -0
  271. infrahub/graphql/mutations/graphql_query.py +21 -13
  272. infrahub/graphql/mutations/ipam.py +41 -39
  273. infrahub/graphql/mutations/main.py +226 -66
  274. infrahub/graphql/mutations/menu.py +12 -12
  275. infrahub/graphql/mutations/models.py +2 -4
  276. infrahub/graphql/mutations/node_getter/by_default_filter.py +1 -3
  277. infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
  278. infrahub/graphql/mutations/node_getter/by_id.py +1 -3
  279. infrahub/graphql/mutations/node_getter/interface.py +1 -2
  280. infrahub/graphql/mutations/proposed_change.py +39 -31
  281. infrahub/graphql/mutations/relationship.py +372 -129
  282. infrahub/graphql/mutations/repository.py +46 -40
  283. infrahub/graphql/mutations/resource_manager.py +26 -26
  284. infrahub/graphql/mutations/schema.py +70 -37
  285. infrahub/graphql/mutations/tasks.py +10 -7
  286. infrahub/graphql/mutations/webhook.py +137 -0
  287. infrahub/graphql/parser.py +5 -5
  288. infrahub/graphql/permissions.py +3 -10
  289. infrahub/graphql/queries/account.py +22 -18
  290. infrahub/graphql/queries/branch.py +6 -4
  291. infrahub/graphql/queries/diff/tree.py +67 -56
  292. infrahub/graphql/queries/event.py +115 -0
  293. infrahub/graphql/queries/internal.py +3 -3
  294. infrahub/graphql/queries/ipam.py +25 -20
  295. infrahub/graphql/queries/relationship.py +13 -12
  296. infrahub/graphql/queries/resource_manager.py +37 -25
  297. infrahub/graphql/queries/search.py +11 -10
  298. infrahub/graphql/queries/status.py +12 -9
  299. infrahub/graphql/queries/task.py +11 -9
  300. infrahub/graphql/resolvers/many_relationship.py +15 -15
  301. infrahub/graphql/resolvers/resolver.py +58 -37
  302. infrahub/graphql/resolvers/single_relationship.py +16 -10
  303. infrahub/graphql/schema.py +4 -0
  304. infrahub/graphql/subscription/__init__.py +1 -1
  305. infrahub/graphql/subscription/events.py +1 -1
  306. infrahub/graphql/subscription/graphql_query.py +8 -8
  307. infrahub/graphql/types/branch.py +2 -2
  308. infrahub/graphql/types/common.py +6 -1
  309. infrahub/graphql/types/context.py +12 -0
  310. infrahub/graphql/types/enums.py +2 -0
  311. infrahub/graphql/types/event.py +167 -0
  312. infrahub/graphql/types/interface.py +2 -2
  313. infrahub/graphql/types/node.py +5 -5
  314. infrahub/graphql/types/permission.py +2 -2
  315. infrahub/graphql/types/relationship.py +3 -3
  316. infrahub/graphql/types/standard_node.py +9 -11
  317. infrahub/graphql/utils.py +30 -184
  318. infrahub/groups/ancestors.py +29 -0
  319. infrahub/groups/parsers.py +107 -0
  320. infrahub/groups/tasks.py +2 -3
  321. infrahub/lock.py +21 -21
  322. infrahub/menu/generator.py +7 -8
  323. infrahub/menu/menu.py +107 -139
  324. infrahub/menu/models.py +121 -20
  325. infrahub/menu/repository.py +111 -0
  326. infrahub/menu/utils.py +5 -8
  327. infrahub/message_bus/__init__.py +11 -13
  328. infrahub/message_bus/messages/__init__.py +1 -25
  329. infrahub/message_bus/messages/check_generator_run.py +3 -3
  330. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  331. infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
  332. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  333. infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
  334. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  335. infrahub/message_bus/messages/send_echo_request.py +1 -1
  336. infrahub/message_bus/operations/__init__.py +4 -15
  337. infrahub/message_bus/operations/check/__init__.py +2 -2
  338. infrahub/message_bus/operations/check/generator.py +2 -3
  339. infrahub/message_bus/operations/event/__init__.py +2 -2
  340. infrahub/message_bus/operations/event/branch.py +7 -3
  341. infrahub/message_bus/operations/event/worker.py +0 -3
  342. infrahub/message_bus/operations/finalize/validator.py +52 -2
  343. infrahub/message_bus/operations/git/file.py +2 -2
  344. infrahub/message_bus/operations/git/repository.py +1 -1
  345. infrahub/message_bus/operations/requests/__init__.py +0 -4
  346. infrahub/message_bus/operations/requests/generator_definition.py +22 -24
  347. infrahub/message_bus/operations/requests/proposed_change.py +39 -20
  348. infrahub/message_bus/operations/send/echo.py +1 -1
  349. infrahub/message_bus/types.py +1 -1
  350. infrahub/permissions/globals.py +15 -0
  351. infrahub/pools/number.py +2 -4
  352. infrahub/pools/prefix.py +29 -165
  353. infrahub/prefect_server/__init__.py +0 -0
  354. infrahub/prefect_server/app.py +18 -0
  355. infrahub/prefect_server/database.py +20 -0
  356. infrahub/prefect_server/events.py +28 -0
  357. infrahub/prefect_server/models.py +46 -0
  358. infrahub/proposed_change/models.py +18 -1
  359. infrahub/proposed_change/tasks.py +204 -53
  360. infrahub/pytest_plugin.py +13 -10
  361. infrahub/server.py +13 -12
  362. infrahub/services/__init__.py +148 -63
  363. infrahub/services/adapters/cache/__init__.py +11 -11
  364. infrahub/services/adapters/cache/nats.py +42 -25
  365. infrahub/services/adapters/cache/redis.py +3 -11
  366. infrahub/services/adapters/event/__init__.py +11 -19
  367. infrahub/services/adapters/http/__init__.py +0 -5
  368. infrahub/services/adapters/http/httpx.py +22 -15
  369. infrahub/services/adapters/message_bus/__init__.py +25 -8
  370. infrahub/services/adapters/message_bus/local.py +9 -7
  371. infrahub/services/adapters/message_bus/nats.py +14 -8
  372. infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
  373. infrahub/services/adapters/workflow/__init__.py +11 -8
  374. infrahub/services/adapters/workflow/local.py +27 -6
  375. infrahub/services/adapters/workflow/worker.py +23 -7
  376. infrahub/services/component.py +43 -40
  377. infrahub/services/protocols.py +7 -7
  378. infrahub/services/scheduler.py +30 -29
  379. infrahub/storage.py +2 -4
  380. infrahub/task_manager/constants.py +1 -1
  381. infrahub/task_manager/event.py +275 -0
  382. infrahub/task_manager/models.py +147 -3
  383. infrahub/task_manager/task.py +1 -1
  384. infrahub/tasks/artifact.py +20 -21
  385. infrahub/tasks/registry.py +1 -1
  386. infrahub/telemetry/__init__.py +0 -0
  387. infrahub/telemetry/constants.py +9 -0
  388. infrahub/telemetry/database.py +86 -0
  389. infrahub/telemetry/models.py +65 -0
  390. infrahub/telemetry/task_manager.py +77 -0
  391. infrahub/telemetry/tasks.py +119 -0
  392. infrahub/telemetry/utils.py +11 -0
  393. infrahub/transformations/tasks.py +5 -7
  394. infrahub/trigger/__init__.py +0 -0
  395. infrahub/trigger/catalogue.py +13 -0
  396. infrahub/trigger/constants.py +1 -0
  397. infrahub/trigger/models.py +118 -0
  398. infrahub/trigger/setup.py +90 -0
  399. infrahub/trigger/tasks.py +36 -0
  400. infrahub/types.py +1 -1
  401. infrahub/utils.py +12 -2
  402. infrahub/validators/__init__.py +0 -0
  403. infrahub/validators/events.py +42 -0
  404. infrahub/validators/tasks.py +41 -0
  405. infrahub/webhook/gather.py +17 -0
  406. infrahub/webhook/models.py +180 -42
  407. infrahub/webhook/tasks.py +149 -203
  408. infrahub/webhook/triggers.py +44 -0
  409. infrahub/workers/infrahub_async.py +38 -27
  410. infrahub/workers/utils.py +63 -0
  411. infrahub/workflows/catalogue.py +98 -71
  412. infrahub/workflows/initialization.py +12 -8
  413. infrahub/workflows/models.py +29 -5
  414. infrahub/workflows/utils.py +11 -2
  415. infrahub_sdk/client.py +19 -0
  416. infrahub_sdk/context.py +13 -0
  417. infrahub_sdk/ctl/branch.py +3 -2
  418. infrahub_sdk/ctl/utils.py +0 -16
  419. infrahub_sdk/exceptions.py +6 -0
  420. infrahub_sdk/generator.py +3 -0
  421. infrahub_sdk/graphql.py +45 -13
  422. infrahub_sdk/node.py +66 -20
  423. infrahub_sdk/protocols.py +21 -8
  424. infrahub_sdk/protocols_base.py +32 -11
  425. infrahub_sdk/schema/__init__.py +14 -2
  426. infrahub_sdk/schema/main.py +7 -0
  427. infrahub_sdk/task/__init__.py +11 -0
  428. infrahub_sdk/task/constants.py +3 -0
  429. infrahub_sdk/task/exceptions.py +25 -0
  430. infrahub_sdk/task/manager.py +551 -0
  431. infrahub_sdk/task/models.py +74 -0
  432. infrahub_sdk/timestamp.py +142 -33
  433. infrahub_sdk/utils.py +29 -1
  434. {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/METADATA +8 -6
  435. infrahub_server-1.2.0.dist-info/RECORD +746 -0
  436. infrahub_testcontainers/container.py +5 -6
  437. infrahub_testcontainers/docker-compose.test.yml +2 -2
  438. infrahub_testcontainers/helpers.py +5 -1
  439. infrahub/core/branch/constants.py +0 -2
  440. infrahub/core/schema/definitions/core.py +0 -2275
  441. infrahub/graphql/query.py +0 -52
  442. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  443. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  444. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  445. infrahub/message_bus/messages/event_branch_create.py +0 -11
  446. infrahub/message_bus/messages/event_branch_delete.py +0 -11
  447. infrahub/message_bus/messages/event_branch_rebased.py +0 -9
  448. infrahub/message_bus/messages/event_node_mutated.py +0 -15
  449. infrahub/message_bus/messages/event_schema_update.py +0 -9
  450. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  451. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  452. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  453. infrahub/message_bus/operations/check/repository.py +0 -293
  454. infrahub/message_bus/operations/event/node.py +0 -20
  455. infrahub/message_bus/operations/event/schema.py +0 -17
  456. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  457. infrahub/message_bus/operations/requests/repository.py +0 -133
  458. infrahub/schema/constants.py +0 -1
  459. infrahub/schema/tasks.py +0 -76
  460. infrahub/services/adapters/database/__init__.py +0 -9
  461. infrahub/tasks/telemetry.py +0 -127
  462. infrahub/webhook/constants.py +0 -3
  463. infrahub_server-1.1.9.dist-info/RECORD +0 -688
  464. /infrahub/{schema → artifacts}/__init__.py +0 -0
  465. {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/LICENSE.txt +0 -0
  466. {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/WHEEL +0 -0
  467. {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  from collections import defaultdict
2
2
  from enum import Enum
3
- from typing import Iterable, Optional, Union
3
+ from typing import Iterable
4
4
 
5
5
  from infrahub.core import registry
6
6
  from infrahub.core.branch import Branch
@@ -11,7 +11,7 @@ from infrahub.core.query.relationship import (
11
11
  RelationshipGetByIdentifierQuery,
12
12
  RelationshipPeersData,
13
13
  )
14
- from infrahub.core.schema import MainSchemaTypes, NodeSchema, ProfileSchema
14
+ from infrahub.core.schema import MainSchemaTypes, NodeSchema, ProfileSchema, TemplateSchema
15
15
  from infrahub.core.timestamp import Timestamp
16
16
  from infrahub.database import InfrahubDatabase
17
17
  from infrahub.exceptions import ValidationError
@@ -28,7 +28,7 @@ class NodeDeleteIndex:
28
28
  # {node_schema: {DeleteRelationshipType: {relationship_identifier: peer_node_schema}}}
29
29
  self._dependency_graph: dict[str, dict[DeleteRelationshipType, dict[str, set[str]]]] = {}
30
30
 
31
- def index(self, start_schemas: Iterable[NodeSchema | ProfileSchema]) -> None:
31
+ def index(self, start_schemas: Iterable[NodeSchema | ProfileSchema | TemplateSchema]) -> None:
32
32
  self._index_cascading_deletes(start_schemas=start_schemas)
33
33
  self._index_dependent_schema(start_schemas=start_schemas)
34
34
 
@@ -50,7 +50,7 @@ class NodeDeleteIndex:
50
50
  self._dependency_graph[kind][relationship_type] = defaultdict(set)
51
51
  self._dependency_graph[kind][relationship_type][relationship_identifier].update(peer_kinds)
52
52
 
53
- def _index_cascading_deletes(self, start_schemas: Iterable[NodeSchema | ProfileSchema]) -> None:
53
+ def _index_cascading_deletes(self, start_schemas: Iterable[NodeSchema | ProfileSchema | TemplateSchema]) -> None:
54
54
  kinds_to_check: set[str] = {schema.kind for schema in start_schemas}
55
55
  while True:
56
56
  try:
@@ -72,7 +72,7 @@ class NodeDeleteIndex:
72
72
  if peer_kind not in self._dependency_graph:
73
73
  kinds_to_check.add(peer_kind)
74
74
 
75
- def _index_dependent_schema(self, start_schemas: Iterable[NodeSchema | ProfileSchema]) -> None:
75
+ def _index_dependent_schema(self, start_schemas: Iterable[NodeSchema | ProfileSchema | TemplateSchema]) -> None:
76
76
  start_schema_kinds: set[str] = set()
77
77
  for start_schema in start_schemas:
78
78
  start_schema_kinds.add(start_schema.kind)
@@ -124,16 +124,14 @@ class NodeDeleteValidator:
124
124
  self._all_schemas_map = schema_branch.get_all(duplicate=False)
125
125
  self.index: NodeDeleteIndex = NodeDeleteIndex(all_schemas_map=self._all_schemas_map)
126
126
 
127
- async def get_ids_to_delete(self, nodes: Iterable[Node], at: Optional[Union[Timestamp, str]] = None) -> set[str]:
127
+ async def get_ids_to_delete(self, nodes: Iterable[Node], at: Timestamp | str | None = None) -> set[str]:
128
128
  start_schemas = {node.get_schema() for node in nodes}
129
129
  self.index.index(start_schemas=start_schemas)
130
130
  at = Timestamp(at)
131
131
 
132
132
  return await self._analyze_delete_dependencies(start_nodes=nodes, at=at)
133
133
 
134
- async def _analyze_delete_dependencies(
135
- self, start_nodes: Iterable[Node], at: Optional[Union[Timestamp, str]]
136
- ) -> set[str]:
134
+ async def _analyze_delete_dependencies(self, start_nodes: Iterable[Node], at: Timestamp | str | None) -> set[str]:
137
135
  full_relationship_identifiers = self.index.get_relationship_identifiers()
138
136
  if not full_relationship_identifiers:
139
137
  return {node.get_id() for node in start_nodes}
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from infrahub.core.ipam.size import get_prefix_space
6
6
  from infrahub.core.ipam.utilization import PrefixUtilizationGetter
@@ -16,10 +16,10 @@ class BuiltinIPPrefix(Node):
16
16
  async def to_graphql(
17
17
  self,
18
18
  db: InfrahubDatabase,
19
- fields: Optional[dict] = None,
20
- related_node_ids: Optional[set] = None,
19
+ fields: dict | None = None,
20
+ related_node_ids: set | None = None,
21
21
  filter_sensitive: bool = False,
22
- permissions: Optional[dict] = None,
22
+ permissions: dict | None = None, # noqa: ARG002
23
23
  include_properties: bool = True,
24
24
  ) -> dict:
25
25
  response = await super().to_graphql(
@@ -40,8 +40,8 @@ class BuiltinIPPrefix(Node):
40
40
  retrieved = await NodeManager.get_one(
41
41
  db=db, branch=self._branch, id=self.id, fields={"member_type": None, "prefix": None}
42
42
  )
43
- self.member_type = retrieved.member_type # type: ignore[union-attr] # pylint: disable=attribute-defined-outside-init
44
- self.prefix = retrieved.prefix # type: ignore[union-attr] # pylint: disable=attribute-defined-outside-init
43
+ self.member_type = retrieved.member_type # type: ignore[union-attr]
44
+ self.prefix = retrieved.prefix # type: ignore[union-attr]
45
45
  utilization_getter = PrefixUtilizationGetter(db=db, ip_prefixes=[self])
46
46
  utilization = await utilization_getter.get_use_percentage(
47
47
  ip_prefixes=[self], branch_names=[self._branch.name]
@@ -51,12 +51,12 @@ class BuiltinIPPrefix(Node):
51
51
  return response
52
52
 
53
53
  async def get_resource_weight(self, db: InfrahubDatabase) -> int:
54
- member_type = self.member_type.value # type: ignore[has-type] # pylint: disable=access-member-before-definition
55
- prefixlen = self.prefix.prefixlen # type: ignore[has-type] # pylint: disable=access-member-before-definition
54
+ member_type = self.member_type.value # type: ignore[has-type]
55
+ prefixlen = self.prefix.prefixlen # type: ignore[has-type]
56
56
  if member_type is None or prefixlen is None:
57
57
  retrieved = await NodeManager.get_one(
58
58
  db=db, branch=self._branch, id=self.id, fields={"member_type": None, "prefix": None}
59
59
  )
60
- self.member_type = retrieved.member_type # type: ignore[union-attr] # pylint: disable=attribute-defined-outside-init
61
- self.prefix = retrieved.prefix # type: ignore[union-attr] # pylint: disable=attribute-defined-outside-init
60
+ self.member_type = retrieved.member_type # type: ignore[union-attr]
61
+ self.prefix = retrieved.prefix # type: ignore[union-attr]
62
62
  return get_prefix_space(self)
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from infrahub.permissions.constants import PermissionDecisionFlag
6
6
 
@@ -14,10 +14,10 @@ class CoreGlobalPermission(Node):
14
14
  async def to_graphql(
15
15
  self,
16
16
  db: InfrahubDatabase,
17
- fields: Optional[dict] = None,
18
- related_node_ids: Optional[set] = None,
17
+ fields: dict | None = None,
18
+ related_node_ids: set | None = None,
19
19
  filter_sensitive: bool = False,
20
- permissions: Optional[dict] = None,
20
+ permissions: dict | None = None,
21
21
  include_properties: bool = True,
22
22
  ) -> dict:
23
23
  response = await super().to_graphql(
@@ -41,10 +41,10 @@ class CoreObjectPermission(Node):
41
41
  async def to_graphql(
42
42
  self,
43
43
  db: InfrahubDatabase,
44
- fields: Optional[dict] = None,
45
- related_node_ids: Optional[set] = None,
44
+ fields: dict | None = None,
45
+ related_node_ids: set | None = None,
46
46
  filter_sensitive: bool = False,
47
- permissions: Optional[dict] = None,
47
+ permissions: dict | None = None,
48
48
  include_properties: bool = True,
49
49
  ) -> dict:
50
50
  response = await super().to_graphql(
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import ipaddress
4
- from typing import TYPE_CHECKING, Any, Optional
4
+ from typing import TYPE_CHECKING, Any
5
5
 
6
6
  from infrahub.core import registry
7
7
  from infrahub.core.ipam.reconciler import IpamReconciler
@@ -26,10 +26,10 @@ class CoreIPAddressPool(Node):
26
26
  self,
27
27
  db: InfrahubDatabase,
28
28
  branch: Branch,
29
- identifier: Optional[str] = None,
30
- data: Optional[dict[str, Any]] = None,
31
- address_type: Optional[str] = None,
32
- prefixlen: Optional[int] = None,
29
+ identifier: str | None = None,
30
+ data: dict[str, Any] | None = None,
31
+ address_type: str | None = None,
32
+ prefixlen: int | None = None,
33
33
  ) -> Node:
34
34
  # Check if there is already a resource allocated with this identifier
35
35
  # if not, pull all existing prefixes and allocated the next available
@@ -80,7 +80,7 @@ class CoreIPAddressPool(Node):
80
80
 
81
81
  return node
82
82
 
83
- async def get_next(self, db: InfrahubDatabase, prefixlen: Optional[int] = None) -> IPAddressType:
83
+ async def get_next(self, db: InfrahubDatabase, prefixlen: int | None = None) -> IPAddressType:
84
84
  # Measure utilization of all prefixes identified as resources
85
85
  resources = await self.resources.get_peers(db=db) # type: ignore[attr-defined]
86
86
  ip_namespace = await self.ip_namespace.get_peer(db=db) # type: ignore[attr-defined]
@@ -1,7 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import ipaddress
4
- from typing import TYPE_CHECKING, Any, Optional
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from netaddr import IPSet
5
7
 
6
8
  from infrahub.core import registry
7
9
  from infrahub.core.ipam.reconciler import IpamReconciler
@@ -11,7 +13,7 @@ from infrahub.core.query.resource_manager import (
11
13
  PrefixPoolSetReserved,
12
14
  )
13
15
  from infrahub.exceptions import ValidationError
14
- from infrahub.pools.prefix import PrefixPool
16
+ from infrahub.pools.prefix import get_next_available_prefix
15
17
 
16
18
  from .. import Node
17
19
 
@@ -26,11 +28,11 @@ class CoreIPPrefixPool(Node):
26
28
  self,
27
29
  db: InfrahubDatabase,
28
30
  branch: Branch,
29
- identifier: Optional[str] = None,
30
- data: Optional[dict[str, Any]] = None,
31
- prefixlen: Optional[int] = None,
32
- member_type: Optional[str] = None,
33
- prefix_type: Optional[str] = None,
31
+ identifier: str | None = None,
32
+ data: dict[str, Any] | None = None,
33
+ prefixlen: int | None = None,
34
+ member_type: str | None = None,
35
+ prefix_type: str | None = None,
34
36
  ) -> Node:
35
37
  # Check if there is already a resource allocated with this identifier
36
38
  # if not, pull all existing prefixes and allocated the next available
@@ -99,14 +101,15 @@ class CoreIPPrefixPool(Node):
99
101
  branch_agnostic=True,
100
102
  )
101
103
 
102
- pool = PrefixPool(resource.prefix.value) # type: ignore[attr-defined]
104
+ pool = IPSet([resource.prefix.value])
103
105
  for subnet in subnets:
104
- pool.reserve(subnet=str(subnet.prefix))
106
+ pool.remove(addr=str(subnet.prefix))
105
107
 
106
108
  try:
107
- next_available = pool.get(prefixlen=prefixlen)
109
+ prefix_ver = ipaddress.ip_network(resource.prefix.value).version
110
+ next_available = get_next_available_prefix(pool=pool, prefix_length=prefixlen, prefix_ver=prefix_ver)
108
111
  return next_available
109
- except IndexError:
112
+ except ValueError:
110
113
  continue
111
114
 
112
115
  raise IndexError("No more resources available")
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from infrahub.core.query.resource_manager import NumberPoolGetReserved, NumberPoolGetUsed, NumberPoolSetReserved
6
6
  from infrahub.exceptions import PoolExhaustedError
@@ -18,7 +18,7 @@ class CoreNumberPool(Node):
18
18
  db: InfrahubDatabase,
19
19
  branch: Branch,
20
20
  node: Node,
21
- identifier: Optional[str] = None,
21
+ identifier: str | None = None,
22
22
  ) -> int:
23
23
  identifier = identifier or node.get_id()
24
24
  # Check if there is already a resource allocated with this identifier
@@ -55,7 +55,7 @@ class CoreNumberPool(Node):
55
55
  return next_number
56
56
 
57
57
 
58
- def find_next_free(start: int, end: int, taken: list[int | None]) -> Optional[int]:
58
+ def find_next_free(start: int, end: int, taken: list[int | None]) -> int | None:
59
59
  used_numbers = [number for number in taken if number is not None]
60
60
  used_set = set(used_numbers)
61
61
 
@@ -19,8 +19,6 @@ from infrahub.core.query.standard_node import (
19
19
  )
20
20
  from infrahub.exceptions import Error, InitializationError
21
21
 
22
- # pylint: disable=redefined-builtin
23
-
24
22
  if TYPE_CHECKING:
25
23
  from neo4j.graph import Node as Neo4jNode
26
24
  from pydantic.fields import FieldInfo
@@ -173,9 +171,9 @@ class StandardNode(BaseModel):
173
171
 
174
172
  if value == NULL_VALUE:
175
173
  attrs[key] = None
176
- elif issubclass(field_type, (int, float, bool, str, UUID)):
174
+ elif issubclass(field_type, int | float | bool | str | UUID):
177
175
  attrs[key] = value
178
- elif isinstance(value, (str, bytes)):
176
+ elif isinstance(value, str | bytes):
179
177
  attrs[key] = ujson.loads(value)
180
178
 
181
179
  return cls(**attrs)
@@ -203,7 +201,7 @@ class StandardNode(BaseModel):
203
201
  data[attr_name] = ujson.dumps(clean_value)
204
202
  else:
205
203
  data[attr_name] = attr_value.model_dump_json()
206
- elif issubclass(field_type, (int, float, bool, str, UUID)):
204
+ elif issubclass(field_type, int | float | bool | str | UUID):
207
205
  data[attr_name] = attr_value
208
206
  else:
209
207
  data[attr_name] = ujson.dumps(attr_value)
infrahub/core/path.py CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from collections import defaultdict
4
4
  from itertools import chain
5
- from typing import TYPE_CHECKING, Any, Optional, Union
5
+ from typing import TYPE_CHECKING, Any
6
6
 
7
7
  from pydantic import BaseModel, Field
8
8
  from typing_extensions import Self
@@ -56,12 +56,12 @@ class DataPath(InfrahubPath):
56
56
  path_type: PathType
57
57
  node_id: str = Field(..., description="Kind of the model in the schema")
58
58
  kind: str = Field(..., description="Kind of the main node")
59
- field_name: Optional[str] = Field(
59
+ field_name: str | None = Field(
60
60
  default=None, description="Name of the field (either an attribute or a relationship)"
61
61
  )
62
- property_name: Optional[str] = Field(default=None, description="Name of the property")
63
- peer_id: Optional[str] = Field(default=None, description="")
64
- value: Optional[Any] = Field(default=None, description="Optional value of the resource")
62
+ property_name: str | None = Field(default=None, description="Name of the property")
63
+ peer_id: str | None = Field(default=None, description="")
64
+ value: Any | None = Field(default=None, description="Optional value of the resource")
65
65
 
66
66
  @property
67
67
  def resource_type(self) -> PathResourceType:
@@ -109,11 +109,11 @@ class GroupedDataPaths:
109
109
  class SchemaPath(InfrahubPath):
110
110
  path_type: SchemaPathType
111
111
  schema_kind: str = Field(..., description="Kind of the model in the schema")
112
- schema_id: Optional[str] = Field(default=None, description="UUID of the model in the schema")
113
- field_name: Optional[str] = Field(
112
+ schema_id: str | None = Field(default=None, description="UUID of the model in the schema")
113
+ field_name: str | None = Field(
114
114
  default=None, description="Name of the field (either an attribute or a relationship)"
115
115
  )
116
- property_name: Optional[str] = Field(default=None, description="Name of the property")
116
+ property_name: str | None = Field(default=None, description="Name of the property")
117
117
 
118
118
  @property
119
119
  def resource_type(self) -> PathResourceType:
@@ -133,10 +133,10 @@ class SchemaPath(InfrahubPath):
133
133
  @classmethod
134
134
  def init(
135
135
  cls,
136
- schema: Union[NodeSchema, GenericSchema],
137
- schema_id: Optional[str] = None,
138
- field_name: Optional[str] = None,
139
- property_name: Optional[str] = None,
136
+ schema: NodeSchema | GenericSchema,
137
+ schema_id: str | None = None,
138
+ field_name: str | None = None,
139
+ property_name: str | None = None,
140
140
  ) -> Self:
141
141
  if field_name and not schema.get_field(name=field_name, raise_on_error=False):
142
142
  raise ValueError(f"Field : {field_name} is not valid for {schema.kind}")
infrahub/core/property.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional, Union
3
+ from typing import TYPE_CHECKING
4
4
  from uuid import UUID
5
5
 
6
6
  from pydantic import BaseModel
@@ -32,7 +32,7 @@ class FlagPropertyMixin:
32
32
  is_visible = True
33
33
  is_protected = False
34
34
 
35
- def _init_flag_property_mixin(self, kwargs: Optional[dict] = None) -> None:
35
+ def _init_flag_property_mixin(self, kwargs: dict | None = None) -> None:
36
36
  if not kwargs:
37
37
  return
38
38
 
@@ -47,7 +47,7 @@ class NodePropertyMixin:
47
47
  branch: Branch
48
48
  at: Timestamp
49
49
 
50
- def _init_node_property_mixin(self, kwargs: Optional[dict] = None) -> None:
50
+ def _init_node_property_mixin(self, kwargs: dict | None = None) -> None:
51
51
  for node in self._node_properties:
52
52
  setattr(self, f"_{node}", None)
53
53
  setattr(self, f"{node}_id", None)
@@ -66,7 +66,7 @@ class NodePropertyMixin:
66
66
  return self._get_node_property_from_cache(name="source")
67
67
 
68
68
  @source.setter
69
- def source(self, value: Union[str, Node, UUID]) -> None:
69
+ def source(self, value: str | Node | UUID) -> None:
70
70
  self._set_node_property(name="source", value=value)
71
71
 
72
72
  @property
@@ -74,25 +74,25 @@ class NodePropertyMixin:
74
74
  return self._get_node_property_from_cache(name="owner")
75
75
 
76
76
  @owner.setter
77
- def owner(self, value: Optional[Union[str, Node, UUID]]) -> None:
77
+ def owner(self, value: str | Node | UUID | None) -> None:
78
78
  self._set_node_property(name="owner", value=value)
79
79
 
80
80
  def clear_owner(self) -> None:
81
81
  self._set_node_property(name="owner", value=None)
82
82
 
83
- async def get_source(self, db: InfrahubDatabase) -> Optional[Node]:
83
+ async def get_source(self, db: InfrahubDatabase) -> Node | None:
84
84
  return await self._get_node_property(name="source", db=db)
85
85
 
86
86
  def clear_source(self) -> None:
87
87
  self._set_node_property(name="source", value=None)
88
88
 
89
- def set_source(self, value: Union[str, Node, UUID]) -> None:
89
+ def set_source(self, value: str | Node | UUID) -> None:
90
90
  self._set_node_property(name="source", value=value)
91
91
 
92
- async def get_owner(self, db: InfrahubDatabase) -> Optional[Node]:
92
+ async def get_owner(self, db: InfrahubDatabase) -> Node | None:
93
93
  return await self._get_node_property(name="owner", db=db)
94
94
 
95
- def set_owner(self, value: Union[str, Node, UUID]) -> None:
95
+ def set_owner(self, value: str | Node | UUID) -> None:
96
96
  self._set_node_property(name="owner", value=value)
97
97
 
98
98
  def _get_node_property_from_cache(self, name: str) -> Node:
@@ -107,7 +107,7 @@ class NodePropertyMixin:
107
107
 
108
108
  return item
109
109
 
110
- async def _get_node_property(self, db: InfrahubDatabase, name: str) -> Optional[Node]:
110
+ async def _get_node_property(self, db: InfrahubDatabase, name: str) -> Node | None:
111
111
  """Return the node attribute.
112
112
  If the node is already present in cache, serve from the cache
113
113
  If the node is not present, query it on the fly using the node_id
@@ -117,13 +117,13 @@ class NodePropertyMixin:
117
117
 
118
118
  return getattr(self, f"_{name}", None)
119
119
 
120
- def _set_node_property(self, name: str, value: Optional[Union[str, Node, UUID]]) -> None:
120
+ def _set_node_property(self, name: str, value: str | Node | UUID | None) -> None:
121
121
  """Set the value of the node_property.
122
122
  If the value is a string, we assume it's an ID and we'll save it to query it later (if needed)
123
123
  If the value is a Node, we save the node and we extract the ID
124
124
  if the value is None, we just initialize the 2 variables."""
125
125
 
126
- if isinstance(value, (str, UUID)):
126
+ if isinstance(value, str | UUID):
127
127
  setattr(self, f"{name}_id", value)
128
128
  setattr(self, f"_{name}", None)
129
129
  elif isinstance(value, dict) and "id" in value:
@@ -148,6 +148,14 @@ class CoreMenu(CoreNode):
148
148
  children: RelationshipManager
149
149
 
150
150
 
151
+ class CoreObjectComponentTemplate(CoreNode):
152
+ template_name: String
153
+
154
+
155
+ class CoreObjectTemplate(CoreNode):
156
+ template_name: String
157
+
158
+
151
159
  class CoreProfile(CoreNode):
152
160
  profile_name: String
153
161
  profile_priority: IntegerOptional
@@ -193,6 +201,9 @@ class CoreValidator(CoreNode):
193
201
 
194
202
  class CoreWebhook(CoreNode):
195
203
  name: String
204
+ event_type: Enum
205
+ branch_scope: Dropdown
206
+ node_kind: StringOptional
196
207
  description: StringOptional
197
208
  url: URL
198
209
  validate_certificates: BooleanOptional
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Optional, Protocol, Union, runtime_checkable
3
+ from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
4
4
 
5
5
  from typing_extensions import Self
6
6
 
@@ -9,8 +9,6 @@ if TYPE_CHECKING:
9
9
 
10
10
  from infrahub.core.schema.schema_branch import SchemaBranch
11
11
 
12
- # pylint: disable=redefined-builtin
13
-
14
12
 
15
13
  @runtime_checkable
16
14
  class Timestamp(Protocol): ...
@@ -24,6 +22,10 @@ class NodeSchema(Protocol): ...
24
22
  class ProfileSchema(Protocol): ...
25
23
 
26
24
 
25
+ @runtime_checkable
26
+ class TemplateSchema(Protocol): ...
27
+
28
+
27
29
  @runtime_checkable
28
30
  class Branch(Protocol): ...
29
31
 
@@ -36,23 +38,23 @@ class InfrahubDatabase(Protocol):
36
38
  @property
37
39
  def is_transaction(self) -> bool: ...
38
40
 
39
- def add_schema(self, schema: SchemaBranch, name: Optional[str] = None) -> None: ...
40
- def start_session(self, read_only: bool = False, schemas: Optional[list[SchemaBranch]] = None) -> Self: ...
41
- def start_transaction(self, schemas: Optional[list[SchemaBranch]] = None) -> Self: ...
41
+ def add_schema(self, schema: SchemaBranch, name: str | None = None) -> None: ...
42
+ def start_session(self, read_only: bool = False, schemas: list[SchemaBranch] | None = None) -> Self: ...
43
+ def start_transaction(self, schemas: list[SchemaBranch] | None = None) -> Self: ...
42
44
  async def session(self) -> AsyncSession: ...
43
- async def transaction(self, name: Optional[str]) -> AsyncTransaction: ...
45
+ async def transaction(self, name: str | None) -> AsyncTransaction: ...
44
46
  async def close(self) -> None: ...
45
47
 
46
48
  async def execute_query(
47
- self, query: str, params: Optional[dict[str, Any]] = None, name: str = "undefined"
49
+ self, query: str, params: dict[str, Any] | None = None, name: str = "undefined"
48
50
  ) -> list[Record]: ...
49
51
 
50
52
  async def execute_query_with_metadata(
51
- self, query: str, params: Optional[dict[str, Any]] = None, name: str = "undefined"
53
+ self, query: str, params: dict[str, Any] | None = None, name: str = "undefined"
52
54
  ) -> tuple[list[Record], dict[str, Any]]: ...
53
55
 
54
56
  async def run_query(
55
- self, query: str, params: Optional[dict[str, Any]] = None, name: str = "undefined"
57
+ self, query: str, params: dict[str, Any] | None = None, name: str = "undefined"
56
58
  ) -> AsyncResult: ...
57
59
 
58
60
  def render_list_comprehension(self, items: str, item_name: str) -> str: ...
@@ -71,29 +73,29 @@ class CoreNode(Protocol):
71
73
  @classmethod
72
74
  async def init(
73
75
  cls,
74
- schema: Union[NodeSchema, ProfileSchema, str],
76
+ schema: NodeSchema | ProfileSchema | str,
75
77
  db: InfrahubDatabase,
76
- branch: Optional[Union[Branch, str]] = None,
77
- at: Optional[Union[Timestamp, str]] = None,
78
+ branch: Branch | str | None = None,
79
+ at: Timestamp | str | None = None,
78
80
  ) -> Self: ...
79
- async def new(self, db: InfrahubDatabase, id: Optional[str] = None, **kwargs: Any) -> Self: ...
80
- async def save(self, db: InfrahubDatabase, at: Optional[Timestamp] = None) -> Self: ...
81
- async def delete(self, db: InfrahubDatabase, at: Optional[Timestamp] = None) -> None: ...
81
+ async def new(self, db: InfrahubDatabase, id: str | None = None, **kwargs: Any) -> Self: ...
82
+ async def save(self, db: InfrahubDatabase, at: Timestamp | None = None) -> Self: ...
83
+ async def delete(self, db: InfrahubDatabase, at: Timestamp | None = None) -> None: ...
82
84
  async def load(
83
85
  self,
84
86
  db: InfrahubDatabase,
85
- id: Optional[str] = None,
86
- db_id: Optional[str] = None,
87
- updated_at: Optional[Union[Timestamp, str]] = None,
87
+ id: str | None = None,
88
+ db_id: str | None = None,
89
+ updated_at: Timestamp | str | None = None,
88
90
  **kwargs: Any,
89
91
  ) -> Self: ...
90
92
  async def to_graphql(
91
93
  self,
92
94
  db: InfrahubDatabase,
93
- fields: Optional[dict] = None,
94
- related_node_ids: Optional[set] = None,
95
+ fields: dict | None = None,
96
+ related_node_ids: set | None = None,
95
97
  filter_sensitive: bool = False,
96
- permissions: Optional[dict] = None,
98
+ permissions: dict | None = None,
97
99
  ) -> dict: ...
98
- async def render_display_label(self, db: Optional[InfrahubDatabase] = None) -> str: ...
100
+ async def render_display_label(self, db: InfrahubDatabase | None = None) -> str: ...
99
101
  async def from_graphql(self, data: dict, db: InfrahubDatabase) -> bool: ...