infrahub-server 1.3.5__py3-none-any.whl → 1.4.0b0__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 (158) hide show
  1. infrahub/api/internal.py +5 -0
  2. infrahub/artifacts/tasks.py +17 -22
  3. infrahub/branch/merge_mutation_checker.py +38 -0
  4. infrahub/cli/__init__.py +2 -2
  5. infrahub/cli/context.py +7 -3
  6. infrahub/cli/db.py +5 -16
  7. infrahub/cli/upgrade.py +7 -29
  8. infrahub/computed_attribute/tasks.py +36 -46
  9. infrahub/config.py +53 -2
  10. infrahub/constants/environment.py +1 -0
  11. infrahub/core/attribute.py +9 -7
  12. infrahub/core/branch/tasks.py +43 -41
  13. infrahub/core/constants/__init__.py +20 -6
  14. infrahub/core/constants/infrahubkind.py +2 -0
  15. infrahub/core/diff/coordinator.py +3 -1
  16. infrahub/core/diff/repository/repository.py +0 -8
  17. infrahub/core/diff/tasks.py +11 -8
  18. infrahub/core/graph/__init__.py +1 -1
  19. infrahub/core/graph/index.py +1 -2
  20. infrahub/core/graph/schema.py +50 -29
  21. infrahub/core/initialization.py +62 -33
  22. infrahub/core/ipam/tasks.py +4 -3
  23. infrahub/core/merge.py +8 -10
  24. infrahub/core/migrations/graph/__init__.py +2 -0
  25. infrahub/core/migrations/graph/m035_drop_attr_value_index.py +45 -0
  26. infrahub/core/migrations/query/attribute_add.py +27 -2
  27. infrahub/core/migrations/schema/tasks.py +6 -5
  28. infrahub/core/node/proposed_change.py +43 -0
  29. infrahub/core/protocols.py +12 -0
  30. infrahub/core/query/attribute.py +32 -14
  31. infrahub/core/query/diff.py +11 -0
  32. infrahub/core/query/ipam.py +13 -7
  33. infrahub/core/query/node.py +51 -10
  34. infrahub/core/query/resource_manager.py +3 -3
  35. infrahub/core/schema/basenode_schema.py +8 -0
  36. infrahub/core/schema/definitions/core/__init__.py +10 -1
  37. infrahub/core/schema/definitions/core/ipam.py +28 -2
  38. infrahub/core/schema/definitions/core/propose_change.py +15 -0
  39. infrahub/core/schema/definitions/core/webhook.py +3 -0
  40. infrahub/core/schema/generic_schema.py +10 -0
  41. infrahub/core/schema/manager.py +10 -1
  42. infrahub/core/schema/node_schema.py +22 -17
  43. infrahub/core/schema/profile_schema.py +8 -0
  44. infrahub/core/schema/schema_branch.py +9 -5
  45. infrahub/core/schema/template_schema.py +8 -0
  46. infrahub/core/validators/checks_runner.py +5 -5
  47. infrahub/core/validators/tasks.py +6 -7
  48. infrahub/core/validators/uniqueness/checker.py +4 -2
  49. infrahub/core/validators/uniqueness/model.py +1 -0
  50. infrahub/core/validators/uniqueness/query.py +57 -7
  51. infrahub/database/__init__.py +2 -1
  52. infrahub/events/__init__.py +18 -0
  53. infrahub/events/constants.py +7 -0
  54. infrahub/events/generator.py +29 -2
  55. infrahub/events/proposed_change_action.py +181 -0
  56. infrahub/generators/tasks.py +24 -20
  57. infrahub/git/base.py +4 -7
  58. infrahub/git/integrator.py +21 -12
  59. infrahub/git/repository.py +15 -30
  60. infrahub/git/tasks.py +121 -106
  61. infrahub/graphql/field_extractor.py +69 -0
  62. infrahub/graphql/manager.py +15 -11
  63. infrahub/graphql/mutations/account.py +2 -2
  64. infrahub/graphql/mutations/action.py +8 -2
  65. infrahub/graphql/mutations/artifact_definition.py +4 -1
  66. infrahub/graphql/mutations/branch.py +10 -5
  67. infrahub/graphql/mutations/graphql_query.py +2 -1
  68. infrahub/graphql/mutations/main.py +14 -8
  69. infrahub/graphql/mutations/menu.py +2 -1
  70. infrahub/graphql/mutations/proposed_change.py +225 -8
  71. infrahub/graphql/mutations/relationship.py +5 -0
  72. infrahub/graphql/mutations/repository.py +2 -1
  73. infrahub/graphql/mutations/tasks.py +7 -9
  74. infrahub/graphql/mutations/webhook.py +4 -1
  75. infrahub/graphql/parser.py +15 -6
  76. infrahub/graphql/queries/__init__.py +10 -1
  77. infrahub/graphql/queries/account.py +3 -3
  78. infrahub/graphql/queries/branch.py +2 -2
  79. infrahub/graphql/queries/diff/tree.py +3 -3
  80. infrahub/graphql/queries/event.py +13 -3
  81. infrahub/graphql/queries/ipam.py +23 -1
  82. infrahub/graphql/queries/proposed_change.py +84 -0
  83. infrahub/graphql/queries/relationship.py +2 -2
  84. infrahub/graphql/queries/resource_manager.py +3 -3
  85. infrahub/graphql/queries/search.py +3 -2
  86. infrahub/graphql/queries/status.py +3 -2
  87. infrahub/graphql/queries/task.py +2 -2
  88. infrahub/graphql/resolvers/ipam.py +440 -0
  89. infrahub/graphql/resolvers/many_relationship.py +4 -3
  90. infrahub/graphql/resolvers/resolver.py +5 -5
  91. infrahub/graphql/resolvers/single_relationship.py +3 -2
  92. infrahub/graphql/schema.py +25 -5
  93. infrahub/graphql/types/__init__.py +2 -2
  94. infrahub/graphql/types/attribute.py +3 -3
  95. infrahub/graphql/types/event.py +60 -0
  96. infrahub/groups/tasks.py +6 -6
  97. infrahub/lock.py +3 -2
  98. infrahub/menu/generator.py +8 -0
  99. infrahub/message_bus/operations/__init__.py +9 -12
  100. infrahub/message_bus/operations/git/file.py +6 -5
  101. infrahub/message_bus/operations/git/repository.py +12 -20
  102. infrahub/message_bus/operations/refresh/registry.py +15 -9
  103. infrahub/message_bus/operations/send/echo.py +7 -4
  104. infrahub/message_bus/types.py +1 -0
  105. infrahub/permissions/globals.py +1 -4
  106. infrahub/permissions/manager.py +8 -5
  107. infrahub/pools/prefix.py +7 -5
  108. infrahub/prefect_server/app.py +31 -0
  109. infrahub/prefect_server/bootstrap.py +18 -0
  110. infrahub/proposed_change/action_checker.py +206 -0
  111. infrahub/proposed_change/approval_revoker.py +40 -0
  112. infrahub/proposed_change/branch_diff.py +3 -1
  113. infrahub/proposed_change/checker.py +45 -0
  114. infrahub/proposed_change/constants.py +32 -2
  115. infrahub/proposed_change/tasks.py +182 -150
  116. infrahub/py.typed +0 -0
  117. infrahub/server.py +29 -17
  118. infrahub/services/__init__.py +13 -28
  119. infrahub/services/adapters/cache/__init__.py +4 -0
  120. infrahub/services/adapters/cache/nats.py +2 -0
  121. infrahub/services/adapters/cache/redis.py +3 -0
  122. infrahub/services/adapters/message_bus/__init__.py +0 -2
  123. infrahub/services/adapters/message_bus/local.py +1 -2
  124. infrahub/services/adapters/message_bus/nats.py +6 -8
  125. infrahub/services/adapters/message_bus/rabbitmq.py +7 -9
  126. infrahub/services/adapters/workflow/__init__.py +1 -0
  127. infrahub/services/adapters/workflow/local.py +1 -8
  128. infrahub/services/component.py +2 -1
  129. infrahub/task_manager/event.py +52 -0
  130. infrahub/task_manager/models.py +9 -0
  131. infrahub/tasks/artifact.py +6 -7
  132. infrahub/tasks/check.py +4 -7
  133. infrahub/telemetry/tasks.py +15 -18
  134. infrahub/transformations/tasks.py +10 -6
  135. infrahub/trigger/tasks.py +4 -3
  136. infrahub/types.py +4 -0
  137. infrahub/validators/events.py +7 -7
  138. infrahub/validators/tasks.py +6 -7
  139. infrahub/webhook/models.py +45 -45
  140. infrahub/webhook/tasks.py +25 -24
  141. infrahub/workers/dependencies.py +143 -0
  142. infrahub/workers/infrahub_async.py +19 -43
  143. infrahub/workflows/catalogue.py +16 -2
  144. infrahub/workflows/initialization.py +5 -4
  145. infrahub/workflows/models.py +2 -0
  146. infrahub_sdk/client.py +6 -6
  147. infrahub_sdk/ctl/repository.py +51 -0
  148. infrahub_sdk/ctl/schema.py +9 -9
  149. infrahub_sdk/protocols.py +40 -6
  150. {infrahub_server-1.3.5.dist-info → infrahub_server-1.4.0b0.dist-info}/METADATA +5 -4
  151. {infrahub_server-1.3.5.dist-info → infrahub_server-1.4.0b0.dist-info}/RECORD +158 -144
  152. infrahub_testcontainers/container.py +17 -0
  153. infrahub_testcontainers/docker-compose-cluster.test.yml +56 -1
  154. infrahub_testcontainers/docker-compose.test.yml +56 -1
  155. infrahub_testcontainers/helpers.py +4 -1
  156. {infrahub_server-1.3.5.dist-info → infrahub_server-1.4.0b0.dist-info}/LICENSE.txt +0 -0
  157. {infrahub_server-1.3.5.dist-info → infrahub_server-1.4.0b0.dist-info}/WHEEL +0 -0
  158. {infrahub_server-1.3.5.dist-info → infrahub_server-1.4.0b0.dist-info}/entry_points.txt +0 -0
