infrahub-server 1.1.8__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 (470) 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 +39 -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 +23 -20
  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/graph/__init__.py +1 -1
  68. infrahub/core/initialization.py +1 -10
  69. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  70. infrahub/core/ipam/constants.py +3 -4
  71. infrahub/core/ipam/reconciler.py +13 -13
  72. infrahub/core/ipam/tasks.py +2 -3
  73. infrahub/core/ipam/utilization.py +10 -13
  74. infrahub/core/manager.py +52 -47
  75. infrahub/core/merge.py +12 -9
  76. infrahub/core/migrations/__init__.py +1 -3
  77. infrahub/core/migrations/graph/__init__.py +7 -3
  78. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  79. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  80. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  81. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  82. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  83. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  84. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  85. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  86. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  87. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  88. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  89. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  90. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  91. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  92. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  93. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  94. infrahub/core/migrations/graph/m017_add_core_profile.py +2 -6
  95. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +3 -3
  96. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +4 -4
  97. infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -3
  98. infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
  99. infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
  100. infrahub/core/migrations/query/attribute_add.py +3 -3
  101. infrahub/core/migrations/query/attribute_rename.py +1 -1
  102. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  103. infrahub/core/migrations/query/node_duplicate.py +1 -1
  104. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  105. infrahub/core/migrations/query/schema_attribute_update.py +3 -3
  106. infrahub/core/migrations/schema/models.py +19 -4
  107. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  108. infrahub/core/migrations/schema/node_remove.py +1 -1
  109. infrahub/core/migrations/schema/tasks.py +7 -7
  110. infrahub/core/migrations/shared.py +10 -12
  111. infrahub/core/models.py +13 -14
  112. infrahub/core/node/__init__.py +172 -57
  113. infrahub/core/node/base.py +3 -5
  114. infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
  115. infrahub/core/node/constraints/grouped_uniqueness.py +5 -5
  116. infrahub/core/node/constraints/interface.py +1 -2
  117. infrahub/core/node/delete_validator.py +7 -9
  118. infrahub/core/node/ipam.py +10 -10
  119. infrahub/core/node/permissions.py +7 -7
  120. infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
  121. infrahub/core/node/resource_manager/ip_prefix_pool.py +14 -11
  122. infrahub/core/node/resource_manager/number_pool.py +3 -3
  123. infrahub/core/node/standard.py +3 -5
  124. infrahub/core/path.py +12 -12
  125. infrahub/core/property.py +12 -12
  126. infrahub/core/protocols.py +11 -0
  127. infrahub/core/protocols_base.py +25 -23
  128. infrahub/core/query/__init__.py +35 -38
  129. infrahub/core/query/attribute.py +13 -13
  130. infrahub/core/query/branch.py +5 -5
  131. infrahub/core/query/delete.py +1 -1
  132. infrahub/core/query/diff.py +7 -7
  133. infrahub/core/query/ipam.py +4 -4
  134. infrahub/core/query/node.py +26 -24
  135. infrahub/core/query/relationship.py +143 -46
  136. infrahub/core/query/resource_manager.py +10 -10
  137. infrahub/core/query/standard_node.py +9 -9
  138. infrahub/core/query/subquery.py +9 -9
  139. infrahub/core/query/task.py +3 -3
  140. infrahub/core/query/task_log.py +1 -1
  141. infrahub/core/query/utils.py +5 -5
  142. infrahub/core/registry.py +13 -17
  143. infrahub/core/relationship/constraints/count.py +4 -5
  144. infrahub/core/relationship/constraints/peer_kind.py +4 -5
  145. infrahub/core/relationship/constraints/profiles_kind.py +2 -2
  146. infrahub/core/relationship/model.py +103 -67
  147. infrahub/core/schema/__init__.py +6 -4
  148. infrahub/core/schema/attribute_schema.py +16 -8
  149. infrahub/core/schema/basenode_schema.py +38 -26
  150. infrahub/core/schema/computed_attribute.py +3 -3
  151. infrahub/core/schema/definitions/core/__init__.py +147 -0
  152. infrahub/core/schema/definitions/core/account.py +171 -0
  153. infrahub/core/schema/definitions/core/artifact.py +136 -0
  154. infrahub/core/schema/definitions/core/builtin.py +24 -0
  155. infrahub/core/schema/definitions/core/check.py +68 -0
  156. infrahub/core/schema/definitions/core/core.py +17 -0
  157. infrahub/core/schema/definitions/core/generator.py +100 -0
  158. infrahub/core/schema/definitions/core/graphql_query.py +79 -0
  159. infrahub/core/schema/definitions/core/group.py +108 -0
  160. infrahub/core/schema/definitions/core/ipam.py +193 -0
  161. infrahub/core/schema/definitions/core/lineage.py +19 -0
  162. infrahub/core/schema/definitions/core/menu.py +48 -0
  163. infrahub/core/schema/definitions/core/permission.py +163 -0
  164. infrahub/core/schema/definitions/core/profile.py +18 -0
  165. infrahub/core/schema/definitions/core/propose_change.py +97 -0
  166. infrahub/core/schema/definitions/core/propose_change_comment.py +193 -0
  167. infrahub/core/schema/definitions/core/propose_change_validator.py +328 -0
  168. infrahub/core/schema/definitions/core/repository.py +286 -0
  169. infrahub/core/schema/definitions/core/resource_pool.py +170 -0
  170. infrahub/core/schema/definitions/core/template.py +27 -0
  171. infrahub/core/schema/definitions/core/transform.py +96 -0
  172. infrahub/core/schema/definitions/core/webhook.py +134 -0
  173. infrahub/core/schema/definitions/internal.py +32 -16
  174. infrahub/core/schema/dropdown.py +3 -4
  175. infrahub/core/schema/generated/attribute_schema.py +15 -18
  176. infrahub/core/schema/generated/base_node_schema.py +12 -14
  177. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  178. infrahub/core/schema/generated/node_schema.py +8 -5
  179. infrahub/core/schema/generated/relationship_schema.py +9 -11
  180. infrahub/core/schema/generic_schema.py +6 -2
  181. infrahub/core/schema/manager.py +46 -43
  182. infrahub/core/schema/node_schema.py +6 -2
  183. infrahub/core/schema/profile_schema.py +4 -0
  184. infrahub/core/schema/relationship_schema.py +15 -7
  185. infrahub/core/schema/schema_branch.py +423 -89
  186. infrahub/core/schema/schema_branch_computed.py +41 -4
  187. infrahub/core/schema/template_schema.py +36 -0
  188. infrahub/core/task/task.py +3 -3
  189. infrahub/core/task/user_task.py +21 -19
  190. infrahub/core/timestamp.py +3 -3
  191. infrahub/core/utils.py +12 -12
  192. infrahub/core/validators/__init__.py +1 -3
  193. infrahub/core/validators/aggregated_checker.py +2 -2
  194. infrahub/core/validators/attribute/choices.py +3 -3
  195. infrahub/core/validators/attribute/enum.py +3 -3
  196. infrahub/core/validators/attribute/kind.py +3 -3
  197. infrahub/core/validators/attribute/length.py +3 -3
  198. infrahub/core/validators/attribute/optional.py +3 -3
  199. infrahub/core/validators/attribute/regex.py +3 -3
  200. infrahub/core/validators/attribute/unique.py +3 -3
  201. infrahub/core/validators/checks_runner.py +60 -0
  202. infrahub/core/validators/determiner.py +1 -3
  203. infrahub/core/validators/model.py +1 -3
  204. infrahub/core/validators/models/validate_migration.py +17 -4
  205. infrahub/core/validators/node/attribute.py +2 -2
  206. infrahub/core/validators/node/generate_profile.py +3 -3
  207. infrahub/core/validators/node/hierarchy.py +3 -3
  208. infrahub/core/validators/node/inherit_from.py +2 -2
  209. infrahub/core/validators/node/relationship.py +2 -2
  210. infrahub/core/validators/query.py +1 -1
  211. infrahub/core/validators/relationship/count.py +5 -5
  212. infrahub/core/validators/relationship/optional.py +3 -3
  213. infrahub/core/validators/relationship/peer.py +3 -3
  214. infrahub/core/validators/shared.py +2 -2
  215. infrahub/core/validators/tasks.py +8 -6
  216. infrahub/core/validators/uniqueness/checker.py +5 -6
  217. infrahub/core/validators/uniqueness/index.py +2 -2
  218. infrahub/core/validators/uniqueness/model.py +11 -11
  219. infrahub/core/validators/uniqueness/query.py +1 -1
  220. infrahub/database/__init__.py +28 -24
  221. infrahub/database/memgraph.py +1 -1
  222. infrahub/database/metrics.py +7 -1
  223. infrahub/dependencies/builder/diff/combiner.py +1 -1
  224. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  225. infrahub/dependencies/builder/diff/deserializer.py +1 -1
  226. infrahub/dependencies/builder/diff/enricher/summary_counts.py +8 -0
  227. infrahub/dependencies/builder/diff/parent_node_adder.py +1 -1
  228. infrahub/dependencies/component/registry.py +2 -2
  229. infrahub/events/__init__.py +25 -2
  230. infrahub/events/artifact_action.py +64 -0
  231. infrahub/events/branch_action.py +57 -20
  232. infrahub/events/generator.py +71 -0
  233. infrahub/events/group_action.py +103 -0
  234. infrahub/events/models.py +160 -53
  235. infrahub/events/node_action.py +140 -23
  236. infrahub/events/repository_action.py +7 -20
  237. infrahub/events/schema_action.py +18 -10
  238. infrahub/events/utils.py +16 -0
  239. infrahub/events/validator_action.py +55 -0
  240. infrahub/exceptions.py +12 -3
  241. infrahub/generators/models.py +2 -3
  242. infrahub/generators/tasks.py +34 -15
  243. infrahub/git/base.py +10 -12
  244. infrahub/git/constants.py +0 -1
  245. infrahub/git/integrator.py +82 -57
  246. infrahub/git/models.py +101 -9
  247. infrahub/git/repository.py +9 -10
  248. infrahub/git/tasks.py +450 -112
  249. infrahub/git/utils.py +48 -0
  250. infrahub/git/worktree.py +1 -2
  251. infrahub/git_credential/askpass.py +1 -2
  252. infrahub/git_credential/helper.py +2 -3
  253. infrahub/graphql/analyzer.py +572 -11
  254. infrahub/graphql/app.py +47 -41
  255. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  256. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  257. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  258. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  259. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  260. infrahub/graphql/context.py +39 -0
  261. infrahub/graphql/enums.py +1 -1
  262. infrahub/graphql/initialization.py +8 -1
  263. infrahub/graphql/loaders/node.py +3 -13
  264. infrahub/graphql/loaders/peers.py +77 -0
  265. infrahub/graphql/loaders/shared.py +13 -0
  266. infrahub/graphql/manager.py +75 -72
  267. infrahub/graphql/mutations/account.py +20 -13
  268. infrahub/graphql/mutations/artifact_definition.py +18 -14
  269. infrahub/graphql/mutations/branch.py +86 -40
  270. infrahub/graphql/mutations/computed_attribute.py +26 -18
  271. infrahub/graphql/mutations/diff.py +17 -8
  272. infrahub/graphql/mutations/diff_conflict.py +14 -8
  273. infrahub/graphql/mutations/generator.py +83 -0
  274. infrahub/graphql/mutations/graphql_query.py +21 -13
  275. infrahub/graphql/mutations/ipam.py +41 -39
  276. infrahub/graphql/mutations/main.py +226 -66
  277. infrahub/graphql/mutations/menu.py +12 -12
  278. infrahub/graphql/mutations/models.py +2 -4
  279. infrahub/graphql/mutations/node_getter/by_default_filter.py +1 -3
  280. infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
  281. infrahub/graphql/mutations/node_getter/by_id.py +1 -3
  282. infrahub/graphql/mutations/node_getter/interface.py +1 -2
  283. infrahub/graphql/mutations/proposed_change.py +39 -31
  284. infrahub/graphql/mutations/relationship.py +372 -129
  285. infrahub/graphql/mutations/repository.py +46 -40
  286. infrahub/graphql/mutations/resource_manager.py +26 -26
  287. infrahub/graphql/mutations/schema.py +70 -37
  288. infrahub/graphql/mutations/tasks.py +10 -7
  289. infrahub/graphql/mutations/webhook.py +137 -0
  290. infrahub/graphql/parser.py +5 -5
  291. infrahub/graphql/permissions.py +3 -10
  292. infrahub/graphql/queries/account.py +22 -18
  293. infrahub/graphql/queries/branch.py +6 -4
  294. infrahub/graphql/queries/diff/tree.py +67 -56
  295. infrahub/graphql/queries/event.py +115 -0
  296. infrahub/graphql/queries/internal.py +3 -3
  297. infrahub/graphql/queries/ipam.py +25 -20
  298. infrahub/graphql/queries/relationship.py +13 -12
  299. infrahub/graphql/queries/resource_manager.py +37 -25
  300. infrahub/graphql/queries/search.py +11 -10
  301. infrahub/graphql/queries/status.py +12 -9
  302. infrahub/graphql/queries/task.py +11 -9
  303. infrahub/graphql/resolvers/many_relationship.py +264 -0
  304. infrahub/graphql/resolvers/resolver.py +60 -139
  305. infrahub/graphql/resolvers/single_relationship.py +16 -10
  306. infrahub/graphql/schema.py +4 -0
  307. infrahub/graphql/subscription/__init__.py +1 -1
  308. infrahub/graphql/subscription/events.py +1 -1
  309. infrahub/graphql/subscription/graphql_query.py +10 -8
  310. infrahub/graphql/types/branch.py +2 -2
  311. infrahub/graphql/types/common.py +6 -1
  312. infrahub/graphql/types/context.py +12 -0
  313. infrahub/graphql/types/enums.py +2 -0
  314. infrahub/graphql/types/event.py +167 -0
  315. infrahub/graphql/types/interface.py +2 -2
  316. infrahub/graphql/types/node.py +5 -5
  317. infrahub/graphql/types/permission.py +2 -2
  318. infrahub/graphql/types/relationship.py +3 -3
  319. infrahub/graphql/types/standard_node.py +9 -11
  320. infrahub/graphql/utils.py +30 -184
  321. infrahub/groups/ancestors.py +29 -0
  322. infrahub/groups/parsers.py +107 -0
  323. infrahub/groups/tasks.py +2 -3
  324. infrahub/lock.py +21 -21
  325. infrahub/menu/generator.py +7 -8
  326. infrahub/menu/menu.py +107 -139
  327. infrahub/menu/models.py +121 -20
  328. infrahub/menu/repository.py +111 -0
  329. infrahub/menu/utils.py +5 -8
  330. infrahub/message_bus/__init__.py +11 -13
  331. infrahub/message_bus/messages/__init__.py +1 -25
  332. infrahub/message_bus/messages/check_generator_run.py +3 -3
  333. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  334. infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
  335. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  336. infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
  337. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  338. infrahub/message_bus/messages/send_echo_request.py +1 -1
  339. infrahub/message_bus/operations/__init__.py +4 -15
  340. infrahub/message_bus/operations/check/__init__.py +2 -2
  341. infrahub/message_bus/operations/check/generator.py +2 -3
  342. infrahub/message_bus/operations/event/__init__.py +2 -2
  343. infrahub/message_bus/operations/event/branch.py +7 -3
  344. infrahub/message_bus/operations/event/worker.py +0 -3
  345. infrahub/message_bus/operations/finalize/validator.py +52 -2
  346. infrahub/message_bus/operations/git/file.py +2 -2
  347. infrahub/message_bus/operations/git/repository.py +1 -1
  348. infrahub/message_bus/operations/requests/__init__.py +0 -4
  349. infrahub/message_bus/operations/requests/generator_definition.py +22 -24
  350. infrahub/message_bus/operations/requests/proposed_change.py +39 -20
  351. infrahub/message_bus/operations/send/echo.py +1 -1
  352. infrahub/message_bus/types.py +1 -1
  353. infrahub/permissions/globals.py +15 -0
  354. infrahub/pools/number.py +2 -4
  355. infrahub/pools/prefix.py +29 -165
  356. infrahub/prefect_server/__init__.py +0 -0
  357. infrahub/prefect_server/app.py +18 -0
  358. infrahub/prefect_server/database.py +20 -0
  359. infrahub/prefect_server/events.py +28 -0
  360. infrahub/prefect_server/models.py +46 -0
  361. infrahub/proposed_change/models.py +18 -1
  362. infrahub/proposed_change/tasks.py +204 -53
  363. infrahub/pytest_plugin.py +13 -10
  364. infrahub/server.py +13 -12
  365. infrahub/services/__init__.py +148 -63
  366. infrahub/services/adapters/cache/__init__.py +11 -11
  367. infrahub/services/adapters/cache/nats.py +42 -25
  368. infrahub/services/adapters/cache/redis.py +3 -11
  369. infrahub/services/adapters/event/__init__.py +11 -19
  370. infrahub/services/adapters/http/__init__.py +0 -5
  371. infrahub/services/adapters/http/httpx.py +22 -15
  372. infrahub/services/adapters/message_bus/__init__.py +25 -8
  373. infrahub/services/adapters/message_bus/local.py +9 -7
  374. infrahub/services/adapters/message_bus/nats.py +14 -8
  375. infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
  376. infrahub/services/adapters/workflow/__init__.py +11 -8
  377. infrahub/services/adapters/workflow/local.py +27 -6
  378. infrahub/services/adapters/workflow/worker.py +23 -7
  379. infrahub/services/component.py +43 -40
  380. infrahub/services/protocols.py +7 -7
  381. infrahub/services/scheduler.py +30 -29
  382. infrahub/storage.py +2 -4
  383. infrahub/task_manager/constants.py +1 -1
  384. infrahub/task_manager/event.py +275 -0
  385. infrahub/task_manager/models.py +147 -3
  386. infrahub/task_manager/task.py +1 -1
  387. infrahub/tasks/artifact.py +20 -21
  388. infrahub/tasks/registry.py +1 -1
  389. infrahub/telemetry/__init__.py +0 -0
  390. infrahub/telemetry/constants.py +9 -0
  391. infrahub/telemetry/database.py +86 -0
  392. infrahub/telemetry/models.py +65 -0
  393. infrahub/telemetry/task_manager.py +77 -0
  394. infrahub/telemetry/tasks.py +119 -0
  395. infrahub/telemetry/utils.py +11 -0
  396. infrahub/transformations/tasks.py +5 -7
  397. infrahub/trigger/__init__.py +0 -0
  398. infrahub/trigger/catalogue.py +13 -0
  399. infrahub/trigger/constants.py +1 -0
  400. infrahub/trigger/models.py +118 -0
  401. infrahub/trigger/setup.py +90 -0
  402. infrahub/trigger/tasks.py +36 -0
  403. infrahub/types.py +1 -1
  404. infrahub/utils.py +12 -2
  405. infrahub/validators/__init__.py +0 -0
  406. infrahub/validators/events.py +42 -0
  407. infrahub/validators/tasks.py +41 -0
  408. infrahub/webhook/gather.py +17 -0
  409. infrahub/webhook/models.py +180 -42
  410. infrahub/webhook/tasks.py +149 -203
  411. infrahub/webhook/triggers.py +44 -0
  412. infrahub/workers/infrahub_async.py +38 -27
  413. infrahub/workers/utils.py +63 -0
  414. infrahub/workflows/catalogue.py +98 -71
  415. infrahub/workflows/initialization.py +12 -8
  416. infrahub/workflows/models.py +29 -5
  417. infrahub/workflows/utils.py +11 -2
  418. infrahub_sdk/client.py +19 -0
  419. infrahub_sdk/context.py +13 -0
  420. infrahub_sdk/ctl/branch.py +3 -2
  421. infrahub_sdk/ctl/utils.py +0 -16
  422. infrahub_sdk/exceptions.py +6 -0
  423. infrahub_sdk/generator.py +3 -0
  424. infrahub_sdk/graphql.py +45 -13
  425. infrahub_sdk/node.py +66 -20
  426. infrahub_sdk/protocols.py +21 -8
  427. infrahub_sdk/protocols_base.py +32 -11
  428. infrahub_sdk/schema/__init__.py +14 -2
  429. infrahub_sdk/schema/main.py +7 -0
  430. infrahub_sdk/task/__init__.py +11 -0
  431. infrahub_sdk/task/constants.py +3 -0
  432. infrahub_sdk/task/exceptions.py +25 -0
  433. infrahub_sdk/task/manager.py +551 -0
  434. infrahub_sdk/task/models.py +74 -0
  435. infrahub_sdk/timestamp.py +142 -33
  436. infrahub_sdk/utils.py +29 -1
  437. {infrahub_server-1.1.8.dist-info → infrahub_server-1.2.0.dist-info}/METADATA +8 -6
  438. infrahub_server-1.2.0.dist-info/RECORD +746 -0
  439. infrahub_testcontainers/container.py +14 -4
  440. infrahub_testcontainers/docker-compose.test.yml +5 -8
  441. infrahub_testcontainers/helpers.py +5 -1
  442. infrahub/core/branch/constants.py +0 -2
  443. infrahub/core/schema/definitions/core.py +0 -2275
  444. infrahub/graphql/query.py +0 -52
  445. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  446. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  447. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  448. infrahub/message_bus/messages/event_branch_create.py +0 -11
  449. infrahub/message_bus/messages/event_branch_delete.py +0 -11
  450. infrahub/message_bus/messages/event_branch_rebased.py +0 -9
  451. infrahub/message_bus/messages/event_node_mutated.py +0 -15
  452. infrahub/message_bus/messages/event_schema_update.py +0 -9
  453. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  454. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  455. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  456. infrahub/message_bus/operations/check/repository.py +0 -293
  457. infrahub/message_bus/operations/event/node.py +0 -20
  458. infrahub/message_bus/operations/event/schema.py +0 -17
  459. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  460. infrahub/message_bus/operations/requests/repository.py +0 -133
  461. infrahub/schema/constants.py +0 -1
  462. infrahub/schema/tasks.py +0 -76
  463. infrahub/services/adapters/database/__init__.py +0 -9
  464. infrahub/tasks/telemetry.py +0 -127
  465. infrahub/webhook/constants.py +0 -3
  466. infrahub_server-1.1.8.dist-info/RECORD +0 -684
  467. /infrahub/{schema → artifacts}/__init__.py +0 -0
  468. {infrahub_server-1.1.8.dist-info → infrahub_server-1.2.0.dist-info}/LICENSE.txt +0 -0
  469. {infrahub_server-1.1.8.dist-info → infrahub_server-1.2.0.dist-info}/WHEEL +0 -0
  470. {infrahub_server-1.1.8.dist-info → infrahub_server-1.2.0.dist-info}/entry_points.txt +0 -0
