Skip to content

Commit 3a6e234

Browse files
authored
Set optional value for attr/rel of sub-templates (#5984)
Templates which are not explicitely generated by user should honour the optional value of each attribute and relationship to avoid issues when instantiating objects from them.
1 parent 2e27a43 commit 3a6e234

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

backend/infrahub/core/schema/schema_branch.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,12 +1833,11 @@ def add_relationships_to_template(self, node: NodeSchema) -> None:
18331833
template_schema.relationships = [
18341834
r for r in template_schema.relationships if r.kind == RelationshipKind.TEMPLATE
18351835
]
1836+
# Tell if the user explicitely requested this template
1837+
is_autogenerated_subtemplate = node.generate_template is False
18361838

18371839
for relationship in node.relationships:
1838-
if relationship.peer in [
1839-
InfrahubKind.GENERICGROUP,
1840-
InfrahubKind.PROFILE,
1841-
] or relationship.kind not in [
1840+
if relationship.peer in [InfrahubKind.GENERICGROUP, InfrahubKind.PROFILE] or relationship.kind not in [
18421841
RelationshipKind.COMPONENT,
18431842
RelationshipKind.PARENT,
18441843
RelationshipKind.ATTRIBUTE,
@@ -1856,8 +1855,9 @@ def add_relationships_to_template(self, node: NodeSchema) -> None:
18561855
name=relationship.name,
18571856
peer=rel_template_peer,
18581857
kind=relationship.kind,
1859-
optional=relationship.kind
1860-
in [RelationshipKind.COMPONENT, RelationshipKind.ATTRIBUTE, RelationshipKind.GENERIC],
1858+
optional=relationship.optional
1859+
if is_autogenerated_subtemplate
1860+
else relationship.kind != RelationshipKind.PARENT,
18611861
cardinality=relationship.cardinality,
18621862
branch=relationship.branch,
18631863
identifier=self._generate_identifier_string(template_schema.kind, rel_template_peer),
@@ -1928,12 +1928,15 @@ def generate_object_template_from_node(
19281928
if inherited in need_template_kinds:
19291929
template.inherit_from.append(self._get_object_template_kind(node_kind=inherited))
19301930

1931+
# Tell if the user explicitely requested this template
1932+
is_autogenerated_subtemplate = node.generate_template is False
19311933
for node_attr in node.attributes:
19321934
if node_attr.unique:
19331935
continue
19341936

19351937
attr = AttributeSchema(
1936-
optional=True, **node_attr.model_dump(exclude=["id", "unique", "optional", "read_only", "inherited"])
1938+
optional=node_attr.optional if is_autogenerated_subtemplate else True,
1939+
**node_attr.model_dump(exclude=["id", "unique", "optional", "read_only", "inherited"]),
19371940
)
19381941
template.attributes.append(attr)
19391942

backend/tests/unit/core/schema_manager/test_manager_schema.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2955,5 +2955,13 @@ async def test_manage_object_templates_with_component_relationships():
29552955
assert test_device.generate_template
29562956
assert test_device.get_relationship(name="object_template").peer == test_object_template_device.kind
29572957

2958-
# Make sure interfaces relationship is converted tp interface templates
2958+
# Make sure interfaces relationship is converted to interface templates
29592959
assert test_object_template_device.get_relationship("interfaces").peer == f"Template{TestKind.INTERFACE}"
2960+
2961+
# Verify attributes mapping of components
2962+
test_interface_template = schema_branch.get(name=f"Template{TestKind.PHYSICAL_INTERFACE}", duplicate=False)
2963+
test_interface = schema_branch.get(name=TestKind.PHYSICAL_INTERFACE, duplicate=False)
2964+
for attr in test_interface.attributes:
2965+
template_attr = test_interface_template.get_attribute(name=attr.name)
2966+
# Optional value in component template should match original's
2967+
assert attr.optional == template_attr.optional

0 commit comments

Comments
 (0)