Subject: [Netconf] ietf-netconf.yang (2)

From: Andy Bierman <[email-masked]>
Date: Tue, 14 Apr 2009 09:32:28 -0700

Hi,

Here is the updated version based on Martin's comments.

IMO, the total lack of support in YANG for NETCONF capabilities
is a mistake.  It leaves a big hole in the tool automation chain,
for a very basic feature of the NETCONF architecture.  It forces
simple boolean logic into description statements, where it must
be read by every single implementor, the English text understood
correctly, and then manually implemented correctly.

This is not just some corner-case, because this module happens
to be netconf.yang.  The ietf-partial-lock data model is designed
to utilize the :xpath capability, and is only defined in description
statements.  The ietf-netconf-state data model contains
sections which are only relevant if :notifications is supported,
or if :partial-lock is supported.  Again, only defined in
description statements.

So, out of the 4 very first 'content layer' standard data models,
(not counting netconf.yang) half of them need an 'if-capability'
statement. That seems like a pretty solid use-case to me.

Andy

module ietf-netconf {

   namespace "urn:ietf:params:xml:ns:netconf:base:1.0";

   prefix nc;

   // for the uri data type
   import ietf-inet-types { prefix inet; }

   description 
      "NETCONF Protocol 
        * Simple Data Types
        * RPC methods
      ";

   reference
      "Translated from RFC 4741.";

   contact
     "TBD: WG contact info here";

   revision 2009-04-14 {
     description 
       "Initial version (2)";
   }

   extension get-filter-element-attributes {
      description
        "If this extension is present within the
         an 'anyxml' statement named 'filter', which must be
         conceptually defined within the RPC input section
         for the 'get' and 'get-config' RPC operations,
         then the following unqualified XML attribute is
         supported within the 'filter' element, within
         a 'get' or 'get-config' protocol operation:

           type : optional attribute with allowed
                  value strings 'subtree' and 'xpath'.
                  If missing, the default value is 'subtree'.

         If the xpath feature is supported, then the
         following unqualified XML attribute is
         also supported:

           select: optional attribute containing a
                   string representing an XPath expression.
                   The 'type' attribute must be equal to 'xpath'
                   if this attribute is present.";
   }

   // NETCONF Simple Types

   typedef SessionId {
     description "NETCONF Session Id";
     type uint32 {
       range "1..max"; 
     }
   }

   typedef SessionIdOrZero {
     description 
       "NETCONF Session Id or Zero to indicate none";
     type uint32; 
   }

   typedef ErrorType {
     description "NETCONF Error Type";
     type enumeration {
       enum transport;
       enum rpc;
       enum protocol;
       enum application;
     }
   }

   typedef ErrorTag {
     description "NETCONF Error Tag";
     type enumeration { 
       enum in-use;
       enum invalid-value;
       enum too-big;
       enum missing-attribute;
       enum bad-attribute;
       enum unknown-attribute;
       enum missing-element;
       enum bad-element;
       enum unknown-element;
       enum unknown-namespace;
       enum access-denied;
       enum lock-denied;
       enum resource-denied;
       enum rollback-failed;
       enum data-exists;
       enum data-missing;
       enum operation-not-supported;
       enum operation-failed;
       enum partial-operation;
     }
   }

   typedef ErrorSeverity {
     description "NETCONF Error Severity";
     type enumeration { 
       enum error;
       enum warning;
     }
   }

   typedef TestOptionType {
     description 
       "NETCONF 'test-option' Element Content.
        This is extended with the test-only enumeration.
        The 'set' option has no real effect since
        the entire PDU is always validated before any
        of it is applied (always test-then-set).";
     type enumeration {
       enum test-then-set;
       enum set;
       //  enum test-only;   !!!! not part of the standard yet
     }
     default "set";
   }

   typedef ErrorOptionType {
     description "NETCONF 'error-option' Element Content";
     type enumeration { 
       enum stop-on-error;
       enum continue-on-error;
       enum rollback-on-error;
     }
     default "stop-on-error";
   }

   typedef EditOperationType {
     description "NETCONF 'operation' Attribute Content";
     type enumeration { 
       enum merge;
       enum replace;
       enum create;
       enum delete;
     }
     default "merge";
   }

   typedef DefaultOperationType {
     description "NETCONF 'default-operation' Element Content";
     type enumeration { 
       enum merge;
       enum replace;
       enum none;
     }
     default "merge";
   }

