Subject: [netmod] Y09 introduce optional keys

From: Martin Bjorklund <[email-masked]>
Date: Thu, 07 Aug 2014 20:07:57 +0200 (CEST)

Hi,

Here is a proposal for how to introduce optional keys.

In summary, we allow a key leaf to be marked as "mandatory false", and
also allow such a leaf to have a default value.  All key leafs can be
optional, but a list instance MUST have at least one of the key leafs
instantiated, in order to be able to uniquely identify each instance.
The combination of all given keys MUST be unique.

For example, with the list:

   list foo {
     key "a b";
     leaf a {
       type string;
       mandatory false;
     }
     leaf b {
       type string;
       mandatory false;
     }
   }

We might have:

   <foo>
     <a>hi</a>
   </foo>
   <foo>
     <b>hi</b>
   </foo>
   <foo>
     <a>hi</hi>
     <b>mom</b>
   </foo>

One way of viewing this is that if a list instance does not have a
certain key instantiated, its value is NULL (or its defualt).  So in
the example above we have the tree instances:

   ("hi", NULL)
   (NULL, "hi")
   ("hi", "mom")

------

In order to allow this, the following changes need to be done.

In section 7.6.5, The leaf's mandatory Statement:

OLD:

   The "mandatory" statement, which is optional, takes as an argument
   the string "true" or "false", and puts a constraint on valid data.
   If not specified, the default is "false".

   If "mandatory" is "true", the behavior of the constraint depends on
   the type of the leaf's closest ancestor node in the schema tree that
   is not a non-presence container (see Section 7.5.1):

NEW:

   The "mandatory" statement, which is optional, takes as an argument
   the string "true" or "false", and puts a constraint on valid data.
   If not specified, the default is "false" for leafs that are not
   list keys, and "true" for leafs that are list keys.

   For leafs that are not list keys, if "mandatory" is "true", the
   behavior of the constraint depends on the type of the leaf's
   closest ancestor node in the schema tree that is not a non-presence
   container (see Section 7.5.1):

And add NEW:

   For a leaf that is a list key, if "mandatory" is "true", the leaf
   MUST exist in a list instance.

In section 7.8.2.  The list's key Statement:

OLD:

   The combined values of all the leafs specified in the key are used to
   uniquely identify a list entry.  All key leafs MUST be given values
   when a list entry is created.  Thus, any default values in the key
   leafs or their types are ignored.  It also implies that any mandatory
   statement in the key leafs are ignored.

   A leaf that is part of the key can be of any built-in or derived
   type, except it MUST NOT be the built-in type "empty".

NEW:

   The combined values of all the leaf instances specified in the key,
   including leafs with default values, are used to uniquely identify
   a list entry.  All key leafs that are marked as mandatory MUST be
   given values when a list entry is created.  A list instance MUST
   have at least one key leaf instantiated.

   A leaf that is part of the key can be of any built-in or derived
   type.

In section 7.8.3.1.  Usage Example:

Add this:

  With the following list:

    list target {
      key "ip vrf";
      leaf ip {
        type inet:ip-address;
      }
      leaf vrf {
        type string;
      }
      ...
    }

  the following configuration is valid:

    <target>
      <ip>192.0.2.1</ip>
    </target>
    <target>
      <ip>192.0.2.1</ip>
      <vrf>vrf-2</vrf>
    </target>

In section 7.8.6.  NETCONF <edit-config> Operations:

OLD:

   List entries can be created, deleted, replaced, and modified through
   <edit-config>, by using the "operation" attribute in the list's XML
   element.  In each case, the values of all keys are used to uniquely
   identify a list entry.  If all keys are not specified for a list
   entry, a "missing-element" error is returned.

NEW:

   List entries can be created, deleted, replaced, and modified through
   <edit-config>, by using the "operation" attribute in the list's XML
   element.  In each case, the values of all instantiated keys are
   used to uniquely identify a list entry.  If a mandatory key is not
   specified for a list entry, a "missing-element" error is returned.

In secrion 9.13.  The instance-identifier Built-In Type:

OLD:

   For
   identifying list entries with keys, each predicate consists of one
   equality test per key, and each key MUST have a corresponding
   predicate.

NEW:

   For
   identifying list entries with keys, each predicate consists of one
   equality test per existing key leaf.

/martin

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Thu, 7 Aug 2014 20:35:14 +0200

Martin,

can you update Y09-01 in the issues list with this more detailed
proposal? (Or add Y09-02 if you think this is different from what
Y09-01 says today.)

Thanks,

/js

On Thu, Aug 07, 2014 at 08:07:57PM +0200, Martin Bjorklund wrote:
> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod

-- 
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: Martin Bjorklund <[email-masked]>
Date: Thu, 07 Aug 2014 20:43:24 +0200 (CEST)

> proposal? (Or add Y09-02 if you think this is different from what

Done.

/martin

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Fri, 8 Aug 2014 07:56:25 +0200

Martin,

two quick questions/comments:

a) Is it allowed to add an optional key while revising a YANG module?

b) It seems to be not possible to augmentation an optional key (e.g. a
   VRF) since this would require to replace the 'key' statement. (In
   hindsight, perhaps it would have been better to mark the leafs that
   form the key instead of listing them in a key statement.)

/js

---

From: Martin Bjorklund <[email-masked]>
Date: Fri, 08 Aug 2014 09:44:34 +0200 (CEST)

> a) Is it allowed to add an optional key while revising a YANG module?

Yes I think so.

  In section 10.  Updating a Module:

  NEW:

    #+BEGIN_EXAMPLE
    o  A new leaf may be added to the "key" statement, provided the leaf
       is optional.
    #+END_EXAMPLE

>    form the key instead of listing them in a key statement.)

Maybe.  OTOH augmenting an optional key is not safe for old clients.

/martin

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Fri, 8 Aug 2014 09:53:58 +0200

> Maybe.  OTOH augmenting an optional key is not safe for old clients.

Why is it unsafe for an old client? How is this different from adding
an optional key during a revision of a module?

/js

---

From: Martin Bjorklund <[email-masked]>
Date: Fri, 08 Aug 2014 10:02:37 +0200 (CEST)

Juergen Schoenwaelder <[email-masked]> wrote:
> Why is it unsafe for an old client?

Suppose we had:

   list target {
     key "ip";
     ...
   }

And a client understands that.  The someone (somwhow) augments "vrf"
as an additional optional key.  We might now have entries:

   (10.0.0.1, "vrf-1")
   (10.0.0.1, "vrf-2")

But the client that doesn't know about the augmentation sees

   (10.0.0.1)
   (10.0.0.1)

which doesn't work.

> How is this different from adding

B/c in this case there is a new revision of the module, so the client
knows that what it has might not completely work (module the upgrade
rules).

The important difference is that the client can detect this situation,
but not the augment situation.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 11 Aug 2014 11:37:59 +0200

> In section 7.8.3.1.  Usage Example:

"mandatory false;" should be here, right?

We should also get rid of the CLR that keys cannot be of type "empty",
see Y09-01.

Lada

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

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 11 Aug 2014 11:48:30 +0200

>    form the key instead of listing them in a key statement.)

This possibility is IMO quite needed. One use case is the list of static
routes: an easy and elegant solution would be to define "destination-prefix" as the
only key in the core routing model, and allow new keys to be added via
augments. The inability of doing so leads to bogus "id" keys that are
confusing and annoying.

Lada

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 11 Aug 2014 11:53:52 +0200

> But the client that doesn't know about the augmentation sees

I don't agree. The client does see the augmenting module, and this
information cannot be freely ignored.

Lada