@@ -43,6 +43,7 @@ from infrahub.core.diff.coordinator import DiffCoordinator
43
43
  from infrahub.core.diff.model.diff import DiffElementType, SchemaConflict
44
44
  from infrahub.core.diff.model.path import NodeDiffFieldSummary
45
45
  from infrahub.core.integrity.object_conflict.conflict_recorder import ObjectConflictValidatorRecorder
46
+ from infrahub.core.manager import NodeManager
46
47
  from infrahub.core.protocols import CoreDataCheck, CoreValidator
47
48
  from infrahub.core.protocols import CoreProposedChange as InternalCoreProposedChange
48
49
  from infrahub.core.timestamp import Timestamp
@@ -51,6 +52,7 @@ from infrahub.core.validators.determiner import ConstraintValidatorDeterminer
51
52
  from infrahub.core.validators.models.validate_migration import SchemaValidateMigrationData
52
53
  from infrahub.core.validators.tasks import schema_validate_migrations
53
54
  from infrahub.dependencies.registry import get_component_registry
55
+ from infrahub.events import EventMeta, ProposedChangeMergedEvent
54
56
  from infrahub.exceptions import MergeFailedError
55
57
  from infrahub.generators.models import ProposedChangeGeneratorDefinition
56
58
  from infrahub.git.base import extract_repo_file_information
@@ -83,8 +85,8 @@ from infrahub.proposed_change.models import (
83
85
  RunGeneratorAsCheckModel,
84
86
  )
85
87
  from infrahub.pytest_plugin import InfrahubBackendPlugin
86
- from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
87
88
  from infrahub.validators.tasks import start_validator