infrahub/menu/models.py CHANGED
@@ -1,15 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from typing import TYPE_CHECKING
4
+ from typing import TYPE_CHECKING, Any
5
5
 
6
- from pydantic import BaseModel, Field
6
+ from pydantic import BaseModel, Field, computed_field
7
7
  from typing_extensions import Self
8
8
 
9
9
  from infrahub.core.account import GlobalPermission
10
10
  from infrahub.core.node import Node
11
11
  from infrahub.core.protocols import CoreMenuItem
12
- from infrahub.core.schema import GenericSchema, MainSchemaTypes, NodeSchema, ProfileSchema
12
+ from infrahub.core.schema import GenericSchema, MainSchemaTypes, NodeSchema, ProfileSchema, TemplateSchema
13
13
 
14
14
  from .constants import MenuSection
15
15
 
@@ -17,8 +17,8 @@ if TYPE_CHECKING:
17
17
  from infrahub.database import InfrahubDatabase
18
18
 
19
19
 
20
- def get_full_name(obj: CoreMenuItem | NodeSchema | GenericSchema | ProfileSchema) -> str:
21
- if isinstance(obj, (NodeSchema, GenericSchema, ProfileSchema)):
20
+ def get_full_name(obj: CoreMenuItem | NodeSchema | GenericSchema | ProfileSchema | TemplateSchema) -> str:
21
+ if isinstance(obj, NodeSchema | GenericSchema | ProfileSchema | TemplateSchema):
22
22
  return _get_full_name_schema(obj)
