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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. infrahub/api/artifact.py +16 -4
  2. infrahub/api/dependencies.py +8 -0
  3. infrahub/api/oauth2.py +0 -1
  4. infrahub/api/oidc.py +0 -1
  5. infrahub/api/query.py +18 -7
  6. infrahub/api/schema.py +32 -6
  7. infrahub/api/transformation.py +12 -5
  8. infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +5 -3
  9. infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
  10. infrahub/cli/__init__.py +0 -2
  11. infrahub/cli/db.py +6 -7
  12. infrahub/cli/events.py +8 -3
  13. infrahub/cli/git_agent.py +9 -7
  14. infrahub/cli/tasks.py +4 -6
  15. infrahub/computed_attribute/models.py +1 -1
  16. infrahub/computed_attribute/tasks.py +64 -17
  17. infrahub/computed_attribute/triggers.py +90 -0
  18. infrahub/config.py +1 -1
  19. infrahub/context.py +39 -0
  20. infrahub/core/account.py +5 -8
  21. infrahub/core/attribute.py +54 -22
  22. infrahub/core/branch/models.py +4 -4
  23. infrahub/core/branch/tasks.py +137 -129
  24. infrahub/core/changelog/__init__.py +0 -0
  25. infrahub/core/changelog/diff.py +283 -0
  26. infrahub/core/changelog/models.py +499 -0
  27. infrahub/core/constants/__init__.py +43 -2
  28. infrahub/core/constants/infrahubkind.py +1 -0
  29. infrahub/core/constants/schema.py +2 -0
  30. infrahub/core/diff/combiner.py +12 -8
  31. infrahub/core/diff/coordinator.py +49 -70
  32. infrahub/core/diff/data_check_synchronizer.py +86 -7
  33. infrahub/core/diff/enricher/aggregated.py +3 -3
  34. infrahub/core/diff/enricher/cardinality_one.py +7 -7
  35. infrahub/core/diff/enricher/hierarchy.py +22 -7
  36. infrahub/core/diff/enricher/labels.py +19 -4
  37. infrahub/core/diff/enricher/path_identifier.py +7 -9
  38. infrahub/core/diff/enricher/summary_counts.py +3 -1
  39. infrahub/core/diff/merger/merger.py +8 -4
  40. infrahub/core/diff/model/path.py +76 -35
  41. infrahub/core/diff/parent_node_adder.py +78 -0
  42. infrahub/core/diff/payload_builder.py +13 -2
  43. infrahub/core/diff/query/all_conflicts.py +6 -3
  44. infrahub/core/diff/query/artifact.py +1 -1
  45. infrahub/core/diff/query/delete_query.py +1 -1
  46. infrahub/core/diff/query/diff_get.py +3 -2
  47. infrahub/core/diff/query/diff_summary.py +1 -1
  48. infrahub/core/diff/query/field_specifiers.py +3 -1
  49. infrahub/core/diff/query/field_summary.py +3 -2
  50. infrahub/core/diff/query/filters.py +14 -3
  51. infrahub/core/diff/query/get_conflict_query.py +1 -1
  52. infrahub/core/diff/query/has_conflicts_query.py +6 -3
  53. infrahub/core/diff/query/merge.py +3 -3
  54. infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
  55. infrahub/core/diff/query/roots_metadata.py +9 -2
  56. infrahub/core/diff/query/save.py +233 -142
  57. infrahub/core/diff/query/summary_counts_enricher.py +267 -0
  58. infrahub/core/diff/query/time_range_query.py +3 -2
  59. infrahub/core/diff/query/update_conflict_query.py +1 -1
  60. infrahub/core/diff/query_parser.py +49 -24
  61. infrahub/core/diff/repository/deserializer.py +32 -28
  62. infrahub/core/diff/repository/repository.py +215 -41
  63. infrahub/core/diff/tasks.py +13 -12
  64. infrahub/core/enums.py +1 -1
  65. infrahub/core/graph/__init__.py +1 -1
  66. infrahub/core/graph/index.py +3 -0
  67. infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
  68. infrahub/core/ipam/reconciler.py +1 -1
  69. infrahub/core/ipam/tasks.py +2 -3
  70. infrahub/core/manager.py +20 -15
  71. infrahub/core/merge.py +5 -2
  72. infrahub/core/migrations/graph/__init__.py +4 -0
  73. infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
  74. infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
  75. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
  76. infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
  77. infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
  78. infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
  79. infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
  80. infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
  81. infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
  82. infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
  83. infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
  84. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
  85. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
  86. infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
  87. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
  88. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
  89. infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
  90. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
  91. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
  92. infrahub/core/migrations/graph/m020_add_generate_template_attr.py +48 -0
  93. infrahub/core/migrations/query/attribute_add.py +1 -1
  94. infrahub/core/migrations/query/attribute_rename.py +1 -1
  95. infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
  96. infrahub/core/migrations/query/node_duplicate.py +39 -19
  97. infrahub/core/migrations/query/relationship_duplicate.py +1 -1
  98. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  99. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  100. infrahub/core/migrations/schema/node_remove.py +27 -13
  101. infrahub/core/migrations/schema/tasks.py +5 -5
  102. infrahub/core/migrations/shared.py +4 -4
  103. infrahub/core/models.py +7 -8
  104. infrahub/core/node/__init__.py +170 -46
  105. infrahub/core/node/base.py +1 -1
  106. infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
  107. infrahub/core/node/delete_validator.py +4 -4
  108. infrahub/core/node/ipam.py +13 -8
  109. infrahub/core/node/permissions.py +4 -0
  110. infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
  111. infrahub/core/node/standard.py +3 -5
  112. infrahub/core/property.py +1 -1
  113. infrahub/core/protocols.py +6 -0
  114. infrahub/core/protocols_base.py +4 -2
  115. infrahub/core/query/__init__.py +2 -5
  116. infrahub/core/query/attribute.py +9 -9
  117. infrahub/core/query/branch.py +5 -5
  118. infrahub/core/query/delete.py +1 -1
  119. infrahub/core/query/diff.py +45 -7
  120. infrahub/core/query/ipam.py +4 -4
  121. infrahub/core/query/node.py +19 -14
  122. infrahub/core/query/relationship.py +213 -26
  123. infrahub/core/query/resource_manager.py +13 -11
  124. infrahub/core/query/standard_node.py +6 -6
  125. infrahub/core/query/task.py +3 -3
  126. infrahub/core/query/task_log.py +1 -1
  127. infrahub/core/query/utils.py +5 -5
  128. infrahub/core/registry.py +0 -2
  129. infrahub/core/relationship/constraints/count.py +1 -1
  130. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  131. infrahub/core/relationship/model.py +76 -38
  132. infrahub/core/schema/__init__.py +6 -4
  133. infrahub/core/schema/attribute_schema.py +8 -0
  134. infrahub/core/schema/basenode_schema.py +13 -3
  135. infrahub/core/schema/definitions/core/__init__.py +153 -0
  136. infrahub/core/schema/definitions/core/account.py +168 -0
  137. infrahub/core/schema/definitions/core/artifact.py +127 -0
  138. infrahub/core/schema/definitions/core/builtin.py +21 -0
  139. infrahub/core/schema/definitions/core/check.py +60 -0
  140. infrahub/core/schema/definitions/core/generator.py +96 -0
  141. infrahub/core/schema/definitions/core/graphql_query.py +77 -0
  142. infrahub/core/schema/definitions/core/group.py +105 -0
  143. infrahub/core/schema/definitions/core/ipam.py +252 -0
  144. infrahub/core/schema/definitions/core/lineage.py +17 -0
  145. infrahub/core/schema/definitions/core/menu.py +46 -0
  146. infrahub/core/schema/definitions/core/permission.py +161 -0
  147. infrahub/core/schema/definitions/core/profile.py +29 -0
  148. infrahub/core/schema/definitions/core/propose_change.py +88 -0
  149. infrahub/core/schema/definitions/core/propose_change_comment.py +188 -0
  150. infrahub/core/schema/definitions/core/propose_change_validator.py +326 -0
  151. infrahub/core/schema/definitions/core/repository.py +280 -0
  152. infrahub/core/schema/definitions/core/resource_pool.py +180 -0
  153. infrahub/core/schema/definitions/core/template.py +12 -0
  154. infrahub/core/schema/definitions/core/transform.py +87 -0
  155. infrahub/core/schema/definitions/core/webhook.py +108 -0
  156. infrahub/core/schema/definitions/internal.py +16 -0
  157. infrahub/core/schema/generated/genericnode_schema.py +5 -0
  158. infrahub/core/schema/generated/node_schema.py +5 -0
  159. infrahub/core/schema/generic_schema.py +5 -1
  160. infrahub/core/schema/manager.py +45 -42
  161. infrahub/core/schema/node_schema.py +4 -0
  162. infrahub/core/schema/profile_schema.py +4 -0
  163. infrahub/core/schema/relationship_schema.py +10 -2
  164. infrahub/core/schema/schema_branch.py +260 -16
  165. infrahub/core/schema/template_schema.py +36 -0
  166. infrahub/core/task/user_task.py +7 -5
  167. infrahub/core/timestamp.py +3 -3
  168. infrahub/core/utils.py +3 -2
  169. infrahub/core/validators/attribute/choices.py +1 -1
  170. infrahub/core/validators/attribute/enum.py +1 -1
  171. infrahub/core/validators/attribute/kind.py +1 -1
  172. infrahub/core/validators/attribute/length.py +1 -1
  173. infrahub/core/validators/attribute/optional.py +1 -1
  174. infrahub/core/validators/attribute/regex.py +1 -1
  175. infrahub/core/validators/attribute/unique.py +1 -1
  176. infrahub/core/validators/checks_runner.py +37 -0
  177. infrahub/core/validators/node/generate_profile.py +1 -1
  178. infrahub/core/validators/node/hierarchy.py +1 -1
  179. infrahub/core/validators/query.py +1 -1
  180. infrahub/core/validators/relationship/count.py +1 -1
  181. infrahub/core/validators/relationship/optional.py +1 -1
  182. infrahub/core/validators/relationship/peer.py +1 -1
  183. infrahub/core/validators/tasks.py +8 -6
  184. infrahub/core/validators/uniqueness/query.py +20 -17
  185. infrahub/database/__init__.py +16 -2
  186. infrahub/database/memgraph.py +1 -1
  187. infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
  188. infrahub/dependencies/builder/diff/combiner.py +1 -1
  189. infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
  190. infrahub/dependencies/builder/diff/coordinator.py +0 -2
  191. infrahub/dependencies/builder/diff/deserializer.py +4 -2
  192. infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
  193. infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
  194. infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
  195. infrahub/events/artifact_action.py +76 -0
  196. infrahub/events/branch_action.py +50 -21
  197. infrahub/events/group_action.py +117 -0
  198. infrahub/events/models.py +164 -51
  199. infrahub/events/node_action.py +70 -8
  200. infrahub/events/repository_action.py +8 -8
  201. infrahub/events/schema_action.py +21 -8
  202. infrahub/exceptions.py +9 -0
  203. infrahub/generators/models.py +1 -0
  204. infrahub/generators/tasks.py +34 -15
  205. infrahub/git/base.py +3 -5
  206. infrahub/git/constants.py +0 -1
  207. infrahub/git/integrator.py +60 -36
  208. infrahub/git/models.py +80 -1
  209. infrahub/git/repository.py +7 -8
  210. infrahub/git/tasks.py +432 -112
  211. infrahub/git_credential/helper.py +2 -3
  212. infrahub/graphql/analyzer.py +572 -11
  213. infrahub/graphql/app.py +34 -26
  214. infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
  215. infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
  216. infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
  217. infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
  218. infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
  219. infrahub/graphql/context.py +33 -0
  220. infrahub/graphql/enums.py +1 -1
  221. infrahub/graphql/initialization.py +5 -1
  222. infrahub/graphql/loaders/node.py +2 -2
  223. infrahub/graphql/manager.py +63 -63
  224. infrahub/graphql/mutations/account.py +20 -13
  225. infrahub/graphql/mutations/artifact_definition.py +16 -12
  226. infrahub/graphql/mutations/branch.py +86 -40
  227. infrahub/graphql/mutations/computed_attribute.py +24 -13
  228. infrahub/graphql/mutations/diff.py +54 -14
  229. infrahub/graphql/mutations/diff_conflict.py +14 -8
  230. infrahub/graphql/mutations/generator.py +83 -0
  231. infrahub/graphql/mutations/graphql_query.py +19 -11
  232. infrahub/graphql/mutations/ipam.py +25 -23
  233. infrahub/graphql/mutations/main.py +243 -50
  234. infrahub/graphql/mutations/menu.py +10 -10
  235. infrahub/graphql/mutations/proposed_change.py +36 -28
  236. infrahub/graphql/mutations/relationship.py +343 -104
  237. infrahub/graphql/mutations/repository.py +41 -35
  238. infrahub/graphql/mutations/resource_manager.py +26 -26
  239. infrahub/graphql/mutations/schema.py +66 -33
  240. infrahub/graphql/mutations/tasks.py +16 -10
  241. infrahub/graphql/parser.py +1 -1
  242. infrahub/graphql/permissions.py +3 -10
  243. infrahub/graphql/queries/account.py +22 -18
  244. infrahub/graphql/queries/branch.py +6 -4
  245. infrahub/graphql/queries/diff/tree.py +63 -52
  246. infrahub/graphql/queries/event.py +115 -0
  247. infrahub/graphql/queries/internal.py +3 -3
  248. infrahub/graphql/queries/ipam.py +23 -18
  249. infrahub/graphql/queries/relationship.py +11 -10
  250. infrahub/graphql/queries/resource_manager.py +43 -27
  251. infrahub/graphql/queries/search.py +9 -8
  252. infrahub/graphql/queries/status.py +12 -9
  253. infrahub/graphql/queries/task.py +11 -9
  254. infrahub/graphql/resolvers/resolver.py +69 -43
  255. infrahub/graphql/resolvers/single_relationship.py +16 -10
  256. infrahub/graphql/schema.py +4 -0
  257. infrahub/graphql/subscription/__init__.py +1 -1
  258. infrahub/graphql/subscription/events.py +1 -1
  259. infrahub/graphql/subscription/graphql_query.py +8 -8
  260. infrahub/graphql/types/branch.py +2 -2
  261. infrahub/graphql/types/common.py +6 -1
  262. infrahub/graphql/types/context.py +12 -0
  263. infrahub/graphql/types/enums.py +2 -0
  264. infrahub/graphql/types/event.py +158 -0
  265. infrahub/graphql/types/interface.py +2 -2
  266. infrahub/graphql/types/node.py +3 -3
  267. infrahub/graphql/types/permission.py +2 -2
  268. infrahub/graphql/types/relationship.py +3 -3
  269. infrahub/graphql/types/standard_node.py +9 -11
  270. infrahub/graphql/utils.py +28 -182
  271. infrahub/groups/tasks.py +2 -3
  272. infrahub/lock.py +21 -21
  273. infrahub/menu/generator.py +0 -1
  274. infrahub/menu/menu.py +116 -138
  275. infrahub/menu/models.py +4 -4
  276. infrahub/message_bus/__init__.py +11 -13
  277. infrahub/message_bus/messages/__init__.py +0 -14
  278. infrahub/message_bus/messages/check_generator_run.py +1 -3
  279. infrahub/message_bus/messages/event_branch_merge.py +3 -0
  280. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
  281. infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
  282. infrahub/message_bus/messages/send_echo_request.py +1 -1
  283. infrahub/message_bus/operations/__init__.py +4 -13
  284. infrahub/message_bus/operations/check/__init__.py +2 -2
  285. infrahub/message_bus/operations/check/generator.py +1 -3
  286. infrahub/message_bus/operations/event/branch.py +7 -3
  287. infrahub/message_bus/operations/event/schema.py +1 -1
  288. infrahub/message_bus/operations/event/worker.py +0 -3
  289. infrahub/message_bus/operations/finalize/validator.py +1 -1
  290. infrahub/message_bus/operations/git/file.py +2 -2
  291. infrahub/message_bus/operations/git/repository.py +1 -1
  292. infrahub/message_bus/operations/requests/__init__.py +0 -4
  293. infrahub/message_bus/operations/requests/generator_definition.py +2 -4
  294. infrahub/message_bus/operations/requests/proposed_change.py +37 -20
  295. infrahub/message_bus/operations/send/echo.py +1 -1
  296. infrahub/message_bus/types.py +1 -1
  297. infrahub/permissions/__init__.py +2 -1
  298. infrahub/permissions/globals.py +15 -0
  299. infrahub/permissions/types.py +26 -0
  300. infrahub/pools/prefix.py +29 -165
  301. infrahub/prefect_server/__init__.py +0 -0
  302. infrahub/prefect_server/app.py +18 -0
  303. infrahub/prefect_server/database.py +20 -0
  304. infrahub/prefect_server/events.py +28 -0
  305. infrahub/prefect_server/models.py +46 -0
  306. infrahub/proposed_change/models.py +18 -1
  307. infrahub/proposed_change/tasks.py +195 -53
  308. infrahub/pytest_plugin.py +4 -4
  309. infrahub/server.py +13 -12
  310. infrahub/services/__init__.py +148 -63
  311. infrahub/services/adapters/cache/__init__.py +11 -11
  312. infrahub/services/adapters/cache/nats.py +42 -25
  313. infrahub/services/adapters/cache/redis.py +3 -11
  314. infrahub/services/adapters/event/__init__.py +10 -18
  315. infrahub/services/adapters/http/__init__.py +0 -5
  316. infrahub/services/adapters/http/httpx.py +22 -15
  317. infrahub/services/adapters/message_bus/__init__.py +25 -8
  318. infrahub/services/adapters/message_bus/local.py +9 -7
  319. infrahub/services/adapters/message_bus/nats.py +14 -8
  320. infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
  321. infrahub/services/adapters/workflow/__init__.py +11 -8
  322. infrahub/services/adapters/workflow/local.py +27 -6
  323. infrahub/services/adapters/workflow/worker.py +23 -7
  324. infrahub/services/component.py +43 -40
  325. infrahub/services/protocols.py +7 -7
  326. infrahub/services/scheduler.py +30 -29
  327. infrahub/storage.py +2 -4
  328. infrahub/task_manager/constants.py +1 -1
  329. infrahub/task_manager/event.py +261 -0
  330. infrahub/task_manager/models.py +147 -3
  331. infrahub/task_manager/task.py +1 -1
  332. infrahub/tasks/artifact.py +19 -18
  333. infrahub/tasks/registry.py +1 -1
  334. infrahub/tasks/telemetry.py +13 -14
  335. infrahub/transformations/tasks.py +3 -5
  336. infrahub/trigger/__init__.py +0 -0
  337. infrahub/trigger/catalogue.py +16 -0
  338. infrahub/trigger/constants.py +9 -0
  339. infrahub/trigger/models.py +105 -0
  340. infrahub/trigger/tasks.py +91 -0
  341. infrahub/types.py +1 -1
  342. infrahub/utils.py +1 -1
  343. infrahub/webhook/constants.py +0 -2
  344. infrahub/webhook/models.py +161 -40
  345. infrahub/webhook/tasks.py +123 -202
  346. infrahub/webhook/triggers.py +27 -0
  347. infrahub/workers/infrahub_async.py +36 -25
  348. infrahub/workers/utils.py +63 -0
  349. infrahub/workflows/catalogue.py +71 -52
  350. infrahub/workflows/initialization.py +14 -8
  351. infrahub/workflows/models.py +28 -4
  352. infrahub/workflows/utils.py +1 -1
  353. infrahub_sdk/client.py +8 -0
  354. infrahub_sdk/ctl/branch.py +3 -2
  355. infrahub_sdk/ctl/check.py +3 -3
  356. infrahub_sdk/ctl/cli_commands.py +16 -11
  357. infrahub_sdk/ctl/exceptions.py +0 -6
  358. infrahub_sdk/ctl/exporter.py +1 -1
  359. infrahub_sdk/ctl/generator.py +5 -5
  360. infrahub_sdk/ctl/importer.py +3 -2
  361. infrahub_sdk/ctl/menu.py +1 -1
  362. infrahub_sdk/ctl/object.py +1 -1
  363. infrahub_sdk/ctl/repository.py +23 -15
  364. infrahub_sdk/ctl/schema.py +2 -2
  365. infrahub_sdk/ctl/utils.py +4 -19
  366. infrahub_sdk/ctl/validate.py +2 -1
  367. infrahub_sdk/exceptions.py +12 -0
  368. infrahub_sdk/generator.py +3 -0
  369. infrahub_sdk/node.py +4 -4
  370. infrahub_sdk/protocols.py +21 -8
  371. infrahub_sdk/schema/__init__.py +14 -2
  372. infrahub_sdk/schema/main.py +7 -0
  373. infrahub_sdk/task/__init__.py +1 -0
  374. infrahub_sdk/task/constants.py +3 -0
  375. infrahub_sdk/task/exceptions.py +25 -0
  376. infrahub_sdk/task/manager.py +545 -0
  377. infrahub_sdk/task/models.py +74 -0
  378. infrahub_sdk/timestamp.py +134 -33
  379. infrahub_sdk/utils.py +39 -1
  380. infrahub_sdk/yaml.py +2 -3
  381. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/METADATA +47 -12
  382. infrahub_server-1.2.0b1.dist-info/RECORD +725 -0
  383. infrahub_testcontainers/container.py +14 -6
  384. infrahub_testcontainers/docker-compose.test.yml +24 -5
  385. infrahub_testcontainers/haproxy.cfg +43 -0
  386. infrahub_testcontainers/helpers.py +85 -1
  387. infrahub/core/branch/constants.py +0 -2
  388. infrahub/core/schema/definitions/core.py +0 -2274
  389. infrahub/graphql/query.py +0 -52
  390. infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
  391. infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
  392. infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
  393. infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
  394. infrahub/message_bus/messages/request_repository_checks.py +0 -12
  395. infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
  396. infrahub/message_bus/operations/check/repository.py +0 -293
  397. infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
  398. infrahub/message_bus/operations/requests/repository.py +0 -133
  399. infrahub/schema/constants.py +0 -1
  400. infrahub/schema/tasks.py +0 -76
  401. infrahub/services/adapters/database/__init__.py +0 -9
  402. infrahub_sdk/ctl/_file.py +0 -13
  403. infrahub_server-1.1.6.dist-info/RECORD +0 -681
  404. /infrahub/{schema → artifacts}/__init__.py +0 -0
  405. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/LICENSE.txt +0 -0
  406. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/WHEEL +0 -0
  407. {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/entry_points.txt +0 -0
@@ -1,13 +1,18 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import asyncio
4
+ from typing import TYPE_CHECKING, Any
5
+
3
6
  from infrahub_sdk.exceptions import ModuleImportError
4
7
  from infrahub_sdk.node import InfrahubNode
5
8
  from infrahub_sdk.protocols import CoreGeneratorInstance
6
9
  from infrahub_sdk.schema.repository import InfrahubGeneratorDefinitionConfig
7
- from prefect import flow, task
10
+ from prefect import State, flow, task
8
11
  from prefect.cache_policies import NONE
12
+ from prefect.states import Completed, Failed
9
13
 
10
14
  from infrahub import lock
15
+ from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
11
16
  from infrahub.core.constants import GeneratorInstanceStatus, InfrahubKind
12
17
  from infrahub.generators.models import (
13
18
  ProposedChangeGeneratorDefinition,
@@ -16,18 +21,19 @@ from infrahub.generators.models import (
16
21
  )
17
22
  from infrahub.git.base import extract_repo_file_information
18
23
  from infrahub.git.repository import get_initialized_repo
19
- from infrahub.services import InfrahubServices, services
24
+ from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
20
25
  from infrahub.workflows.catalogue import REQUEST_GENERATOR_DEFINITION_RUN, REQUEST_GENERATOR_RUN
21
26
  from infrahub.workflows.utils import add_tags
22
27
 
28
+ if TYPE_CHECKING:
29
+ from collections.abc import Coroutine
30
+
23
31
 
24
32
  @flow(
25
33
  name="generator-run",
26
34
  flow_run_name="Run generator {model.generator_definition.definition_name}",
27
35
  )
28
- async def run_generator(model: RequestGeneratorRun) -> None:
29
- service = services.service
30
-
36
+ async def run_generator(model: RequestGeneratorRun, service: InfrahubServices) -> None:
31
37
  await add_tags(branches=[model.branch_name], nodes=[model.target_id])
32
38
 
33
39
  repository = await get_initialized_repo(
@@ -80,7 +86,7 @@ async def run_generator(model: RequestGeneratorRun) -> None:
80
86
  await generator_instance.update(do_full_update=True)
81
87
 
82
88
 
83
- @task(name="generator-define-instance", task_run_name="Define Instance", cache_policy=NONE)
89
+ @task(name="generator-define-instance", task_run_name="Define Instance", cache_policy=NONE) # type: ignore[arg-type]
84
90
  async def _define_instance(model: RequestGeneratorRun, service: InfrahubServices) -> CoreGeneratorInstance:
85
91
  if model.generator_instance:
86
92
  instance = await service.client.get(
@@ -119,9 +125,7 @@ async def _define_instance(model: RequestGeneratorRun, service: InfrahubServices
119
125
 
120
126
 
121
127
  @flow(name="generator-definition-run", flow_run_name="Run all generators")
122
- async def run_generator_definition(branch: str) -> None:
123
- service = services.service
124
-
128
+ async def run_generator_definition(branch: str, context: InfrahubContext, service: InfrahubServices) -> None:
125
129
  await add_tags(branches=[branch])
126
130
 
127
131
  generators = await service.client.filters(
@@ -146,16 +150,18 @@ async def run_generator_definition(branch: str) -> None:
146
150
 
147
151
  for generator_definition in generator_definitions:
148
152
  model = RequestGeneratorDefinitionRun(branch=branch, generator_definition=generator_definition)
149
- await service.workflow.submit_workflow(workflow=REQUEST_GENERATOR_DEFINITION_RUN, parameters={"model": model})
153
+ await service.workflow.submit_workflow(
154
+ workflow=REQUEST_GENERATOR_DEFINITION_RUN, context=context, parameters={"model": model}
155
+ )
150
156
 
151
157
 
152
158
  @flow(
153
159
  name="request-generator-definition-run",
154
160
  flow_run_name="Execute generator {model.generator_definition.definition_name}",
155
161
  )
156
- async def request_generator_definition_run(model: RequestGeneratorDefinitionRun) -> None:
157
- service = services.service
158
-
162
+ async def request_generator_definition_run(
163
+ model: RequestGeneratorDefinitionRun, context: InfrahubContext, service: InfrahubServices
164
+ ) -> State[Any]:
159
165
  await add_tags(branches=[model.branch], nodes=[model.generator_definition.definition_id])
160
166
 
161
167
  group = await service.client.get(
@@ -191,8 +197,13 @@ async def request_generator_definition_run(model: RequestGeneratorDefinitionRun)
191
197
  raise_when_missing=True,
192
198
  )
193
199
 
200
+ tasks: list[Coroutine[Any, Any, Any]] = []
194
201
  for relationship in group.members.peers:
195
202
  member = relationship.peer
203
+
204
+ if model.target_members and member.id not in model.target_members:
205
+ continue
206
+
196
207
  generator_instance = instance_by_member.get(member.id)
197
208
  request_generator_run_model = RequestGeneratorRun(
198
209
  generator_definition=model.generator_definition,
@@ -207,6 +218,14 @@ async def request_generator_definition_run(model: RequestGeneratorDefinitionRun)
207
218
  target_id=member.id,
208
219
  target_name=member.display_label,
209
220
  )
210
- await service.workflow.submit_workflow(
211
- workflow=REQUEST_GENERATOR_RUN, parameters={"model": request_generator_run_model}
221
+ tasks.append(
222
+ service.workflow.execute_workflow(
223
+ workflow=REQUEST_GENERATOR_RUN, context=context, parameters={"model": request_generator_run_model}
224
+ )
212
225
  )
226
+
227
+ try:
228
+ await asyncio.gather(*tasks)
229
+ return Completed(message=f"Successfully run {len(tasks)} generators")
230
+ except Exception as exc:
231
+ return Failed(message="One or more generators failed", error=exc)
infrahub/git/base.py CHANGED
@@ -122,7 +122,7 @@ class BranchInLocal(BaseModel):
122
122
  has_worktree: bool = False
123
123
 
124
124
 
125
- class InfrahubRepositoryBase(BaseModel, ABC): # pylint: disable=too-many-public-methods
125
+ class InfrahubRepositoryBase(BaseModel, ABC):
126
126
  """
127
127
  Local version of a Git repository organized to work with Infrahub.
128
128
  The idea is that all commits that are being tracked in the graph will be checkout out
@@ -395,9 +395,7 @@ class InfrahubRepositoryBase(BaseModel, ABC): # pylint: disable=too-many-public
395
395
  return [Worktree.init(response) for response in responses]
396
396
 
397
397
  def get_client(self) -> InfrahubClient:
398
- if self.client:
399
- return self.client
400
- return self.service.client
398
+ return self.sdk
401
399
 
402
400
  def get_location(self) -> str:
403
401
  if self.location:
@@ -702,7 +700,7 @@ class InfrahubRepositoryBase(BaseModel, ABC): # pylint: disable=too-many-public
702
700
  log.info("New commit detected", repository=self.name, branch=branch_name)
703
701
  updated_branches.append(branch_name)
704
702
 
705
- return sorted(list(new_branches)), sorted(updated_branches)
703
+ return sorted(new_branches), sorted(updated_branches)
706
704
 
707
705
  def validate_remote_branch(self, branch_name: str) -> bool:
708
706
  """Process a remote branch to validate that we can use it safely.
infrahub/git/constants.py CHANGED
@@ -1,4 +1,3 @@
1
- AUTOMATION_NAME = "Trigger-repository-commit-update-event"
2
1
  COMMITS_DIRECTORY_NAME = "commits"
3
2
  BRANCHES_DIRECTORY_NAME = "branches"
4
3
  TEMPORARY_DIRECTORY_NAME = "temp"
@@ -38,10 +38,13 @@ from pydantic import ValidationError as PydanticValidationError
38
38
  from typing_extensions import Self
39
39
 
40
40
  from infrahub.core.constants import ArtifactStatus, ContentType, InfrahubKind, RepositorySyncStatus
41
+ from infrahub.core.registry import registry
42
+ from infrahub.events.artifact_action import ArtifactEvent
43
+ from infrahub.events.models import EventMeta
41
44
  from infrahub.events.repository_action import CommitUpdatedEvent
42
45
  from infrahub.exceptions import CheckError, RepositoryInvalidFileSystemError, TransformError
43
46
  from infrahub.git.base import InfrahubRepositoryBase, extract_repo_file_information
44
- from infrahub.services import InfrahubServices
47
+ from infrahub.log import get_logger
45
48
  from infrahub.workflows.utils import add_tags
46
49
 
47
50
  if TYPE_CHECKING:
@@ -52,10 +55,9 @@ if TYPE_CHECKING:
52
55
  from infrahub_sdk.schema.repository import InfrahubRepositoryArtifactDefinitionConfig
53
56
  from infrahub_sdk.transforms import InfrahubTransform
54
57
 
58
+ from infrahub.artifacts.models import CheckArtifactCreate
55
59
  from infrahub.git.models import RequestArtifactGenerate
56
- from infrahub.message_bus import messages
57
-
58
- # pylint: disable=too-many-lines
60
+ from infrahub.services import InfrahubServices
59
61
 
60
62
 
61
63
  class ArtifactGenerateResult(BaseModel):
@@ -120,7 +122,7 @@ class TransformPythonInformation(BaseModel):
120
122
  """Timeout for the function."""
121
123
 
122
124
 
123
- class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=too-many-public-methods
125
+ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
124
126
  """
125
127
  This class provides interfaces to read and process information from .infrahub.yml files and can perform
126
128
  actions for objects defined within those files.
@@ -130,20 +132,20 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
130
132
  """
131
133
 
132
134
  @classmethod
133
- async def init(cls, commit: str | None = None, service: InfrahubServices | None = None, **kwargs: Any) -> Self:
134
- service = service or InfrahubServices()
135
+ async def init(cls, service: InfrahubServices, commit: str | None = None, **kwargs: Any) -> Self:
135
136
  self = cls(service=service, **kwargs)
137
+ log = get_logger()
136
138
  try:
137
139
  self.validate_local_directories()
138
140
  except RepositoryInvalidFileSystemError:
139
141
  await self.ensure_location_is_defined()
140
142
  await self.create_locally(infrahub_branch_name=self.infrahub_branch_name, update_commit_value=False)
141
- service.log.info(f"Initialized the local directory for {self.name} because it was missing.")
143
+ log.info(f"Initialized the local directory for {self.name} because it was missing.")
142
144
 
143
145
  if commit:
144
146
  self.get_commit_worktree(commit=commit)
145
147
 
146
- service.log.debug(
148
+ log.debug(
147
149
  f"Initiated the object on an existing directory for {self.name}",
148
150
  )
149
151
  return self
@@ -181,7 +183,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
181
183
  branch_name=infrahub_branch_name, commit=commit, config_file=config_file
182
184
  )
183
185
 
184
- await self.import_all_python_files(
186
+ await self.import_all_python_files( # type: ignore[call-overload]
185
187
  branch_name=infrahub_branch_name, commit=commit, config_file=config_file
186
188
  )
187
189
  await self.import_jinja2_transforms(
@@ -191,7 +193,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
191
193
  branch_name=infrahub_branch_name, commit=commit, config_file=config_file
192
194
  )
193
195
 
194
- except Exception as exc: # pylint: disable=broad-exception-caught
196
+ except Exception as exc:
195
197
  sync_status = RepositorySyncStatus.ERROR_IMPORT
196
198
  error = exc
197
199
 
@@ -200,9 +202,13 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
200
202
  if error:
201
203
  raise error
202
204
 
205
+ infrahub_branch = registry.get_branch_from_registry(branch=infrahub_branch_name)
203
206
  await self.service.event.send(
204
207
  CommitUpdatedEvent(
205
- branch=infrahub_branch_name, commit=commit, repository_name=self.name, repository_id=str(self.id)
208
+ commit=commit,
209
+ repository_name=self.name,
210
+ repository_id=str(self.id),
211
+ meta=EventMeta.with_dummy_context(branch=infrahub_branch),
206
212
  )
207
213
  )
208
214
 
@@ -230,11 +236,11 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
230
236
  tracker="mutation-repository-update-admin-status",
231
237
  )
232
238
 
233
- @task(name="import-jinja2-tansforms", task_run_name="Import Jinja2 transform", cache_policy=NONE)
239
+ @task(name="import-jinja2-tansforms", task_run_name="Import Jinja2 transform", cache_policy=NONE) # type: ignore[arg-type]
234
240
  async def import_jinja2_transforms(
235
241
  self,
236
242
  branch_name: str,
237
- commit: str, # pylint: disable=unused-argument
243
+ commit: str, # noqa: ARG002
238
244
  config_file: InfrahubRepositoryConfig,
239
245
  ) -> None:
240
246
  log = get_run_logger()
@@ -312,7 +318,6 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
312
318
  async def compare_jinja2_transform(
313
319
  cls, existing_transform: CoreTransformJinja2, local_transform: InfrahubRepositoryJinja2
314
320
  ) -> bool:
315
- # pylint: disable=no-member
316
321
  if (
317
322
  existing_transform.description.value != local_transform.description
318
323
  or existing_transform.template_path.value != local_transform.template_path
@@ -325,7 +330,6 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
325
330
  async def update_jinja2_transform(
326
331
  self, existing_transform: CoreTransformJinja2, local_transform: InfrahubRepositoryJinja2
327
332
  ) -> None:
328
- # pylint: disable=no-member
329
333
  if existing_transform.description.value != local_transform.description:
330
334
  existing_transform.description.value = local_transform.description
331
335
 
@@ -337,11 +341,11 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
337
341
 
338
342
  await existing_transform.save()
339
343
 
340
- @task(name="import-artifact-definitions", task_run_name="Import Artifact Definitions", cache_policy=NONE)
344
+ @task(name="import-artifact-definitions", task_run_name="Import Artifact Definitions", cache_policy=NONE) # type: ignore[arg-type]
341
345
  async def import_artifact_definitions(
342
346
  self,
343
347
  branch_name: str,
344
- commit: str, # pylint: disable=unused-argument
348
+ commit: str, # noqa: ARG002
345
349
  config_file: InfrahubRepositoryConfig,
346
350
  ) -> None:
347
351
  log = get_run_logger()
@@ -438,7 +442,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
438
442
 
439
443
  await existing_artifact_definition.save()
440
444
 
441
- @task(name="repository-get-config", task_run_name="get repository config", cache_policy=NONE)
445
+ @task(name="repository-get-config", task_run_name="get repository config", cache_policy=NONE) # type: ignore[arg-type]
442
446
  async def get_repository_config(self, branch_name: str, commit: str) -> Optional[InfrahubRepositoryConfig]:
443
447
  branch_wt = self.get_worktree(identifier=commit or branch_name)
444
448
  log = get_run_logger()
@@ -467,9 +471,8 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
467
471
  log.error(f"Unable to load the configuration file {config_file_name}, the format is not valid : {exc}")
468
472
  return None
469
473
 
470
- @task(name="import-schema-files", task_run_name="Import schema files", cache_policy=NONE)
474
+ @task(name="import-schema-files", task_run_name="Import schema files", cache_policy=NONE) # type: ignore[arg-type]
471
475
  async def import_schema_files(self, branch_name: str, commit: str, config_file: InfrahubRepositoryConfig) -> None:
472
- # pylint: disable=too-many-branches
473
476
  log = get_run_logger()
474
477
  branch_wt = self.get_worktree(identifier=commit or branch_name)
475
478
 
@@ -540,7 +543,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
540
543
  for schema_file in schemas_data:
541
544
  log.info(f"schema '{schema_file.identifier}' loaded successfully!")
542
545
 
543
- @task(name="import-graphql-queries", task_run_name="Import GraphQL Queries", cache_policy=NONE)
546
+ @task(name="import-graphql-queries", task_run_name="Import GraphQL Queries", cache_policy=NONE) # type: ignore[arg-type]
544
547
  async def import_all_graphql_query(
545
548
  self, branch_name: str, commit: str, config_file: InfrahubRepositoryConfig
546
549
  ) -> None:
@@ -598,7 +601,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
598
601
  await obj.save()
599
602
  return obj
600
603
 
601
- @task(name="import-python-check-definitions", task_run_name="Import Python Check Definitions", cache_policy=NONE)
604
+ @task(name="import-python-check-definitions", task_run_name="Import Python Check Definitions", cache_policy=NONE) # type: ignore[arg-type]
602
605
  async def import_python_check_definitions(
603
606
  self, branch_name: str, commit: str, config_file: InfrahubRepositoryConfig
604
607
  ) -> None:
@@ -669,7 +672,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
669
672
  log.info(f"CheckDefinition '{check_name!r}' not found locally, deleting")
670
673
  await check_definition_in_graph[check_name].delete()
671
674
 
672
- @task(name="import-generator-definitions", task_run_name="Import Generator Definitions", cache_policy=NONE)
675
+ @task(name="import-generator-definitions", task_run_name="Import Generator Definitions", cache_policy=NONE) # type: ignore[arg-type]
673
676
  async def import_generator_definitions(
674
677
  self, branch_name: str, commit: str, config_file: InfrahubRepositoryConfig
675
678
  ) -> None:
@@ -748,7 +751,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
748
751
  if targets:
749
752
  generator.targets = targets[0].id
750
753
 
751
- if ( # pylint: disable=too-many-boolean-expressions
754
+ if (
752
755
  existing_generator.query.id != generator.query
753
756
  or existing_generator.file_path.value != str(generator.file_path)
754
757
  or existing_generator.class_name.value != generator.class_name
@@ -759,7 +762,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
759
762
  return True
760
763
  return False
761
764
 
762
- @task(name="import-python-transforms", task_run_name="Import Python Transforms", cache_policy=NONE)
765
+ @task(name="import-python-transforms", task_run_name="Import Python Transforms", cache_policy=NONE) # type: ignore[arg-type]
763
766
  async def import_python_transforms(
764
767
  self, branch_name: str, commit: str, config_file: InfrahubRepositoryConfig
765
768
  ) -> None:
@@ -830,7 +833,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
830
833
  log.info(f"TransformPython {transform_name!r} not found locally, deleting")
831
834
  await transform_definition_in_graph[transform_name].delete()
832
835
 
833
- @task(name="check-definition-get", task_run_name="Get Check Definition", cache_policy=NONE)
836
+ @task(name="check-definition-get", task_run_name="Get Check Definition", cache_policy=NONE) # type: ignore[arg-type]
834
837
  async def get_check_definition(
835
838
  self,
836
839
  branch_name: str,
@@ -863,14 +866,14 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
863
866
  )
864
867
  )
865
868
 
866
- except Exception as exc: # pylint: disable=broad-exception-caught
869
+ except Exception as exc:
867
870
  log.error(
868
871
  f"An error occurred while processing the CheckDefinition {check_class.__name__} from {file_path} : {exc} "
869
872
  )
870
873
  raise
871
874
  return checks
872
875
 
873
- @task(name="python-transform-get", task_run_name="Get Python Transform", cache_policy=NONE)
876
+ @task(name="python-transform-get", task_run_name="Get Python Transform", cache_policy=NONE) # type: ignore[arg-type]
874
877
  async def get_python_transforms(
875
878
  self, branch_name: str, module: types.ModuleType, file_path: str, transform: InfrahubPythonTransformConfig
876
879
  ) -> list[TransformPythonInformation]:
@@ -896,7 +899,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
896
899
  )
897
900
  )
898
901
 
899
- except Exception as exc: # pylint: disable=broad-exception-caught
902
+ except Exception as exc:
900
903
  log.error(
901
904
  f"An error occurred while processing the PythonTransform {transform.name} from {file_path} : {exc} "
902
905
  )
@@ -1003,7 +1006,6 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
1003
1006
  ) -> bool:
1004
1007
  """Compare an existing Python Check Object with a Check Class
1005
1008
  and identify if we need to update the object in the database."""
1006
- # pylint: disable=too-many-boolean-expressions
1007
1009
  if (
1008
1010
  existing_check.query.id != check.query
1009
1011
  or existing_check.file_path.value != check.file_path
@@ -1072,7 +1074,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
1072
1074
  await self.import_python_transforms(branch_name=branch_name, commit=commit, config_file=config_file)
1073
1075
  await self.import_generator_definitions(branch_name=branch_name, commit=commit, config_file=config_file)
1074
1076
 
1075
- @task(name="jinja2-template-render", task_run_name="Render Jinja2 template", cache_policy=NONE)
1077
+ @task(name="jinja2-template-render", task_run_name="Render Jinja2 template", cache_policy=NONE) # type: ignore[arg-type]
1076
1078
  async def render_jinja2_template(self, commit: str, location: str, data: dict) -> str:
1077
1079
  log = get_run_logger()
1078
1080
  commit_worktree = self.get_commit_worktree(commit=commit)
@@ -1088,7 +1090,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
1088
1090
  log.error(str(exc), exc_info=True)
1089
1091
  raise TransformError(repository_name=self.name, commit=commit, location=location, message=str(exc)) from exc
1090
1092
 
1091
- @task(name="python-check-execute", task_run_name="Execute Python Check", cache_policy=NONE)
1093
+ @task(name="python-check-execute", task_run_name="Execute Python Check", cache_policy=NONE) # type: ignore[arg-type]
1092
1094
  async def execute_python_check(
1093
1095
  self,
1094
1096
  branch_name: str,
@@ -1147,9 +1149,9 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
1147
1149
  repository_name=self.name, class_name=class_name, commit=commit, location=location, message=str(exc)
1148
1150
  ) from exc
1149
1151
 
1150
- @task(name="python-transform-execute", task_run_name="Execute Python Transform", cache_policy=NONE)
1152
+ @task(name="python-transform-execute", task_run_name="Execute Python Transform", cache_policy=NONE) # type: ignore[arg-type]
1151
1153
  async def execute_python_transform(
1152
- self, branch_name: str, commit: str, location: str, client: InfrahubClient, data: Optional[dict] = None
1154
+ self, branch_name: str, commit: str, location: str, client: InfrahubClient, data: dict | None = None
1153
1155
  ) -> Any:
1154
1156
  """Execute A Python Transform stored in the repository."""
1155
1157
  log = get_run_logger()
@@ -1265,7 +1267,10 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
1265
1267
  return ArtifactGenerateResult(changed=True, checksum=checksum, storage_id=storage_id, artifact_id=artifact.id)
1266
1268
 
1267
1269
  async def render_artifact(
1268
- self, artifact: CoreArtifact, message: Union[messages.CheckArtifactCreate, RequestArtifactGenerate]
1270
+ self,
1271
+ artifact: CoreArtifact,
1272
+ artifact_created: bool,
1273
+ message: Union[CheckArtifactCreate, RequestArtifactGenerate],
1269
1274
  ) -> ArtifactGenerateResult:
1270
1275
  response = await self.sdk.query_gql_query(
1271
1276
  name=message.query,
@@ -1276,6 +1281,10 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
1276
1281
  branch_name=message.branch_name,
1277
1282
  timeout=message.timeout,
1278
1283
  )
1284
+ branch = registry.get_branch_from_registry(branch=message.branch_name)
1285
+
1286
+ previous_checksum = artifact.checksum.value
1287
+ previous_storage_id = artifact.storage_id.value
1279
1288
 
1280
1289
  if message.transform_type == InfrahubKind.TRANSFORMJINJA2:
1281
1290
  artifact_content = await self.render_jinja2_template.with_options(timeout_seconds=message.timeout)(
@@ -1314,4 +1323,19 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase): # pylint: disable=t
1314
1323
  if artifact.name.value != message.artifact_name:
1315
1324
  artifact.name.value = message.artifact_name
1316
1325
  await artifact.save()
1326
+
1327
+ event = ArtifactEvent(
1328
+ node_id=artifact.id,
1329
+ target_id=message.target_id,
1330
+ target_kind=message.target_kind,
1331
+ artifact_definition_id=message.artifact_definition,
1332
+ meta=EventMeta.from_context(context=message.context, branch=branch),
1333
+ checksum=checksum,
1334
+ checksum_previous=previous_checksum,
1335
+ storage_id=storage_id,
1336
+ storage_id_previous=previous_storage_id,
1337
+ created=artifact_created,
1338
+ )
1339
+
1340
+ await self.service.event.send(event=event)
1317
1341
  return ArtifactGenerateResult(changed=True, checksum=checksum, storage_id=storage_id, artifact_id=artifact.id)
infrahub/git/models.py CHANGED
@@ -1,6 +1,9 @@
1
1
  from typing import Optional
2
2
 
3
- from pydantic import BaseModel, Field
3
+ from pydantic import BaseModel, ConfigDict, Field
4
+
5
+ from infrahub.context import InfrahubContext
6
+ from infrahub.message_bus.types import ProposedChangeBranchDiff
4
7
 
5
8
 
6
9
  class RequestArtifactDefinitionGenerate(BaseModel):
@@ -29,11 +32,13 @@ class RequestArtifactGenerate(BaseModel):
29
32
  repository_kind: str = Field(..., description="The kind of the Repository")
30
33
  branch_name: str = Field(..., description="The branch where the check is run")
31
34
  target_id: str = Field(..., description="The ID of the target object for this artifact")
35
+ target_kind: str = Field(..., description="The kind of the target object for this artifact")
32
36
  target_name: str = Field(..., description="Name of the artifact target")
33
37
  artifact_id: Optional[str] = Field(default=None, description="The id of the artifact if it previously existed")
34
38
  query: str = Field(..., description="The name of the query to use when collecting data")
35
39
  timeout: int = Field(..., description="Timeout for requests used to generate this artifact")
36
40
  variables: dict = Field(..., description="Input variables when generating the artifact")
41
+ context: InfrahubContext = Field(..., description="The context of the task")
37
42
 
38
43
 
39
44
  class GitRepositoryAdd(BaseModel):
@@ -110,3 +115,77 @@ class GitDiffNamesOnlyResponse(BaseModel):
110
115
  files_added: list[str] = Field(..., description="Files added")
111
116
  files_changed: list[str] = Field(..., description="Files changed")
112
117
  files_removed: list[str] = Field(..., description="Files removed")
118
+
119
+
120
+ class UserCheckDefinitionData(BaseModel):
121
+ """Triggers user defined checks to run based on a Check Definition."""
122
+
123
+ model_config = ConfigDict(arbitrary_types_allowed=True)
124
+
125
+ check_definition_id: str = Field(..., description="The unique ID of the check definition")
126
+ commit: str = Field(..., description="The commit to target")
127
+ repository_id: str = Field(..., description="The unique ID of the Repository")
128
+ repository_name: str = Field(..., description="The name of the Repository")
129
+ branch_name: str = Field(..., description="The branch where the check is run")
130
+ file_path: str = Field(..., description="The path and filename of the check")
131
+ class_name: str = Field(..., description="The name of the class containing the check")
132
+ proposed_change: str = Field(..., description="The unique ID of the Proposed Change")
133
+ branch_diff: ProposedChangeBranchDiff = Field(..., description="The calculated diff between the two branches")
134
+
135
+
136
+ class UserCheckData(BaseModel):
137
+ """Runs a check as defined within a CoreCheckDefinition within a repository."""
138
+
139
+ model_config = ConfigDict(arbitrary_types_allowed=True)
140
+
141
+ validator_id: str = Field(..., description="The id of the validator associated with this check")
142
+ validator_execution_id: str = Field(..., description="The id of current execution of the associated validator")
143
+ check_execution_id: str = Field(..., description="The unique ID for the current execution of this check")
144
+ check_definition_id: str = Field(..., description="The unique ID of the check definition")
145
+ commit: str = Field(..., description="The commit to target")
146
+ repository_id: str = Field(..., description="The unique ID of the Repository")
147
+ repository_name: str = Field(..., description="The name of the Repository")
148
+ branch_name: str = Field(..., description="The branch where the check is run")
149
+ file_path: str = Field(..., description="The path and filename of the check")
150
+ class_name: str = Field(..., description="The name of the class containing the check")
151
+ proposed_change: str = Field(..., description="The unique ID of the Proposed Change")
152
+ variables: dict = Field(default_factory=dict, description="Input variables when running the check")
153
+ name: str = Field(..., description="The name of the check")
154
+ branch_diff: ProposedChangeBranchDiff = Field(..., description="The calculated diff between the two branches")
155
+ timeout: int = Field(..., description="The timeout for the check")
156
+
157
+
158
+ class TriggerRepositoryUserChecks(BaseModel):
159
+ """Sent to trigger the user defined checks on a repository."""
160
+
161
+ model_config = ConfigDict(arbitrary_types_allowed=True)
162
+
163
+ proposed_change: str = Field(..., description="The unique ID of the Proposed Change")
164
+ repository_id: str = Field(..., description="The unique ID of the Repository")
165
+ repository_name: str = Field(..., description="The name of the Repository")
166
+ source_branch: str = Field(..., description="The source branch")
167
+ source_branch_sync_with_git: bool = Field(..., description="Indicates if the source branch should sync with git")
168
+ target_branch: str = Field(..., description="The target branch")
169
+ branch_diff: ProposedChangeBranchDiff = Field(..., description="The calculated diff between the two branches")
170
+
171
+
172
+ class TriggerRepositoryInternalChecks(BaseModel):
173
+ """Sent to trigger the checks for a repository to be executed."""
174
+
175
+ proposed_change: str = Field(..., description="The unique ID of the Proposed Change")
176
+ repository: str = Field(..., description="The unique ID of the Repository")
177
+ source_branch: str = Field(..., description="The source branch")
178
+ target_branch: str = Field(..., description="The target branch")
179
+
180
+
181
+ class CheckRepositoryMergeConflicts(BaseModel):
182
+ """Runs a check to validate if there are merge conflicts for a proposed change between two branches."""
183
+
184
+ validator_id: str = Field(..., description="The id of the validator associated with this check")
185
+ validator_execution_id: str = Field(..., description="The id of current execution of the associated validator")
186
+ check_execution_id: str = Field(..., description="The unique ID for the current execution of this check")
187
+ proposed_change: str = Field(..., description="The unique ID of the Proposed Change")
188
+ repository_id: str = Field(..., description="The unique ID of the Repository")
189
+ repository_name: str = Field(..., description="The name of the Repository")
190
+ source_branch: str = Field(..., description="The source branch")
191
+ target_branch: str = Field(..., description="The target branch")
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Any, Union
3
+ from typing import TYPE_CHECKING, Any, Union
4
4
 
5
5
  from git.exc import BadName, GitCommandError
6
6
  from infrahub_sdk.exceptions import GraphQLError
@@ -10,7 +10,9 @@ from infrahub.core.constants import InfrahubKind, RepositoryInternalStatus
10
10
  from infrahub.exceptions import RepositoryError
11
11
  from infrahub.git.integrator import InfrahubRepositoryIntegrator
12
12
  from infrahub.log import get_logger
13
- from infrahub.services import InfrahubServices
13
+
14
+ if TYPE_CHECKING:
15
+ from infrahub.services import InfrahubServices
14
16
 
15
17
  log = get_logger()
16
18
 
@@ -24,9 +26,8 @@ class InfrahubRepository(InfrahubRepositoryIntegrator):
24
26
 
25
27
  @classmethod
26
28
  async def new(
27
- cls, service: InfrahubServices | None = None, update_commit_value: bool = True, **kwargs: Any
29
+ cls, service: InfrahubServices, update_commit_value: bool = True, **kwargs: Any
28
30
  ) -> InfrahubRepository:
29
- service = service or InfrahubServices()
30
31
  self = cls(service=service, **kwargs)
31
32
  await self.create_locally(
32
33
  infrahub_branch_name=self.infrahub_branch_name, update_commit_value=update_commit_value
@@ -208,9 +209,7 @@ class InfrahubReadOnlyRepository(InfrahubRepositoryIntegrator):
208
209
  ref: str | None = Field(None, description="Ref to track on the external repository")
209
210
 
210
211
  @classmethod
211
- async def new(cls, service: InfrahubServices | None = None, **kwargs: Any) -> InfrahubReadOnlyRepository:
212
- service = service or InfrahubServices()
213
-
212
+ async def new(cls, service: InfrahubServices, **kwargs: Any) -> InfrahubReadOnlyRepository:
214
213
  if "ref" not in kwargs or "infrahub_branch_name" not in kwargs:
215
214
  raise ValueError("ref and infrahub_branch_name are mandatory to initialize a new Read-Only repository")
216
215
 
@@ -219,7 +218,7 @@ class InfrahubReadOnlyRepository(InfrahubRepositoryIntegrator):
219
218
  log.info("Created new repository locally.", repository=self.name)
220
219
  return self
221
220
 
222
- def get_commit_value(self, branch_name: str, remote: bool = False) -> str:
221
+ def get_commit_value(self, branch_name: str, remote: bool = False) -> str: # noqa: ARG002
223
222
  """Always get the latest commit for this repository's ref on the remote"""
224
223
  git_repo = self.get_git_repo_main()
225
224
  git_repo.remotes.origin.fetch()