Skip to content

Commit

Permalink
Fix RFC compliance of identityref value types
Browse files Browse the repository at this point in the history
The current code is not compliant to Netconf RFC - RFC6020
https://datatracker.ietf.org/doc/html/rfc6020#section-9.10.5
Also restconf is not compliant to a similar RFC - RFC7951
https://datatracker.ietf.org/doc/html/rfc7951#section-6.8

This change fixes the XML generation tool pyang-apteryx-xml.py to
generate enough information so that Netconf and Restconf can
set identyref type values with the correct reference information.

A basic model test.xml, was modified to set the new the XML
properties on a basic type.
  • Loading branch information
gcampbell512 authored and carlgsmith committed Jul 16, 2024
1 parent db08f21 commit 3ace1d0
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
2 changes: 1 addition & 1 deletion models/test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<NODE name="animal" help="This is a list of animals">
<NODE name="*" help="The animal entry with key name">
<NODE name="name" mode="rw" help="This is the name of the animal"/>
<NODE name="type" mode="rw" default="big" help="This is the type of the animal">
<NODE name="type" idref_href="http://test.com/ns/yang/animal-types" idref_prefix="a-types" idref_module="animal-testing-types" mode="rw" default="big" help="This is the type of the animal">
<VALUE name="big" value="1"/>
<VALUE name="little" value="2"/>
</NODE>
Expand Down
35 changes: 35 additions & 0 deletions pyang-apteryx-xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,40 @@ def node_descendant_of(self, node, keyword):
node = node.parent
return False

def value_attrib_identityref(self, res, ntype):
if hasattr(ntype, "i_type_spec") and hasattr(ntype.i_type_spec, "idbases"):
for ch in ntype.i_type_spec.idbases:
sp_parts = ch.arg.split(':', 2);
if ch.i_module.i_prefixes is not None:
for pref, mname in ch.i_module.i_prefixes.items():
if pref == sp_parts[0]:
module_name = mname[:][0]
subm = ch.i_module.i_ctx.get_module(module_name)
if subm is not None:
ns = subm.search_one('namespace')
if ns is not None and subm.i_prefix is not None:
res.attrib["idref_href"] = ns.arg
res.attrib["idref_prefix"] = subm.i_prefix
res.attrib["idref_module"] = module_name
return

def value_identityref(self, node, res):
ntype = node.search_one("type")
if ntype and ntype.i_typedef is not None:
ntype = ntype.i_typedef.search_one("type")
if ntype is not None:
if ntype.arg == "identityref":
self.value_attrib_identityref(res, ntype)
if ntype.arg == "union" and hasattr(ntype, "i_type_spec"):
if (hasattr(ntype.i_type_spec, "types")):
base_idref = True
for ch in ntype.i_type_spec.types:
if ch.arg != "identityref":
base_idref = False
break
if base_idref and hasattr(ch, "i_type_spec"):
self.value_attrib_identityref(res, ch)

def sample_element(self, node, parent, module, path):
if path is None:
return parent, module, None
Expand All @@ -335,6 +369,7 @@ def sample_element(self, node, parent, module, path):
if node.keyword == 'rpc' or node.keyword == 'action':
res.attrib["mode"] = "rwx"
if node.keyword == 'leaf':
self.value_identityref(node, res)
if node.i_config:
res.attrib["mode"] = "rw"
elif self.node_descendant_of(node, "input"):
Expand Down
18 changes: 18 additions & 0 deletions schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -3587,9 +3587,27 @@ _sch_gnode_to_json (sch_instance * instance, sch_node * schema, xmlNs *ns, GNode
else if (APTERYX_HAS_VALUE (node))
{
char *value = g_strdup (APTERYX_VALUE (node) ? APTERYX_VALUE (node) : "");

if (flags & SCH_F_JSON_TYPES)
{
value = sch_translate_to (schema, value);
}

if (value)
{
/* Check to see if the schema has any identityref information */
xmlChar *idref_module = xmlGetProp ((xmlNode *)schema, (const xmlChar *)"idref_module");
if (idref_module)
{
char *temp = value;
value = g_strdup_printf ("%s:%s", (char *) idref_module, value);
g_free (temp);
xmlFree (idref_module);
}
}

if (flags & SCH_F_JSON_TYPES)
{
data = encode_json_type (schema, value);
}
else
Expand Down

0 comments on commit 3ace1d0

Please sign in to comment.