23
23
  return _get_full_name_node(obj)
24
24
 
@@ -35,21 +35,26 @@ def _get_full_name_schema(node: MainSchemaTypes) -> str:
35
35
  class MenuDict:
36
36
  data: dict[str, MenuItemDict] = field(default_factory=dict)
37
37
 
38
+ def get_item_location(self, name: str) -> list[str]:
39
+ location, _ = self._find_child_item(name=name, children=self.data)
40
+ return location
41
+
38
42
  def find_item(self, name: str) -> MenuItemDict | None:
39
- return self._find_child_item(name=name, children=self.data)
43
+ _, item = self._find_child_item(name=name, children=self.data)
44
+ return item
40
45
 
41
46
  @classmethod
42
- def _find_child_item(cls, name: str, children: dict[str, MenuItemDict]) -> MenuItemDict | None:
47
+ def _find_child_item(cls, name: str, children: dict[str, MenuItemDict]) -> tuple[list[str], MenuItemDict | None]:
43
48
  if name in children.keys():
44
- return children[name]
49
+ return [], children[name]
45
50
 
46
51
  for child in children.values():
47
52
  if not child.children:
48
53
  continue
49
- found = cls._find_child_item(name=name, children=child.children)
54
+ position, found = cls._find_child_item(name=name, children=child.children)
50
55
  if found:
