diff --git a/infrahub_sdk/client.py b/infrahub_sdk/client.py index 4f6aa8a2..792f1212 100644 --- a/infrahub_sdk/client.py +++ b/infrahub_sdk/client.py @@ -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 @@ -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( diff --git a/infrahub_sdk/protocols.py b/infrahub_sdk/protocols.py index 7a69b5f8..d002e433 100644 --- a/infrahub_sdk/protocols.py +++ b/infrahub_sdk/protocols.py @@ -68,6 +68,12 @@ class BuiltinIPPrefix(CoreNode): children: RelationshipManager +class CoreAction(CoreNode): + name: String + description: StringOptional + triggers: RelationshipManager + + class CoreArtifactTarget(CoreNode): artifacts: RelationshipManager @@ -154,6 +160,10 @@ class CoreMenu(CoreNode): children: RelationshipManager +class CoreNodeTriggerMatch(CoreNode): + trigger: RelatedNode + + class CoreObjectComponentTemplate(CoreNode): template_name: String @@ -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 @@ -328,6 +346,10 @@ class CoreFileThread(CoreThread): repository: RelatedNode +class CoreGeneratorAction(CoreAction): + generator: RelatedNode + + class CoreGeneratorCheck(CoreCheck): instance: String @@ -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 @@ -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 @@ -448,6 +499,11 @@ class CoreRepository(LineageOwner, LineageSource, CoreGenericRepository, CoreTas commit: StringOptional +class CoreRepositoryGroup(CoreGroup): + content: Dropdown + repository: RelatedNode + + class CoreRepositoryValidator(CoreValidator): repository: RelatedNode @@ -545,6 +601,12 @@ class BuiltinIPPrefixSync(CoreNodeSync): children: RelationshipManagerSync +class CoreActionSync(CoreNodeSync): + name: String + description: StringOptional + triggers: RelationshipManagerSync + + class CoreArtifactTargetSync(CoreNodeSync): artifacts: RelationshipManagerSync @@ -631,6 +693,10 @@ class CoreMenuSync(CoreNodeSync): children: RelationshipManagerSync +class CoreNodeTriggerMatchSync(CoreNodeSync): + trigger: RelatedNodeSync + + class CoreObjectComponentTemplateSync(CoreNodeSync): template_name: String @@ -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 @@ -805,6 +879,10 @@ class CoreFileThreadSync(CoreThreadSync): repository: RelatedNodeSync +class CoreGeneratorActionSync(CoreActionSync): + generator: RelatedNodeSync + + class CoreGeneratorCheckSync(CoreCheckSync): instance: String @@ -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 @@ -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 @@ -925,6 +1032,11 @@ class CoreRepositorySync(LineageOwnerSync, LineageSourceSync, CoreGenericReposit commit: StringOptional +class CoreRepositoryGroupSync(CoreGroupSync): + content: Dropdown + repository: RelatedNodeSync + + class CoreRepositoryValidatorSync(CoreValidatorSync): repository: RelatedNodeSync diff --git a/infrahub_sdk/query_groups.py b/infrahub_sdk/query_groups.py index 4bb732b2..94b16a10 100644 --- a/infrahub_sdk/query_groups.py +++ b/infrahub_sdk/query_groups.py @@ -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 @@ -25,6 +25,7 @@ def __init__(self) -> None: 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, @@ -32,6 +33,8 @@ def set_properties( 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. @@ -43,6 +46,8 @@ def set_properties( 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""" @@ -87,7 +92,9 @@ def __init__(self, client: InfrahubClient) -> None: 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( + kind=self.group_type, name__value=group_name, include=["members"], branch=self.branch + ) except NodeNotFoundError: return None @@ -151,6 +158,8 @@ async def update_group(self) -> None: name=group_name, description=description, members=members, + branch=self.branch, + **self.group_params, ) await group.save(allow_upsert=True, update_group_context=False) @@ -243,6 +252,8 @@ def update_group(self) -> None: name=group_name, description=description, members=members, + branch=self.branch, + **self.group_params, ) group.save(allow_upsert=True, update_group_context=False) diff --git a/infrahub_sdk/schema/repository.py b/infrahub_sdk/schema/repository.py index b5c58d2f..69d63832 100644 --- a/infrahub_sdk/schema/repository.py +++ b/infrahub_sdk/schema/repository.py @@ -147,6 +147,18 @@ 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", @@ -154,6 +166,8 @@ def load_query(self, relative_path: str = ".") -> str: InfrahubPythonTransformConfig: "python_transforms", InfrahubGeneratorDefinitionConfig: "generator_definitions", InfrahubRepositoryGraphQLConfig: "queries", + InfrahubObjectConfig: "objects", + InfrahubMenuConfig: "menus", } @@ -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", diff --git a/infrahub_sdk/spec/object.py b/infrahub_sdk/spec/object.py index acbf1551..23a11c10 100644 --- a/infrahub_sdk/spec/object.py +++ b/infrahub_sdk/spec/object.py @@ -459,7 +459,7 @@ async def create_node( 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}") for rel in remaining_rels: context = {} diff --git a/infrahub_sdk/testing/schemas/car_person.py b/infrahub_sdk/testing/schemas/car_person.py index 2da7ab4d..3a1c3dc3 100644 --- a/infrahub_sdk/testing/schemas/car_person.py +++ b/infrahub_sdk/testing/schemas/car_person.py @@ -48,6 +48,7 @@ def schema_person_base(self) -> NodeSchema: namespace=NAMESPACE, include_in_menu=True, label="Person", + default_filter="name__value", human_friendly_id=["name__value"], attributes=[ Attr(name="name", kind=AttributeKind.TEXT, unique=True),