89
+ from infrahub.workers.dependencies import get_cache, get_client, get_database, get_event_service, get_workflow
88
90
  from infrahub.workflows.catalogue import (
89
91
  GIT_REPOSITORIES_CHECK_ARTIFACT_CREATE,
90
92
  GIT_REPOSITORY_INTERNAL_CHECKS_TRIGGER,
@@ -102,21 +104,24 @@ from infrahub.workflows.catalogue import (
102
104
  from infrahub.workflows.utils import add_tags
103
105
 
104
106
  from .branch_diff import get_diff_summary_cache, get_modified_kinds
107
+ from .checker import verify_proposed_change_is_mergeable
105
108
 
106
109
  if TYPE_CHECKING:
110
+ from infrahub_sdk.client import InfrahubClient
107
111
  from infrahub_sdk.diff import NodeDiff
108
112
 
109
113
  from infrahub.core.models import SchemaUpdateConstraintInfo
110
114
  from infrahub.core.schema.schema_branch import SchemaBranch
115
+ from infrahub.database import InfrahubDatabase
111
116
 
112
117
 
113
118
  async def _proposed_change_transition_state(
114
119
  state: ProposedChangeState,
115
- service: InfrahubServices,
120
+ database: InfrahubDatabase,
116
121
  proposed_change: InternalCoreProposedChange | None = None,
117
122
  proposed_change_id: str | None = None,
118
123
  ) -> None:
119
- async with service.database.start_session() as db:
124
+ async with database.start_session() as db:
120
125
  if proposed_change is None and proposed_change_id:
121
126
  proposed_change = await registry.manager.get_one(
122
127
  db=db, id=proposed_change_id, kind=InternalCoreProposedChange, raise_on_error=True
@@ -152,19 +157,34 @@ async def merge_proposed_change(
152
157
  proposed_change_id: str,
153
158
  proposed_change_name: str, # noqa: ARG001
154
159
  context: InfrahubContext,
155
- service: InfrahubServices,
156
160
  ) -> State:
157
161
  log = get_run_logger()
158
-
159
162
  await add_tags(nodes=[proposed_change_id])
163
+ database = await get_database()
160
164
 
161
- async with service.database.start_session() as db:
162
- proposed_change = await registry.manager.get_one(
163
- db=db, id=proposed_change_id, kind=InternalCoreProposedChange, raise_on_error=True
164
- )
165
+ proposed_change = await registry.manager.get_one(
166
+ db=database,
167
+ id=proposed_change_id,
168
+ kind=InternalCoreProposedChange,
169
+ raise_on_error=True,
170
+ prefetch_relationships=True,
171
+ )
165
172
 
173
+ async with database.start_session() as db:
166
174
  log.info("Validating if all conditions are met to merge the proposed change")
167
175
 
176
+ try:
177
+ await verify_proposed_change_is_mergeable(
178
+ proposed_change=proposed_change, # type: ignore[arg-type]
179
+ db=db,
180
+ account_session=context.account,
181
+ )
182
+ except ValueError as exc:
183
+ await _proposed_change_transition_state(
184
+ proposed_change=proposed_change, state=ProposedChangeState.OPEN, database=db
185
+ )
186
+ return Failed(message=str(exc))
187
+
168
188
  source_branch = await Branch.get_by_name(db=db, name=proposed_change.source_branch.value)
169
189
  validations = await proposed_change.validations.get_peers(db=db, peer_type=CoreValidator)
170
190
  for validation in validations.values():
@@ -175,7 +195,7 @@ async def merge_proposed_change(
175
195
  ):
176
196
  # Ignoring Data integrity checks as they are handled again later
177
197
  await _proposed_change_transition_state(
178
- proposed_change=proposed_change, state=ProposedChangeState.OPEN, service=service
198
+ proposed_change=proposed_change, state=ProposedChangeState.OPEN, database=db
179
199
  )
180
200
  return Failed(message="Unable to merge proposed change containing failing checks")
181
201
  if validator_kind == InfrahubKind.DATAVALIDATOR:
@@ -183,7 +203,7 @@ async def merge_proposed_change(
183
203
  for check in data_checks.values():
184
204
  if check.conflicts.value and not check.keep_branch.value:
185
205
  await _proposed_change_transition_state(
186
- proposed_change=proposed_change, state=ProposedChangeState.OPEN, service=service
206
+ proposed_change=proposed_change, state=ProposedChangeState.OPEN, database=db
187
207
  )
188
208
  return Failed(
189
209
  message="Data conflicts found on branch and missing decisions about what branch to keep"
@@ -191,20 +211,34 @@ async def merge_proposed_change(
191
211
 
192
212
  log.info("Proposed change is eligible to be merged")
193
213
  try:
194
- await merge_branch(
195
- branch=source_branch.name, context=context, service=service, proposed_change_id=proposed_change_id
196
- )
214
+ await merge_branch(branch=source_branch.name, context=context, proposed_change_id=proposed_change_id)
197
215
  except MergeFailedError as exc:
198
216
  await _proposed_change_transition_state(
199
- proposed_change=proposed_change, state=ProposedChangeState.OPEN, service=service
217
+ proposed_change=proposed_change, state=ProposedChangeState.OPEN, database=db
200
218
  )
201
219
  return Failed(message=f"Merge failure when trying to merge {exc.message}")
202
220
 
203
221
  log.info(f"Branch {source_branch.name} has been merged successfully")
204
222
 
205
223
  await _proposed_change_transition_state(
206
- proposed_change=proposed_change, state=ProposedChangeState.MERGED, service=service
224
+ proposed_change=proposed_change, state=ProposedChangeState.MERGED, database=db
225
+ )
226
+
227
+ current_user = await NodeManager.get_one_by_id_or_default_filter(
228
+ id=context.account.account_id, kind=InfrahubKind.GENERICACCOUNT, db=db
229
+ )
230
+ event_service = await get_event_service()
231
+ await event_service.send(
232
+ event=ProposedChangeMergedEvent(
233
+ proposed_change_id=proposed_change.id,
234
+ proposed_change_name=proposed_change.name.value,
235
+ proposed_change_state=proposed_change.state.value,
236
+ merged_by_account_id=current_user.id,
237
+ merged_by_account_name=current_user.name.value,
238
+ meta=EventMeta.from_context(context=context),
239
+ )
207
240
  )
241
+
208
242
  return Completed(message="proposed change merged successfully")
209
243
 
210
244
 
@@ -213,16 +247,18 @@ async def merge_proposed_change(
213
247
  flow_run_name="Cancel all proposed change associated with branch {branch_name}",
214
248
  description="Cancel all Proposed change associated with a branch.",
215
249
  )
216
- async def cancel_proposed_changes_branch(branch_name: str, service: InfrahubServices) -> None:
250
+ async def cancel_proposed_changes_branch(branch_name: str) -> None:
217
251
  await add_tags(branches=[branch_name])
218
252
 
219
- proposed_changed_opened = await service.client.filters(
253
+ client = get_client()
254
+
255
+ proposed_changed_opened = await client.filters(
220
256
  kind=CoreProposedChange,
221
257
  include=["id", "source_branch"],
222
258
  state__value=ProposedChangeState.OPEN.value,
223
259
  source_branch__value=branch_name,
224
260
  )
225
- proposed_changed_closed = await service.client.filters(
261
+ proposed_changed_closed = await client.filters(
226
262
  kind=CoreProposedChange,
227
263
  include=["id", "source_branch"],
228
264
  state__value=ProposedChangeState.CLOSED.value,
@@ -230,31 +266,27 @@ async def cancel_proposed_changes_branch(branch_name: str, service: InfrahubServ
230
266
  )
231
267
 
232
268
  for proposed_change in proposed_changed_opened + proposed_changed_closed:
233
- await cancel_proposed_change(proposed_change=proposed_change, service=service)
269
+ await cancel_proposed_change(proposed_change=proposed_change, client=get_client())
234
270
 
235
271
 
236
- @task(name="Cancel a propose change", description="Cancel a propose change", cache_policy=NONE) # type: ignore[arg-type]
237
- async def cancel_proposed_change(proposed_change: CoreProposedChange, service: InfrahubServices) -> None:
272
+ @task(name="Cancel a proposed change", description="Cancel a proposed change", cache_policy=NONE) # type: ignore[arg-type]
273
+ async def cancel_proposed_change(proposed_change: CoreProposedChange, client: InfrahubClient) -> None:
238
274
  await add_tags(nodes=[proposed_change.id])
239
275
  log = get_run_logger()
240
276
 
241
277
  log.info("Canceling proposed change as the source branch was deleted")
242
- proposed_change = await service.client.get(kind=CoreProposedChange, id=proposed_change.id)
278
+ proposed_change = await client.get(kind=CoreProposedChange, id=proposed_change.id)
243
279
  proposed_change.state.value = ProposedChangeState.CANCELED.value
244
280
  await proposed_change.save()
245
281
 
246
282
 
247
- @flow(
248
- name="proposed-changed-data-integrity",
249
- flow_run_name="Triggers data integrity check",
250
- )
251
- async def run_proposed_change_data_integrity_check(
252
- model: RequestProposedChangeDataIntegrity, service: InfrahubServices
253
- ) -> None:
283
+ @flow(name="proposed-changed-data-integrity", flow_run_name="Triggers data integrity check")
284
+ async def run_proposed_change_data_integrity_check(model: RequestProposedChangeDataIntegrity) -> None:
254
285
  """Triggers a data integrity validation check on the provided proposed change to start."""
255
286
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
256
287
 
257
- async with service.database.start_session() as dbs:
288
+ database = await get_database()
289
+ async with database.start_session() as dbs:
258
290
  destination_branch = await registry.get_branch(db=dbs, branch=model.destination_branch)
259
291
  source_branch = await registry.get_branch(db=dbs, branch=model.source_branch)
260
292
  component_registry = get_component_registry()
@@ -263,16 +295,13 @@ async def run_proposed_change_data_integrity_check(
263
295
  await diff_coordinator.update_branch_diff(base_branch=destination_branch, diff_branch=source_branch)
264
296
 
265
297
 
266
- @flow(
267
- name="proposed-changed-run-generator",
268
- flow_run_name="Run generators",
269
- )
270
- async def run_generators(
271
- model: RequestProposedChangeRunGenerators, context: InfrahubContext, service: InfrahubServices
272
- ) -> None:
298
+ @flow(name="proposed-changed-run-generator", flow_run_name="Run generators")
299
+ async def run_generators(model: RequestProposedChangeRunGenerators, context: InfrahubContext) -> None:
273
300
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change], db_change=True)
274
301
 
275
- generators = await service.client.filters(
302
+ client = get_client()
303
+
304
+ generators = await client.filters(
276
305
  kind=CoreGeneratorDefinition,
277
306
  prefetch_relationships=True,
278
307
  populate_store=True,
@@ -294,7 +323,7 @@ async def run_generators(
294
323
  for generator in generators
295
324
  ]
296
325
 
297
- diff_summary = await get_diff_summary_cache(pipeline_id=model.branch_diff.pipeline_id, cache=service.cache)
326
+ diff_summary = await get_diff_summary_cache(pipeline_id=model.branch_diff.pipeline_id)
298
327
  modified_kinds = get_modified_kinds(diff_summary=diff_summary, branch=model.source_branch)
299
328
 
300
329
  for generator_definition in generator_definitions:
@@ -327,7 +356,7 @@ async def run_generators(
327
356
  source_branch_sync_with_git=model.source_branch_sync_with_git,
328
357
  destination_branch=model.destination_branch,
329
358
  )
330
- await service.workflow.submit_workflow(
359
+ await get_workflow().submit_workflow(
331
360
  workflow=REQUEST_GENERATOR_DEFINITION_CHECK,
332
361
  parameters={"model": request_generator_def_check_model},
333
362
  context=context,
@@ -341,7 +370,7 @@ async def run_generators(
341
370
  destination_branch=model.destination_branch,
342
371
  branch_diff=model.branch_diff,
343
372
  )
344
- await service.workflow.submit_workflow(
373
+ await get_workflow().submit_workflow(
345
374
  workflow=REQUEST_PROPOSED_CHANGE_REFRESH_ARTIFACTS,
346
375
  parameters={"model": request_refresh_artifact_model},
347
376
  context=context,
@@ -355,20 +384,15 @@ async def run_generators(
355
384
  destination_branch=model.destination_branch,
356
385
  branch_diff=model.branch_diff,
357
386
  )
358
- await service.workflow.submit_workflow(
387
+ await get_workflow().submit_workflow(
359
388
  workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
360
389
  context=context,
361
390
  parameters={"model": model_proposed_change_repo_checks},
362
391
  )
363
392
 
364
393
 
365
- @flow(
366
- name="proposed-changed-schema-integrity",
367
- flow_run_name="Process schema integrity",
368
- )
369
- async def run_proposed_change_schema_integrity_check(
370
- model: RequestProposedChangeSchemaIntegrity, service: InfrahubServices
371
- ) -> None:
394
+ @flow(name="proposed-changed-schema-integrity", flow_run_name="Process schema integrity")
395
+ async def run_proposed_change_schema_integrity_check(model: RequestProposedChangeSchemaIntegrity) -> None:
372
396
  # For now, we retrieve the latest schema for each branch from the registry
373
397
  # In the future it would be good to generate the object SchemaUpdateValidationResult from message.branch_diff
374
398
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
@@ -381,7 +405,7 @@ async def run_proposed_change_schema_integrity_check(
381
405
  schema_diff = dest_schema.diff(other=candidate_schema)
382
406
  validation_result = dest_schema.validate_update(other=candidate_schema, diff=schema_diff)
383
407
 
384
- diff_summary = await get_diff_summary_cache(pipeline_id=model.branch_diff.pipeline_id, cache=service.cache)
408
+ diff_summary = await get_diff_summary_cache(pipeline_id=model.branch_diff.pipeline_id)
385
409
  constraints_from_data_diff = await _get_proposed_change_schema_integrity_constraints(
386
410
  schema=candidate_schema, diff_summary=diff_summary
387
411
  )
@@ -398,8 +422,7 @@ async def run_proposed_change_schema_integrity_check(
398
422
  responses = await schema_validate_migrations(
399
423
  message=SchemaValidateMigrationData(
400
424
  branch=source_branch, schema_branch=candidate_schema, constraints=list(constraints)
401
- ),
402
- service=service,
425
+ )
403
426
  )
404
427
 
405
428
  # TODO we need to report a failure if an error happened during the execution of a validator
@@ -421,7 +444,8 @@ async def run_proposed_change_schema_integrity_check(
421
444
  if not conflicts:
422
445
  return
423
446
 
424
- async with service.database.start_transaction() as db:
447
+ database = await get_database()
448
+ async with database.start_transaction() as db:
425
449
  object_conflict_validator_recorder = ObjectConflictValidatorRecorder(
426
450
  db=db,
427
451
  validator_kind=InfrahubKind.SCHEMAVALIDATOR,
@@ -458,13 +482,8 @@ async def _get_proposed_change_schema_integrity_constraints(
458
482
  return await determiner.get_constraints(node_diffs=list(node_diff_field_summary_map.values()))
459
483
 
460
484
 
461
- @flow(
462
- name="proposed-changed-repository-checks",
463
- flow_run_name="Process user defined checks",
464
- )
465
- async def repository_checks(
466
- model: RequestProposedChangeRepositoryChecks, service: InfrahubServices, context: InfrahubContext
467
- ) -> None:
485
+ @flow(name="proposed-changed-repository-checks", flow_run_name="Process user defined checks")
486
+ async def repository_checks(model: RequestProposedChangeRepositoryChecks, context: InfrahubContext) -> None:
468
487
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
469
488
 
470
489
  for repository in model.branch_diff.repositories:
@@ -479,7 +498,7 @@ async def repository_checks(
479
498
  source_branch=model.source_branch,
480
499
  target_branch=model.destination_branch,
481
500
  )
482
- await service.workflow.submit_workflow(
501
+ await get_workflow().submit_workflow(
483
502
  workflow=GIT_REPOSITORY_INTERNAL_CHECKS_TRIGGER,
484
503
  context=context,
485
504
  parameters={"model": trigger_internal_checks_model},
@@ -494,26 +513,35 @@ async def repository_checks(
494
513
  target_branch=model.destination_branch,
495
514
  branch_diff=model.branch_diff,
496
515
  )
497
- await service.workflow.submit_workflow(
516
+ await get_workflow().submit_workflow(
498
517
  workflow=GIT_REPOSITORY_USER_CHECKS_TRIGGER,
499
518
  context=context,
500
519
  parameters={"model": trigger_user_checks_model},
501
520
  )
502
521
 
503
522
 
504
- @flow(
505
- name="proposed-changed-user-tests",
506
- flow_run_name="Run unit tests in repositories",
507
- )
508
- async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests, service: InfrahubServices) -> None:
509
- log = get_run_logger()
523
+ @flow(name="proposed-changed-user-tests", flow_run_name="Run unit tests in repositories")
524
+ async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests) -> None:
510
525
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
511
- proposed_change = await service.client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
526
+
527
+ log = get_run_logger()
528
+ client = get_client()
529
+
530
+ proposed_change = await client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
512
531
 
513
532
  def _execute(
514
533
  directory: Path, repository: ProposedChangeRepository, proposed_change: InfrahubNode
515
534
  ) -> int | pytest.ExitCode:
516
- config_file = str(directory / ".infrahub.yml")
535
+ # Check for both .infrahub.yml and .infrahub.yaml, prefer .yml if both exist
536
+ config_file_yml = directory / ".infrahub.yml"
537
+ config_file_yaml = directory / ".infrahub.yaml"
538
+
539
+ if config_file_yml.is_file():
540
+ config_file = str(config_file_yml)
541
+ elif config_file_yaml.is_file():
542
+ config_file = str(config_file_yaml)
543
+ else:
544
+ config_file = str(config_file_yml) # Default to .yml for error messages
517
545
  test_directory = directory / "tests"
518
546
  log = get_logger()
519
547
 
@@ -526,6 +554,16 @@ async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests,
526
554
  )
527
555
  return 1
528
556
 
557
+ # Check if config file exists and log error if neither extension is found
558
+ if not config_file_yml.is_file() and not config_file_yaml.is_file():
559
+ log.error(
560
+ event="repository_tests_failed",
561
+ proposed_change=proposed_change,
562
+ repository=repository.repository_name,
563
+ message="Configuration file not found (.infrahub.yml or .infrahub.yaml)",
564
+ )
565
+ return 1
566
+
529
567
  # Redirect stdout/stderr to avoid showing pytest lines in the git agent
530
568
  old_out = sys.stdout
531
569
  old_err = sys.stderr
@@ -542,7 +580,7 @@ async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests,
542
580
  "-qqqq",
543
581
  "-s",
544
582
  ],
545
- plugins=[InfrahubBackendPlugin(service.client.config, repository.repository_id, proposed_change.id)],
583
+ plugins=[InfrahubBackendPlugin(client.config, repository.repository_id, proposed_change.id)],
546
584
  )
547
585
 
548
586
  # Restore stdout/stderr back to their orignal states
@@ -554,9 +592,9 @@ async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests,
554
592
  for repository in model.branch_diff.repositories:
555
593
  if model.source_branch_sync_with_git:
556
594
  repo = await get_initialized_repo(
595
+ client=client,
557
596
  repository_id=repository.repository_id,
558
597
  name=repository.repository_name,
559
- service=service,
560
598
  repository_kind=repository.kind,
561
599
  )
562
600
  commit = repo.get_commit_value(proposed_change.source_branch.value)
@@ -570,18 +608,18 @@ async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests,
570
608
  name="artifacts-generation-validation",
571
609
  flow_run_name="Validating generation of artifacts for {model.artifact_definition.definition_name}",
572
610
  )
573
- async def validate_artifacts_generation(
574
- model: RequestArtifactDefinitionCheck, service: InfrahubServices, context: InfrahubContext
575
- ) -> None:
611
+ async def validate_artifacts_generation(model: RequestArtifactDefinitionCheck, context: InfrahubContext) -> None:
576
612
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change], db_change=True)
577
613
 
578
614
  log = get_run_logger()
579
- artifact_definition = await service.client.get(
615
+ client = get_client()
616
+
617
+ artifact_definition = await client.get(
580
618
  kind=InfrahubKind.ARTIFACTDEFINITION,
581
619
  id=model.artifact_definition.definition_id,
582
620
  branch=model.source_branch,
583
621
  )
584
- proposed_change = await service.client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
622
+ proposed_change = await client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
585
623
 
586
624
  validator_name = f"Artifact Validator: {model.artifact_definition.definition_name}"
587
625
 
@@ -597,7 +635,7 @@ async def validate_artifacts_generation(
597
635
  previous_validator = existing_validator
598
636
 
599
637
  validator = await start_validator(
600
- service=service,
638
+ client=client,
601
639
  validator=previous_validator,
602
640
  validator_type=CoreArtifactValidator,
603
641
  proposed_change=model.proposed_change,
@@ -612,7 +650,7 @@ async def validate_artifacts_generation(
612
650
  group = artifact_definition.targets.peer
613
651
  await group.members.fetch()
614
652
 
615
- existing_artifacts = await service.client.filters(
653
+ existing_artifacts = await client.filters(
616
654
  kind=InfrahubKind.ARTIFACT,
617
655
  definition__ids=[model.artifact_definition.definition_id],
618
656
  include=["object"],
@@ -661,7 +699,7 @@ async def validate_artifacts_generation(
661
699
  )
662
700
 
663
701
  checks.append(
664
- service.workflow.execute_workflow(
702
+ get_workflow().execute_workflow(
665
703
  workflow=GIT_REPOSITORIES_CHECK_ARTIFACT_CREATE,
666
704
  parameters={"model": check_model},
667
705
  expected_return=ValidatorConclusion,
@@ -669,11 +707,11 @@ async def validate_artifacts_generation(
669
707
  )
670
708
 
671
709
  await run_checks_and_update_validator(
710
+ event_service=await get_event_service(),
672
711
  checks=checks,
673
712
  validator=validator,
674
713
  proposed_change_id=model.proposed_change,
675
714
  context=context,
676
- service=service,
677
715
  )
678
716
 
679
717
 
@@ -698,17 +736,16 @@ def _should_render_artifact(artifact_id: str | None, managed_branch: bool, impac
698
736
  name="run-generator-as-check",
699
737
  flow_run_name="Execute Generator {model.generator_definition.definition_name} for {model.target_name}",
700
738
  )
701
- async def run_generator_as_check(
702
- model: RunGeneratorAsCheckModel, service: InfrahubServices, context: InfrahubContext
703
- ) -> ValidatorConclusion:
739
+ async def run_generator_as_check(model: RunGeneratorAsCheckModel, context: InfrahubContext) -> ValidatorConclusion:
704
740
  await add_tags(branches=[model.branch_name], nodes=[model.proposed_change], db_change=True)
705
741
 
742
+ client = get_client()
706
743
  log = get_run_logger()
707
744
 
708
745
  repository = await get_initialized_repo(
746
+ client=client,
709
747
  repository_id=model.repository_id,
710
748
  name=model.repository_name,
711
- service=service,
712
749
  repository_kind=model.repository_kind,
713
750
  commit=model.commit,
714
751
  )
@@ -731,7 +768,7 @@ async def run_generator_as_check(
731
768
  repo_directory=repository.directory_root,
732
769
  worktree_directory=commit_worktree.directory,
733
770
  )
734
- generator_instance = await _define_instance(model=model, service=service)
771
+ generator_instance = await _define_instance(model=model, client=client)
735
772
 
736
773
  check_message = "Instance successfully generated"
737
774
  try:
@@ -743,7 +780,7 @@ async def run_generator_as_check(
743
780
 
744
781
  generator = generator_class(
745
782
  query=generator_definition.query,
746
- client=service.client,
783
+ client=client,
747
784
  branch=model.branch_name,
748
785
  params=model.variables,
749
786
  generator_instance=generator_instance.id,
@@ -768,7 +805,7 @@ async def run_generator_as_check(
768
805
  await generator_instance.update(do_full_update=True)
769
806
 
770
807
  check = None
771
- existing_check = await service.client.filters(
808
+ existing_check = await client.filters(
772
809
  kind=InfrahubKind.GENERATORCHECK, validator__ids=model.validator_id, instance__value=generator_instance.id
773
810
  )
774
811
  if existing_check:
@@ -779,7 +816,7 @@ async def run_generator_as_check(
779
816
  check.conclusion.value = conclusion.value
780
817
  await check.save()
781
818
  else:
782
- check = await service.client.create(
819
+ check = await client.create(
783
820
  kind=InfrahubKind.GENERATORCHECK,
784
821
  data={
785
822
  "name": model.target_name,
@@ -797,9 +834,9 @@ async def run_generator_as_check(
797
834
  return conclusion
798
835
 
799
836
 
800
- async def _define_instance(model: RunGeneratorAsCheckModel, service: InfrahubServices) -> InfrahubNode:
837
+ async def _define_instance(model: RunGeneratorAsCheckModel, client: InfrahubClient) -> InfrahubNode:
801
838
  if model.generator_instance:
802
- instance = await service.client.get(
839
+ instance = await client.get(
803
840
  kind=InfrahubKind.GENERATORINSTANCE, id=model.generator_instance, branch=model.branch_name
804
841
  )
805
842
  instance.status.value = GeneratorInstanceStatus.PENDING.value
@@ -809,7 +846,7 @@ async def _define_instance(model: RunGeneratorAsCheckModel, service: InfrahubSer
809
846
  async with lock.registry.get(
810
847
  f"{model.target_id}-{model.generator_definition.definition_id}", namespace="generator"
811
848
  ):
812
- instances = await service.client.filters(
849
+ instances = await client.filters(
813
850
  kind=InfrahubKind.GENERATORINSTANCE,
814
851
  definition__ids=[model.generator_definition.definition_id],
815
852
  object__ids=[model.target_id],
@@ -820,7 +857,7 @@ async def _define_instance(model: RunGeneratorAsCheckModel, service: InfrahubSer
820
857
  instance.status.value = GeneratorInstanceStatus.PENDING.value
821
858
  await instance.update(do_full_update=True)
822
859
  else:
823
- instance = await service.client.create(
860
+ instance = await client.create(
824
861
  kind=InfrahubKind.GENERATORINSTANCE,
825
862
  branch=model.branch_name,
826
863
  data={
@@ -838,13 +875,13 @@ async def _define_instance(model: RunGeneratorAsCheckModel, service: InfrahubSer
838
875
  name="request-generator-definition-check",
839
876
  flow_run_name="Validate Generator selection for {model.generator_definition.definition_name}",
840
877
  )
841
- async def request_generator_definition_check(
842
- model: RequestGeneratorDefinitionCheck, service: InfrahubServices, context: InfrahubContext
843
- ) -> None:
844
- log = get_run_logger()
878
+ async def request_generator_definition_check(model: RequestGeneratorDefinitionCheck, context: InfrahubContext) -> None:
845
879
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
846
880
 
847
- proposed_change = await service.client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
881
+ log = get_run_logger()
882
+ client = get_client()
883
+
884
+ proposed_change = await client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
848
885
 
849
886
  validator_name = f"Generator Validator: {model.generator_definition.definition_name}"
850
887
  await proposed_change.validations.fetch()
@@ -859,7 +896,7 @@ async def request_generator_definition_check(
859
896
  previous_validator = existing_validator
860
897
 
861
898
  validator = await start_validator(
862
- service=service,
899
+ client=client,
863
900
  validator=previous_validator,
864
901
  validator_type=CoreGeneratorValidator,
865
902
  proposed_change=model.proposed_change,
@@ -870,7 +907,7 @@ async def request_generator_definition_check(
870
907
  context=context,
871
908
  )
872
909
 
873
- group = await service.client.get(
910
+ group = await client.get(
874
911
  kind=InfrahubKind.GENERICGROUP,
875
912
  prefetch_relationships=True,
876
913
  populate_store=True,
@@ -879,7 +916,7 @@ async def request_generator_definition_check(
879
916
  )
880
917
  await group.members.fetch()
881
918
 
882
- existing_instances = await service.client.filters(
919
+ existing_instances = await client.filters(
883
920
  kind=InfrahubKind.GENERATORINSTANCE,
884
921
  definition__ids=[model.generator_definition.definition_id],
885
922
  include=["object"],
@@ -922,7 +959,7 @@ async def request_generator_definition_check(
922
959
  check_generator_run_models.append(check_generator_run_model)
923
960
 
924
961
  checks_coroutines = [
925
- service.workflow.execute_workflow(
962
+ get_workflow().execute_workflow(
926
963
  workflow=RUN_GENERATOR_AS_CHECK,
927
964
  parameters={"model": check_generator_run_model},
928
965
  expected_return=ValidatorConclusion,
@@ -932,10 +969,10 @@ async def request_generator_definition_check(
932
969
  ]
933
970
 
934
971
  await run_checks_and_update_validator(
972
+ event_service=await get_event_service(),
935
973
  checks=checks_coroutines,
936
974
  validator=validator,
937
975
  context=context,
938
- service=service,
939
976
  proposed_change_id=proposed_change.id,
940
977
  )
941
978
 
@@ -981,13 +1018,12 @@ class DefinitionSelect(IntFlag):
981
1018
 
982
1019
 
983
1020
  @flow(name="proposed-changed-pipeline", flow_run_name="Execute proposed changed pipeline")
984
- async def run_proposed_change_pipeline(
985
- model: RequestProposedChangePipeline, service: InfrahubServices, context: InfrahubContext
986
- ) -> None:
987
- repositories = await _get_proposed_change_repositories(model=model, service=service)
1021
+ async def run_proposed_change_pipeline(model: RequestProposedChangePipeline, context: InfrahubContext) -> None:
1022
+ client = get_client()
1023
+ repositories = await _get_proposed_change_repositories(model=model, client=client)
988
1024
 
989
1025
  if model.source_branch_sync_with_git and await _validate_repository_merge_conflicts(
990
- repositories=repositories, service=service
1026
+ repositories=repositories, client=client
991
1027
  ):
992
1028
  for repo in repositories:
993
1029
  if not repo.read_only and repo.internal_status == RepositoryInternalStatus.ACTIVE.value:
@@ -997,27 +1033,30 @@ async def run_proposed_change_pipeline(
997
1033
  source_branch=repo.source_branch,
998
1034
  target_branch=repo.destination_branch,
999
1035
  )
1000
- await service.workflow.submit_workflow(
1036
+ await get_workflow().submit_workflow(
1001
1037
  workflow=GIT_REPOSITORY_INTERNAL_CHECKS_TRIGGER,
1002
1038
  context=context,
1003
1039
  parameters={"model": trigger_repo_checks_model},
1004
1040
  )
1005
1041
  return
1006
1042
 
1007
- await _gather_repository_repository_diffs(repositories=repositories, service=service)
1043
+ await _gather_repository_repository_diffs(repositories=repositories, client=client)
1008
1044
 
1009
- async with service.database.start_session() as dbs:
1045
+ database = await get_database()
1046
+ async with database.start_session() as dbs:
1010
1047
  destination_branch = await registry.get_branch(db=dbs, branch=model.destination_branch)
1011
1048
  source_branch = await registry.get_branch(db=dbs, branch=model.source_branch)
1012
1049
  component_registry = get_component_registry()
1013
1050
  diff_coordinator = await component_registry.get_component(DiffCoordinator, db=dbs, branch=source_branch)
1014
1051
  await diff_coordinator.update_branch_diff(base_branch=destination_branch, diff_branch=source_branch)
1015
1052
 
1016
- diff_summary = await service.client.get_diff_summary(branch=model.source_branch)
1017
- await set_diff_summary_cache(pipeline_id=model.pipeline_id, diff_summary=diff_summary, cache=service.cache)
1053
+ client = get_client()
1054
+
1055
+ diff_summary = await client.get_diff_summary(branch=model.source_branch)
1056
+ await set_diff_summary_cache(pipeline_id=model.pipeline_id, diff_summary=diff_summary, cache=await get_cache())
1018
1057
  branch_diff = ProposedChangeBranchDiff(pipeline_id=model.pipeline_id, repositories=repositories)
1019
1058
  await _populate_subscribers(
1020
- branch_diff=branch_diff, diff_summary=diff_summary, service=service, branch=model.source_branch
1059
+ branch_diff=branch_diff, diff_summary=diff_summary, branch=model.source_branch, client=client
1021
1060
  )
1022
1061
 
1023
1062
  if model.check_type is CheckType.ARTIFACT:
@@ -1028,7 +1067,7 @@ async def run_proposed_change_pipeline(
1028
1067
  destination_branch=model.destination_branch,
1029
1068
  branch_diff=branch_diff,
1030
1069
  )
1031
- await service.workflow.submit_workflow(
1070
+ await get_workflow().submit_workflow(
1032
1071
  workflow=REQUEST_PROPOSED_CHANGE_REFRESH_ARTIFACTS,
1033
1072
  parameters={"model": request_refresh_artifact_model},
1034
1073
  context=context,
@@ -1044,7 +1083,7 @@ async def run_proposed_change_pipeline(
1044
1083
  refresh_artifacts=model.check_type is CheckType.ALL,
1045
1084
  do_repository_checks=model.check_type is CheckType.ALL,
1046
1085
  )
1047
- await service.workflow.submit_workflow(
1086
+ await get_workflow().submit_workflow(
1048
1087
  workflow=REQUEST_PROPOSED_CHANGE_RUN_GENERATORS,
1049
1088
  context=context,
1050
1089
  parameters={"model": model_proposed_change_run_generator},
@@ -1060,7 +1099,7 @@ async def run_proposed_change_pipeline(
1060
1099
  destination_branch=model.destination_branch,
1061
1100
  branch_diff=branch_diff,
1062
1101
  )
1063
- await service.workflow.submit_workflow(
1102
+ await get_workflow().submit_workflow(
1064
1103
  workflow=REQUEST_PROPOSED_CHANGE_DATA_INTEGRITY,
1065
1104
  context=context,
1066
1105
  parameters={"model": model_proposed_change_data_integrity},
@@ -1074,7 +1113,7 @@ async def run_proposed_change_pipeline(
1074
1113
  destination_branch=model.destination_branch,
1075
1114
  branch_diff=branch_diff,
1076
1115
  )
1077
- await service.workflow.submit_workflow(
1116
+ await get_workflow().submit_workflow(
1078
1117
  workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
1079
1118
  context=context,
1080
1119
  parameters={"model": model_proposed_change_repo_checks},
@@ -1083,7 +1122,7 @@ async def run_proposed_change_pipeline(
1083
1122
  if model.check_type in [CheckType.ALL, CheckType.SCHEMA] and has_data_changes(
1084
1123
  diff_summary=diff_summary, branch=model.source_branch
1085
1124
  ):
1086
- await service.workflow.submit_workflow(
1125
+ await get_workflow().submit_workflow(
1087
1126
  workflow=REQUEST_PROPOSED_CHANGE_SCHEMA_INTEGRITY,
1088
1127
  context=context,
1089
1128
  parameters={
@@ -1098,7 +1137,7 @@ async def run_proposed_change_pipeline(
1098
1137
  )
1099
1138
 
1100
1139
  if model.check_type in [CheckType.ALL, CheckType.TEST]:
1101
- await service.workflow.submit_workflow(
1140
+ await get_workflow().submit_workflow(
1102
1141
  workflow=REQUEST_PROPOSED_CHANGE_USER_TESTS,
1103
1142
  context=context,
1104
1143
  parameters={
@@ -1117,20 +1156,20 @@ async def run_proposed_change_pipeline(
1117
1156
  name="proposed-changed-refresh-artifacts",
1118
1157
  flow_run_name="Trigger artifacts refresh",
1119
1158
  )
1120
- async def refresh_artifacts(
1121
- model: RequestProposedChangeRefreshArtifacts, service: InfrahubServices, context: InfrahubContext
1122
- ) -> None:
1159
+ async def refresh_artifacts(model: RequestProposedChangeRefreshArtifacts, context: InfrahubContext) -> None:
1123
1160
  await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
1124
1161
  log = get_run_logger()
1125
1162
 
1126
- definition_information = await service.client.execute_graphql(
1163
+ client = get_client()
1164
+
1165
+ definition_information = await client.execute_graphql(
1127
1166
  query=GATHER_ARTIFACT_DEFINITIONS,
1128
1167
  branch_name=model.source_branch,
1129
1168
  )
1130
1169
  artifact_definitions = _parse_artifact_definitions(
1131
1170
  definitions=definition_information[InfrahubKind.ARTIFACTDEFINITION]["edges"]
1132
1171
  )
1133
- diff_summary = await get_diff_summary_cache(pipeline_id=model.branch_diff.pipeline_id, cache=service.cache)
1172
+ diff_summary = await get_diff_summary_cache(pipeline_id=model.branch_diff.pipeline_id)
1134
1173
  modified_kinds = get_modified_kinds(diff_summary=diff_summary, branch=model.source_branch)
1135
1174
 
1136
1175
  for artifact_definition in artifact_definitions:
@@ -1172,7 +1211,7 @@ async def refresh_artifacts(
1172
1211
  destination_branch=model.destination_branch,
1173
1212
  )
1174
1213
 
1175
- await service.workflow.submit_workflow(
1214
+ await get_workflow().submit_workflow(
1176
1215
  REQUEST_ARTIFACT_DEFINITION_CHECK,
1177
1216
  parameters={"model": request_artifacts_definitions_model},
1178
1217
  context=context,
@@ -1442,15 +1481,13 @@ def _parse_artifact_definitions(definitions: list[dict]) -> list[ProposedChangeA
1442
1481
 
1443
1482
 
1444
1483
  async def _get_proposed_change_repositories(
1445
- model: RequestProposedChangePipeline, service: InfrahubServices
1484
+ model: RequestProposedChangePipeline, client: InfrahubClient
1446
1485
  ) -> list[ProposedChangeRepository]:
1447
- destination_all = await service.client.execute_graphql(
1486
+ destination_all = await client.execute_graphql(
1448
1487
  query=DESTINATION_ALLREPOSITORIES, branch_name=model.destination_branch
1449
1488
  )
1450
- source_managed = await service.client.execute_graphql(query=SOURCE_REPOSITORIES, branch_name=model.source_branch)
1451
- source_readonly = await service.client.execute_graphql(
1452
- query=SOURCE_READONLY_REPOSITORIES, branch_name=model.source_branch
1453
- )
1489
+ source_managed = await client.execute_graphql(query=SOURCE_REPOSITORIES, branch_name=model.source_branch)
1490
+ source_readonly = await client.execute_graphql(query=SOURCE_READONLY_REPOSITORIES, branch_name=model.source_branch)
1454
1491
 
1455
1492
  destination_all = destination_all[InfrahubKind.GENERICREPOSITORY]["edges"]
1456
1493
  source_all = (
@@ -1460,20 +1497,20 @@ async def _get_proposed_change_repositories(
1460
1497
  return _parse_proposed_change_repositories(model=model, source=source_all, destination=destination_all)
1461
1498
 
1462
1499
 
1463
- @task(name="proposed-change-validate-repository-conflicts", task_run_name="Validate conflicts on repository") # type: ignore[arg-type]
1500
+ @task(
1501
+ name="proposed-change-validate-repository-conflicts",
1502
+ task_run_name="Validate conflicts on repository",
1503
+ cache_policy=NONE,
1504
+ ) # type: ignore[arg-type]
1464
1505
  async def _validate_repository_merge_conflicts(
1465
- repositories: list[ProposedChangeRepository], service: InfrahubServices
1506
+ repositories: list[ProposedChangeRepository], client: InfrahubClient
1466
1507
  ) -> bool:
1467
1508
  log = get_run_logger()
1509
+
1468
1510
  conflicts = False
1469
1511
  for repo in repositories:
1470
1512
  if repo.has_diff and not repo.is_staging:
1471
- git_repo = await InfrahubRepository.init(
1472
- id=repo.repository_id,
1473
- name=repo.repository_name,
1474
- client=service.client,
1475
- service=service,
1476
- )
1513
+ git_repo = await InfrahubRepository.init(id=repo.repository_id, name=repo.repository_name, client=client)
1477
1514
  async with lock.registry.get(name=repo.repository_name, namespace="repository"):
1478
1515
  repo.conflicts = await git_repo.get_conflicts(
1479
1516
  source_branch=repo.source_branch, dest_branch=repo.destination_branch
@@ -1488,17 +1525,12 @@ async def _validate_repository_merge_conflicts(
1488
1525
 
1489
1526
 
1490
1527
  async def _gather_repository_repository_diffs(
1491
- repositories: list[ProposedChangeRepository], service: InfrahubServices
1528
+ repositories: list[ProposedChangeRepository], client: InfrahubClient
1492
1529
  ) -> None:
1493
1530
  for repo in repositories:
1494
1531
  if repo.has_diff and repo.source_commit and repo.destination_commit:
1495
1532
  # TODO we need to find a way to return all files in the repo if the repo is new
1496
- git_repo = await InfrahubRepository.init(
1497
- id=repo.repository_id,
1498
- name=repo.repository_name,
1499
- client=service.client,
1500
- service=service,
1501
- )
1533
+ git_repo = await InfrahubRepository.init(id=repo.repository_id, name=repo.repository_name, client=client)
1502
1534
 
1503
1535
  files_changed: list[str] = []
1504
1536
  files_added: list[str] = []
@@ -1517,9 +1549,9 @@ async def _gather_repository_repository_diffs(
1517
1549
 
1518
1550
 
1519
1551
  async def _populate_subscribers(
1520
- branch_diff: ProposedChangeBranchDiff, diff_summary: list[NodeDiff], service: InfrahubServices, branch: str
1552
+ branch_diff: ProposedChangeBranchDiff, diff_summary: list[NodeDiff], branch: str, client: InfrahubClient
1521
1553
  ) -> None:
1522
- result = await service.client.execute_graphql(
1554
+ result = await client.execute_graphql(
1523
1555
  query=GATHER_GRAPHQL_QUERY_SUBSCRIBERS,
1524
1556
  branch_name=branch,
1525
1557
  variables={"members": get_modified_node_ids(diff_summary=diff_summary, branch=branch)},