51
- return found
52
- return None
56
+ return [str(child.identifier)] + position, found
57
+ return [], None
53
58
 
54
59
  def to_rest(self) -> Menu:
55
60
  data: dict[str, list[MenuItemList]] = {}
@@ -62,10 +67,15 @@ class MenuDict:
62
67
 
63
68
  return Menu(sections=data)
64
69
 
65
- # @staticmethod
66
- # def _sort_menu_items(items: dict[str, MenuItem]) -> dict[str, MenuItem]:
67
- # sorted_dict = dict(sorted(items.items(), key=lambda x: (x[1].order_weight, x[0]), reverse=False))
68
- # return sorted_dict
70
+ @classmethod
71
+ def from_definition_list(cls, definitions: list[MenuItemDefinition]) -> Self:
72
+ menu = cls()
73
+ for definition in definitions:
74
+ menu.data[definition.full_name] = MenuItemDict.from_definition(definition=definition)
75
+ return menu
76
+
77
+ def get_all_identifiers(self) -> set[str]:
78
+ return {identifier for item in self.data.values() for identifier in item.get_all_identifiers()}
69
79
 
70
80
 
71
81
  @dataclass
@@ -74,7 +84,11 @@ class Menu:
74
84
 
75
85
 
76
86
  class MenuItem(BaseModel):
77
- identifier: str = Field(..., description="Unique identifier for this menu item")
87
+ id: str | None = None
88
+ namespace: str = Field(..., description="Namespace of the menu item")
89
+ name: str = Field(..., description="Name of the menu item")
90
+ description: str = Field(default="", description="Description of the menu item")
91
+ protected: bool = Field(default=False, description="Whether the menu item is protected")
78
92
  label: str = Field(..., description="Title of the menu item")
79
93
  path: str = Field(default="", description="URL endpoint if applicable")
80
94
  icon: str = Field(default="", description="The icon to show for the current view")
@@ -83,10 +97,27 @@ class MenuItem(BaseModel):
83
97
  section: MenuSection = MenuSection.OBJECT
84
98
  permissions: list[str] = Field(default_factory=list)
85
99
 
