<as a contributor>
Following Lou’s recommendation, my proposed changes for rfc6087bis Section 5.23
follow:
5.23. Operational Data
In YANG, any data that has a "config" statement value of "false"
could be considered operational data. The relationship between
configuration (i.e., "config" statement has a value of "true") and
operational data can be complex.
- One challenge for client developers is determining if the configured
- value is being used, which requires the developer to know which
- operational data parameters are associated with the particular
+ One challenge for client applications is determining if a configured
+ value is being used, which requires the application to know which
+ operational data parameters are associated with a particular
configuration object (or group of objects).
In the simplest use-cases, there is no interaction between
configuration and operational data. For example, the arbitrary
administrative name or sequence number assigned to an access control
rule. The configured value is always the value that is being used by
the system.
However, some configuration parameters interact with routing and
- other signalling protocols, such that the operational value in use by
+ other signaling protocols, such that the operational value in use by
the system may not be the same as the configured value. Other
parameters specify the desired state, but environmental and other
factors can cause the actual state to be different.
- For example a "temperature" configuration setting only represents the
+ For example, a "temperature" configuration setting only represents the
desired temperature. An operational data parameter is needed that
reports the actual temperature in order to determine if the cooling
system is operating correctly. YANG has no mechanism other than the
"description" statement to associate the desired temperature and the
actual temperature.
[Editor’s Note: we should define a ‘related-config’ statement ASAP!]
Careful consideration needs to be given to the location of
operational data. It can either be located within the configuration
subtree for which it applies, or it can be located outside the
particular configuration subtree. Placing operational data within
- the configuration subtree is appropriate if the operational values
- can only exist if the configuration exists.
+ the configuration subtree is ideal, as the association between the
+ configuration and operational state is clear. However, doing so must
+ be done with the knowledge that NETCONF and RESTCONF can
+ currently only return the operational state for configured values,
+ not system generated values such as system created interfaces or
+ routing table entries. This is because the config false nodes are
+ descendants of config true nodes and hence cannot be returned
+ for nodes that haven’t been configured. At least, this is the case
+ for how NETCONF and RESTCONF currently support returning
+ mixed config true and config false content.
- The "interfaces" and "interfaces-state" subtrees defined in [RFC7223]
- are an example of a complex relationship between configuration and
- operational data. The operational values can include interface
- entries that have been discovered or initialized by the system. An
- interface may be in use that has not been configured at all.
- Therefore, the operational data for an interface cannot be located
- within the configuration for that same interface.
+ In order to support returning operational state for system generated
+ values, some YANG module designers have created a parallel top-level
+ config false hierarchy that mirrors the structure of the config true
+ hierarchy. For instance, this is seen in the ‘interfaces-state’ node in
+ [RFC7223]. By doing this, it enables the operational state for system
+ generated values to be returned, since then all the ancestor nodes are
+ config false as well. However, this approach is not ideal as it leads to
+ needing to maintain duplicate structures and also requires the use of
+ description statements to describe the association between the two
+ structures.
+ To address this situation, the NETMOD and NETCONF working groups
+ are at this time in the process of defining a holistic operational state
+ solution that entails both a revised conceptual datastore model and
+ the necessary protocol extensions to enable, in part, both NETCONF
+ and RESTCONF to be able to return operational state for system
+ generated values using the same config true hierarchy used to return
+ the operational state for configured values.
+ This being the case, it is RECOMMENDED that YANG module designers
+ always mix config true and config false nodes into a single hierarchy.
+ This is so the YANG modules will be in proper form for when the
+ holistic operational state solution is available. To address any
+ immediate needs to also report the operational state for system
+ generated values, it is RECOMMENDED to define a second module
+ that imports the first module and defines a parallel top-level
+ config false hierarchy that mirrors the structure of the config true
+ hierarchy in the first module. This recommendation is made to
+ enable NETCONF/RESTCONF servers supporting the finalized
+ opstate solution to choose when to stop supporting the second
+ module, as it would then only be needed to support legacy
+ opstate-unaware clients.
FOUR SCENARIOS:
1) an opstate-unaware server might only support “ietf-foo”, as it is deemed
unnecessary to provide the operational state for system-generated bars. A
client can get the operational state for just the configured bars using
NETCONF’s <get> or RESTCONF’s content ‘all’ query parameter.
2) an opstate-unaware server might support both “ietf-foo” and
“ietf-foo-state”, as it is deemed important to provide the operational state
for system-generated bars. Same as above, a client can get the operational
state for just the configured bars, when targeting the “ietf-foo” module.
Better though, a client can get the operational state for both configured and
system-generated bars together when targeting the “ietf-foo-state” module. A
client that is savvy enough to do this would of course not want the redundant
operational state data from the ietf-foo module and therefore would likely only
use NETCONF’s <get-config> and/or RESTCONF’s content ‘config’ query parameter
when targeting the “ietf-foo” module.
3) an opstate-aware server might only support “ietf-foo”, as it can provide the
operational state for both configured and system-generated bars using protocol
mechanisms defined by the holistic opstate solution (e.g., via an “operational”
datastore), and it doesn’t care about enabling legacy opstate-unaware clients
to be able to obtain the operational state for the system generated bars.
4) an opstate-aware server might support both “ietf-foo” and “ietf-foo-state”,
so that it can provide the operational state for both configured and
system-generated bars to both opstate-aware and opstate-unaware clients. This
is hopefully a temporary condition as eventually the clients will be upgraded
to be opstate-aware and then the vendor can deprecate support for the
ietf-foo-state module.
WHY IMPORT? The text above includes the statement “it is RECOMMENDED to
define a second module that imports the first module”. Technically, there
isn’t a need for the import as of yet, but I’m very much thinking that we
should *quickly* define a YANG statement called “related-config” that allows
the client to programmatically related which config true nodes in the first
module might are associated to the config false nodes in the second module.
Obviously, this would only make the association for configured values, and the
client could assume that any key-misses are the result of the that operational
state being for a system-generated value. The association has to be in that
direction because config false nodes can point to config true nodes, but not
visa versa.
<EXAMPLE>
Assume we have module “ietf-foo” as follows:
module ietf-foo {
namespace “foo-namespace”;
container foo {
list bar {
key a;
leaf a {
type string;
}
leaf b {
type int8;
config false;
}
}
}
}
whereby it’s possible that the system may generate some bars as well. To
address this, we create a second module “ietf-foo-state” (ideally using tool)
that discards are the config true leafs and sets the entire tree to config
false. The resulting module follows:
module ietf-foo-state {
namespace “foo-state-namespace”;
import ietf-foo { prefix “f”; }
container foo-state {
config false; <-- everything below is config false
list bar {
key a;
related-config { <-- config false point to config true (only present
for *configured* bars)
path “/f:foo/f:bar/f:a”
}
leaf a { <-- this “config true” leaf is kept only because it’s the key
(but now it’s config false)
type string;
}
leaf b {
type int8;
config false;
}
}
}
}
</EXAMPLE>
<SNIP - I didn’t try to rewrite any of the below stuff from Section 5.23. Some
of it would be obsolete from the text above, but other parts may still be
useful...>
Sometimes the configured value represents some sort of procedure to
be followed, in which the system will select an actual value, based
on protocol negotiation.
leaf duplex-admin-mode {
type enumeration {
enum auto;
enum half;
enum full;
}
}
leaf duplex-oper-mode {
config false;
type enumeration {
enum half;
enum full;
}
}
For example a "duplex" mode configuration may be "auto" to auto-
negotiate the actual value to be used. The operational parameter
will never contain the value "auto". It will always contain the
result of the auto-negotiation, such as "half" or "full". This is
just one way in which the configuration data model is not exactly the
same as the operational data model. Another is if the detailed
properties of the data are different for configured vs. learned
entries.
If all the data model properties are aligned between configuration
and operational data, then it can be useful to define the
configuration parameters within a grouping, and then replicate that
grouping within the operational data portion of the data model.
grouping parms {
// do not use config-stmt in any of the nodes
// placed in this grouping
}
container foo {
uses parms; // these are all config=true by default
state {
config false; // only exists if foo config exists
uses parms;
}
}
Note that this mechanism can also be used if the configuration and
operational data are in separate sub-trees:
container bar { // bar config can exist without bar-state
config true;
uses parms;
}
container bar-state { // bar-state can exist without bar
config false;
uses parms;
}
The need to replicate objects or define different operational data
objects depends on the data model. It is not possible to define one
approach that will be optimal for all data models. Designers SHOULD
describe the relationship in detail between configuration objects and
any associated operational data objects. The "description"
statements for both the configuration and the operational data SHOULD
be used for this purpose.
</SNIP>
Thanks,
Kent
_______________________________________________
netmod mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/netmod