Subject: [netmod] Does the YANG "status" statement inherit from its parent node?

From: Robert Wilton <[email-masked]>
Date: Tue, 20 Dec 2016 17:09:15 +0000

Hi,

The definition of "status" in RFC 7950 in section 7.21.2 (full text 
below), states:

If no status is specified, the default is "current".

 From my interpretation of the text in the draft, this implies that the 
status of the "new" child leaf in the following example is "current", 
and that this example is allowed!

My questions are:
  - Is my interpretation of the current text correct?
  - Is this actually the best behaviour, or should it inherit like the 
config statement?  Should I raise an errata for this?

container old {
   status deprecated;
   leaf new {
     description "what status do I have?";
   }
}

Thanks,
Rob

Full 7.21.2 text from 7950:

7.21.2.  The "status" Statement

    The "status" statement takes as an argument one of the strings
    "current", "deprecated", or "obsolete".

    o  "current" means that the definition is current and valid.

    o  "deprecated" indicates an obsolete definition, but it permits
       new/continued implementation in order to foster interoperability
       with older/existing implementations.

    o  "obsolete" means that the definition is obsolete and SHOULD NOT be
       implemented and/or can be removed from implementations.

    If no status is specified, the default is "current".

    If a definition is "current", it MUST NOT reference a "deprecated" or
    "obsolete" definition within the same module.

    If a definition is "deprecated", it MUST NOT reference an "obsolete"
    definition within the same module.

    For example, the following is illegal:

      typedef my-type {
        status deprecated;
        type int32;
      }

      leaf my-leaf {
        status current;
        type my-type; // illegal, since my-type is deprecated
      }

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 20 Dec 2016 21:03:35 +0100 (CET)

>  - Is my interpretation of the current text correct?

Yes.

>    config statement?

I think the idea was that if the status != current, it is better for
the reader if it is explicitly stated.

>  Should I raise an errata for this?

No.

However, we could have said that a current node under a deprecated
node (etc) in the same module is an error, in order to force people
(through the useage of YANG validators) to detect and fix this.

/martin

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Tue, 20 Dec 2016 21:15:27 +0100

> (through the useage of YANG validators) to detect and fix this.

Is it an error or just something that deserves a warning and the
author's attention? I am asking since we also have augmentations and
if I mark a container as deprecated, this will not immediately cause
an module augmenting the containter to get updated, hence I end up
with definitions marked current in a deprecated container. And there
are other situations where definitions may not be of the same status,
i.e., a module (without import by revision) uses a type or grouping
that in later revisions got marked deprecated. I think all of these
status mismatches are things tools should warn about but I am not sure
these are hard errors, in particular for 'deprecated'. Things may lead
to stronger warnings for definitions marked 'obsolete'.

/js

-- 
Juergen Schoenwaelder           Jacobs University Bremen gGmbH
Phone: +49 421 200 3587         Campus Ring 1 | 28759 Bremen | Germany
Fax:   +49 421 200 3103         <http://www.jacobs-university.de/>

---

From: Andy Bierman <[email-masked]>
Date: Tue, 20 Dec 2016 12:28:45 -0800

Hi,

I just checked the following YANG:

    container foo {
      status deprecated;
      leaf L1 {
         status current;
         type string;
      }
    }

pyang does not complain about it at all.
yangdump-pro issues a warning

Warning: Invalid status: child node 'L1' = 'current' and parent node 'foo'
= 'deprecated'
t1003.yang:9.7: warning(1024): invalid status for child node

IMO the status is inherited from its parent.
The entire subtree is deprecated or obsolete.
What does it even mean (from operations POV) to have an child nodes
that are current but the ancestors are not?

Andy

On Tue, Dec 20, 2016 at 12:15 PM, Juergen Schoenwaelder <
[email-masked]> wrote:

> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod
>

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 21 Dec 2016 10:16:43 +0100

> (through the useage of YANG validators) to detect and fix this.

Since "current" is the default, correctly deprecating a subtree would
mean to explicitly add the "status" statement to every single node in
the subtree.