100
+ @computed_field
101
+ def identifier(self) -> str:
102
+ return f"{self.namespace}{self.name}"
103
+
104
+ def get_path(self) -> str | None:
105
+ if self.path:
106
+ return self.path
107
+
108
+ if self.kind:
109
+ return f"/objects/{self.kind}"
110
+
111
+ return None
112
+
86
113
  @classmethod
87
114
  def from_node(cls, obj: CoreMenuItem) -> Self:
88
115
  return cls(
89
- identifier=get_full_name(obj),
116
+ id=obj.get_id(),
117
+ name=obj.name.value,
118
+ namespace=obj.namespace.value,
119
+ protected=obj.protected.value,
120
+ description=obj.description.value or "",
90
121
  label=obj.label.value or "",
91
122
  icon=obj.icon.value or "",
92
123
  order_weight=obj.order_weight.value,
@@ -96,10 +127,30 @@ class MenuItem(BaseModel):
96
127
  permissions=obj.required_permissions.value or [],
97
128
  )
98
129
 
130
+ async def to_node(self, db: InfrahubDatabase, parent: CoreMenuItem | None = None) -> CoreMenuItem:
131
+ obj = await Node.init(db=db, schema=CoreMenuItem)
132
+ await obj.new(
133
+ db=db,
134
+ namespace=self.namespace,
135
+ name=self.name,
136
+ label=self.label,
137
+ kind=self.kind,
138
+ path=self.get_path(),
139
+ description=self.description or None,
140
+ icon=self.icon or None,
141
+ protected=self.protected,
142
+ section=self.section.value,
143
+ order_weight=self.order_weight,
144
+ parent=parent.id if parent else None,
145
+ required_permissions=self.permissions,
146
+ )
147
+ return obj
148
+
99
149
  @classmethod
100
- def from_schema(cls, model: NodeSchema | GenericSchema | ProfileSchema) -> Self:
150
+ def from_schema(cls, model: NodeSchema | GenericSchema | ProfileSchema | TemplateSchema) -> Self:
101
151
  return cls(
102
- identifier=get_full_name(model),
152
+ name=model.name,
153
+ namespace=model.namespace,
103
154
  label=model.label or model.kind,
104
155
  path=f"/objects/{model.kind}",
105
156
  icon=model.icon or "",
@@ -111,8 +162,14 @@ class MenuItemDict(MenuItem):
111
162
  hidden: bool = False
112
163
  children: dict[str, MenuItemDict] = Field(default_factory=dict, description="Child objects")
113
164
 
165
+ def get_all_identifiers(self) -> set[str]:
166
+ identifiers: set[str] = {str(self.identifier)}
167
+ for child in self.children.values():
168
+ identifiers.update(child.get_all_identifiers())
169
+ return identifiers
170
+
114
171
  def to_list(self) -> MenuItemList:
115
- data = self.model_dump(exclude={"children"})
172
+ data = self.model_dump(exclude={"children", "id"})
116
173
  unsorted_children = [child.to_list() for child in self.children.values() if child.hidden is False]
117
174
  data["children"] = sorted(unsorted_children, key=lambda d: d.order_weight)
118
175
  return MenuItemList(**data)
@@ -125,6 +182,35 @@ class MenuItemDict(MenuItem):
125
182
  permissions.append(GlobalPermission.from_string(input=permission))
126
183
  return permissions
127
184
 
185
+ def diff_attributes(self, other: Self) -> dict[str, Any]:
186
+ other_attributes = other.model_dump(exclude={"children"})
187
+ self_attributes = self.model_dump(exclude={"children"})
188
+ return {
189
+ key: value
190
+ for key, value in other_attributes.items()
191
+ if value != self_attributes[key] and key not in ["id", "children"]
192
+ }
193
+
194
+ @classmethod
195
+ def from_definition(cls, definition: MenuItemDefinition) -> Self:
196
+ menu_item = cls(
197
+ name=definition.name,
198
+ namespace=definition.namespace,
199
+ label=definition.label,
200
+ path=definition.get_path() or "",
201
+ icon=definition.icon,
202
+ kind=definition.kind,
203
+ protected=definition.protected,
204
+ section=definition.section,
205
+ permissions=definition.permissions,
206
+ order_weight=definition.order_weight,
207
+ )
208
+
209
+ for child in definition.children:
210
+ menu_item.children[child.full_name] = MenuItemDict.from_definition(definition=child)
211
+
212
+ return menu_item
213
+
128
214
 
129
215
  class MenuItemList(MenuItem):
130
216
  children: list[MenuItemList] = Field(default_factory=list, description="Child objects")
@@ -162,6 +248,21 @@ class MenuItemDefinition(BaseModel):
162
248
  )
163
249
  return obj
164
250
 
251
+ @classmethod
252
+ async def from_node(cls, node: CoreMenuItem) -> Self:
253
+ return cls(
254
+ namespace=node.namespace.value,
255
+ name=node.name.value,
256
+ label=node.label.value or "",
257
+ description=node.description.value or "",
258
+ icon=node.icon.value or "",
259
+ protected=node.protected.value,
260
+ path=node.path.value or "",
261
+ kind=node.kind.value or "",
262
+ section=node.section.value,
263
+ order_weight=node.order_weight.value,
264
+ )
265
+
165
266
  def get_path(self) -> str | None:
166
267
  if self.path:
167
268
  return self.path
