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.
- infrahub/actions/tasks.py +200 -16
- infrahub/api/artifact.py +3 -0
- infrahub/api/query.py +2 -0
- infrahub/api/schema.py +3 -0
- infrahub/auth.py +5 -5
- infrahub/cli/db.py +2 -2
- infrahub/config.py +7 -2
- infrahub/core/attribute.py +22 -19
- infrahub/core/branch/models.py +2 -2
- infrahub/core/branch/needs_rebase_status.py +11 -0
- infrahub/core/branch/tasks.py +2 -2
- infrahub/core/constants/__init__.py +1 -0
- infrahub/core/convert_object_type/object_conversion.py +201 -0
- infrahub/core/convert_object_type/repository_conversion.py +89 -0
- infrahub/core/convert_object_type/schema_mapping.py +27 -3
- infrahub/core/diff/query/artifact.py +12 -9
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/initialization.py +2 -2
- infrahub/core/manager.py +3 -81
- infrahub/core/migrations/graph/__init__.py +2 -0
- infrahub/core/migrations/graph/m040_profile_attrs_in_db.py +166 -0
- infrahub/core/node/__init__.py +26 -3
- infrahub/core/node/create.py +79 -38
- infrahub/core/node/lock_utils.py +98 -0
- infrahub/core/property.py +11 -0
- infrahub/core/protocols.py +1 -0
- infrahub/core/query/attribute.py +27 -15
- infrahub/core/query/node.py +47 -184
- infrahub/core/query/relationship.py +43 -26
- infrahub/core/query/subquery.py +0 -8
- infrahub/core/relationship/model.py +59 -19
- infrahub/core/schema/attribute_schema.py +0 -2
- infrahub/core/schema/definitions/core/repository.py +7 -0
- infrahub/core/schema/relationship_schema.py +0 -1
- infrahub/core/schema/schema_branch.py +3 -2
- infrahub/generators/models.py +31 -12
- infrahub/generators/tasks.py +3 -1
- infrahub/git/base.py +38 -1
- infrahub/graphql/api/dependencies.py +2 -4
- infrahub/graphql/api/endpoints.py +2 -2
- infrahub/graphql/app.py +2 -4
- infrahub/graphql/initialization.py +2 -3
- infrahub/graphql/manager.py +212 -137
- infrahub/graphql/middleware.py +12 -0
- infrahub/graphql/mutations/branch.py +11 -0
- infrahub/graphql/mutations/computed_attribute.py +110 -3
- infrahub/graphql/mutations/convert_object_type.py +34 -13
- infrahub/graphql/mutations/ipam.py +21 -8
- infrahub/graphql/mutations/main.py +37 -153
- infrahub/graphql/mutations/profile.py +195 -0
- infrahub/graphql/mutations/proposed_change.py +2 -1
- infrahub/graphql/mutations/repository.py +22 -83
- infrahub/graphql/mutations/webhook.py +1 -1
- infrahub/graphql/registry.py +173 -0
- infrahub/graphql/schema.py +4 -1
- infrahub/lock.py +52 -26
- infrahub/locks/__init__.py +0 -0
- infrahub/locks/tasks.py +37 -0
- infrahub/patch/plan_writer.py +2 -2
- infrahub/profiles/__init__.py +0 -0
- infrahub/profiles/node_applier.py +101 -0
- infrahub/profiles/queries/__init__.py +0 -0
- infrahub/profiles/queries/get_profile_data.py +99 -0
- infrahub/profiles/tasks.py +63 -0
- infrahub/repositories/__init__.py +0 -0
- infrahub/repositories/create_repository.py +113 -0
- infrahub/tasks/registry.py +6 -4
- infrahub/webhook/models.py +1 -1
- infrahub/workflows/catalogue.py +38 -3
- infrahub/workflows/models.py +17 -2
- infrahub_sdk/branch.py +5 -8
- infrahub_sdk/client.py +364 -84
- infrahub_sdk/convert_object_type.py +61 -0
- infrahub_sdk/ctl/check.py +2 -3
- infrahub_sdk/ctl/cli_commands.py +16 -12
- infrahub_sdk/ctl/config.py +8 -2
- infrahub_sdk/ctl/generator.py +2 -3
- infrahub_sdk/ctl/repository.py +39 -1
- infrahub_sdk/ctl/schema.py +12 -1
- infrahub_sdk/ctl/utils.py +4 -0
- infrahub_sdk/ctl/validate.py +5 -3
- infrahub_sdk/diff.py +4 -5
- infrahub_sdk/exceptions.py +2 -0
- infrahub_sdk/graphql.py +7 -2
- infrahub_sdk/node/attribute.py +2 -0
- infrahub_sdk/node/node.py +28 -20
- infrahub_sdk/playback.py +1 -2
- infrahub_sdk/protocols.py +40 -6
- infrahub_sdk/pytest_plugin/plugin.py +7 -4
- infrahub_sdk/pytest_plugin/utils.py +40 -0
- infrahub_sdk/repository.py +1 -2
- infrahub_sdk/schema/main.py +1 -0
- infrahub_sdk/spec/object.py +43 -4
- infrahub_sdk/spec/range_expansion.py +118 -0
- infrahub_sdk/timestamp.py +18 -6
- {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/METADATA +20 -24
- {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/RECORD +102 -84
- infrahub_testcontainers/models.py +2 -2
- infrahub_testcontainers/performance_test.py +4 -4
- infrahub/core/convert_object_type/conversion.py +0 -134
- {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.4.9.dist-info → infrahub_server-1.5.0b0.dist-info}/WHEEL +0 -0
- {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__(
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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":
|
|
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=
|
|
2001
|
+
identifier=PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
|
|
2001
2002
|
peer=node.kind,
|
|
2002
2003
|
kind=RelationshipKind.PROFILE,
|
|
2003
2004
|
cardinality=RelationshipCardinality.MANY,
|
infrahub/generators/models.py
CHANGED
|
@@ -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:
|
|
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
|
|
35
|
-
definition_id: str
|
|
36
|
-
definition_name: str
|
|
37
|
-
query_name: str
|
|
38
|
-
convert_query_response: bool
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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.")
|
infrahub/generators/tasks.py
CHANGED
|
@@ -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(
|
|
40
|
-
return InfrahubGraphQLApp(build_graphql_query_permission_checker()
|
|
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.
|
|
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 =
|
|
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=
|
|
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 =
|
|
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,
|