Subject: [netmod] How to constrain a leaf to a read-only list of supported values?

From: Balazs Lengyel <[email-masked]>
Date: Mon, 29 Aug 2016 18:00:51 +0200

Hello,

We have the following design pattern.

1) An enumeration or a set of identities are defined that define a set 
of options generally supported by Ericsson products.  (e.g. supported 
compression algorithms)
2) The specific node sets in run-time a leaf-list indicating the set of 
values that this specific node supports (e.g. 
nodes-supported-compression-types: zip, gzip, bz)
3) For some function the user has to select a specific option value 
(e.g. leaf file-compression for transferring backup files)

Problem: how do you restrict values for (3) - file-compression so that 
it is one of the nodes-supported-compression-types. The natural solution 
would be to use a must expression or a leaf-ref, but as 
nodes-supported-compression-types is config-false data, it is not 
allowed to constrain the config=true leaf, file-compression, with it.

It would be perfectly reasonable because the 
nodes-supported-compression-types only change during upgrade, but YANG 
does not allow this.

I would still like to have some modeled solution, not just plain English 
stating the constraint. Any idea how to do it?

regards Balazs

-- 
Balazs Lengyel                       Ericsson Hungary Ltd.
Senior Specialist
Mobile: +36-70-330-7909              email: [email-masked]

---

From: Jan Lindblad <[email-masked]>
Date: Tue, 30 Aug 2016 15:14:21 +0200

Balazs,

> 1) An enumeration or a set of identities are defined that define a set of options generally supported by Ericsson products.  (e.g. supported compression algorithms)
> 2) The specific node sets in run-time a leaf-list indicating the set of values that this specific node supports (e.g. nodes-supported-compression-types: zip, gzip, bz)
> 3) For some function the user has to select a specific option value (e.g. leaf file-compression for transferring backup files)
> 
> Problem: how do you restrict values for (3) - file-compression so that it is one of the nodes-supported-compression-types. The natural solution would be to use a must expression or a leaf-ref, but as nodes-supported-compression-types is config-false data, it is not allowed to constrain the config=true leaf, file-compression, with it.
> 
> It would be perfectly reasonable because the nodes-supported-compression-types only change during upgrade, but YANG does not allow this.
> 
> I would still like to have some modeled solution, not just plain English stating the constraint. Any idea how to do it?

I have seen this use case many times. I usually solve this by making a container with device specific limits, lists of supported values, etc, which is config true but with nacm rules preventing everyone from making changes. Then I have a device specific database initialization file with the correct settings for this device, which is loaded into the database at first boot.

/jan

---

From: [email-masked] (Dale R. Worley)
Date: Tue, 30 Aug 2016 10:07:45 -0400

> allowed to constrain the config=true leaf, file-compression, with it.

I'm no expert at this, but it seems to me that the way to do it is to
have the overall data structure be config-true but make the contained
supported-compression-types be config-false.  You can nest config-false
nodes in a config-true structure.  The Yang would be something like
this:

typedef Compression-Method {
  ...
}

list node {
  config true;
  key name;

  string name;

  leaf-list supported-compression-methods {
    type Compression-Method;
    config false;
  }

  Compression-Method compression-method;
  must "compression-method ... supported-compression-methods";
}

Dale

---

From: Balazs Lengyel <[email-masked]>
Date: Wed, 31 Aug 2016 09:35:01 +0200

Hello Jan,

This may be the best solution we have, but nacm rules may be changed, 
and then device limits might be edited by the operator, and then we have 
a problem.

The good solution would be to indicate that this is read-only static 
data, and allow must, leafref towards it. However I don't see a way to 
do this in YANG at the moment short of an ericsson-extension.

regards Balazs

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 31 Aug 2016 10:54:00 +0200 (CEST)

Balazs Lengyel <[email-masked]> wrote:
> and then device limits might be edited by the operator, and then we
> have a problem.
> 

I think this is the only correct solution available today.  I.e.,
describe the behavior in description text, and/or add an extension
that makes this formal and machnie readable for your tools:

  leaf-list supported-compression-algorithm {
    config false;
    type eri:compression-algorithm;
    description
      "Lists the compression algorithms supported by this device.";
  }

  leaf compression-algorithm {
    config true;
    type eri:compression-algorithm;
    description
      "Must be one of the values listed in
       supported-compression-algorithm.";
    eri:restrict-to "../supported-compression-algorithm";
  }

But I assume that the list of supported-compression-algorithm can
change with a software upgrade, and if so, how do you handle the case
that the config contains a value that is removed in a software
upgrade?

/martin