I think that "obsolete" should apply to the whole subtree, no matter
what status descendants have, and "deprecated" should apply to the whole
subtree except for parts that are obsolete.

Lada

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

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 21 Dec 2016 10:32:08 +0100 (CET)

Yes.

> subtree except for parts that are obsolete.

Maybe, but this is not how it works in YANG 1 and 1.1.  For the
reasoning behind this, see above.  Maybe this is not perfect, and
something that we should look into if we update YANG.  But I don't
think this is a problem.

/martin

---

From: Andy Bierman <[email-masked]>
Date: Wed, 21 Dec 2016 01:52:30 -0800

> > mean to explicitly add the "status" statement to every single node in

Please explain what it means for YANG to say
"The parent node is deprecated and going away but the child nodes are not.
They are current and are staying around."  This does not seem to make any
sense.

Clearly an obsolete node removes all access of its descendant nodes.
There is no way to access /foo/child if /foo has been removed from the
server.
So how do I access a deprecated /foo/child node inside an obsolete /foo
container?

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 21 Dec 2016 10:52:49 +0100

> On 21 Dec 2016, at 10:32, Martin Bjorklund <[email-masked]> wrote:
> 

I think it is a problem. We can see a lot of these things before long because of the update rules. For example, it may apply to all the *-state trees, and tagging every single node therein with "deprecated" or "obsolete" is a useless exercise.

Lada

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 21 Dec 2016 11:54:38 +0100 (CET)

> They are current and are staying around."  This does not seem to make any

Agreed.  But this should be invalid also if the status statements are
given explicitly:

  container a {
    status deprecated;
    container b {
      status current;
    }
  }

Yes.

> So how do I access a deprecated /foo/child node inside an obsolete /foo

You can't.

/martin

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 21 Dec 2016 12:03:06 +0100 (CET)

Ladislav Lhotka <[email-masked]> wrote:
> I think it is a problem. We can see a lot of these things before
> long because of the update rules. For example, it may apply to all
> the *-state trees, and tagging every single node therein with
> "deprecated" or "obsolete" is a useless exercise.

I don't think it is a useless exercise.  It helps the reader to
quickly see that a node is deprecated, without having to search the
text for all ancestors' status.

/martin

---

From: Robert Wilton <[email-masked]>
Date: Wed, 21 Dec 2016 13:47:01 +0000

I think that it should be a error to have a current node under a 
deprecated node in the same module, and similarly for 
deprecated/obsolete.  I.e. to be consistent with the following text from 
7950 sec 7.21.2:

'If a definition is "current", it MUST NOT reference a "deprecated" 
or"obsolete" definition within the same module.'

I agree that it is useful if tools generate warnings if a module 
augments (or references) a deprecated or obsolete node (as per Juergen's 
comments below).

I don't have an issue with explicitly marking the child nodes as 
deprecated/obsolete, but intuitively I would have expected this to 
inherit like the config statement.

Rob

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 21 Dec 2016 14:57:27 +0100

