infrahub-server 1.4.9__py3-none-any.whl → 1.5.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 (103) hide show
  1. infrahub/actions/tasks.py +200 -16
  2. infrahub/api/artifact.py +3 -0
  3. infrahub/api/query.py +2 -0
  4. infrahub/api/schema.py +3 -0
  5. infrahub/auth.py +5 -5
  6. infrahub/cli/db.py +2 -2
  7. infrahub/config.py +7 -2
  8. infrahub/core/attribute.py +22 -19
  9. infrahub/core/branch/models.py +2 -2
  10. infrahub/core/branch/needs_rebase_status.py +11 -0
  11. infrahub/core/branch/tasks.py +2 -2
  12. infrahub/core/constants/__init__.py +1 -0
  13. infrahub/core/convert_object_type/object_conversion.py +201 -0
  14. infrahub/core/convert_object_type/repository_conversion.py +89 -0
  15. infrahub/core/convert_object_type/schema_mapping.py +27 -3
  16. infrahub/core/diff/query/artifact.py +12 -9
  17. infrahub/core/graph/__init__.py +1 -1
  18. infrahub/core/initialization.py +2 -2
  19. infrahub/core/manager.py +3 -81
  20. infrahub/core/migrations/graph/__init__.py +2 -0
  21. infrahub/core/migrations/graph/m040_profile_attrs_in_db.py +166 -0
  22. infrahub/core/node/__init__.py +26 -3
  23. infrahub/core/node/create.py +79 -38
  24. infrahub/core/node/lock_utils.py +98 -0
  25. infrahub/core/property.py +11 -0
  26. infrahub/core/protocols.py +1 -0
  27. infrahub/core/query/attribute.py +27 -15
  28. infrahub/core/query/node.py +47 -184
  29. infrahub/core/query/relationship.py +43 -26
  30. infrahub/core/query/subquery.py +0 -8
  31. infrahub/core/relationship/model.py +59 -19
  32. infrahub/core/schema/attribute_schema.py +0 -2
  33. infrahub/core/schema/definitions/core/repository.py +7 -0
  34. infrahub/core/schema/relationship_schema.py +0 -1
  35. infrahub/core/schema/schema_branch.py +3 -2
  36. infrahub/generators/models.py +31 -12
  37. infrahub/generators/tasks.py +3 -1
  38. infrahub/git/base.py +38 -1
  39. infrahub/graphql/api/dependencies.py +2 -4
  40. infrahub/graphql/api/endpoints.py +2 -2
  41. infrahub/graphql/app.py +2 -4
  42. infrahub/graphql/initialization.py +2 -3
  43. infrahub/graphql/manager.py +212 -137
  44. infrahub/graphql/middleware.py +12 -0
  45. infrahub/graphql/mutations/branch.py +11 -0
  46. infrahub/graphql/mutations/computed_attribute.py +110 -3
  47. infrahub/graphql/mutations/convert_object_type.py +34 -13
  48. infrahub/graphql/mutations/ipam.py +21 -8
  49. infrahub/graphql/mutations/main.py +37 -153
  50. infrahub/graphql/mutations/profile.py +195 -0
  51. infrahub/graphql/mutations/proposed_change.py +2 -1
  52. infrahub/graphql/mutations/repository.py +22 -83
  53. infrahub/graphql/mutations/webhook.py +1 -1
  54. infrahub/graphql/registry.py +173 -0
  55. infrahub/graphql/schema.py +4 -1
  56. infrahub/lock.py +52 -26
  57. infrahub/locks/__init__.py +0 -0
  58. infrahub/locks/tasks.py +37 -0
  59. infrahub/patch/plan_writer.py +2 -2
  60. infrahub/profiles/__init__.py +0 -0
  61. infrahub/profiles/node_applier.py +101 -0
  62. infrahub/profiles/queries/__init__.py +0 -0
  63. infrahub/profiles/queries/get_profile_data.py +99 -0
  64. infrahub/profiles/tasks.py +63 -0
  65. infrahub/repositories/__init__.py +0 -0
  66. infrahub/repositories/create_repository.py +113 -0
  67. infrahub/tasks/registry.py +6 -4
  68. infrahub/webhook/models.py +1 -1
  69. infrahub/workflows/catalogue.py +38 -3
  70. infrahub/workflows/models.py +17 -2
  71. infrahub_sdk/branch.py +5 -8
  72. infrahub_sdk/client.py +364 -84
  73. infrahub_sdk/convert_object_type.py +61 -0
  74. infrahub_sdk/ctl/check.py +2 -3
  75. infrahub_sdk/ctl/cli_commands.py +16 -12
  76. infrahub_sdk/ctl/config.py +8 -2
  77. infrahub_sdk/ctl/generator.py +2 -3
  78. infrahub_sdk/ctl/repository.py +39 -1
  79. infrahub_sdk/ctl/schema.py +12 -1
  80. infrahub_sdk/ctl/utils.py +4 -0
  81. infrahub_sdk/ctl/validate.py +5 -3
  82. infrahub_sdk/diff.py +4 -5
  83. infrahub_sdk/exceptions.py +2 -0
  84. infrahub_sdk/graphql.py +7 -2
  85. infrahub_sdk/node/attribute.py +2 -0
  86. infrahub_sdk/node/node.py +28 -20
  87. infrahub_sdk/playback.py +1 -2
  88. infrahub_sdk/protocols.py +40 -6
  89. infrahub_sdk/pytest_plugin/plugin.py +7 -4
  90. infrahub_sdk/pytest_plugin/utils.py +40 -0
  91. infrahub_sdk/repository.py +1 -2
  92. infrahub_sdk/schema/main.py +1 -0
  93. infrahub_sdk/spec/object.py +43 -4
  94. infrahub_sdk/spec/range_expansion.py +118 -0
  95. infrahub_sdk/timestamp.py +18 -6
  96. {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/METADATA +20 -24
  97. {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/RECORD +102 -84
  98. infrahub_testcontainers/models.py +2 -2
  99. infrahub_testcontainers/performance_test.py +4 -4
  100. infrahub/core/convert_object_type/conversion.py +0 -134
  101. {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/LICENSE.txt +0 -0
  102. {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/WHEEL +0 -0
  103. {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/entry_points.txt +0 -0
@@ -381,14 +381,33 @@ class Relationship(FlagPropertyMixin, NodePropertyMixin):
381
381
 
382
382
  node = await self.get_node(db=db)
383
383
 
384
+ flag_properties_to_update = {}
385
+ for prop_name in self._flag_properties:
386
+ if prop_name not in properties_to_update:
387
+ continue
388
+ value = getattr(self, prop_name)
389
+ if value is not None:
390
+ flag_properties_to_update[prop_name] = value
391
+
392
+ node_properties_to_update = {}
393
+ for prop_name in self._node_properties:
394
+ if prop_name not in properties_to_update:
395
+ continue
396
+ if value := getattr(self, f"{prop_name}_id"):
397
+ node_properties_to_update[prop_name] = value
398
+
399
+ if not flag_properties_to_update and not node_properties_to_update:
400
+ return
401
+
384
402
  query = await RelationshipUpdatePropertyQuery.init(
385
403
  db=db,
404
+ branch=branch,
386
405
  source=node,
387
406
  rel=self,
388
- properties_to_update=properties_to_update,
389
- data=data,
390
- branch=branch,
391
407
  at=update_at,
408
+ flag_properties_to_update=flag_properties_to_update,
409
+ node_properties_to_update=node_properties_to_update,
410
+ rel_node_id=data.rel_node_id,
392
411
  )
393
412
  await query.execute(db=db)
394
413
 
@@ -570,7 +589,9 @@ class RelationshipValidatorList:
570
589
  ValidationError: If the number of relationships is not within the min and max count.
571
590
  """
572
591
 
573
- def __init__(self, *relationships: Relationship, name: str, min_count: int = 0, max_count: int = 0) -> None:
592
+ def __init__(
593
+ self, *relationships: Relationship, name: str, min_count: int | None = 0, max_count: int | None = 0
594
+ ) -> None:
574
595
  """Initialize list for Relationship but with validation against min/max count.
575
596
 
576
597
  Args:
@@ -580,8 +601,14 @@ class RelationshipValidatorList:
580
601
  Raises:
581
602
  ValidationError: The number of relationships is not within the min and max count.
582
603
  """
583
- if max_count < min_count:
604
+ if max_count is not None and min_count is not None and max_count < min_count:
584
605
  raise ValidationError({"msg": "max_count must be greater than min_count"})
606
+
607
+ if max_count is None:
608
+ max_count = 0
609
+ if min_count is None:
610
+ min_count = 0
611
+
585
612
  self.min_count: int = min_count
586
613
  self.max_count: int = max_count
587
614
  self.name = name
@@ -726,15 +753,22 @@ class RelationshipManager:
726
753
  # TODO Ideally this information should come from the Schema
727
754
  self.rel_class = Relationship
728
755
 
729
- self._relationships: RelationshipValidatorList = RelationshipValidatorList(
730
- name=self.schema.name,
731
- min_count=0 if self.schema.optional else self.schema.min_count,
732
- max_count=self.schema.max_count,
733
- )
756
+ self._relationships: RelationshipValidatorList = self._get_init_relationships()
734
757
  self._relationship_id_details: RelationshipUpdateDetails | None = None
735
758
  self.has_fetched_relationships: bool = False
736
759
  self.lock = asyncio.Lock()
737
760
 
761
+ def _get_init_relationships(self) -> RelationshipValidatorList:
762
+ min_count = self.schema.min_count
763
+ max_count: int | None = self.schema.max_count if self.schema.max_count > 0 else None
764
+ if self.schema.optional:
765
+ min_count = 0
766
+ return RelationshipValidatorList(
767
+ name=self.schema.name,
768
+ min_count=min_count,
769
+ max_count=max_count,
770
+ )
771
+
738
772
  @classmethod
739
773
  async def init(
740
774
  cls,
@@ -909,6 +943,19 @@ class RelationshipManager:
909
943
  return registry.get_global_branch()
910
944
  return self.branch
911
945
 
946
+ async def get_db_peers(
947
+ self, db: InfrahubDatabase, at: Timestamp | None = None, branch_agnostic: bool = False
948
+ ) -> list[RelationshipPeerData]:
949
+ query = await RelationshipGetPeerQuery.init(
950
+ db=db,
951
+ source=self.node,
952
+ at=at or self.at,
953
+ rel=self.rel_class(schema=self.schema, branch=self.branch, node=self.node),
954
+ branch_agnostic=branch_agnostic,
955
+ )
956
+ await query.execute(db=db)
957
+ return list(query.get_peers())
958
+
912
959
  async def fetch_relationship_ids(
913
960
  self,
914
961
  db: InfrahubDatabase,
@@ -926,16 +973,9 @@ class RelationshipManager:
926
973
 
927
974
  current_peer_ids = [rel.get_peer_id() for rel in self._relationships]
928
975
 
929
- query = await RelationshipGetPeerQuery.init(
930
- db=db,
931
- source=self.node,
932
- at=at or self.at,
933
- rel=self.rel_class(schema=self.schema, branch=self.branch, node=self.node),
934
- branch_agnostic=branch_agnostic,
935
- )
936
- await query.execute(db=db)
976
+ peers = await self.get_db_peers(db=db, at=at, branch_agnostic=branch_agnostic)
937
977
 
938
- peers_database: dict = {str(peer.peer_id): peer for peer in query.get_peers()}
978
+ peers_database: dict = {str(peer.peer_id): peer for peer in peers}
939
979
  peer_ids = list(peers_database.keys())
940
980
 
941
981
  # Calculate which peer should be added or removed
@@ -202,7 +202,6 @@ class AttributeSchema(GeneratedAttributeSchema):
202
202
  param_prefix: str | None = None,
203
203
  db: InfrahubDatabase | None = None,
204
204
  partial_match: bool = False,
205
- support_profiles: bool = False,
206
205
  ) -> tuple[list[QueryElement], dict[str, Any], list[str]]:
207
206
  if self.enum:
208
207
  filter_value = self.convert_enum_to_value(filter_value)
@@ -217,7 +216,6 @@ class AttributeSchema(GeneratedAttributeSchema):
217
216
  param_prefix=param_prefix,
218
217
  db=db,
219
218
  partial_match=partial_match,
220
- support_profiles=support_profiles,
221
219
  )
222
220
 
223
221
 
@@ -282,5 +282,12 @@ core_generic_repository = GenericSchema(
282
282
  cardinality=Cardinality.MANY,
283
283
  order_weight=12000,
284
284
  ),
285
+ Rel(
286
+ name="groups_objects",
287
+ peer=InfrahubKind.REPOSITORYGROUP,
288
+ optional=True,
289
+ cardinality=Cardinality.MANY,
290
+ order_weight=13000,
291
+ ),
285
292
  ],
286
293
  )
@@ -91,7 +91,6 @@ class RelationshipSchema(GeneratedRelationshipSchema):
91
91
  include_match: bool = True,
92
92
  param_prefix: str | None = None,
93
93
  partial_match: bool = False,
94
- support_profiles: bool = False, # noqa: ARG002
95
94
  ) -> tuple[list[QueryElement], dict[str, Any], list[str]]:
96
95
  """Generate Query String Snippet to filter the right node."""
97
96
 
@@ -18,6 +18,7 @@ from infrahub.computed_attribute.constants import VALID_KINDS as VALID_COMPUTED_
18
18
  from infrahub.core.constants import (
19
19
  OBJECT_TEMPLATE_NAME_ATTR,
20
20
  OBJECT_TEMPLATE_RELATIONSHIP_NAME,
21
+ PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
21
22
  RESERVED_ATTR_GEN_NAMES,
22
23
  RESERVED_ATTR_REL_NAMES,
23
24
  RESTRICTED_NAMESPACES,
@@ -1934,7 +1935,7 @@ class SchemaBranch:
1934
1935
 
1935
1936
  profiles_rel_settings: dict[str, Any] = {
1936
1937
  "name": "profiles",
1937
- "identifier": "node__profile",
1938
+ "identifier": PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
1938
1939
  "peer": InfrahubKind.PROFILE,
1939
1940
  "kind": RelationshipKind.PROFILE,
1940
1941
  "cardinality": RelationshipCardinality.MANY,
@@ -1997,7 +1998,7 @@ class SchemaBranch:
1997
1998
  relationships=[
1998
1999
  RelationshipSchema(
1999
2000
  name="related_nodes",
2000
- identifier="node__profile",
2001
+ identifier=PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
2001
2002
  peer=node.kind,
2002
2003
  kind=RelationshipKind.PROFILE,
2003
2004
  cardinality=RelationshipCardinality.MANY,
@@ -6,7 +6,7 @@ from pydantic import BaseModel, ConfigDict, Field
6
6
  class RequestGeneratorRun(BaseModel):
7
7
  """Runs a generator."""
8
8
 
9
- generator_definition: ProposedChangeGeneratorDefinition = Field(..., description="The Generator definition")
9
+ generator_definition: GeneratorDefinitionModel = Field(..., description="The Generator definition")
10
10
  generator_instance: str | None = Field(
11
11
  default=None, description="The id of the generator instance if it previously existed"
12
12
  )
@@ -31,14 +31,33 @@ class RequestGeneratorDefinitionRun(BaseModel):
31
31
  target_members: list[str] = Field(default_factory=list, description="List of targets to run the generator for")
32
32
 
33
33
 
34
- class ProposedChangeGeneratorDefinition(BaseModel):
35
- definition_id: str
36
- definition_name: str
37
- query_name: str
38
- convert_query_response: bool
39
- query_models: list[str]
40
- repository_id: str
41
- class_name: str
42
- file_path: str
43
- parameters: dict
44
- group_id: str
34
+ class GeneratorDefinitionModel(BaseModel):
35
+ definition_id: str = Field(..., description="The id of the generator definition.")
36
+ definition_name: str = Field(..., description="The name of the generator definition.")
37
+ query_name: str = Field(..., description="The name of the query to use when collecting data.")
38
+ convert_query_response: bool = Field(
39
+ ...,
40
+ description="Decide if the generator should convert the result of the GraphQL query to SDK InfrahubNode objects.",
41
+ )
42
+ class_name: str = Field(..., description="The name of the generator class to run.")
43
+ file_path: str = Field(..., description="The file path of the generator in the repository.")
44
+ group_id: str = Field(..., description="The group to target when running this generator")
45
+ parameters: dict = Field(..., description="The input parameters required to run this check")
46
+
47
+ @classmethod
48
+ def from_pc_generator_definition(cls, model: ProposedChangeGeneratorDefinition) -> GeneratorDefinitionModel:
49
+ return GeneratorDefinitionModel(
50
+ definition_id=model.definition_id,
51
+ definition_name=model.definition_name,
52
+ query_name=model.query_name,
53
+ convert_query_response=model.convert_query_response,
54
+ class_name=model.class_name,
55
+ file_path=model.file_path,
56
+ group_id=model.group_id,
57
+ parameters=model.parameters,
58
+ )
59
+
60
+
61
+ class ProposedChangeGeneratorDefinition(GeneratorDefinitionModel):
62
+ query_models: list[str] = Field(..., description="The models to use when collecting data.")
63
+ repository_id: str = Field(..., description="The id of the repository.")
@@ -15,6 +15,7 @@ from infrahub import lock
15
15
  from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
16
16
  from infrahub.core.constants import GeneratorInstanceStatus, InfrahubKind
17
17
  from infrahub.generators.models import (
18
+ GeneratorDefinitionModel,
18
19
  ProposedChangeGeneratorDefinition,
19
20
  RequestGeneratorDefinitionRun,
20
21
  RequestGeneratorRun,
@@ -52,6 +53,7 @@ async def run_generator(model: RequestGeneratorRun) -> None:
52
53
  name=model.generator_definition.definition_name,
53
54
  class_name=model.generator_definition.class_name,
54
55
  file_path=model.generator_definition.file_path,
56
+ parameters=model.generator_definition.parameters,
55
57
  query=model.generator_definition.query_name,
56
58
  targets=model.generator_definition.group_id,
57
59
  convert_query_response=model.generator_definition.convert_query_response,
@@ -213,7 +215,7 @@ async def request_generator_definition_run(
213
215
 
214
216
  generator_instance = instance_by_member.get(member.id)
215
217
  request_generator_run_model = RequestGeneratorRun(
216
- generator_definition=model.generator_definition,
218
+ generator_definition=GeneratorDefinitionModel.from_pc_generator_definition(model.generator_definition),
217
219
  commit=repository.commit.value,
218
220
  generator_instance=generator_instance,
219
221
  repository_id=repository.id,
infrahub/git/base.py CHANGED
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, NoReturn
7
7
  from uuid import UUID # noqa: TC003
8
8
 
9
9
  import git
10
- from git import Blob, Repo
10
+ from git import BadName, Blob, Repo
11
11
  from git.exc import GitCommandError, InvalidGitRepositoryError
12
12
  from git.refs.remote import RemoteReference
13
13
  from infrahub_sdk import InfrahubClient # noqa: TC002
@@ -67,6 +67,15 @@ class RepoFileInformation(BaseModel):
67
67
  """Extension of the file Example: py """
68
68
 
69
69
 
70
+ class RepoChangedFiles(BaseModel):
71
+ added: list[str] = Field(default_factory=list)
72
+ copied: list[tuple[str, str]] = Field(default_factory=list)
73
+ deleted: list[str] = Field(default_factory=list)
74
+ renamed: list[tuple[str, str]] = Field(default_factory=list)
75
+ modified: list[str] = Field(default_factory=list)
76
+ type_changed: list[tuple[str, str]] = Field(default_factory=list)
77
+
78
+
70
79
  def extract_repo_file_information(
71
80
  full_filename: Path, repo_directory: Path, worktree_directory: Path | None = None
72
81
  ) -> RepoFileInformation:
@@ -970,3 +979,31 @@ class InfrahubRepositoryBase(BaseModel, ABC):
970
979
  if branch_name == self.default_branch and branch_name != registry.default_branch:
971
980
  return registry.default_branch
972
981
  return branch_name
982
+
983
+ def get_changed_files(self, first_commit: str, second_commit: str | None = None) -> RepoChangedFiles:
984
+ """Return the changes between two commits in this repo."""
985
+ changes = RepoChangedFiles()
986
+ repo = self.get_git_repo_main()
987
+
988
+ try:
989
+ commit_a = repo.commit(first_commit)
990
+ commit_b = repo.commit(second_commit) if second_commit else repo.head.commit
991
+ except BadName as exc:
992
+ raise CommitNotFoundError(identifier=str(self.id), commit=exc.args[0]) from exc
993
+
994
+ for diff in commit_a.diff(commit_b):
995
+ match diff.change_type:
996
+ case "A":
997
+ changes.added.append(diff.b_path)
998
+ case "C":
999
+ changes.copied.append((diff.a_path, diff.b_path))
1000
+ case "D":
1001
+ changes.deleted.append(diff.a_path)
1002
+ case "R":
1003
+ changes.renamed.append((diff.a_path, diff.b_path))
1004
+ case "M":
1005
+ changes.modified.append(diff.b_path)
1006
+ case "T":
1007
+ changes.type_changed.append((diff.a_path, diff.b_path))
1008
+
1009
+ return changes
@@ -1,5 +1,3 @@
1
- from typing import Any
2
-
3
1
  from infrahub import config
4
2
 
5
3
  from ..app import InfrahubGraphQLApp
@@ -36,5 +34,5 @@ def build_graphql_query_permission_checker() -> GraphQLQueryPermissionChecker:
36
34
  )
37
35
 
38
36
 
39
- def build_graphql_app(**kwargs: Any) -> InfrahubGraphQLApp:
40
- return InfrahubGraphQLApp(build_graphql_query_permission_checker(), **kwargs)
37
+ def build_graphql_app() -> InfrahubGraphQLApp:
38
+ return InfrahubGraphQLApp(build_graphql_query_permission_checker())
@@ -9,7 +9,7 @@ from starlette.routing import Route, WebSocketRoute
9
9
 
10
10
  from infrahub.api.dependencies import get_branch_dep, get_current_user
11
11
  from infrahub.core import registry
12
- from infrahub.graphql.manager import GraphQLSchemaManager
12
+ from infrahub.graphql.registry import registry as graphql_registry
13
13
 
14
14
  from .dependencies import build_graphql_app
15
15
 
@@ -32,6 +32,6 @@ async def get_graphql_schema(
32
32
  branch: Branch = Depends(get_branch_dep), _: AccountSession = Depends(get_current_user)
33
33
  ) -> PlainTextResponse:
34
34
  schema_branch = registry.schema.get_schema_branch(name=branch.name)
35
- gqlm = GraphQLSchemaManager.get_manager_for_branch(branch=branch, schema_branch=schema_branch)
35
+ gqlm = graphql_registry.get_manager_for_branch(branch=branch, schema_branch=schema_branch)
36
36
  graphql_schema = gqlm.get_graphql_schema()
37
37
  return PlainTextResponse(content=print_schema(graphql_schema))
infrahub/graphql/app.py CHANGED
@@ -23,7 +23,6 @@ from graphql import (
23
23
  ExecutionResult,
24
24
  GraphQLError,
25
25
  GraphQLFormattedError,
26
- Middleware,
27
26
  OperationType,
28
27
  graphql,
29
28
  parse,
@@ -59,6 +58,7 @@ from .metrics import (
59
58
  GRAPHQL_RESPONSE_SIZE_METRICS,
60
59
  GRAPHQL_TOP_LEVEL_QUERIES_METRICS,
61
60
  )
61
+ from .middleware import raise_on_mutation_on_branch_needing_rebase
62
62
 
63
63
  if TYPE_CHECKING:
64
64
  import graphene
@@ -99,7 +99,6 @@ class InfrahubGraphQLApp:
99
99
  *,
100
100
  on_get: Callable[[Request], Response | Awaitable[Response]] | None = None,
101
101
  root_value: RootValue = None,
102
- middleware: Middleware | None = None,
103
102
  error_formatter: Callable[[GraphQLError], GraphQLFormattedError] = format_error,
104
103
  execution_context_class: type[ExecutionContext] | None = None,
105
104
  ) -> None:
@@ -107,7 +106,6 @@ class InfrahubGraphQLApp:
107
106
  self.on_get = on_get
108
107
  self.root_value = root_value
109
108
  self.error_formatter = error_formatter
110
- self.middleware = middleware
111
109
  self.execution_context_class = execution_context_class
112
110
  self.logger = get_logger(name="infrahub.graphql")
113
111
  self.permission_checker = permission_checker
@@ -259,7 +257,7 @@ class InfrahubGraphQLApp:
259
257
  source=query,
260
258
  context_value=graphql_params.context,
261
259
  root_value=self.root_value,
262
- middleware=self.middleware,
260
+ middleware=[raise_on_mutation_on_branch_needing_rebase],
263
261
  variable_values=variable_values,
264
262
  operation_name=operation_name,
265
263
  execution_context_class=self.execution_context_class,
@@ -9,12 +9,11 @@ from infrahub.context import InfrahubContext
9
9
  from infrahub.core import registry
10
10
  from infrahub.core.timestamp import Timestamp
11
11
  from infrahub.exceptions import InitializationError
12
+ from infrahub.graphql.registry import registry as graphql_registry
12
13
  from infrahub.graphql.resolvers.many_relationship import ManyRelationshipResolver
13
14
  from infrahub.graphql.resolvers.single_relationship import SingleRelationshipResolver
14
15
  from infrahub.permissions import PermissionManager
15
16
 
16
- from .manager import GraphQLSchemaManager
17
-
18
17
  if TYPE_CHECKING:
19
18
  from graphql import GraphQLSchema
20
19
  from starlette.requests import HTTPConnection
@@ -91,7 +90,7 @@ async def prepare_graphql_params(
91
90
  ) -> GraphqlParams:
92
91
  branch = registry.get_branch_from_registry(branch=branch)
93
92
  schema_branch = registry.schema.get_schema_branch(name=branch.name)
94
- gqlm = GraphQLSchemaManager.get_manager_for_branch(branch=branch, schema_branch=schema_branch)
93
+ gqlm = graphql_registry.get_manager_for_branch(branch=branch, schema_branch=schema_branch)
95
94
  gql_schema = gqlm.get_graphql_schema(
96
95
  include_query=include_query,
97
96
  include_mutation=include_mutation,