   typedef ConfirmTimeoutType {
     description 
       "NETCONF 'confirm-timeout' Element Content";
     type uint32 { 
       range "1..max";
     }
     units "seconds";
     default "600";   // 10 minutes
   }

   typedef ConfigURIType {
     type inet:uri;
   }

   // NETCONF Standard RPC Methods

   rpc get-config {
      description
        "Retrieve all or part of a specified configuration.";

      reference "RFC 4741, section 7.2";

      input {
        container source {
          description "Particular configuration to retrieve.";

          choice config-source {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf running {
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
          }
        }

        anyxml filter {
          description "Subtree or Xpath filter to use.";
          nc:get-filter-element-attributes;
        }
      }

      output {
        container data {
          description 
            "Copy of the source database subset which matched
             the filter criteria (if any).";
          presence 
            "An empty data container indicates that the
             request did not produce any results.";
       }
     }
   }

   rpc edit-config {
      description
        "The 'edit-config' operation loads all or part of a specified
         configuration to the specified target configuration.  This
         operation allows the new configuration to be expressed in several
         ways, such as using a local file, a remote file, or inline.  If
         the target configuration does not exist, it will be created.  If a
         NETCONF peer supports the :url capability (Section 8.8), the <url>
         element can appear instead of the <config> parameter and should
         identify a local configuration file.

         The device analyzes the source and target configurations and
         performs the requested changes.  The target configuration is not
         necessarily replaced, as with the <copy-config> message.  Instead,
         the target configuration is changed in accordance with the
         source's data and requested operations.";

      reference "RFC 4741, section 7.2";

      input {
        container target {
          description "Particular configuration to edit.";

          choice config-target {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf running {
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
          }
        }

        leaf default-operation {
          description 
            "Default operation to apply if not explicitly set.";
          type DefaultOperationType;
        }

        leaf test-option {
          description 
            "Test option if validate capability supported.
             The 'validate' capability must be present to set
             this object to 'test-then-set'.";
          type TestOptionType;
        }

        leaf error-option {
          description "Error recovery option.";
          type ErrorOptionType;
        }

        choice edit-content {
          mandatory true;
          container config {
            description 
              "Inline Config content: 'config' element.";
          }
          leaf url {
            description 
              "Pointer to Config content: 'url' element.";
            type ConfigURIType;
          }
        }
      }
   }

   rpc copy-config {
      description
        "Create or replace an entire configuration datastore with the
         contents of another complete configuration datastore.  If the
         target datastore exists, it is overwritten.  Otherwise, a new one
         is created, if allowed.

         If a NETCONF peer supports the :url capability (Section 8.8), the
         'url' element can appear as the <source> or <target> parameter.

         Even if it advertises the :writable-running capability, a device
         may choose not to support the <running/> configuration datastore
         as the <target> parameter of a <copy-config> operation.  A device
         may choose not to support remote-to-remote copy operations, where
         both the <source> and <target> parameters use the <url> element.

        If the source and target parameters identify the same URL or
        configuration datastore, an error MUST be returned with an error-
        tag containing invalid-value.";

      reference "RFC 4741, section 7.3";

      input {
        container target {
          description "Particular configuration to copy to.";

          choice config-target {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf running {
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
          }
        }

        container source {
          description "Particular configuration to copy from.";

          choice config-source {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf running {
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
          }
        }
      }
   }

   rpc delete-config {
      description
        "Delete a configuration datastore.  The 'running' configuration
         datastore cannot be deleted.

         If a NETCONF peer supports the :url capability (Section 8.8), the
         'url' element can appear as the <target> parameter.";

      reference "RFC 4741, section 7.4";

      input {
        container target {
          description "Particular configuration to delete.";

          choice config-target {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
          }
        }
      }
   }

   rpc lock {
      description
        "The lock operation allows the client to lock the configuration
         system of a device.  Such locks are intended to be short-lived and
         allow a client to make a change without fear of interaction with
         other NETCONF clients, non-NETCONF clients (e.g., SNMP and command
         line interface (CLI) scripts), and human users. ...";

      reference "RFC 4741, section 7.5";

      input {
        container target {
          description "Particular configuration to lock";

          choice config-target {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf running {
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
          }
        }
      }
   }

   rpc unlock {
      description
        "The unlock operation is used to release a configuration lock,
         previously obtained with the 'lock' operation.

         An unlock operation will not succeed if any of the following
         conditions are true:

         *  the specified lock is not currently active

         *  the session issuing the <unlock> operation is not the same
            session that obtained the lock

         The server MUST respond with either an <ok> element or an
         'rpc-error'.";

      reference "RFC 4741, section 7.6";

      input {
        container target {
          description "Particular configuration to unlock.";

          choice config-target {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf running {
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
          }
        }
      }
   }

   rpc get {
      description
        "Retrieve running configuration and device state information.";

      reference "RFC 4741, section 7.7";

      input {
        anyxml filter {
          description
            "This parameter specifies the portion of the system
             configuration and state data to retrieve.  If this parameter is
             empty, all the device configuration and state information is
             returned.

             The filter element may optionally contain a 'type' attribute.
             This attribute indicates the type of filtering syntax used
             within the filter element.  The default filtering mechanism in
             NETCONF is referred to as subtree filtering and is described in
             Section 6.  The value 'subtree' explicitly identifies this type
             of filtering.

             If the NETCONF peer supports the :xpath capability
             (Section 8.9), the value 'xpath' may be used to indicate that
             the select attribute of the filter element contains an XPath
             expression.";
          nc:get-filter-element-attributes;
        }
      }

      output {
        container data {
          description 
            "Copy of the 'running' database subset which matched
             the filter criteria (if any).";
          presence 
            "An empty data container indicates that the
             request did not produce any results.";
        }
      }
   }

   rpc close-session {
      description
        "Request graceful termination of a NETCONF session.

         When a NETCONF server receives a <close-session> request, it will
         gracefully close the session.  The server will release any locks
         and resources associated with the session and gracefully close any
         associated connections.  Any NETCONF requests received after a
         'close-session' request will be ignored.";

      reference "RFC 4741, section 7.8";
   }

   rpc kill-session {
      description
        "Force the termination of a NETCONF session.

         When a NETCONF entity receives a <kill-session> request for an
         open session, it will abort any operations currently in process,
         release any locks and resources associated with the session, and
         close any associated connections.

         If a NETCONF server receives a <kill-session> request while
         processing a confirmed commit (Section 8.4), it must restore the
         configuration to its state before the confirmed commit was issued.

         Otherwise, the <kill-session> operation does not roll back
         configuration or other device state modifications made by the
         entity holding the lock.";

      reference "RFC 4741, section 7.9";

      input {
        leaf session-id {
          description "Particular session to kill.";
          type SessionId;
          mandatory true;
        }
      }
   }

   rpc commit {
      description
        "Only available if 'candidate' capability is supported.

         When a candidate configuration's content is complete, the
         configuration data can be committed, publishing the data set to
         the rest of the device and requesting the device to conform to
         the behavior described in the new configuration.

         To commit the candidate configuration as the device's new
         current configuration, use the <commit> operation.

         The 'commit' operation instructs the device to implement the
         configuration data contained in the candidate configuration.
         If the device is unable to commit all of the changes in the
         candidate configuration datastore, then the running
         configuration MUST remain unchanged.  If the device does
         succeed in committing, the running configuration MUST be
         updated with the contents of the candidate configuration.

         If the system does not have the :candidate capability, the
         'commit' operation is not available.";

      reference "RFC 4741, section 8.3.4.1";

      input {
        leaf confirmed {
          description 
            "Request a confirmed commit.  Only available if 
             'confirmed-commit' capability is supported.";
          reference "RFC 4741, section 8.4.5.1";
          type empty;
        }

        leaf confirm-timeout {
          description 
            "Request a specific timeout period for a confirmed commit
             if 'confirmed-commit' capability supported.";
          reference "RFC 4741, section 8.4.5.1";
          type ConfirmTimeoutType;
        }
      }
   }

   rpc discard-changes {
      description
        "Only available if 'candidate' capability is supported.

         If the client decides that the candidate configuration should not be
         committed, the 'discard-changes' operation can be used to revert the
         candidate configuration to the current running configuration.

         This operation discards any uncommitted changes by resetting the
         candidate configuration with the content of the running
         configuration.";

      reference "RFC 4741, section 8.3.4.2";
   }

   rpc validate {
      description
         "Only available if 'validate' capability is supported.

          Validates the contents of the specified configuration.";

      reference "RFC 4741, section 8.6.4.1";

      input {
        container source {
          description "Particular configuration to validate.";

          choice config-source {
            mandatory true;

            leaf candidate {
              description 
                "Only available if 'candidate' capability supported.";
              type empty;
            }
            leaf running {
              type empty;
            }
            leaf startup {
              description 
                "Only available if 'startup' capability supported.";
              type empty;
            }
            leaf url {
              description 
                "URL pointing to config data. Only available
                 if 'url' capability supported.";
              type ConfigURIType;
            }
            container config {
              description 
                "Inline Config content: 'config' element.";
            }
          }
        }
      }
   }

}

---

From: Andy Bierman <[email-masked]>
Date: Sun, 26 Apr 2009 08:54:58 -0700

> Here is the updated version based on Martin's comments.

I did not get any comments on the YANG module
or the total lack of support for NETCONF capabilities.

There is a disconnect between how the NETMOD WG views
the data modeling world and how standard NETCONF data models
already in place are using capabilities.

The claim is that capabilities are not needed in YANG
because they are for the protocol layer, and features
are for the content layer.  This assertion has proven
to be false in 2 of the first 4 YANG standard data models.

The result is that any YANG file that tries to describe
capability-based constructs is really describing a superset
of all possible versions -- just like XSD, and just as worthless.

A schema that works for all possible implementations
but doesn't work for any specific implementation is
not that useful to real CM work.

I suggest that the NETCONF and NETMOD WGs think about
this problem some more.

Andy

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

---

From: WashamFan <[email-masked]>
Date: Mon, 27 Apr 2009 12:16:26 +0800

>    ... ...
>    ... ...

If set option has no real effect, why not leave out this option? And
the relevant text in RFC4741 says the test-option is supported by :validate
capability, can we still say that again?

>     ... ...

Should be 7.1 instead.

>               request did not produce any results.";

Why not use 'anyxml data;' as in sec 7.10.4, yang-05?

>            description "Error recovery option.";

I think we should state clearly that rollback-on-error can be used only if
:rollback capability is supported.

>                "Pointer to Config content: 'url' element.";

I can not find any text in RFC4741 defining the use of url as above.

> ... ...

washam

---

From: Andy Bierman <[email-masked]>
Date: Sun, 26 Apr 2009 21:43:19 -0700

> capability, can we still say that again?

oops.  that is my editorial text,
not from RFC 4741.

I'm not sure what 'set' means.
If it means the manager is supposed to be capable
of injecting any data into the <running> config
without the agent checking it, then no, thanks.
No way, no how is my code going to knowingly inject
data without validating first.  IMO, database integrity
is a fairly important part of NETCONF.  I think there
are other implementations where 'set' and 'test-then-set'
do the same thing as well.

>>        reference "RFC 4741, section 7.2";

OK

> Why not use 'anyxml data;' as in sec 7.10.4, yang-05?

because this RPC function will not return <data> as a leaf.
There will always be element node children of the data element.
If the filter yields no results, then <data/> is the result,
indicating no accessible data was found matching the filter.

> :rollback capability is supported.

OK

> I can not find any text in RFC4741 defining the use of url as above.

8.8.5.1.  <edit-config>

    The :url capability modifies the <edit-config> operation to accept
    the <url> element as an alternative to the <config> parameter.  If
    the <url> element is specified, then it should identify a local
    configuration file.

note the lowercase 'should' instead of SHOULD or MUST.
It means the agent can accept whatever it wants (as
advertised in the :url capability 'schemes' parameter).

Andy

---

From: Phil Shafer <[email-masked]>
Date: Mon, 27 Apr 2009 09:24:25 -0400

>do the same thing as well.

And there are implementations where "set" means the requested changes
immediately affect the configuration.  For candidate config, this
works quite well, and for running, it may be integral to your data
model.  For example, if your data model maps directly into cli
commands, the data may map to directly issuing those underlaying
commands.

One of the strengths of NETCONF is that there is flexibility to
allow multiple views of configuration data to coexist under one
protocol.  We didn't set out to make the world fall into a single
uniform view, but to allow the device to define and document how
data is handled in a way that allows client applications to have
sufficient insight to manipulate a configuration properly and
effectively.

Thanks,
 Phil