> On 21 Dec 2016, at 14:47, Robert Wilton <[email-masked]> wrote:
> 
> I think that it should be a error to have a current node under a deprecated node in the same module, and similarly for deprecated/obsolete.  I.e. to be consistent with the following text from 7950 sec 7.21.2:
> 
> 'If a definition is "current", it MUST NOT reference a "deprecated" or"obsolete" definition within the same module.'
> 
> I agree that it is useful if tools generate warnings if a module augments (or references) a deprecated or obsolete node (as per Juergen's comments below).
> 
> I don't have an issue with explicitly marking the child nodes as deprecated/obsolete, but intuitively I would have expected this to inherit like the config statement.

+1

If everybody agrees that "current" under "deprecated"/"obsolete" is an error, then "current" shouldn't be the default in such situations.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Wed, 21 Dec 2016 08:21:08 -0800

> Agreed.  But this should be invalid also if the status statements are

IMO the default should be inherit from parent, like the config-stmt.
It clutters the YANG module to add a status-stmt to every descendant node.
The status also applies to augment.  If /foo is deprecated than any
external augments
that adds nodes under /foo is also deprecated.  (Most obvious when you
change deprecated
to obsolete).

>       status current;

I tested pyang with explicit statements and no warnings are given:

  container A {
    status deprecated;
    leaf AA {
      type string;
      status current;
    }
  }

  container B {
    status obsolete;
    leaf BB {
      type string;
      status current;
    }
  }

> > So how do I access a deprecated /foo/child node inside an obsolete /foo

So the status-stmt clearly applies to descendant-or-self.

Andy

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Wed, 21 Dec 2016 23:30:38 +0100

> It clutters the YANG module to add a status-stmt to every descendant node.

Yes, explicit status statements clutter the module but they make it
very explicit for the reader that stuff is deprecated or obsolete.  In
SMIv2, we had explicit status clauses everywhere and I have been a big
fan of making current a default so this does not clutter the
module. But I am also a big fan of making a status != current very
explicit so a reader knows for sure which definitions can be ignored.
(Perhaps it is just me but I often search in RFCs and/or YANG modules
and then having to track back the tree to find out whether something I
hit is deprecated or obsolete is a real burden. (In hindsight, I
probably would have preferred to have config true not inherited but
work like the status statement - having to search along the nesting
structure to find out what something means is actually not that reader
friendly - and bits are cheap these days. And the priority order back
in a day was 'readers first, writers second, tool makers last'.)

> external augments that adds nodes under /foo is also deprecated.
> (Most obvious when you change deprecated to obsolete).

I may disagree with this, in particular for 'deprecated'. Assuming
there are multiple organizations involved, I think we have a problem
if one organization can deprecate augmentations maintained by another
organization.

Deprecated essentially says 'this will go away, stop using it if you
can'.

> >       status current;

I think this example is actually not complete non-sense. It says 'this
container will go away, stop using it if you can'. There is still
something current under it and this should be fixed. And this is in
particular true for augmentations, e.g.,

augment /a {
  container c {
  }
}

should be OK - tools may generate warnings to tell the maintainer of
the augmentation to pay attention to the fact that /a may get retired.

Now, the IETF may decide that for published modules, something current
in a deprecated container is to be avoided. But this is then a policy
decision, from the language point of view I consider the case of
something current under a deprecated container not a real error.

/js

---

From: Andy Bierman <[email-masked]>
Date: Wed, 21 Dec 2016 14:47:49 -0800

Hi,

YANG data is hierarchical.
It makes no sense at all the consider the descendant nodes current
when the parent is deprecated or obsolete.  If the parent goes away
then it is impossible to access any descendant nodes, so the
default status of 'current' is meaningless in this case.

If you augment somebody else's subtree and they decide to deprecate
or obsolete it, your data is also deprecated or obsolete.
That's how hierarchcal data works.

Andy

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Thu, 22 Dec 2016 00:41:35 +0100

> That's how hierarchcal data works.

We disagree, in particular when it comes to deprecated. And as I
mentioned in a previous email, the bigger picture is not just about
containers and nesting hierarchies. We can deprecate typedefs,
groupings, we may deprecate a leaf that is referred to by other
leafrefs etc. With your idea that deprecating something means that
everything that directly or indirectly refers to this something gets
automatically deprecated as well, we may turn 'deprecated' into a
pointless tool.

In general, it is impossible to determine what all directly or
indirectly refers to a certain definition unless you have access to
all YANG modules in the world. So how can you ever take a decision to
deprecate something if there is no reliable way to assess the impact?
Hence, the deprecate status becomes effectively pointless. I rather
have an interpretation of deprecated that actually serves a purpose,
namely making maintainers of current definitions aware that their
current definitions depend on something now deprecated.

Perhaps I am blinded by the way @deprecate or __attribute__
((deprecated)) or [[deprecated]] work in various programming
languages. All these annotations do not deprecate my code, they just
cause the generation of warnings so that I get aware of the issue and
can do my homework.

/js

---

From: Andy Bierman <[email-masked]>
Date: Wed, 21 Dec 2016 15:55:16 -0800

> cause the generation of warnings so that I get aware of the issue and
There are no protocols that let you manage orphaned data nodes
without any parent.  No way to represent it in XML or JSON either.
No way to specify a RESTCONF target resource that leaves out
some intermediate data nodes.

It seems obvious that the deprecated warning (this node may go away)
also applies to all descendant nodes.  Once the node is changed from
deprecated to obsolete, all the descendant nodes are gone as well,
so ignoring the warning because YANG says the default is current seems
unwise.

/js

Andy

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Thu, 22 Dec 2016 01:13:46 +0100

> so ignoring the warning because YANG says the default is current seems

I have been writing about 'deprecated'. I can't say it more clearly.

/js

---

From: Andy Bierman <[email-masked]>
Date: Wed, 21 Dec 2016 16:15:51 -0800

> I have been writing about 'deprecated'. I can't say it more clearly.
So have I ...
This is hierarchical data.
If the parent goes away, so do the child nodes.
Seems quite simple to understand.

Andy

---

From: Randy Presuhn <[email-masked]>
Date: Wed, 21 Dec 2016 22:22:11 -0800

Hi -

On 12/21/2016 3:55 PM, Andy Bierman wrote:
>
>
> On Wed, Dec 21, 2016 at 3:41 PM, Juergen Schoenwaelder
> <[email-masked]
> <mailto:[email-masked]>> wrote:
...
> some intermediate data nodes.

Deprecating (or obsoleting) a definition does not orphan data nodes.
Perhaps I'm blinded by the way SNMP works, but it seems to me that
a robust client will need to be able to process data corresponding
to deprecated (or obsolete) definitions.  Likewise, developers
of server-side software may find themselves in situations where
supporting obsolete definitions is a commercial necessity.  Things
certainly played out that way in the SNMP world.  I agree with Juergen
that tool-generated warnings seem to be the correct way to go.

> deprecated to obsolete, all the descendant nodes are gone as well,

No, they're not *gone*.  The *advisability* of implementing them has
changed, but the definitions still exist, and implementer judgement
is still needed.  The change in status only means that a client is
less able to rely on the assumption that those definitions will be
supported by a given system - but there's very little that it can
rely on being implemented anyway, so it doesn't really change much
for a robust client.

> so ignoring the warning because YANG says the default is current seems

I do agree with this bit of conclusion, but sometimes after looking
at a warning and considering the larger context, ignoring the
warning *is* the right thing to do.

Randy

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 22 Dec 2016 08:49:44 +0100

> On 22 Dec 2016, at 07:22, Randy Presuhn <[email-masked]> wrote:
> 
> Hi -
> 

I agree that making a node deprecated or obsolete doesn't mean that its descendants are orphaned, it just means they cannot be current, and then "current" shouldn't be the default status for them - also because the descendants may come from other modules (via groupings and augments) that cannot be changed.

Even if the default status is inherited, tools can still generate warnings. A data modeller can decide whether and where it makes sense to have the "status" statement explicitly, but isn't forced to do it everywhere.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Thu, 22 Dec 2016 02:00:22 -0800

On Wed, Dec 21, 2016 at 11:49 PM, Ladislav Lhotka <[email-masked]> wrote:

> I agree that making a node deprecated or obsolete doesn't mean that its
> descendants are orphaned, it just means they cannot be current, and then
> "current" shouldn't be the default status for them - also because the
> descendants may come from other modules (via groupings and augments) that
> cannot be changed.
>
> Even if the default status is inherited, tools can still generate
> warnings. A data modeller can decide whether and where it makes sense to
> have the "status" statement explicitly, but isn't forced to do it
> everywhere.
>
>

NETCONF and RESTCONF have no mechanisms for accessing data other than
top-down from the top-level YANG data node to the target node.
Removing an ancestor node from the server implementation effectively removes
the entire subtree from the implementation.  (The value of the YANG
status-stmt
of the descendant nodes has nothing to do with it)

Andy

---

From: Robert Wilton <[email-masked]>
Date: Thu, 22 Dec 2016 10:16:17 +0000

On 22/12/2016 10:00, Andy Bierman wrote:
>
>
> On Wed, Dec 21, 2016 at 11:49 PM, Ladislav Lhotka <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>
>     > On 22 Dec 2016, at 07:22, Randy Presuhn
>     <[email-masked]
>     <mailto:[email-masked]>> wrote:
>     >
>     > Hi -
>     >
>     <mailto:[email-masked]>
>     >> <mailto:[email-masked]
>     <mailto:[email-masked]>>> wrote:
>     > ...
>     I agree that making a node deprecated or obsolete doesn't mean
>     that its descendants are orphaned, it just means they cannot be
>     current, and then "current" shouldn't be the default status for
>     them - also because the descendants may come from other modules
>     (via groupings and augments) that cannot be changed.
>
>     warnings. A data modeller can decide whether and where it makes
>     sense to have the "status" statement explicitly, but isn't forced
>     to do it everywhere.
>
>
>

I agree that this certainly seems to be the case if a node is marked as 
obsolete.  It seems that it implicitly forces all child nodes to be 
obsolete as well regardless of which module they were defined in.

Rob

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 22 Dec 2016 11:22:42 +0100 (CET)

Robert Wilton <[email-masked]> wrote:
> I agree that this certainly seems to be the case if a node is marked
> as obsolete.  It seems that it implicitly forces all child nodes to be

No I don't think this is correct.  If module B augment X in module A,
and X is obsolete, it does NOT mean that the augmented nodes in B are
automatically obsolete.  However, in an implementation that doesn't
implement X, the augmented nodes from B are obviously also not
implemented.

/martin

---

From: Robert Wilton <[email-masked]>
Date: Thu, 22 Dec 2016 10:39:45 +0000

> implement X, the augmented nodes from B are obviously also not
I can get where you are coming from, but if you had a GUI viewer that 
was looking at the combined schema tree, I think that you would to see 
those descendant children nodes marked in some way to indicate that 
implementations may validly not return them. Reporting them as current 
when one of their parent nodes was obsolete would seem to be deceptive.

Is it that you are trying to differentiate between being explicitly 
obsolete vs 'implicitly obsolete' through parentage?

Rob

> .

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 22 Dec 2016 11:49:40 +0100 (CET)

> obsolete vs 'implicitly obsolete' through parentage?

I think that within a module, if a parent is obsolete, then all its
child should also be obsolete (*).  But I do think that the status
should be explicitly stated.

But marking definition as obsolete in one module cannot automatically
make definitions in *other* modules obsolete.

(*) _maybe_ 7950 can be interpreted in this way when it says:

   If a definition is "current", it MUST NOT reference a "deprecated" or
   "obsolete" definition within the same module

If you're in a good mood, you could argue that a child always
"references" its parent.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 22 Dec 2016 11:53:48 +0100

> On 22 Dec 2016, at 11:00, Andy Bierman <[email-masked]> wrote:
> 
> 
> 
> the entire subtree from the implementation.  (The value of the YANG status-stmt

Expected server/protocol behaviour for nodes of a given status is specified in sec. 7.21.2 and IMO it is a different issue. What may need to be clarified wrt YANG is how to figure out the status of each node from the data model. In particular,

- what ancestor/descendant combinations of statuses are permitted

- what is the default if "status" statement is omitted.

Lada

---

From: Robert Wilton <[email-masked]>
Date: Thu, 22 Dec 2016 11:24:31 +0000

> should be explicitly stated.
OK.  I assume that this statement applies to deprecated as well.  I 
don't feel particularly strongly on this point.  If you mark something 
as obsolete/deprecated, then explicitly having to find and mark all 
references/children doesn't seem like a bad thing because it makes the 
full impact obvious (if pyang is enhanced to check for this).

> make definitions in *other* modules obsolete.
I'm not so sure.

It seems to me that in practice, they are directly equivalent as if they 
were marked as obsolete.  I.e. clients cannot rely on them being 
available because the obsolete parent may not be implemented.

If the augmenting module wants to keep those nodes, then their only 
choice seems to be to explicitly mark them as obsolete, and make a copy 
of the nodes augmenting somewhere else in the schema tree.

> If you're in a good mood, you could argue that a child always
Would it not be better to add some sort of explicit statement as an 
errata to 7950 (once there is agreement on what it should say)?  Or is 
this beyond the scope of what an errata is allowed to do?

Rob

---

From: Andy Bierman <[email-masked]>
Date: Thu, 22 Dec 2016 12:39:20 -0800

On Thu, Dec 22, 2016 at 3:24 AM, Robert Wilton <[email-masked]> wrote:

>>>>>>       >>    cause the generation of warnings so that I get aware of
>>>>>> the
>>>>>>       issue and
>>>>>>       >>    can do my homework.
>>>>>>       >>
>>>>>>       >>
> OK.  I assume that this statement applies to deprecated as well.  I don't
> feel particularly strongly on this point.  If you mark something as
> obsolete/deprecated, then explicitly having to find and mark all
> references/children doesn't seem like a bad thing because it makes the full
> impact obvious (if pyang is enhanced to check for this).
>
>
> were marked as obsolete.  I.e. clients cannot rely on them being available
> because the obsolete parent may not be implemented.
>
> If the augmenting module wants to keep those nodes, then their only choice
> seems to be to explicitly mark them as obsolete, and make a copy of the
> nodes augmenting somewhere else in the schema tree.
>
>
>
> Would it not be better to add some sort of explicit statement as an errata
> to 7950 (once there is agreement on what it should say)?  Or is this beyond
> the scope of what an errata is allowed to do?
>
>
I think the current text is pretty bad.
The term "references" is not very useful and it is not defined anywhere.
IMO a child node implicitly references its parent.  Any child node
could be refactered as an augment:

   container X {
      status obsolete;
      leaf Y {}
   }

equivalent to:

  augment /X {
     leaf Y {}
  }

  container X {
     status obsolete;
  }

Does the augment reference X?  I would say yes.

Even more distressing to me is that the definition of 'obsolete'
says SHOULD NOT implement.  There is no guidence on when
it is OK to ignore the SHOULD NOT.

Also, a deviation-stmt is not allowed to alter the status-stmt.
This seems wrong.  There is no discovery mechanism for a client
to reliably determine what the server implements.

I would prefer that the server advertise a deviation stating explicity
that the server is ignoring the status-stmt

  deviation /X {
     deviate replace {
        status deprecated;
     }
  }

But this is not even permitted by the YANG language.

Andy

---

From: Robert Varga <[email-masked]>
Date: Fri, 23 Dec 2016 01:45:11 +0100

> - what is the default if "status" statement is omitted.

I agree with Andy's view when a single module is concerned. In this 
sense "references" == "its ability to be accessed is granted by being a 
descendant of". I think we may have to have more complex rules taking 
into account enclosing statement and inter-module relationships: what 
harm is done by instantiating an obsolete grouping?

Unfortunately we cannot legally prohibit 'status current' from appearing 
in an augmented (or refined) case from a different module, as not 
breaking downstream models seems to be obsolete's raison d'etre (based 
on 7950 section 11).

Hence the effective status of any 'status current' nodes with an 
obsolete ancestor should be obsolete. I do not think it should be 
required to issue more than a warning.

Regards,
Robert

---

From: Ladislav Lhotka <[email-masked]>
Date: Fri, 23 Dec 2016 14:06:12 +0100

> make definitions in *other* modules obsolete.

OK, so what information is "current/deprecated/obsolete" supposed to
convey? If we interpret it as likelihood that the node is implemented,
then it is clear that no node is more likely to be implemented that any
of its ancestors.

If the target node of an augment isn't implemented because it is
obsolete, then the augment cannot be applied, no matter how we classify
its contents.

> If you're in a good mood, you could argue that a child always

Whatever mood I am in, an augment certainly references its target node,
so according to the above rule it cannot be current unless the target
node is also current.

Lada