@@ -0,0 +1,111 @@
1
+ from infrahub.core.manager import NodeManager
2
+ from infrahub.core.protocols import CoreMenuItem
3
+ from infrahub.database import InfrahubDatabase
4
+
5
+ from .models import MenuDict, MenuItemDefinition, MenuItemDict
6
+
7
+
8
+ class MenuRepository:
9
+ def __init__(self, db: InfrahubDatabase):
10
+ self.db = db
11
+
12
+ async def get_menu(self, nodes: dict[str, CoreMenuItem] | None = None) -> MenuDict:
13
+ menu_nodes = nodes or await self.get_menu_db()
14
+ return await self._convert_menu_from_db(nodes=menu_nodes)
15
+
16
+ async def _convert_menu_from_db(self, nodes: dict[str, CoreMenuItem]) -> MenuDict:
17
+ menu = MenuDict()
18
+ menu_by_ids = {menu_node.get_id(): MenuItemDict.from_node(menu_node) for menu_node in nodes.values()}
19
+
20
+ async def add_children(menu_item: MenuItemDict, menu_node: CoreMenuItem) -> MenuItemDict:
21
+ children = await menu_node.children.get_peers(db=self.db, peer_type=CoreMenuItem)
22
+ for child_id, child_node in children.items():
23
+ child_menu_item = menu_by_ids[child_id]
24
+ child = await add_children(child_menu_item, child_node)
25
+ menu_item.children[str(child.identifier)] = child
26
+ return menu_item
27
+
28
+ for menu_node in nodes.values():
29
+ menu_item = menu_by_ids[menu_node.get_id()]
30
+ parent = await menu_node.parent.get_peer(db=self.db, peer_type=CoreMenuItem)
31
+ if parent:
32
+ continue
33
+
34
+ children = await menu_node.children.get_peers(db=self.db, peer_type=CoreMenuItem)
35
+ for child_id, child_node in children.items():
36
+ child_menu_item = menu_by_ids[child_id]
37
+ child = await add_children(child_menu_item, child_node)
38
+ menu_item.children[str(child.identifier)] = child
39
+
40
+ menu.data[str(menu_item.identifier)] = menu_item
41
+
42
+ return menu
43
+
44
+ async def get_menu_db(self) -> dict[str, CoreMenuItem]:
45
+ menu_nodes = await NodeManager.query(
46
+ schema=CoreMenuItem,
47
+ filters={"namespace__value": "Builtin"},
48
+ prefetch_relationships=True,
49
+ db=self.db,
50
+ )
51
+ return {node.get_id(): node for node in menu_nodes}
52
+
53
+ async def create_menu(self, menu: list[MenuItemDefinition]) -> None:
54
+ for item in menu:
55
+ obj = await item.to_node(db=self.db)
56
+ await obj.save(db=self.db)
57
+ if item.children:
58
+ await self.create_menu_children(parent=obj, children=item.children)
59
+
60
+ async def create_menu_children(self, parent: CoreMenuItem, children: list[MenuItemDefinition]) -> None:
61
+ for child in children:
62
+ obj = await child.to_node(db=self.db, parent=parent)
63
+ await obj.save(db=self.db)
64
+ if child.children:
65
+ await self.create_menu_children(parent=obj, children=child.children)
66
+
67
+ async def update_menu(
68
+ self, existing_menu: MenuDict, new_menu: MenuDict, menu_nodes: dict[str, CoreMenuItem]
69
+ ) -> None:
70
+ async def process_menu_item(menu_item: MenuItemDict, parent: CoreMenuItem | None) -> None:
71
+ existing_item = existing_menu.find_item(name=str(menu_item.identifier))
72
+ if existing_item and existing_item.id:
73
+ node = menu_nodes[existing_item.id]
74
+ await self.update_menu_item(
75
+ node=node, existing_menu_item=existing_item, new_menu_item=menu_item, parent=parent
76
+ )
77
+ else:
78
+ node = await self.create_menu_item(new_menu_item=menu_item, parent=parent)
79
+
80
+ for child_item in menu_item.children.values():
81
+ await process_menu_item(menu_item=child_item, parent=node)
82
+
83
+ for top_level_item in new_menu.data.values():
84
+ await process_menu_item(menu_item=top_level_item, parent=None)
85
+
86
+ # Delete items that are not in the new menu
87
+ menu_to_delete = existing_menu.get_all_identifiers() - new_menu.get_all_identifiers()
88
+ for item_to_delete in menu_to_delete:
89
+ existing_item = existing_menu.find_item(name=item_to_delete)
90
+ if existing_item and existing_item.id:
91
+ node = menu_nodes[existing_item.id]
92
+ await node.delete(db=self.db)
93
+
94
+ async def update_menu_item(
95
+ self,
96
+ node: CoreMenuItem,
97
+ existing_menu_item: MenuItemDict,
98
+ new_menu_item: MenuItemDict,
99
+ parent: CoreMenuItem | None,
100
+ ) -> None:
101
+ attrs_to_update = existing_menu_item.diff_attributes(new_menu_item)
102
+ for attr_name, value in attrs_to_update.items():
103
+ attr = getattr(node, attr_name)
104
+ attr.value = value
105
+ await node.parent.update(data=parent, db=self.db) # type: ignore[arg-type]
106
+ await node.save(db=self.db)
107
+
108
+ async def create_menu_item(self, new_menu_item: MenuItemDict, parent: CoreMenuItem | None) -> CoreMenuItem:
109
+ obj = await new_menu_item.to_node(db=self.db, parent=parent)
110
+ await obj.save(db=self.db)
111
+ return obj
infrahub/menu/utils.py CHANGED
@@ -1,12 +1,9 @@
1
- from infrahub.core.protocols import CoreMenuItem
2
1
  from infrahub.database import InfrahubDatabase
3
2
 
4
- from .models import MenuItemDefinition
3
+ from .menu import default_menu
4
+ from .repository import MenuRepository
5
5
 
6
6
 
7
- async def create_menu_children(db: InfrahubDatabase, parent: CoreMenuItem, children: list[MenuItemDefinition]) -> None:
8
- for child in children:
9
- obj = await child.to_node(db=db, parent=parent)
10
- await obj.save(db=db)
11
- if child.children:
12
- await create_menu_children(db=db, parent=obj, children=child.children)
7
+ async def create_default_menu(db: InfrahubDatabase) -> None:
8
+ repository = MenuRepository(db=db)
9
+ await repository.create_menu(menu=default_menu)
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Any, Optional, Union
3
+ from typing import Any
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
@@ -11,21 +11,19 @@ from infrahub.log import set_log_data
11
11
 
12
12
  class Meta(BaseModel):
13
13
  request_id: str = ""