> >> 2) The specific node sets in run-time a leaf-list indicating the set
> >> of values that this specific node supports
> >> (e.g. nodes-supported-compression-types: zip, gzip, bz)
> >> it is one of the nodes-supported-compression-types. The natural
> >> solution would be to use a must expression or a leaf-ref, but as
> >> I would still like to have some modeled solution, not just plain
> >> English stating the constraint. Any idea how to do it?
> > I have seen this use case many times. I usually solve this by making a
> > container with device specific limits, lists of supported values, etc,
> > which is config true but with nacm rules preventing everyone from
> > making changes. Then I have a device specific database initialization
> > file with the correct settings for this device, which is loaded into
> > the database at first boot.
> >
> > /jan
> >
> 
> -- 
> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod
>

---

From: Vladimir Vassilev <[email-masked]>
Date: Wed, 31 Aug 2016 11:10:48 +0200

If you design your models using identityref and define the identities in 
separate modules e.g. compression-zip.yang, compression-gzip.yang, etc. 
you can just chose not to load the particular YANG models containing the 
identities not supported when your device starts.

If you absolutely can not define your identities in separate YANG files 
(better modularity is indeed the edge YANG has over other modeling 
languages and it should be used) you can use feature with some 
limitations e.g. instead of leaf of type enumeration you will have a 
choice with each case containing if-feature and presence container for 
example.

If you can not change the model to be modular and your implementation 
does not support it 100% then you are not supporting the model and you 
are free to be creative with the workaround but then YANG is not the 
problem.

I also see alternative discussion value in the subject line. Lets say 
one would like to specify in a standard way a list of values supported 
by a device as valid /interface/interface/name values e.g. ("ge0", 
"ge1", .... "xe0", "xe1", "me0"). This can be useful in many ways e.g. 
tab completion. Also the supported types for each of the interface names 
and so on further reducing the entropy. Does anyone else see value in that?

