Skip to content

Add objects field within InfrahubConfig #422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions infrahub_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,18 @@ def start_tracking(
params: dict[str, Any] | None = None,
delete_unused_nodes: bool = False,
group_type: str | None = None,
group_params: dict[str, Any] | None = None,
branch: str | None = None,
) -> Self:
self.mode = InfrahubClientMode.TRACKING
identifier = identifier or self.identifier or "python-sdk"
self.set_context_properties(
identifier=identifier, params=params, delete_unused_nodes=delete_unused_nodes, group_type=group_type
identifier=identifier,
params=params,
delete_unused_nodes=delete_unused_nodes,
group_type=group_type,
group_params=group_params,
branch=branch,
)
return self

Expand All @@ -187,14 +194,22 @@ def set_context_properties(
delete_unused_nodes: bool = True,
reset: bool = True,
group_type: str | None = None,
group_params: dict[str, Any] | None = None,
branch: str | None = None,
) -> None:
if reset:
if isinstance(self, InfrahubClient):
self.group_context = InfrahubGroupContext(self)
elif isinstance(self, InfrahubClientSync):
self.group_context = InfrahubGroupContextSync(self)

self.group_context.set_properties(
identifier=identifier, params=params, delete_unused_nodes=delete_unused_nodes, group_type=group_type
identifier=identifier,
params=params,
delete_unused_nodes=delete_unused_nodes,
group_type=group_type,
group_params=group_params,
branch=branch,
)

