2

目前,我正在与 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似乎不能将它们定义为可选(即:强制 false;) 。

因此,我定义了一个使用列表的模型。这意味着 Python Dict 的某些节点(管理、基准、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 还很陌生!

4

1 回答 1

1

我是对的 - YANG 中的容器总是强制性的吗?

恰恰相反。它们始终是可选的,除非它们包含强制节点(强制叶、最小元素 > 0 的列表或叶列表等)。换句话说,容器从其后代继承此属性。这当然只适用于非存在容器。具有强制子项的存在容器不会继承此属性,因为这会破坏其目的(存在)。您可能错过了 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.

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

是否有另一种方法来模拟这种情况?(没有打破“太多”)

滥用存在容器。它们始终是可选的。您也可以通过将一些强制性子项引入非存在容器来避免使用列表。根据您的初始数据:

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;
        }
      }
    }
  }
}
于 2017-02-13T09:01:50.727 回答