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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. infrahub/api/artifact.py +16 -4
  2. infrahub/api/dependencies.py +8 -0
  3. infrahub/api/oauth2.py +0 -1
  4. infrahub/api/oidc.py +0 -1
  5. infrahub/api/query.py +18 -7
  6. infrahub/api/schema.py +32 -6
  7. infrahub/api/transformation.py +12 -5
  8. infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +5 -3
  9. infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
  10. infrahub/cli/__init__.py +0 -2
  11. infrahub/cli/db.py +6 -7
  12. infrahub/cli/events.py +8 -3
  13. infrahub/cli/git_agent.py +9 -7
  14. infrahub/cli/tasks.py +4 -6
  15. infrahub/computed_attribute/models.py +1 -1
  16. infrahub/computed_attribute/tasks.py +64 -17
  17. infrahub/computed_attribute/triggers.py +90 -0
  18. infrahub/config.py +1 -1
  19. infrahub/context.py +39 -0
  20. infrahub/core/account.py +5 -8
  21. infrahub/core/attribute.py +50 -21
  22. infrahub/core/branch/models.py +4 -4
  23. infrahub/core/branch/tasks.py +130 -125
  24. infrahub/core/changelog/__init__.py +0 -0
  25. infrahub/core/changelog/diff.py +283 -0
  26. infrahub/core/changelog/models.py +499 -0
  27. infrahub/core/constants/__init__.py +43 -2
  28. infrahub/core/constants/infrahubkind.py +1 -0
  29. infrahub/core/constants/schema.py +2 -0
  30. infrahub/core/diff/combiner.py +1 -1
  31. infrahub/core/diff/enricher/cardinality_one.py +6 -1
  32. infrahub/core/diff/enricher/hierarchy.py +22 -7
  33. infrahub/core/diff/enricher/labels.py +6 -1
  34. infrahub/core/diff/enricher/path_identifier.py +5 -1
  35. infrahub/core/diff/enricher/summary_counts.py +107 -0
  36. infrahub/core/diff/merger/merger.py +3 -1
  37. infrahub/core/diff/model/path.py +34 -11
  38. infrahub/core/diff/parent_node_adder.py +78 -0
  39. infrahub/core/diff/payload_builder.py +13 -2
  40. infrahub/core/diff/query/all_conflicts.py +1 -1
  41. infrahub/core/diff/query/artifact.py +1 -1
  42. infrahub/core/diff/query/delete_query.py +1 -1
  43. infrahub/core/diff/query/diff_get.py +1 -1
  44. infrahub/core/diff/query/diff_summary.py +1 -1
  45. infrahub/core/diff/query/field_specifiers.py +1 -1
  46. infrahub/core/diff/query/field_summary.py +1 -1
  47. infrahub/core/diff/query/filters.py +2 -2
  48. infrahub/core/diff/query/get_conflict_query.py +1 -1
  49. infrahub/core/diff/query/has_conflicts_query.py +1 -1
  50. infrahub/core/diff/query/merge.py +3 -3
  51. infrahub/core/diff/query/merge_tracking_id.py +1 -1
  52. infrahub/core/diff/query/roots_metadata.py +1 -1
  53. infrahub/core/diff/query/save.py +191 -185
  54. infrahub/core/diff/query/summary_counts_enricher.py +52 -5
  55. infrahub/core/diff/query/time_range_query.py +1 -1
  56. infrahub/core/diff/query/update_conflict_query.py +1 -1
  57. infrahub/core/diff/repository/deserializer.py +9 -4
  58. infrahub/core/diff/repository/repository.py +156 -38
  59. infrahub/core/diff/tasks.py +13 -12
  60. infrahub/core/enums.py +1 -1
  61. infrahub/core/graph/__init__.py +1 -1
  62. infrahub/core/graph/index.py +3 -0
  63. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  64. infrahub/core/ipam/reconciler.py +1 -1
  65. infrahub/core/ipam/tasks.py +2 -3
  66. infrahub/core/manager.py +20 -15
  67. infrahub/core/merge.py +5 -2
  68. infrahub/core/migrations/graph/__init__.py +4 -0
  69. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  70. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  71. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  72. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  73. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  74. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  75. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  76. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  77. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  78. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  79. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  80. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  81. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  82. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  83. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  84. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  85. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
  86. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
  87. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
  88. infrahub/core/migrations/graph/m020_add_generate_template_attr.py +48 -0
  89. infrahub/core/migrations/query/attribute_add.py +1 -1
  90. infrahub/core/migrations/query/attribute_rename.py +1 -1
  91. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  92. infrahub/core/migrations/query/node_duplicate.py +39 -19
  93. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  94. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  95. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  96. infrahub/core/migrations/schema/node_remove.py +27 -13
  97. infrahub/core/migrations/schema/tasks.py +5 -5
  98. infrahub/core/migrations/shared.py +4 -4
  99. infrahub/core/models.py +7 -8
  100. infrahub/core/node/__init__.py +164 -45
  101. infrahub/core/node/base.py +1 -1
  102. infrahub/core/node/delete_validator.py +4 -4
  103. infrahub/core/node/ipam.py +7 -7
  104. infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
  105. infrahub/core/node/standard.py +3 -5
  106. infrahub/core/property.py +1 -1
  107. infrahub/core/protocols.py +6 -0
  108. infrahub/core/protocols_base.py +4 -2
  109. infrahub/core/query/__init__.py +2 -5
  110. infrahub/core/query/attribute.py +9 -9
  111. infrahub/core/query/branch.py +5 -5
  112. infrahub/core/query/delete.py +1 -1
  113. infrahub/core/query/diff.py +4 -4
  114. infrahub/core/query/ipam.py +4 -4
  115. infrahub/core/query/node.py +11 -12
  116. infrahub/core/query/relationship.py +211 -25
  117. infrahub/core/query/resource_manager.py +10 -10
  118. infrahub/core/query/standard_node.py +6 -6
  119. infrahub/core/query/task.py +3 -3
  120. infrahub/core/query/task_log.py +1 -1
  121. infrahub/core/query/utils.py +5 -5
  122. infrahub/core/registry.py +0 -2
  123. infrahub/core/relationship/constraints/count.py +1 -1
  124. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  125. infrahub/core/relationship/model.py +76 -38
  126. infrahub/core/schema/__init__.py +6 -4
  127. infrahub/core/schema/attribute_schema.py +8 -0
  128. infrahub/core/schema/basenode_schema.py +13 -3
  129. infrahub/core/schema/definitions/core/__init__.py +153 -0
  130. infrahub/core/schema/definitions/core/account.py +168 -0
  131. infrahub/core/schema/definitions/core/artifact.py +127 -0
  132. infrahub/core/schema/definitions/core/builtin.py +21 -0
  133. infrahub/core/schema/definitions/core/check.py +60 -0
  134. infrahub/core/schema/definitions/core/generator.py +96 -0
  135. infrahub/core/schema/definitions/core/graphql_query.py +77 -0
  136. infrahub/core/schema/definitions/core/group.py +105 -0
  137. infrahub/core/schema/definitions/core/ipam.py +252 -0
  138. infrahub/core/schema/definitions/core/lineage.py +17 -0
  139. infrahub/core/schema/definitions/core/menu.py +46 -0
  140. infrahub/core/schema/definitions/core/permission.py +161 -0
  141. infrahub/core/schema/definitions/core/profile.py +29 -0
  142. infrahub/core/schema/definitions/core/propose_change.py +88 -0
  143. infrahub/core/schema/definitions/core/propose_change_comment.py +188 -0
  144. infrahub/core/schema/definitions/core/propose_change_validator.py +326 -0
  145. infrahub/core/schema/definitions/core/repository.py +280 -0
  146. infrahub/core/schema/definitions/core/resource_pool.py +180 -0
  147. infrahub/core/schema/definitions/core/template.py +12 -0
  148. infrahub/core/schema/definitions/core/transform.py +87 -0
  149. infrahub/core/schema/definitions/core/webhook.py +108 -0
  150. infrahub/core/schema/definitions/internal.py +16 -0
  151. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  152. infrahub/core/schema/generated/node_schema.py +5 -0
  153. infrahub/core/schema/generic_schema.py +5 -1
  154. infrahub/core/schema/manager.py +45 -42
  155. infrahub/core/schema/node_schema.py +4 -0
  156. infrahub/core/schema/profile_schema.py +4 -0
  157. infrahub/core/schema/relationship_schema.py +10 -2
  158. infrahub/core/schema/schema_branch.py +260 -16
  159. infrahub/core/schema/template_schema.py +36 -0
  160. infrahub/core/task/user_task.py +7 -5
  161. infrahub/core/timestamp.py +3 -3
  162. infrahub/core/utils.py +2 -2
  163. infrahub/core/validators/attribute/choices.py +1 -1
  164. infrahub/core/validators/attribute/enum.py +1 -1
  165. infrahub/core/validators/attribute/kind.py +1 -1
  166. infrahub/core/validators/attribute/length.py +1 -1
  167. infrahub/core/validators/attribute/optional.py +1 -1
  168. infrahub/core/validators/attribute/regex.py +1 -1
  169. infrahub/core/validators/attribute/unique.py +1 -1
  170. infrahub/core/validators/checks_runner.py +37 -0
  171. infrahub/core/validators/node/generate_profile.py +1 -1
  172. infrahub/core/validators/node/hierarchy.py +1 -1
  173. infrahub/core/validators/query.py +1 -1
  174. infrahub/core/validators/relationship/count.py +1 -1
  175. infrahub/core/validators/relationship/optional.py +1 -1
  176. infrahub/core/validators/relationship/peer.py +1 -1
  177. infrahub/core/validators/tasks.py +8 -6
  178. infrahub/core/validators/uniqueness/query.py +1 -1
  179. infrahub/database/__init__.py +3 -2
  180. infrahub/database/memgraph.py +1 -1
  181. infrahub/dependencies/builder/diff/combiner.py +1 -1
  182. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  183. infrahub/dependencies/builder/diff/deserializer.py +4 -2
  184. infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
  185. infrahub/dependencies/builder/diff/enricher/summary_counts.py +8 -0
  186. infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
  187. infrahub/events/artifact_action.py +76 -0
  188. infrahub/events/branch_action.py +50 -21
  189. infrahub/events/group_action.py +117 -0
  190. infrahub/events/models.py +164 -51
  191. infrahub/events/node_action.py +70 -8
  192. infrahub/events/repository_action.py +8 -8
  193. infrahub/events/schema_action.py +21 -8
  194. infrahub/exceptions.py +9 -0
  195. infrahub/generators/models.py +1 -0
  196. infrahub/generators/tasks.py +34 -15
  197. infrahub/git/base.py +3 -5
  198. infrahub/git/constants.py +0 -1
  199. infrahub/git/integrator.py +60 -36
  200. infrahub/git/models.py +80 -1
  201. infrahub/git/repository.py +7 -8
  202. infrahub/git/tasks.py +432 -112
  203. infrahub/git_credential/helper.py +2 -3
  204. infrahub/graphql/analyzer.py +572 -11
  205. infrahub/graphql/app.py +34 -26
  206. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  207. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  208. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  209. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  210. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  211. infrahub/graphql/context.py +33 -0
  212. infrahub/graphql/enums.py +1 -1
  213. infrahub/graphql/initialization.py +5 -1
  214. infrahub/graphql/loaders/node.py +2 -2
  215. infrahub/graphql/manager.py +63 -63
  216. infrahub/graphql/mutations/account.py +20 -13
  217. infrahub/graphql/mutations/artifact_definition.py +16 -12
  218. infrahub/graphql/mutations/branch.py +86 -40
  219. infrahub/graphql/mutations/computed_attribute.py +24 -15
  220. infrahub/graphql/mutations/diff.py +33 -17
  221. infrahub/graphql/mutations/diff_conflict.py +14 -8
  222. infrahub/graphql/mutations/generator.py +83 -0
  223. infrahub/graphql/mutations/graphql_query.py +19 -11
  224. infrahub/graphql/mutations/ipam.py +25 -23
  225. infrahub/graphql/mutations/main.py +233 -45
  226. infrahub/graphql/mutations/menu.py +10 -10
  227. infrahub/graphql/mutations/proposed_change.py +36 -28
  228. infrahub/graphql/mutations/relationship.py +341 -130
  229. infrahub/graphql/mutations/repository.py +41 -35
  230. infrahub/graphql/mutations/resource_manager.py +26 -26
  231. infrahub/graphql/mutations/schema.py +66 -33
  232. infrahub/graphql/mutations/tasks.py +10 -7
  233. infrahub/graphql/parser.py +1 -1
  234. infrahub/graphql/permissions.py +3 -10
  235. infrahub/graphql/queries/account.py +22 -18
  236. infrahub/graphql/queries/branch.py +6 -4
  237. infrahub/graphql/queries/diff/tree.py +63 -52
  238. infrahub/graphql/queries/event.py +115 -0
  239. infrahub/graphql/queries/internal.py +3 -3
  240. infrahub/graphql/queries/ipam.py +23 -18
  241. infrahub/graphql/queries/relationship.py +11 -10
  242. infrahub/graphql/queries/resource_manager.py +37 -25
  243. infrahub/graphql/queries/search.py +9 -8
  244. infrahub/graphql/queries/status.py +12 -9
  245. infrahub/graphql/queries/task.py +11 -9
  246. infrahub/graphql/resolvers/resolver.py +69 -43
  247. infrahub/graphql/resolvers/single_relationship.py +16 -10
  248. infrahub/graphql/schema.py +4 -0
  249. infrahub/graphql/subscription/__init__.py +1 -1
  250. infrahub/graphql/subscription/events.py +1 -1
  251. infrahub/graphql/subscription/graphql_query.py +8 -8
  252. infrahub/graphql/types/branch.py +2 -2
  253. infrahub/graphql/types/common.py +6 -1
  254. infrahub/graphql/types/context.py +12 -0
  255. infrahub/graphql/types/enums.py +2 -0
  256. infrahub/graphql/types/event.py +158 -0
  257. infrahub/graphql/types/interface.py +2 -2
  258. infrahub/graphql/types/node.py +3 -3
  259. infrahub/graphql/types/permission.py +2 -2
  260. infrahub/graphql/types/relationship.py +3 -3
  261. infrahub/graphql/types/standard_node.py +9 -11
  262. infrahub/graphql/utils.py +28 -182
  263. infrahub/groups/tasks.py +2 -3
  264. infrahub/lock.py +21 -21
  265. infrahub/menu/generator.py +0 -1
  266. infrahub/menu/menu.py +116 -138
  267. infrahub/menu/models.py +4 -4
  268. infrahub/message_bus/__init__.py +11 -13
  269. infrahub/message_bus/messages/__init__.py +0 -14
  270. infrahub/message_bus/messages/check_generator_run.py +1 -3
  271. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  272. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  273. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  274. infrahub/message_bus/messages/send_echo_request.py +1 -1
  275. infrahub/message_bus/operations/__init__.py +4 -13
  276. infrahub/message_bus/operations/check/__init__.py +2 -2
  277. infrahub/message_bus/operations/check/generator.py +1 -3
  278. infrahub/message_bus/operations/event/branch.py +7 -3
  279. infrahub/message_bus/operations/event/schema.py +1 -1
  280. infrahub/message_bus/operations/event/worker.py +0 -3
  281. infrahub/message_bus/operations/finalize/validator.py +1 -1
  282. infrahub/message_bus/operations/git/file.py +2 -2
  283. infrahub/message_bus/operations/git/repository.py +1 -1
  284. infrahub/message_bus/operations/requests/__init__.py +0 -4
  285. infrahub/message_bus/operations/requests/generator_definition.py +2 -4
  286. infrahub/message_bus/operations/requests/proposed_change.py +37 -20
  287. infrahub/message_bus/operations/send/echo.py +1 -1
  288. infrahub/message_bus/types.py +1 -1
  289. infrahub/permissions/globals.py +15 -0
  290. infrahub/pools/prefix.py +29 -165
  291. infrahub/prefect_server/__init__.py +0 -0
  292. infrahub/prefect_server/app.py +18 -0
  293. infrahub/prefect_server/database.py +20 -0
  294. infrahub/prefect_server/events.py +28 -0
  295. infrahub/prefect_server/models.py +46 -0
  296. infrahub/proposed_change/models.py +18 -1
  297. infrahub/proposed_change/tasks.py +195 -53
  298. infrahub/pytest_plugin.py +4 -4
  299. infrahub/server.py +13 -12
  300. infrahub/services/__init__.py +148 -63
  301. infrahub/services/adapters/cache/__init__.py +11 -11
  302. infrahub/services/adapters/cache/nats.py +42 -25
  303. infrahub/services/adapters/cache/redis.py +3 -11
  304. infrahub/services/adapters/event/__init__.py +10 -18
  305. infrahub/services/adapters/http/__init__.py +0 -5
  306. infrahub/services/adapters/http/httpx.py +22 -15
  307. infrahub/services/adapters/message_bus/__init__.py +25 -8
  308. infrahub/services/adapters/message_bus/local.py +9 -7
  309. infrahub/services/adapters/message_bus/nats.py +14 -8
  310. infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
  311. infrahub/services/adapters/workflow/__init__.py +11 -8
  312. infrahub/services/adapters/workflow/local.py +27 -6
  313. infrahub/services/adapters/workflow/worker.py +23 -7
  314. infrahub/services/component.py +43 -40
  315. infrahub/services/protocols.py +7 -7
  316. infrahub/services/scheduler.py +30 -29
  317. infrahub/storage.py +2 -4
  318. infrahub/task_manager/constants.py +1 -1
  319. infrahub/task_manager/event.py +261 -0
  320. infrahub/task_manager/models.py +147 -3
  321. infrahub/task_manager/task.py +1 -1
  322. infrahub/tasks/artifact.py +19 -18
  323. infrahub/tasks/registry.py +1 -1
  324. infrahub/tasks/telemetry.py +13 -14
  325. infrahub/transformations/tasks.py +3 -5
  326. infrahub/trigger/__init__.py +0 -0
  327. infrahub/trigger/catalogue.py +16 -0
  328. infrahub/trigger/constants.py +9 -0
  329. infrahub/trigger/models.py +105 -0
  330. infrahub/trigger/tasks.py +91 -0
  331. infrahub/types.py +1 -1
  332. infrahub/utils.py +1 -1
  333. infrahub/webhook/constants.py +0 -2
  334. infrahub/webhook/models.py +161 -40
  335. infrahub/webhook/tasks.py +123 -202
  336. infrahub/webhook/triggers.py +27 -0
  337. infrahub/workers/infrahub_async.py +36 -25
  338. infrahub/workers/utils.py +63 -0
  339. infrahub/workflows/catalogue.py +71 -52
  340. infrahub/workflows/initialization.py +14 -8
  341. infrahub/workflows/models.py +28 -4
  342. infrahub/workflows/utils.py +1 -1
  343. infrahub_sdk/batch.py +2 -2
  344. infrahub_sdk/client.py +8 -0
  345. infrahub_sdk/config.py +1 -1
  346. infrahub_sdk/ctl/branch.py +3 -2
  347. infrahub_sdk/ctl/check.py +4 -4
  348. infrahub_sdk/ctl/cli_commands.py +16 -11
  349. infrahub_sdk/ctl/exceptions.py +0 -6
  350. infrahub_sdk/ctl/exporter.py +1 -1
  351. infrahub_sdk/ctl/generator.py +5 -5
  352. infrahub_sdk/ctl/importer.py +3 -2
  353. infrahub_sdk/ctl/menu.py +1 -1
  354. infrahub_sdk/ctl/object.py +1 -1
  355. infrahub_sdk/ctl/repository.py +23 -15
  356. infrahub_sdk/ctl/schema.py +2 -2
  357. infrahub_sdk/ctl/utils.py +6 -21
  358. infrahub_sdk/ctl/validate.py +2 -1
  359. infrahub_sdk/data.py +1 -1
  360. infrahub_sdk/exceptions.py +12 -0
  361. infrahub_sdk/generator.py +3 -0
  362. infrahub_sdk/node.py +5 -8
  363. infrahub_sdk/protocols.py +20 -8
  364. infrahub_sdk/schema/__init__.py +14 -5
  365. infrahub_sdk/schema/main.py +7 -0
  366. infrahub_sdk/task/__init__.py +1 -0
  367. infrahub_sdk/task/constants.py +3 -0
  368. infrahub_sdk/task/exceptions.py +25 -0
  369. infrahub_sdk/task/manager.py +545 -0
  370. infrahub_sdk/task/models.py +74 -0
  371. infrahub_sdk/testing/docker.py +30 -0
  372. infrahub_sdk/timestamp.py +134 -33
  373. infrahub_sdk/transfer/exporter/json.py +1 -1
  374. infrahub_sdk/utils.py +39 -1
  375. infrahub_sdk/yaml.py +2 -3
  376. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/METADATA +7 -6
  377. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/RECORD +383 -339
  378. infrahub_testcontainers/container.py +2 -3
  379. infrahub_testcontainers/docker-compose.test.yml +2 -2
  380. infrahub/core/branch/constants.py +0 -2
  381. infrahub/core/schema/definitions/core.py +0 -2274
  382. infrahub/graphql/query.py +0 -52
  383. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  384. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  385. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  386. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  387. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  388. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  389. infrahub/message_bus/operations/check/repository.py +0 -293
  390. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  391. infrahub/message_bus/operations/requests/repository.py +0 -133
  392. infrahub/schema/constants.py +0 -1
  393. infrahub/schema/tasks.py +0 -76
  394. infrahub/services/adapters/database/__init__.py +0 -9
  395. infrahub_sdk/ctl/_file.py +0 -13
  396. /infrahub/{schema → artifacts}/__init__.py +0 -0
  397. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/LICENSE.txt +0 -0
  398. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/WHEEL +0 -0
  399. {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/entry_points.txt +0 -0
@@ -7,12 +7,15 @@ from typing import TYPE_CHECKING
7
7
 
8
8
  from infrahub import config
9
9
  from infrahub.components import ComponentType
10
+ from infrahub.log import get_logger
10
11
  from infrahub.tasks.keepalive import refresh_heartbeat
11
12
  from infrahub.tasks.recurring import trigger_branch_refresh
12
13
 
13
14
  if TYPE_CHECKING:
14
15
  from infrahub.services import InfrahubServices, ServiceFunction
15
16
 
17
+ log = get_logger()
18
+
16
19
 
17
20
  @dataclass
18
21
  class Schedule:
@@ -23,18 +26,17 @@ class Schedule:
23
26
 
24
27
 
25
28
  class InfrahubScheduler:
26
- def __init__(self) -> None:
27
- self.service: InfrahubServices
29
+ # TODO we could remove service dependency by adding kwargs to Schedule instead of passing services
30
+ service: InfrahubServices | None
31
+
32
+ def __init__(self, component_type: ComponentType) -> None:
28
33
  self.running: bool = False
29
34
  self.schedules: list[Schedule] = []
30
35
 
31
- async def initialize(self, service: InfrahubServices) -> None:
32
- self.service = service
33
-
34
36
  self.running = config.SETTINGS.miscellaneous.start_background_runner
35
37
  # Add some randomness to the interval to avoid having all workers pulling the latest update at the same time
36
38
  random_number = random.randint(0, 5)
37
- if self.service.component_type == ComponentType.API_SERVER:
39
+ if component_type == ComponentType.API_SERVER:
38
40
  schedules = [
39
41
  Schedule(name="refresh_api_components", interval=10, function=refresh_heartbeat, start_delay=0),
40
42
  Schedule(
@@ -43,7 +45,7 @@ class InfrahubScheduler:
43
45
  ]
44
46
  self.schedules.extend(schedules)
45
47
 
46
- if self.service.component_type == ComponentType.GIT_AGENT:
48
+ if component_type == ComponentType.GIT_AGENT:
47
49
  schedules = [
48
50
  Schedule(name="refresh_components", interval=10, function=refresh_heartbeat),
49
51
  Schedule(
@@ -54,32 +56,31 @@ class InfrahubScheduler:
54
56
 
55
57
  async def start_schedule(self) -> None:
56
58
  for schedule in self.schedules:
57
- asyncio.create_task(
58
- run_schedule(schedule=schedule, service=self.service), name=f"scheduled_task_{schedule.name}"
59
- )
59
+ asyncio.create_task(self.run_schedule(schedule=schedule), name=f"scheduled_task_{schedule.name}")
60
60
 
61
61
  async def shutdown(self) -> None:
62
62
  self.running = False
63
63
 
64
+ async def run_schedule(self, schedule: Schedule) -> None:
65
+ """Execute the task provided in the schedule as per the defined interval
64
66
 
65
- async def run_schedule(schedule: Schedule, service: InfrahubServices) -> None:
66
- """Execute the task provided in the schedule as per the defined interval
67
-
68
- Once the service is marked to be shutdown the scheduler will stop executing tasks.
69
- """
70
- for _ in range(schedule.start_delay):
71
- if not service.scheduler.running:
72
- return
73
- await asyncio.sleep(delay=1)
74
-
75
- service.log.info("Started recurring task", task=schedule.name)
76
-
77
- while service.scheduler.running:
78
- try:
79
- await schedule.function(service)
80
- except Exception as exc: # pylint: disable=broad-exception-caught
81
- service.log.error(str(exc))
82
- for _ in range(schedule.interval):
83
- if not service.scheduler.running:
67
+ Once the service is marked to be shutdown the scheduler will stop executing tasks.
68
+ """
69
+ for _ in range(schedule.start_delay):
70
+ if not self.running:
84
71
  return
85
72
  await asyncio.sleep(delay=1)
73
+
74
+ if self.service is None:
75
+ raise ValueError("InfrahubScheduler.service is None")
76
+
77
+ self.service.log.info("Started recurring task", task=schedule.name)
78
+ while self.running:
79
+ try:
80
+ await schedule.function(self.service)
81
+ except Exception as exc:
82
+ self.service.log.error(str(exc))
83
+ for _ in range(schedule.interval):
84
+ if not self.running:
85
+ return
86
+ await asyncio.sleep(delay=1)
infrahub/storage.py CHANGED
@@ -53,7 +53,5 @@ class InfrahubObjectStorage:
53
53
  try:
54
54
  with self._storage.open(identifier) as f:
55
55
  return f.read().decode()
56
- except (FileNotFoundError, botocore.exceptions.ClientError):
57
- raise NodeNotFoundError( # pylint: disable=raise-missing-from
58
- node_type="StorageObject", identifier=identifier
59
- )
56
+ except (FileNotFoundError, botocore.exceptions.ClientError) as err:
57
+ raise NodeNotFoundError(node_type="StorageObject", identifier=identifier) from err
@@ -2,7 +2,7 @@ from infrahub.core.constants import TaskConclusion
2
2
 
3
3
  LOG_LEVEL_MAPPING = {10: "debug", 20: "info", 30: "warning", 40: "error", 50: "critical"}
4
4
 
5
- CONCLUSION_STATE_MAPPING = {
5
+ CONCLUSION_STATE_MAPPING: dict[str, TaskConclusion] = {
6
6
  "Scheduled": TaskConclusion.UNKNOWN,
7
7
  "Pending": TaskConclusion.UNKNOWN,
8
8
  "Running": TaskConclusion.UNKNOWN,
@@ -0,0 +1,261 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from prefect.client.orchestration import PrefectClient, get_client
7
+ from prefect.events.schemas.events import Event as PrefectEventModel
8
+ from pydantic import BaseModel, Field, TypeAdapter
9
+
10
+ from infrahub.core.constants import GLOBAL_BRANCH_NAME
11
+ from infrahub.exceptions import ServiceUnavailableError
12
+ from infrahub.log import get_logger
13
+ from infrahub.utils import get_nested_dict
14
+
15
+ log = get_logger()
16
+
17
+ if TYPE_CHECKING:
18
+ from .models import InfrahubEventFilter
19
+
20
+
21
+ class PrefectEventData(PrefectEventModel):
22
+ def get_branch(self) -> str | None:
23
+ for resource in self.related:
24
+ if resource.get("prefect.resource.role") != "infrahub.branch":
25
+ continue
26
+ if "infrahub.resource.label" not in resource:
27
+ continue
28
+ if resource.get("infrahub.resource.label") == GLOBAL_BRANCH_NAME:
29
+ return None
30
+ return resource.get("infrahub.resource.label")
31
+ return None
32
+
33
+ def get_level(self) -> int:
34
+ for resource in self.related:
35
+ level = resource.get("infrahub.event.level")
36
+ if level is None:
37
+ continue
38
+ try:
39
+ return int(level)
40
+ except ValueError:
41
+ return 0
42
+
43
+ return 0
44
+
45
+ def get_parent(self) -> str | None:
46
+ for resource in self.related:
47
+ if resource.get("prefect.resource.role") != "infrahub.child_event":
48
+ continue
49
+ return resource.get("infrahub.event_parent.id")
50
+ return None
51
+
52
+ def get_primary_node(self) -> dict[str, str] | None:
53
+ node_id = self.resource.get("infrahub.node.id")
54
+ node_kind = self.resource.get("infrahub.node.kind")
55
+ if node_id and node_kind:
56
+ return {"id": node_id, "kind": node_kind}
57
+
58
+ return None
59
+
60
+ def get_related_nodes(self) -> list[dict[str, str]]:
61
+ related_nodes = []
62
+ for resource in self.related:
63
+ if resource.get("prefect.resource.role") != "infrahub.related.node":
64
+ continue
65
+
66
+ node_id = resource.get("prefect.resource.id")
67
+ node_kind = resource.get("infrahub.node.kind")
68
+ if node_id == self.resource.get("infrahub.node.id"):
69
+ # Don't include the primary node as a related node.
70
+ continue
71
+ if node_id and node_kind:
72
+ related_nodes.append({"id": node_id, "kind": node_kind})
73
+
74
+ return related_nodes
75
+
76
+ def get_account_id(self) -> str | None:
77
+ for resource in self.related:
78
+ if resource.get("prefect.resource.role") != "infrahub.account":
79
+ continue
80
+ return resource.get("infrahub.resource.id")
81
+ return None
82
+
83
+ def has_children(self) -> bool:
84
+ for resource in self.related:
85
+ if resource.get("prefect.resource.role") != "infrahub.event":
86
+ continue
87
+ if resource.get("infrahub.event.has_children") == "true":
88
+ return True
89
+ return False
90
+ return False
91
+
92
+ def _return_node_mutation(self) -> dict[str, Any]:
93
+ attributes = []
94
+
95
+ for resource in self.related:
96
+ if resource.get("prefect.resource.role") == "infrahub.node.field_update" and resource.get(
97
+ "infrahub.attribute.name"
98
+ ):
99
+ attributes.append(
100
+ {
101
+ "name": resource.get("infrahub.attribute.name", ""),
102
+ "kind": resource.get("infrahub.attribute.kind", ""),
103
+ "value": None
104
+ if resource.get("infrahub.attribute.value") == "NULL"
105
+ else resource.get("infrahub.attribute.value"),
106
+ "value_previous": None
107
+ if resource.get("infrahub.attribute.value_previous") == "NULL"
108
+ else resource.get("infrahub.attribute.value_previous"),
109
+ "action": resource.get("infrahub.attribute.action", "unchanged"),
110
+ }
111
+ )
112
+
113
+ return {"attributes": attributes}
114
+
115
+ def _get_branch_name_from_resource(self) -> str:
116
+ return self.resource.get("infrahub.branch.name") or ""
117
+
118
+ def _return_artifact_event(self) -> dict[str, Any]:
119
+ checksum = ""
120
+ checksum_previous: str | None = None
121
+ storage_id = ""
122
+ storage_id_previous: str | None = None
123
+ artifact_definition_id = ""
124
+ for resource in self.related:
125
+ if resource.role == "infrahub.artifact":
126
+ checksum = resource.get("infrahub.artifact.checksum") or ""
127
+ checksum_previous = resource.get("infrahub.artifact.checksum_previous")
128
+ storage_id = resource.get("infrahub.artifact.storage_id") or ""
129
+ storage_id_previous = resource.get("infrahub.artifact.storage_id_previous")
130
+ artifact_definition_id = resource.get("infrahub.artifact.artifact_definition_id") or ""
131
+
132
+ return {
133
+ "checksum": checksum,
134
+ "checksum_previous": checksum_previous,
135
+ "storage_id": storage_id,
136
+ "storage_id_previous": storage_id_previous,
137
+ "artifact_definition_id": artifact_definition_id,
138
+ }
139
+
140
+ def _return_branch_created(self) -> dict[str, Any]:
141
+ return {"created_branch": self._get_branch_name_from_resource()}
142
+
143
+ def _return_branch_deleted(self) -> dict[str, Any]:
144
+ return {"deleted_branch": self._get_branch_name_from_resource()}
145
+
146
+ def _return_branch_merged(self) -> dict[str, Any]:
147
+ return {"source_branch": self._get_branch_name_from_resource()}
148
+
149
+ def _return_branch_rebased(self) -> dict[str, Any]:
150
+ return {"rebased_branch": self._get_branch_name_from_resource()}
151
+
152
+ def _return_group_event(self) -> dict[str, Any]:
153
+ members = []
154
+ ancestors = []
155
+
156
+ for resource in self.related:
157
+ if resource.role == "infrahub.group.member" and resource.get("infrahub.node.kind"):
158
+ members.append({"id": resource.id, "kind": resource.get("infrahub.node.kind")})
159
+ elif resource.role == "infrahub.group.ancestor" and resource.get("infrahub.node.kind"):
160
+ ancestors.append({"id": resource.id, "kind": resource.get("infrahub.node.kind")})
161
+
162
+ return {"members": members, "ancestors": ancestors}
163
+
164
+ def _return_event_specifics(self) -> dict[str, Any]:
165
+ """Return event specific data based on the type of event being processed"""
166
+
167
+ event_specifics = {}
168
+
169
+ match self.event:
170
+ case "infrahub.artifact.created" | "infrahub.artifact.updated":
171
+ event_specifics = self._return_artifact_event()
172
+ case "infrahub.node.created" | "infrahub.node.updated" | "infrahub.node.deleted":
173
+ event_specifics = self._return_node_mutation()
174
+ case "infrahub.branch.created":
175
+ event_specifics = self._return_branch_created()
176
+ case "infrahub.branch.deleted":
177
+ event_specifics = self._return_branch_deleted()
178
+ case "infrahub.branch.merged":
179
+ event_specifics = self._return_branch_merged()
180
+ case "infrahub.branch.rebased":
181
+ event_specifics = self._return_branch_rebased()
182
+ case "infrahub.group.member_added" | "infrahub.group.member_removed":
183
+ event_specifics = self._return_group_event()
184
+
185
+ return event_specifics
186
+
187
+ def to_graphql(self) -> dict[str, Any]:
188
+ response = {
189
+ "id": str(self.id),
190
+ "event": self.event,
191
+ "branch": self.get_branch(),
192
+ "account_id": self.get_account_id(),
193
+ "occurred_at": self.occurred,
194
+ "has_children": self.has_children(),
195
+ "payload": self.payload,
196
+ "level": self.get_level(),
197
+ "primary_node": self.get_primary_node(),
198
+ "parent_id": self.get_parent(),
199
+ "related_nodes": self.get_related_nodes(),
200
+ }
201
+ response.update(self._return_event_specifics())
202
+ return response
203
+
204
+
205
+ class PrefectEventResponse(BaseModel):
206
+ count: int = Field(..., description="Number of matching events")
207
+ events: list[PrefectEventData] = Field(..., description="Returned events")
208
+
209
+
210
+ class PrefectEvent:
211
+ @classmethod
212
+ async def query_events(
213
+ cls,
214
+ client: PrefectClient,
215
+ limit: int,
216
+ filters: InfrahubEventFilter,
217
+ offset: int | None = None,
218
+ ) -> PrefectEventResponse:
219
+ body = {"limit": limit, "filter": filters.model_dump(mode="json", exclude_none=True), "offset": offset}
220
+
221
+ # Retry due to https://github.com/PrefectHQ/prefect/issues/16299
222
+ for _ in range(1, 5):
223
+ response = await client._client.post("/infrahub/events/filter", json=body)
224
+ if response.status_code == 200:
225
+ break
226
+ await asyncio.sleep(0.1)
227
+
228
+ if response.status_code != 200:
229
+ raise ServiceUnavailableError(
230
+ message=f"Unable to query prefect due to invalid response from the server (status_code={response.status_code})"
231
+ )
232
+ data: dict[str, Any] = response.json()
233
+
234
+ return PrefectEventResponse(
235
+ count=data.get("total", 0),
236
+ events=TypeAdapter(list[PrefectEventData]).validate_python(data.get("events")),
237
+ )
238
+
239
+ @classmethod
240
+ async def query(
241
+ cls,
242
+ fields: dict[str, Any],
243
+ event_filter: InfrahubEventFilter,
244
+ limit: int | None = None,
245
+ offset: int | None = None,
246
+ ) -> dict[str, Any]:
247
+ nodes: list[dict] = []
248
+ limit = limit or 50
249
+
250
+ node_fields = get_nested_dict(nested_dict=fields, keys=["edges", "node"])
251
+
252
+ if not node_fields:
253
+ # This means that it's purely a count query and as such we can override the limit to avoid
254
+ # returning data that will only be discarded
255
+ limit = 1
256
+
257
+ async with get_client(sync_client=False) as client:
258
+ response = await cls.query_events(client=client, filters=event_filter, limit=limit, offset=offset)
259
+ nodes = [{"node": event.to_graphql()} for event in response.events]
260
+
261
+ return {"count": response.count, "edges": nodes}
@@ -1,11 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ import uuid
1
4
  from collections import defaultdict
5
+ from typing import TYPE_CHECKING, Any
2
6
  from uuid import UUID
3
7
 
4
- from prefect.client.schemas.objects import Log as PrefectLog
8
+ from prefect.client.schemas.objects import Log as PrefectLog # noqa: TC002
9
+ from prefect.events.filters import (
10
+ EventFilter,
11
+ EventIDFilter,
12
+ EventNameFilter,
13
+ EventOccurredFilter,
14
+ EventRelatedFilter,
15
+ EventResourceFilter,
16
+ )
17
+ from prefect.events.schemas.events import ResourceSpecification
5
18
  from pydantic import BaseModel, Field
6
19
 
20
+ from infrahub.core.timestamp import Timestamp
21
+
7
22
  from .constants import LOG_LEVEL_MAPPING
8
23
 
24
+ if TYPE_CHECKING:
25
+ from datetime import datetime
26
+
9
27
 
10
28
  class RelatedNodeInfo(BaseModel):
11
29
  id: str
@@ -13,7 +31,7 @@ class RelatedNodeInfo(BaseModel):
13
31
 
14
32
 
15
33
  class RelatedNodesInfo(BaseModel):
16
- flows: dict[UUID, dict[str, RelatedNodeInfo]] = Field(default_factory=lambda: defaultdict(dict))
34
+ flows: dict[UUID, dict[str, RelatedNodeInfo]] = Field(default_factory=lambda: defaultdict(dict)) # type: ignore[arg-type]
17
35
  nodes: dict[str, RelatedNodeInfo] = Field(default_factory=dict)
18
36
 
19
37
  def add_nodes(self, flow_id: UUID, node_ids: list[str]) -> None:
@@ -46,7 +64,7 @@ class RelatedNodesInfo(BaseModel):
46
64
 
47
65
 
48
66
  class FlowLogs(BaseModel):
49
- logs: defaultdict[UUID, list[PrefectLog]] = Field(default_factory=lambda: defaultdict(list))
67
+ logs: defaultdict[UUID, list[PrefectLog]] = Field(default_factory=lambda: defaultdict(list)) # type: ignore[arg-type]
50
68
 
51
69
  def to_graphql(self, flow_id: UUID) -> list[dict]:
52
70
  return [
@@ -63,3 +81,129 @@ class FlowLogs(BaseModel):
63
81
 
64
82
  class FlowProgress(BaseModel):
65
83
  data: dict[UUID, float] = Field(default_factory=dict)
84
+
85
+
86
+ class InfrahubEventFilter(EventFilter):
87
+ matching_related: list[EventRelatedFilter] = Field(default_factory=list)
88
+
89
+ def add_account_filter(self, account__ids: list[str] | None) -> None:
90
+ if account__ids:
91
+ self.matching_related.append(
92
+ EventRelatedFilter(
93
+ labels=ResourceSpecification(
94
+ {"prefect.resource.role": "infrahub.account", "infrahub.resource.id": account__ids}
95
+ )
96
+ )
97
+ )
98
+
99
+ def add_branch_filter(self, branches: list[str] | None = None) -> None:
100
+ if branches:
101
+ self.matching_related.append(
102
+ EventRelatedFilter(
103
+ labels=ResourceSpecification(
104
+ {"prefect.resource.role": "infrahub.branch", "infrahub.resource.label": branches}
105
+ )
106
+ )
107
+ )
108
+
109
+ def add_event_filter(self, level: int | None = None, has_children: bool | None = None) -> None:
110
+ event_filter: dict[str, list[str] | str] = {}
111
+ if level is not None:
112
+ event_filter["infrahub.event.level"] = str(level)
113
+
114
+ if has_children is not None:
115
+ event_filter["infrahub.event.has_children"] = str(has_children).lower()
116
+
117
+ if event_filter:
118
+ event_filter["prefect.resource.role"] = "infrahub.event"
119
+ self.matching_related.append(EventRelatedFilter(labels=ResourceSpecification(event_filter)))
120
+
121
+ def add_event_id_filter(self, ids: list[str] | None = None) -> None:
122
+ if ids:
123
+ self.id = EventIDFilter(id=[uuid.UUID(id) for id in ids])
124
+
125
+ def add_event_type_filter(
126
+ self, event_type: list[str] | None = None, event_type_filter: dict[str, Any] | None = None
127
+ ) -> None:
128
+ event_type = event_type or []
129
+ event_type_filter = event_type_filter or {}
130
+
131
+ if branch_merged := event_type_filter.get("branch_merged"):
132
+ branches: list[str] = branch_merged.get("branches") or []
133
+ if "infrahub.branch.created" not in event_type:
134
+ event_type.append("infrahub.branch.merged")
135
+ if branches:
136
+ self.resource = EventResourceFilter(labels=ResourceSpecification({"infrahub.branch.name": branches}))
137
+
138
+ if branch_rebased := event_type_filter.get("branch_rebased"):
139
+ branches = branch_rebased.get("branches") or []
140
+ if "infrahub.branch.created" not in event_type:
141
+ event_type.append("infrahub.branch.rebased")
142
+ if branches:
143
+ self.resource = EventResourceFilter(labels=ResourceSpecification({"infrahub.branch.name": branches}))
144
+
145
+ if event_type:
146
+ self.event = EventNameFilter(name=event_type)
147
+
148
+ def add_primary_node_filter(self, primary_node__ids: list[str] | None) -> None:
149
+ if primary_node__ids:
150
+ self.resource = EventResourceFilter(labels=ResourceSpecification({"infrahub.node.id": primary_node__ids}))
151
+
152
+ def add_parent_filter(self, parent__ids: list[str] | None) -> None:
153
+ if parent__ids:
154
+ self.matching_related.append(
155
+ EventRelatedFilter(
156
+ labels=ResourceSpecification(
157
+ {"prefect.resource.role": "infrahub.child_event", "infrahub.event_parent.id": parent__ids}
158
+ )
159
+ )
160
+ )
161
+
162
+ def add_related_node_filter(self, related_node__ids: list[str] | None) -> None:
163
+ if related_node__ids:
164
+ self.matching_related.append(
165
+ EventRelatedFilter(
166
+ labels=ResourceSpecification(
167
+ {"prefect.resource.role": "infrahub.related.node", "prefect.resource.id": related_node__ids}
168
+ )
169
+ )
170
+ )
171
+
172
+ @classmethod
173
+ def from_filters(
174
+ cls,
175
+ ids: list[str] | None = None,
176
+ account__ids: list[str] | None = None,
177
+ related_node__ids: list[str] | None = None,
178
+ parent__ids: list[str] | None = None,
179
+ primary_node__ids: list[str] | None = None,
180
+ event_type: list[str] | None = None,
181
+ event_type_filter: dict[str, Any] | None = None,
182
+ branches: list[str] | None = None,
183
+ level: int | None = None,
184
+ has_children: bool | None = None,
185
+ since: datetime | None = None,
186
+ until: datetime | None = None,
187
+ ) -> InfrahubEventFilter:
188
+ occurred_filter = {}
189
+ if since:
190
+ occurred_filter["since"] = Timestamp(since.isoformat()).to_datetime()
191
+
192
+ if until:
193
+ occurred_filter["until"] = Timestamp(until.isoformat()).to_datetime()
194
+
195
+ if occurred_filter:
196
+ filters = cls(occurred=EventOccurredFilter(**occurred_filter))
197
+ else:
198
+ filters = cls()
199
+
200
+ filters.add_event_filter(level=level, has_children=has_children)
201
+ filters.add_event_id_filter(ids=ids)
202
+ filters.add_event_type_filter(event_type=event_type, event_type_filter=event_type_filter)
203
+ filters.add_branch_filter(branches=branches)
204
+ filters.add_account_filter(account__ids=account__ids)
205
+ filters.add_parent_filter(parent__ids=parent__ids)
206
+ filters.add_primary_node_filter(primary_node__ids=primary_node__ids)
207
+ filters.add_related_node_filter(related_node__ids=related_node__ids)
208
+
209
+ return filters
@@ -250,7 +250,7 @@ class PrefectTask:
250
250
  "node": {
251
251
  "title": flow.name,
252
252
  "conclusion": CONCLUSION_STATE_MAPPING.get(
253
- flow.state_name, TaskConclusion.UNKNOWN
253
+ str(flow.state_name), TaskConclusion.UNKNOWN
254
254
  ).value,
255
255
  "state": flow.state_type,
256
256
  "progress": progress_flow.data.get(flow.id, None),
@@ -5,41 +5,42 @@ from prefect import task
5
5
  from prefect.cache_policies import NONE
6
6
 
7
7
  from infrahub import lock
8
+ from infrahub.artifacts.models import CheckArtifactCreate
8
9
  from infrahub.core.constants import InfrahubKind
9
10
  from infrahub.git.models import RequestArtifactGenerate
10
- from infrahub.message_bus import messages
11
11
  from infrahub.services import InfrahubServices
12
12
 
13
13
 
14
- @task(name="define-artifact", task_run_name="Define Artifact", cache_policy=NONE)
14
+ @task(name="define-artifact", task_run_name="Define Artifact", cache_policy=NONE) # type: ignore[arg-type]
15
15
  async def define_artifact(
16
- message: Union[messages.CheckArtifactCreate, RequestArtifactGenerate], service: InfrahubServices
17
- ) -> InfrahubNode:
18
- if message.artifact_id:
19
- artifact = await service.client.get(
20
- kind=InfrahubKind.ARTIFACT, id=message.artifact_id, branch=message.branch_name
21
- )
16
+ model: Union[CheckArtifactCreate, RequestArtifactGenerate], service: InfrahubServices
17
+ ) -> tuple[InfrahubNode, bool]:
18
+ """Return an artifact together with a flag to indicate if the artifact is created now or already existed."""
19
+ created = False
20
+ if model.artifact_id:
21
+ artifact = await service.client.get(kind=InfrahubKind.ARTIFACT, id=model.artifact_id, branch=model.branch_name)
22
22
  else:
23
- async with lock.registry.get(f"{message.target_id}-{message.artifact_definition}", namespace="artifact"):
23
+ async with lock.registry.get(f"{model.target_id}-{model.artifact_definition}", namespace="artifact"):
24
24
  artifacts = await service.client.filters(
25
25
  kind=InfrahubKind.ARTIFACT,
26
- branch=message.branch_name,
27
- definition__ids=[message.artifact_definition],
28
- object__ids=[message.target_id],
26
+ branch=model.branch_name,
27
+ definition__ids=[model.artifact_definition],
28
+ object__ids=[model.target_id],
29
29
  )
30
30
  if artifacts:
31
31
  artifact = artifacts[0]
32
32
  else:
33
33
  artifact = await service.client.create(
34
34
  kind=InfrahubKind.ARTIFACT,
35
- branch=message.branch_name,
35
+ branch=model.branch_name,
36
36
  data={
37
- "name": message.artifact_name,
37
+ "name": model.artifact_name,
38
38
  "status": "Pending",
39
- "object": message.target_id,
40
- "definition": message.artifact_definition,
41
- "content_type": message.content_type,
39
+ "object": model.target_id,
40
+ "definition": model.artifact_definition,
41
+ "content_type": model.content_type,
42
42
  },
43
43
  )
44
44
  await artifact.save()
45
- return artifact
45
+ created = True
46
+ return artifact, created
@@ -18,7 +18,7 @@ async def refresh_branches(db: InfrahubDatabase) -> None:
18
18
  If a branch is already present with a different value for the hash
19
19
  We pull the new schema from the database and we update the registry.
20
20
  """
21
- from infrahub.graphql.manager import GraphQLSchemaManager # pylint: disable=import-outside-toplevel,cyclic-import
21
+ from infrahub.graphql.manager import GraphQLSchemaManager
22
22
 
23
23
  async with lock.registry.local_schema_lock():
24
24
  branches = await registry.branch_object.get_list(db=db)