Skip to content

Conversation

@robshakir
Copy link
Member

 * (M) doc/openconfig_style_guide.md
   - Provide further documentation in the OpenConfig style guide
     on the rules required to allow programmatic schema transformation.
     These rules have been adhered to throughout the lifetime of
     OpenConfig, and are implemented by widely used code generation
     tools. This PR simply records these defacto style guide rules.

     This PR is accompanied by https://github.com/openconfig/oc-pyang/pull/59
     which implements the relevant linter checks for the rules
     described herein.

 * (M) doc/openconfig_style_guide.md
   - Provide further documentation in the OpenConfig style guide
     on the rules required to allow programmatic schema transformation.
     These rules have been adhered to throughout the lifetime of
     OpenConfig, and are implemented by widely used code generation
     tools. This PR simply records these defacto style guide rules.

     This PR is accompanied by openconfig/oc-pyang#59
     which implements the relevant linter checks for the rules
     described herein.
@OpenConfigBot
Copy link

OpenConfigBot commented Jan 10, 2026

No major YANG version changes in commit d36332f

ensure that downstream tooling does not break.

* **`list` nodes MUST NOT share their identifier with any grandparent
node.** It is not legal for `/foos/foo` and `/foo` to exist. This rule
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the term "grandparent node" is clear enough here. I'd generally interpret grandparent to mean direct parent of a direct parent. But in the example above /foo isn't really a grandparent of /foos/foo. /foos isn't the parent of /foo. /foos is a sibling of /foo.
Maybe you mean a list node must not share their identifier with any ancestor node or sibling node of any ancestor? (and is it node or just lists it can't share with?).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to update the phrasing.

In this case, the grandparent is the root (openconfig or whatever), which feels surprising since it isn't a path element.

The "grandparent" description is more clear in a case where they're in a container, e.g. /grandparent/foo and /grandparent/foos/foo, but even in such a case, it's a "parent node" of one of the foo, which could be confusing.

Perhaps we want to say "a node MUST NOT share its identifier with any of the children of its grandparent node."?

exists to allow the `foos` container to be removed during schema
transformation.
* **A leaf-node may not share a name with a grandparent**. It is not legal
for `/a/config/leaf` and `/a/leaf` to both exist nor for `/b/state/leaf`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use further clarification because it looks & feels very close to a convention of OpenConfig for list keys:

 |     +--rw acl-entries
 |        +--rw acl-entry* [sequence-id]
 |           +--rw sequence-id        -> ../config/sequence-id
 |           +--rw config
 |           |  +--rw sequence-id?   uint32

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, perhaps it would be useful to distinguish leaf refs from leafs?

transforming the schema. Clearly, this is wholly reliant on consistency
in the modelling approach.

The following rules MUST be adherered to within the OpenConfig models to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: (spl) "adhered"

`state` containers used for operational state, and surrounding containers for
YANG `list` statements. In some cases (e.g., programmatically generating
configuration), this schema verbosity negatively impacts usability -- e.g.,
requiring programmers to reference longer paths that they could. Tooling
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phrasing: ... requiring programmers to reference paths that are longer than necessary. or similar.

node.** It is not legal for `/foos/foo` and `/foo` to exist. This rule
exists to allow the `foos` container to be removed during schema
transformation.
* **A leaf-node may not share a name with a grandparent**. It is not legal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Referred to as leaf node (without the hyphen) elsewhere in the doc. Make consistent.

ensure that downstream tooling does not break.

* **`list` nodes MUST NOT share their identifier with any grandparent
node.** It is not legal for `/foos/foo` and `/foo` to exist. This rule
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to update the phrasing.

In this case, the grandparent is the root (openconfig or whatever), which feels surprising since it isn't a path element.

The "grandparent" description is more clear in a case where they're in a container, e.g. /grandparent/foo and /grandparent/foos/foo, but even in such a case, it's a "parent node" of one of the foo, which could be confusing.

Perhaps we want to say "a node MUST NOT share its identifier with any of the children of its grandparent node."?


An example of programmatic compression is implemented for the generation of
code in ygot -- both for Go and Protobuf artifact generation
((reference)[https://github.com/openconfig/ygot/blob/master/docs/design.md#openconfig-path-compression]).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Link formatting is backwards. Should be []()

exists to allow the `foos` container to be removed during schema
transformation.
* **A leaf-node may not share a name with a grandparent**. It is not legal
for `/a/config/leaf` and `/a/leaf` to both exist nor for `/b/state/leaf`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, perhaps it would be useful to distinguish leaf refs from leafs?

@earies
Copy link
Contributor

earies commented Jan 15, 2026

Just wanted to post an overall comment/observation - this style proposal is to accomodate patterns for collapsing schema nodes and codegen for ygot and just want to confirm that that then means ygot would not be able to accomodate patterns that fall outside of this boundary - is that correct? (e.g. other model-sets)

I'll admit I haven't looked across various repos verbiage to this matter but the interoperability between OC projects and content outside of OC projects scope has been a growing concern that I'm not sure has been fully articulated other than YMMV.

If that is all correct, do we agree the following from ygot README is sufficient to articulate this?

Whilst ygot is designed to work with any YANG module, for OpenConfig modules, it can provide transformations of
the schema to optimise the data structures that are produced for use in systems that generate data instances of the
models for configuration purposes. These helper methods require that the OpenConfig style guide patterns are implemented, a model can be verified to conform with these requirements using the OpenConfig linter.

@robshakir
Copy link
Member Author

Just wanted to post an overall comment/observation - this style proposal is to accomodate patterns for collapsing schema nodes and codegen for ygot and just want to confirm that that then means ygot would not be able to accomodate patterns that fall outside of this boundary - is that correct? (e.g. other model-sets)

ygot has never done schema compression (what it refers to these transformations as) for any other type of model. It could be extended to do so, but it hasn't been thus far.

I'll admit I haven't looked across various repos verbiage to this matter but the interoperability between OC projects and content outside of OC projects scope has been a growing concern that I'm not sure has been fully articulated other than YMMV.

I'm not sure I understand this comment. Is your concern that ygot is outside of the OpenConfig project's scope?

If that is all correct, do we agree the following from ygot README is sufficient to articulate this?

Whilst ygot is designed to work with any YANG module, for OpenConfig modules, it can provide transformations of the schema to optimise the data structures that are produced for use in systems that generate data instances of the models for configuration purposes. These helper methods require that the OpenConfig style guide patterns are implemented, a model can be verified to conform with these requirements using the OpenConfig linter.

@earies
Copy link
Contributor

earies commented Jan 15, 2026

ygot has never done schema compression (what it refers to these transformations as) for any other type of model. It could be extended to do so, but it hasn't been thus far.

I haven't dug into ygot sources but are you suggesting the schema compression and schema design assumptions are specific to OC model-sets (schema aware)? And if used against alternate model-sets where there is likelyhood to breach these rulesets, ygot can support (assuming coverage of the entirety of YANG 1.0/1.1 language) but not using these compression rules?

I'll admit I haven't looked across various repos verbiage to this matter but the interoperability between OC projects and content outside of OC projects scope has been a growing concern that I'm not sure has been fully articulated other than YMMV.

I'm not sure I understand this comment. Is your concern that ygot is outside of the OpenConfig project's scope?

Was just trying to understand since this imposes a design protocol on the YANG modeling that if this means ygot and OC YANG modeling are only interoperable as a result and how ygot might handle schemas that cannot conform to this ruleset (e.g. native, IETF, etc...)

@dplore
Copy link
Member

dplore commented Jan 21, 2026

ygot has never done schema compression (what it refers to these transformations as) for any other type of model. It could be extended to do so, but it hasn't been thus far.

I haven't dug into ygot sources but are you suggesting the schema compression and schema design assumptions are specific to OC model-sets (schema aware)? And if used against alternate model-sets where there is likelyhood to breach these rulesets, ygot can support (assuming coverage of the entirety of YANG 1.0/1.1 language) but not using these compression rules?

I'll admit I haven't looked across various repos verbiage to this matter but the interoperability between OC projects and content outside of OC projects scope has been a growing concern that I'm not sure has been fully articulated other than YMMV.

I'm not sure I understand this comment. Is your concern that ygot is outside of the OpenConfig project's scope?

Was just trying to understand since this imposes a design protocol on the YANG modeling that if this means ygot and OC YANG modeling are only interoperable as a result and how ygot might handle schemas that cannot conform to this ruleset (e.g. native, IETF, etc...)

Compression is an optional feature of ygot. It can be turned off. ygot has accepted changes to help it consume non-OC models. (ie: openconfig/ygot#1030) But we want to formalize with this PR that we choose a style for OC models which are compressible.

@robshakir
Copy link
Member Author

ygot has never done schema compression (what it refers to these transformations as) for any other type of model. It could be extended to do so, but it hasn't been thus far.

I haven't dug into ygot sources but are you suggesting the schema compression and schema design assumptions are specific to OC model-sets (schema aware)? And if used against alternate model-sets where there is likelyhood to breach these rulesets, ygot can support (assuming coverage of the entirety of YANG 1.0/1.1 language) but not using these compression rules?

That's absolutely correct. There are active users of goyang and ygot that are using models other than OpenConfig. The compression rules are specifically to improve developer experience for models that comply with OpenConfig's style rules. Today, this is actively used for both OpenConfig and OpenTrafficGenerator models.

I'll admit I haven't looked across various repos verbiage to this matter but the interoperability between OC projects and content outside of OC projects scope has been a growing concern that I'm not sure has been fully articulated other than YMMV.

I'm not sure I understand this comment. Is your concern that ygot is outside of the OpenConfig project's scope?

Was just trying to understand since this imposes a design protocol on the YANG modeling that if this means ygot and OC YANG modeling are only interoperable as a result and how ygot might handle schemas that cannot conform to this ruleset (e.g. native, IETF, etc...)

This change simply makes a rule that has been adhered to throughout the modelling explicit (i.e., converts it from a convention to a "rule"). ygot will always support schemas using the "uncompressed" mode (and has done for ~10 years in production network deployments :-)). Essentially, ygot is a generic toolkit for YANG users in Go, but has a "works with OpenConfig" badge since a number of its primary users use OpenConfig. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

6 participants