On 08/31/2016 09:35 AM, Balazs Lengyel wrote:
>>> 1) An enumeration or a set of identities are defined that define a 
>>> set of options generally supported by Ericsson products.  (e.g. 
>>> supported compression algorithms)
>>> of values that this specific node supports (e.g. 
>>> Problem: how do you restrict values for (3) - file-compression so 
>>> that it is one of the nodes-supported-compression-types. The natural 
>>> nodes-supported-compression-types only change during upgrade, but 
>>> YANG does not allow this.
>>>
>> I have seen this use case many times. I usually solve this by making 
>> a container with device specific limits, lists of supported values, 
>> etc, which is config true but with nacm rules preventing everyone 
>> from making changes. Then I have a device specific database 
>> initialization file with the correct settings for this device, which 
>> is loaded into the database at first boot.
>>
>> /jan
>>
>
Vladimir

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 31 Aug 2016 12:38:05 +0200

> On 31 Aug 2016, at 11:10, Vladimir Vassilev <[email-masked]> wrote:
> 
> If you design your models using identityref and define the identities in separate modules e.g. compression-zip.yang, compression-gzip.yang, etc. you can just chose not to load the particular YANG models containing the identities not supported when your device starts.

Right, and I have proposed this approach several times in the past. However, some people prefer that the modules defining identities mirror IANA and similar registries. In the case of iana-interface-types it also means that implementations have to deal with obsolete, obscure and experimental interface types that happen to be in the IANA registry but nobody will ever want to use.

Lada

> 
> If you absolutely can not define your identities in separate YANG files (better modularity is indeed the edge YANG has over other modeling languages and it should be used) you can use feature with some limitations e.g. instead of leaf of type enumeration you will have a choice with each case containing if-feature and presence container for example.
> 
> If you can not change the model to be modular and your implementation does not support it 100% then you are not supporting the model and you are free to be creative with the workaround but then YANG is not the problem.
> 
> I also see alternative discussion value in the subject line. Lets say one would like to specify in a standard way a list of values supported by a device as valid /interface/interface/name values e.g. ("ge0", "ge1", .... "xe0", "xe1", "me0"). This can be useful in many ways e.g. tab completion. Also the supported types for each of the interface names and so on further reducing the entropy. Does anyone else see value in that?
> 
>> This may be the best solution we have, but nacm rules may be changed, and then device limits might be edited by the operator, and then we have a problem.
>> 
>> The good solution would be to indicate that this is read-only static data, and allow must, leafref towards it. However I don't see a way to do this in YANG at the moment short of an ericsson-extension.
>> 
>> regards Balazs
>> 
>> 

--
Ladislav Lhotka, CZ.NIC Labs
PGP Key ID: E74E8C0C

---

From: Balazs Lengyel <[email-masked]>
Date: Wed, 31 Aug 2016 13:10:17 +0200

Hello,

The problem is not just about identities. It can be a value range. 
Sometimes we have a generic module like iana-interface type that list a 
lot of identities, and I don't want to have one YAM file per identity, 
to allow a fine control. Also sadly it is not possible to have a 
deviation removing identities. IMHO would be needed.

I would be more interested in having an extension saying static-data. 
This would state that that part of config is set by the system, and can 
not be modified by the user. So I could have conditions based on it, but 
the user might not modify it.

regards Balazs

---

From: Balazs Lengyel <[email-masked]>
Date: Wed, 31 Aug 2016 13:13:59 +0200

That would be a backward incompatible change, which is a general 
problem, not specific to this issue. (like changing a datatype from 
int16 to int8).

In this sense the data set by the system becomes part of the model and 
thus must be covered by backward compatibility rules.

Balazs

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 31 Aug 2016 13:59:26 +0200

> On 31 Aug 2016, at 13:10, Balazs Lengyel <[email-masked]> wrote:
> 
> Hello,
> 
> The problem is not just about identities. It can be a value range. Sometimes we have a generic module like iana-interface type that

A value range is IMO a good candidate for a deviation.

>  list a lot of identities, and I don't want to have one YAM file per identity, to allow a fine control. Also sadly it is not possible to have a deviation removing identities. IMHO would be needed.

What you can do is to bundle the identity in the same module with config and state data corresponding to that identity. This is what the routing model does with address families: "ipv4-unicast" identity is defined in "ietf-ipv4-unicast-routing", and "ipv6-unicast" identity is defined in "ietf-ipv6-unicast-routing". This is IMO far better than mirroring

http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml

in a module.

> 
> I would be more interested in having an extension saying static-data. This would state that that part of config is set by the system, and can not be modified by the user. So I could have conditions based on it, but the user might not modify it.

This is something like system-controlled interfaces, no?

Lada

---

From: Vladimir Vassilev <[email-masked]>
Date: Wed, 31 Aug 2016 14:16:14 +0200

> Right, and I have proposed this approach several times in the past. However, some people prefer that the modules defining identities mirror IANA and similar registries. In the case of iana-interfac…
+1

The 275 identities defined in iana-if-type.yang appearing as possible 
/interfaces/interface/type tab completion options in a YANG aware cli or 
drop-down menu in gui is annoying and stands out as an obvious problem.

It is not late to split the file. No standard RFC YANG model includes 
iana-if-type.yang yet. The actually referenced identities in current 
drafts is less then 16 (grep-ing in my known YANG model archive) 
{ethernetCsmacd, l2vlan, ieee8023adLag, ifPwType, pos, atm, 
atmSubInterface, sonet, otnOtu, frameRelay, bridge, macSecControlledIF, 
fastdsl}

If not single instance per file maybe dividing the file into categories 
so if your device is atm aware you import iana-if-type-atm.yang and get 
{atm, atmSubInterface}.

However we can probably agree the iana-if-type.yang exception is not a 
valid excuse for new models like the one in the example where there are 
3 compression methods to not modularize the identity definitions into 
separate files and not load identities the implementation does not 
support but instead resolve to workaround solutions.

Vladimir

---

From: Vladimir Vassilev <[email-masked]>
Date: Wed, 31 Aug 2016 15:41:25 +0200

> The problem is not just about identities. It can be a value range.
If your example was about value range then a deviation would be a 
solution. Then we have the same case for modularization. YANG files 
defining deviations loaded when the deviation is relevant and not loaded 
otherwise.
> Sometimes we have a generic module like iana-interface type that list 
> a lot of identities, and I don't want to have one YAM file per 
> identity, to allow a fine control. Also sadly it is not possible to 
> have a deviation removing identities. IMHO would be needed.
Well the biggest problem modularizing your identity definitions is you 
will have more YANG files proportional to the flexibility you want. I 
would have chosen that in the example you provide.
> This would state that that part of config is set by the system, and 
> can not be modified by the user. So I could have conditions based on 
> it, but the user might not modify it.
That is still not as good as modularization of your model and using 
optionally loadable YANG 'deviation's and 'identity' definitions. Even 
if you have "static-data tree" you will be able to use must statements 
to not allow certain range based on that "static data tree" it will 
still be the range defined in the type from the model that will be shown 
to the user editing the configuration in YANG aware CLI or GUI. It is 
still a workaround even if the must statement will fail upon commit.