YANG - 非强制性容器建模

YANG - Modeling non-mandatory containers

目前我正在与 YANG 合作,作为(遗留)Python 项目的一部分。

我有点卡在定义模式的任务上,然后将其用于验证数据,组织为 Python 字典。 如果可能的话,我“希望”保留当前结构,因为很多代码库都在使用这些数据。

一条“未改变”的数据:

"namespace": {                      # Mandatory
    "management": {                 # Optional
        "interfaces": {             # Mandatory
            "m0": {                 # Optional
                "leaf1": "..."
            }
        }
    },
    "benchmark": {                  # Optional
        "interfaces": {             # Mandatory
            "b0": {                 # Optional
                "leaf1": "...",
                "leaf2": "..."
            },
            "b1": {                 # Optional
                "leaf1": "...",
                "leaf2": "..."
            }
        }
    }
}

我的问题是,根据 RFC6020,所有标记为“可选”(在示例中)的内容都将建模为容器,但似乎无法将它们定义为可选(即:强制性错误;) .

因此,我定义了一个使用列表的模型。这意味着 Python Dict 的某些节点(management、benchmark、m0、b0、b1)现在是列表元素,无法以当前方式访问,例如:data['namespace']['management']...

修改后的示例如下所示:

"namespace": [
    {
        "desc": "management",
        "interfaces": [
            {
                "leaf1": "..."
            }
        ]
    },
    {
        "desc": "benchmark",
        "interfaces": [
            {
                "leaf1": "...",
                "leaf2": "..."
            },
            {
                "leaf1": "...",
                "leaf2": "..."
            }
        ]
    }
]

YANG 模型的描述(我当前的片段):

list namespace {
    description "Namespace definitions.";
    key desc;

    leaf desc { type string; }

    uses leaf-definitions;

    list interfaces {
        key leaf1;
        uses leaf-definitions;
    }
}

验证成功,数据(本身)的转换没有问题,但是导致一大堆乱七八糟的代码。

这引出了我的问题:

  1. 我说得对吗 - YANG 中的容器总是强制性的吗?
  2. 是否有其他方法可以对这种情况进行建模? (不打破“太多”)

非常感谢您的意见,因为我是 YANG 的新手!

Am I correct - are containers in YANG always mandatory?

恰恰相反。它们总是可选的,除非它们包含强制节点(强制叶、列表或 leaf-list with min-elements > 0 等)。换句话说,容器从它们的后代那里继承了这个属性。这当然只适用于 non-presence 个容器。具有强制子项的存在容器不会继承此 属性,因为那样会破坏其目的(存在)。您可能错过了 RFC6020 中强制节点的定义:

  A mandatory node is one of:

  o  A leaf, choice, or anyxml node with a "mandatory" statement with
      the value "true".

  o  A list or leaf-list node with a "min-elements" statement with a
      value greater than zero.

  o  A container node without a "presence" statement, which has at
      least one mandatory node as a child.

这应该对您的第二个问题有所帮助。

Is there maybe another way to model this scenario? (Without breaking "too much")

滥用状态容器。它们总是可选的。您也可以通过将一些强制性子项引入 non-presence 容器来避免使用列表。根据您的初始数据:

module mandatory-optional-branch {
  namespace "org:example:mandatory-optional-branch";
  prefix "mob";

  grouping leafs {
    leaf leaf1 {type string;}
    leaf leaf2 {type string;}
  }

  list namespace { // mandatory
    config false;
    min-elements 1;
    max-elements 1;
    container management { // optional by nature
      presence "I have mandatory children, but am not mandatory. Yay for me.
                Of course my presence should have some meaning.";
      list interfaces { // mandatory
        min-elements 1;
        max-elements 1;
        container m0 { // optional - no mandatory node children
          leaf leaf1 {type string;}
        }
      }
    }
    container benchmark { // optional by nature
      presence "Same as 'management' above.";
      list interfaces { // mandatory
        min-elements 1;
        max-elements 1;
        container b0 { // optional - no mandatory node children
          uses leafs;
        }
        container b1 { // optional - no mandatory node children
          uses leafs;
        }
      }
    }
  }
}