14
- correlation_id: Optional[str] = Field(default=None)
15
- reply_to: Optional[str] = Field(default=None)
16
- initiator_id: Optional[str] = Field(
14
+ correlation_id: str | None = Field(default=None)
15
+ reply_to: str | None = Field(default=None)
16
+ initiator_id: str | None = Field(
17
17
  default=None, description="The worker identity of the initial sender of this message"
18
18
  )
19
- retry_count: Optional[int] = Field(
20
- default=None, description="Indicates how many times this message has been retried."
21
- )
22
- headers: Optional[dict[str, Any]] = Field(default=None)
23
- validator_execution_id: Optional[str] = Field(
19
+ retry_count: int | None = Field(default=None, description="Indicates how many times this message has been retried.")
20
+ headers: dict[str, Any] | None = Field(default=None)
21
+ validator_execution_id: str | None = Field(
24
22
  default=None, description="Validator execution ID related to this message"
25
23
  )
26
- check_execution_id: Optional[str] = Field(default=None, description="Check execution ID related to this message")
24
+ check_execution_id: str | None = Field(default=None, description="Check execution ID related to this message")
27
25
  priority: int = Field(default=3, description="Message Priority")
28
- expiration: Optional[int] = Field(default=None, description="TTL before this message expires in seconds")
26
+ expiration: int | None = Field(default=None, description="TTL before this message expires in seconds")
29
27
 
30
28
  @classmethod
31
29
  def default(cls) -> Meta:
@@ -89,9 +87,9 @@ class InfrahubResponse(InfrahubMessage):
89
87
 
90
88
  passed: bool = True
91
89
  routing_key: str
92
- data: Union[dict, InfrahubResponseData] = Field(default_factory=dict)
90
+ data: dict | InfrahubResponseData = Field(default_factory=dict) # type: ignore[arg-type]
93
91
  errors: list[str] = Field(default_factory=list)
94
- initial_message: Optional[dict] = Field(
92
+ initial_message: dict | None = Field(
95
93
  default=None,
96
94
  description="Initial message in dict format, the primary goal of this field is to provide additional context when there is an error",
97
95
  )
@@ -1,16 +1,7 @@
1
1
  from infrahub.message_bus import InfrahubMessage, InfrahubResponse
2
2
 
3
- from .check_artifact_create import CheckArtifactCreate
4
3
  from .check_generator_run import CheckGeneratorRun
5
- from .check_repository_checkdefinition import CheckRepositoryCheckDefinition
6
- from .check_repository_mergeconflicts import CheckRepositoryMergeConflicts
7
- from .check_repository_usercheck import CheckRepositoryUserCheck
8
- from .event_branch_create import EventBranchCreate
9
- from .event_branch_delete import EventBranchDelete
10
4
  from .event_branch_merge import EventBranchMerge
11
- from .event_branch_rebased import EventBranchRebased
12
- from .event_node_mutated import EventNodeMutated
13
- from .event_schema_update import EventSchemaUpdate
14
5
  from .event_worker_newprimaryapi import EventWorkerNewPrimaryAPI
15
6
  from .finalize_validator_execution import FinalizeValidatorExecution
16
7
  from .git_file_get import GitFileGet, GitFileGetResponse
@@ -19,25 +10,13 @@ from .proposed_change.request_proposedchange_refreshartifacts import RequestProp
19
10
  from .refresh_git_fetch import RefreshGitFetch
20
11
  from .refresh_registry_branches import RefreshRegistryBranches
21
12
  from .refresh_registry_rebasedbranch import RefreshRegistryRebasedBranch
22
- from .request_artifactdefinition_check import RequestArtifactDefinitionCheck
23
13
  from .request_generatordefinition_check import RequestGeneratorDefinitionCheck
24
14
  from .request_proposedchange_pipeline import RequestProposedChangePipeline
25
- from .request_repository_checks import RequestRepositoryChecks
26
- from .request_repository_userchecks import RequestRepositoryUserChecks
27
15
  from .send_echo_request import SendEchoRequest, SendEchoRequestResponse
28
16
 
29
17
  MESSAGE_MAP: dict[str, type[InfrahubMessage]] = {
30
- "check.artifact.create": CheckArtifactCreate,
31
18
  "check.generator.run": CheckGeneratorRun,
32
- "check.repository.check_definition": CheckRepositoryCheckDefinition,
33
- "check.repository.merge_conflicts": CheckRepositoryMergeConflicts,
34
- "check.repository.user_check": CheckRepositoryUserCheck,
35
- "event.branch.create": EventBranchCreate,
36
- "event.branch.delete": EventBranchDelete,
37
19
  "event.branch.merge": EventBranchMerge,
38
- "event.branch.rebased": EventBranchRebased,
39
- "event.node.mutated": EventNodeMutated,
40
- "event.schema.update": EventSchemaUpdate,
41
20
  "event.worker.new_primary_api": EventWorkerNewPrimaryAPI,
42
21
  "finalize.validator.execution": FinalizeValidatorExecution,
43
22
  "git.file.get": GitFileGet,
@@ -45,12 +24,9 @@ MESSAGE_MAP: dict[str, type[InfrahubMessage]] = {
45
24
  "refresh.git.fetch": RefreshGitFetch,
46
25
  "refresh.registry.branches": RefreshRegistryBranches,
47
26
  "refresh.registry.rebased_branch": RefreshRegistryRebasedBranch,
48
- "request.artifact_definition.check": RequestArtifactDefinitionCheck,
49
27
  "request.generator_definition.check": RequestGeneratorDefinitionCheck,
50
28
  "request.proposed_change.pipeline": RequestProposedChangePipeline,
51
29
  "request.proposed_change.refresh_artifacts": RequestProposedChangeRefreshArtifacts,
52
- "request.repository.checks": RequestRepositoryChecks,
53
- "request.repository.user_checks": RequestRepositoryUserChecks,
54
30
  "send.echo.request": SendEchoRequest,
55
31
  }
56
32
 
@@ -63,7 +39,7 @@ PRIORITY_MAP = {
63
39
  "check.artifact.create": 2,
64
40
  "check.repository.check_definition": 2,
65
41
  "check.repository.merge_conflicts": 2,
66
- "event.branch.create": 5,
42
+ "send.echo.request": 5, # Currently only for testing purposes, will be removed once all message bus have been migrated to prefect
67
43
  "event.branch.delete": 5,
68
44
  "event.branch.merge": 5,
69
45
  "event.schema.update": 5,
@@ -1,7 +1,6 @@
1
- from typing import Optional
2
-
3
1
  from pydantic import Field
4
2
 
3
+ from infrahub.context import InfrahubContext
5
4
  from infrahub.generators.models import ProposedChangeGeneratorDefinition
6
5
  from infrahub.message_bus import InfrahubMessage
7
6
 
@@ -10,7 +9,7 @@ class CheckGeneratorRun(InfrahubMessage):
10
9
  """A check that runs a generator."""
11
10
 
12
11
  generator_definition: ProposedChangeGeneratorDefinition = Field(..., description="The Generator definition")
13
- generator_instance: Optional[str] = Field(
12
+ generator_instance: str | None = Field(
14
13
  default=None, description="The id of the generator instance if it previously existed"
15
14
  )
16
15
  commit: str = Field(..., description="The commit to target")
@@ -24,3 +23,4 @@ class CheckGeneratorRun(InfrahubMessage):
24
23
  variables: dict = Field(..., description="Input variables when running the generator")
25
24
  validator_id: str = Field(..., description="The ID of the validator")
26
25
  proposed_change: str | None = Field(None, description="The unique ID of the Proposed Change")
26
+ context: InfrahubContext = Field(..., description="The Infrahub context")
@@ -1,5 +1,6 @@
1
1
  from pydantic import Field
2
2
 
3
+ from infrahub.context import InfrahubContext
3
4
  from infrahub.message_bus import InfrahubMessage
4
5
 
5
6
 
@@ -8,3 +9,5 @@ class EventBranchMerge(InfrahubMessage):
8
9
 
9
10
  source_branch: str = Field(..., description="The source branch")
10
11
  target_branch: str = Field(..., description="The target branch")
12
+
13
+ context: InfrahubContext = Field(..., description="The context of the event")
@@ -1,5 +1,6 @@
1
1
  from pydantic import Field
2
2
 
3
+ from infrahub.context import InfrahubContext
3
4
  from infrahub.message_bus import InfrahubMessage
4
5
 
5
6
 
@@ -10,3 +11,5 @@ class FinalizeValidatorExecution(InfrahubMessage):
10
11
  validator_execution_id: str = Field(..., description="The id of current execution of the associated validator")
11
12
  start_time: str = Field(..., description="Start time when the message was first created")
12
13
  validator_type: str = Field(..., description="The type of validator to complete")
14
+ context: InfrahubContext = Field(..., description="The Infrahub context")
15
+ proposed_change: str = Field(..., description="The ID of the proposed change")
@@ -1,5 +1,11 @@
1
+ from pydantic import Field
2
+
3
+ from infrahub.context import InfrahubContext
4
+
1
5
  from .base_with_diff import BaseProposedChangeWithDiffMessage
2
6
 
3
7
 
4
8
  class RequestProposedChangeRefreshArtifacts(BaseProposedChangeWithDiffMessage):
5
9
  """Sent trigger the refresh of artifacts that are impacted by the proposed change."""
10
+
11
+ context: InfrahubContext = Field(..., description="The context of the task")
@@ -1,5 +1,6 @@
1
1
  from pydantic import ConfigDict, Field
2
2
 
3
+ from infrahub.context import InfrahubContext
3
4
  from infrahub.generators.models import ProposedChangeGeneratorDefinition
4
5
  from infrahub.message_bus import InfrahubMessage
5
6
  from infrahub.message_bus.types import ProposedChangeBranchDiff
@@ -16,3 +17,4 @@ class RequestGeneratorDefinitionCheck(InfrahubMessage):
16
17
  source_branch: str = Field(..., description="The source branch")
17
18
  source_branch_sync_with_git: bool = Field(..., description="Indicates if the source branch should sync with git")
18
19
  destination_branch: str = Field(..., description="The target branch")
20
+ context: InfrahubContext = Field(..., description="The Infrahub context")
@@ -1,5 +1,6 @@
1
1
  from pydantic import Field
2
2
 
3
+ from infrahub.context import InfrahubContext
3
4
  from infrahub.core.constants import CheckType
4
5
  from infrahub.message_bus import InfrahubMessage
5
6
 
@@ -14,3 +15,4 @@ class RequestProposedChangePipeline(InfrahubMessage):
14
15
  check_type: CheckType = Field(
15
16
  default=CheckType.ALL, description="Can be used to restrict the pipeline to a specific type of job"
16
17
  )
18
+ context: InfrahubContext = Field(..., description="The context of the task")
@@ -6,7 +6,7 @@ ROUTING_KEY = "send.echo.request"
6
6
 
7
7
 
8
8
  class SendEchoRequest(InfrahubMessage):
9
- """Sent a echo request, i.e., ping message."""
9
+ """Sent a echo request, a ping message for example."""
10
10
 
11
11
  message: str = Field(..., description="The message to send")
12
12
 
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  import ujson
4
2
  from prefect import Flow
5
3
 
@@ -18,14 +16,8 @@ from infrahub.services import InfrahubServices
18
16
  from infrahub.tasks.check import set_check_status
19
17
 
20
18
  COMMAND_MAP = {
21
- "check.artifact.create": check.artifact.create,
22
19
  "check.generator.run": check.generator.run,
23
- "check.repository.check_definition": check.repository.check_definition,
24
- "check.repository.merge_conflicts": check.repository.merge_conflicts,
25
- "check.repository.user_check": check.repository.user_check,
26
20
  "event.branch.merge": event.branch.merge,
27
- "event.node.mutated": event.node.mutated,
28
- "event.schema.update": event.schema.update,
29
21
  "event.worker.new_primary_api": event.worker.new_primary_api,
30
22
  "finalize.validator.execution": finalize.validator.execution,
31
23
  "git.file.get": git.file.get,
@@ -34,18 +26,15 @@ COMMAND_MAP = {
34
26
  "refresh.registry.branches": refresh.registry.branches,
35
27
  "refresh.registry.rebased_branch": refresh.registry.rebased_branch,
36
28
  "request.generator_definition.check": requests.generator_definition.check,
37
- "request.artifact_definition.check": requests.artifact_definition.check,
38
29
  "request.proposed_change.pipeline": requests.proposed_change.pipeline,
39
30
  "request.proposed_change.refresh_artifacts": requests.proposed_change.refresh_artifacts,
40
- "request.repository.checks": requests.repository.checks,
41
- "request.repository.user_checks": requests.repository.user_checks,
42
31
  "send.echo.request": send.echo.request,
43
32
  }
44
33
 
45
34
 
46
35
  async def execute_message(
47
36
  routing_key: str, message_body: bytes, service: InfrahubServices, skip_flow: bool = False
48
- ) -> Optional[MessageTTL]:
37
+ ) -> MessageTTL | None:
49
38
  message_data = ujson.loads(message_body)
50
39
  message = messages.MESSAGE_MAP[routing_key](**message_data)
51
40
  message.set_log_data(routing_key=routing_key)
@@ -54,15 +43,15 @@ async def execute_message(
54
43
  if skip_flow and isinstance(func, Flow):
55
44
  func = func.fn
56
45
  await func(message=message, service=service)
57
- except Exception as exc: # pylint: disable=broad-except
46
+ except Exception as exc:
58
47
  if message.reply_requested:
59
48
  response = RPCErrorResponse(errors=[str(exc)], initial_message=message.model_dump())
60
- await service.reply(message=response, initiator=message)
49
+ await service.message_bus.reply_if_initiator_meta(message=response, initiator=message)
61
50
  return None
62
51
  if message.reached_max_retries:
63
52
  service.log.exception("Message failed after maximum number of retries", error=exc)
64
53
  await set_check_status(message, conclusion="failure", service=service)
65
54
  return None
66
55
  message.increase_retry_count()
67
- await service.send(message, delay=MessageTTL.FIVE, is_retry=True)
56
+ await service.message_bus.send(message, delay=MessageTTL.FIVE, is_retry=True)
68
57
  return MessageTTL.FIVE
@@ -1,3 +1,3 @@
1
- from . import artifact, generator, repository
1
+ from . import generator
2
2
 
3
- __all__ = ["artifact", "generator", "repository"]
3
+ __all__ = ["generator"]
@@ -14,8 +14,6 @@ from infrahub.services import InfrahubServices
14
14
  from infrahub.tasks.check import set_check_status
15
15
  from infrahub.workflows.utils import add_tags
16
16
 
17
- # pylint: disable=duplicate-code
18
-
19
17
 
20
18
  @flow(
21
19
  name="git-repository-check-generator-run",
@@ -74,6 +72,7 @@ async def run(message: messages.CheckGeneratorRun, service: InfrahubServices) ->
74
72
  convert_query_response=generator_definition.convert_query_response,
75
73
  infrahub_node=InfrahubNode,
76
74
  )
75
+ generator._init_client.request_context = message.context.to_request_context()
77
76
  await generator.run(identifier=generator_definition.name)
78
77
  generator_instance.status.value = GeneratorInstanceStatus.READY.value
79
78
  except ModuleImportError as exc:
@@ -81,7 +80,7 @@ async def run(message: messages.CheckGeneratorRun, service: InfrahubServices) ->
81
80
  generator_instance.status.value = GeneratorInstanceStatus.ERROR.value
82
81
  check_message = f"Failed to import generator: {exc.message}"
83
82
  log.exception(check_message, exc_info=exc)
84
- except Exception as exc: # pylint: disable=broad-exception-caught
83
+ except Exception as exc:
85
84
  conclusion = ValidatorConclusion.FAILURE
86
85
  generator_instance.status.value = GeneratorInstanceStatus.ERROR.value
87
86
  check_message = f"Failed to execute generator: {str(exc)}"