def _graphql_url(
Expand Down
112 changes: 112 additions & 0 deletions infrahub_sdk/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ class BuiltinIPPrefix(CoreNode):
children: RelationshipManager


class CoreAction(CoreNode):
name: String
description: StringOptional
triggers: RelationshipManager


class CoreArtifactTarget(CoreNode):
artifacts: RelationshipManager

Expand Down Expand Up @@ -154,6 +160,10 @@ class CoreMenu(CoreNode):
children: RelationshipManager


class CoreNodeTriggerMatch(CoreNode):
trigger: RelatedNode


class CoreObjectComponentTemplate(CoreNode):
template_name: String

Expand Down Expand Up @@ -195,6 +205,14 @@ class CoreTransformation(CoreNode):
tags: RelationshipManager


class CoreTriggerRule(CoreNode):
name: String
description: StringOptional
active: Boolean
branch_scope: Dropdown
action: RelatedNode


class CoreValidator(CoreNode):
label: StringOptional
state: Enum
Expand Down Expand Up @@ -328,6 +346,10 @@ class CoreFileThread(CoreThread):
repository: RelatedNode


class CoreGeneratorAction(CoreAction):
generator: RelatedNode


class CoreGeneratorCheck(CoreCheck):
instance: String

Expand Down Expand Up @@ -382,6 +404,16 @@ class CoreGraphQLQueryGroup(CoreGroup):
query: RelatedNode


class CoreGroupAction(CoreAction):
add_members: Boolean
group: RelatedNode


class CoreGroupTriggerRule(CoreTriggerRule):
members_added: Boolean
group: RelatedNode


class CoreIPAddressPool(CoreResourcePool, LineageSource):
default_address_type: String
default_prefix_length: IntegerOptional
Expand All @@ -401,6 +433,25 @@ class CoreMenuItem(CoreMenu):
pass


class CoreNodeTriggerAttributeMatch(CoreNodeTriggerMatch):
attribute_name: String
value: StringOptional
value_previous: StringOptional
value_match: Dropdown


class CoreNodeTriggerRelationshipMatch(CoreNodeTriggerMatch):
relationship_name: String
added: Boolean
peer: StringOptional


class CoreNodeTriggerRule(CoreTriggerRule):
node_kind: String
mutation_action: Enum
matches: RelationshipManager


class CoreNumberPool(CoreResourcePool, LineageSource):
node: String
node_attribute: String
Expand Down Expand Up @@ -448,6 +499,11 @@ class CoreRepository(LineageOwner, LineageSource, CoreGenericRepository, CoreTas
commit: StringOptional


class CoreRepositoryGroup(CoreGroup):
content: Dropdown
repository: RelatedNode


class CoreRepositoryValidator(CoreValidator):
repository: RelatedNode

Expand Down Expand Up @@ -545,6 +601,12 @@ class BuiltinIPPrefixSync(CoreNodeSync):
children: RelationshipManagerSync


class CoreActionSync(CoreNodeSync):
name: String
description: StringOptional
triggers: RelationshipManagerSync


class CoreArtifactTargetSync(CoreNodeSync):
artifacts: RelationshipManagerSync

Expand Down Expand Up @@ -631,6 +693,10 @@ class CoreMenuSync(CoreNodeSync):
children: RelationshipManagerSync


class CoreNodeTriggerMatchSync(CoreNodeSync):
trigger: RelatedNodeSync


class CoreObjectComponentTemplateSync(CoreNodeSync):
template_name: String

Expand Down Expand Up @@ -672,6 +738,14 @@ class CoreTransformationSync(CoreNodeSync):
tags: RelationshipManagerSync


class CoreTriggerRuleSync(CoreNodeSync):
name: String
description: StringOptional
active: Boolean
branch_scope: Dropdown
action: RelatedNodeSync


class CoreValidatorSync(CoreNodeSync):
label: StringOptional
state: Enum
Expand Down Expand Up @@ -805,6 +879,10 @@ class CoreFileThreadSync(CoreThreadSync):
repository: RelatedNodeSync


class CoreGeneratorActionSync(CoreActionSync):
generator: RelatedNodeSync


class CoreGeneratorCheckSync(CoreCheckSync):
instance: String

Expand Down Expand Up @@ -859,6 +937,16 @@ class CoreGraphQLQueryGroupSync(CoreGroupSync):
query: RelatedNodeSync


class CoreGroupActionSync(CoreActionSync):
add_members: Boolean
group: RelatedNodeSync


class CoreGroupTriggerRuleSync(CoreTriggerRuleSync):
members_added: Boolean
group: RelatedNodeSync


class CoreIPAddressPoolSync(CoreResourcePoolSync, LineageSourceSync):
default_address_type: String
default_prefix_length: IntegerOptional
Expand All @@ -878,6 +966,25 @@ class CoreMenuItemSync(CoreMenuSync):
pass


class CoreNodeTriggerAttributeMatchSync(CoreNodeTriggerMatchSync):
attribute_name: String
value: StringOptional
value_previous: StringOptional
value_match: Dropdown


class CoreNodeTriggerRelationshipMatchSync(CoreNodeTriggerMatchSync):
relationship_name: String
added: Boolean
peer: StringOptional


class CoreNodeTriggerRuleSync(CoreTriggerRuleSync):
node_kind: String
mutation_action: Enum
matches: RelationshipManagerSync


class CoreNumberPoolSync(CoreResourcePoolSync, LineageSourceSync):
node: String
node_attribute: String
Expand Down Expand Up @@ -925,6 +1032,11 @@ class CoreRepositorySync(LineageOwnerSync, LineageSourceSync, CoreGenericReposit
commit: StringOptional


class CoreRepositoryGroupSync(CoreGroupSync):
content: Dropdown
repository: RelatedNodeSync


class CoreRepositoryValidatorSync(CoreValidatorSync):
repository: RelatedNodeSync

Expand Down
15 changes: 13 additions & 2 deletions infrahub_sdk/query_groups.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

from .constants import InfrahubClientMode
from .exceptions import NodeNotFoundError
Expand All @@ -25,13 +25,16 @@
self.params: dict[str, str] = {}
self.delete_unused_nodes: bool = False
self.group_type: str = "CoreStandardGroup"
self.group_params: dict[str, Any] = {}

def set_properties(
self,
identifier: str,
params: dict[str, str] | None = None,
delete_unused_nodes: bool = False,
group_type: str | None = None,
group_params: dict[str, Any] | None = None,
branch: str | None = None,
) -> None:
"""Setter method to set the values of identifier and params.

Expand All @@ -43,6 +46,8 @@
self.params = params or {}
self.delete_unused_nodes = delete_unused_nodes
self.group_type = group_type or self.group_type
self.group_params = group_params or {}
self.branch = branch

def _get_params_as_str(self) -> str:
"""Convert the params in dict format, into a string"""
Expand Down Expand Up @@ -87,7 +92,9 @@
async def get_group(self, store_peers: bool = False) -> InfrahubNode | None:
group_name = self._generate_group_name()
try:
group = await self.client.get(kind=self.group_type, name__value=group_name, include=["members"])
group = await self.client.get(

Check warning on line 95 in infrahub_sdk/query_groups.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/query_groups.py#L95

Added line #L95 was not covered by tests
kind=self.group_type, name__value=group_name, include=["members"], branch=self.branch
)
except NodeNotFoundError:
return None

Expand Down Expand Up @@ -151,6 +158,8 @@
name=group_name,
description=description,
members=members,
branch=self.branch,
**self.group_params,
)
await group.save(allow_upsert=True, update_group_context=False)

Expand Down Expand Up @@ -243,6 +252,8 @@
name=group_name,
description=description,
members=members,
branch=self.branch,
**self.group_params,
)
group.save(allow_upsert=True, update_group_context=False)

Expand Down
16 changes: 16 additions & 0 deletions infrahub_sdk/schema/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,27 @@ def load_query(self, relative_path: str = ".") -> str:
return file.read()


class InfrahubObjectConfig(InfrahubRepositoryConfigElement):
model_config = ConfigDict(extra="forbid")
name: str = Field(..., description="The name associated to the object file")
file_path: Path = Field(..., description="The file within the repository containing object data.")


class InfrahubMenuConfig(InfrahubRepositoryConfigElement):
model_config = ConfigDict(extra="forbid")
name: str = Field(..., description="The name of the menu")
file_path: Path = Field(..., description="The file within the repository containing menu data.")


RESOURCE_MAP: dict[Any, str] = {
InfrahubJinja2TransformConfig: "jinja2_transforms",
InfrahubCheckDefinitionConfig: "check_definitions",
InfrahubRepositoryArtifactDefinitionConfig: "artifact_definitions",
InfrahubPythonTransformConfig: "python_transforms",
InfrahubGeneratorDefinitionConfig: "generator_definitions",
InfrahubRepositoryGraphQLConfig: "queries",
InfrahubObjectConfig: "objects",
InfrahubMenuConfig: "menus",
}


Expand All @@ -176,6 +190,8 @@ class InfrahubRepositoryConfig(BaseModel):
default_factory=list, description="Generator definitions"
)
queries: list[InfrahubRepositoryGraphQLConfig] = Field(default_factory=list, description="GraphQL Queries")
objects: list[Path] = Field(default_factory=list, description="Objects")
menus: list[Path] = Field(default_factory=list, description="Menus")

@field_validator(
"check_definitions",
Expand Down
2 changes: 1 addition & 1 deletion infrahub_sdk/spec/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@
await node.save(allow_upsert=True)

display_label = node.get_human_friendly_id_as_string() or f"{node.get_kind()} : {node.id}"
client.log.info(f"Node: {display_label}")
client.log.info(f"Created node: {display_label}")

Check warning on line 462 in infrahub_sdk/spec/object.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/spec/object.py#L462

Added line #L462 was not covered by tests

for rel in remaining_rels:
context = {}
Expand Down
1 change: 1 addition & 0 deletions infrahub_sdk/testing/schemas/car_person.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def schema_person_base(self) -> NodeSchema:
namespace=NAMESPACE,
include_in_menu=True,
label="Person",
default_filter="name__value",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this because TestProposeChangeRepository imports the git repository which loads the data where peers are referenced using notation "John Doe", which does not work when default_filter is not set on the schema. We use this notation instead of the hfid notation [John Doe] because backend tests also import the repository but with schemas only defining default_filter. If above schema is meant to be used by users, it would probably be cleaner to define the hfid on backend tests schemas and use hfid notation, but these schemas are used by a lot of tests so there is a risk that some tests break.

human_friendly_id=["name__value"],
attributes=[
Attr(name="name", kind=AttributeKind.TEXT, unique=True),
Expand Down