data(下发的数据)+ YANG = 下发给设备的配置
上图中很好的表示了 YANG 起到的作用,YANG 本身并不是数据,而更像是一种配置模板,起到约束数据的作用。
那么 YANG Model 一般是由谁定义的呢?
YANG Model 的定义,主要有两个角色:
标准化的 YANG Model ,由 IETF,OpenConfig 等机构进行规划定义。这类的 YANG 主要是考虑到多尝试的兼容性问题,而推出的统一的 YANG Module。所有厂商都需要支持。
各个厂商实现自定义私有的 YANG。这类 YANG Model 主要是为了厂商实现某些私有或特有功能 YANG. 比如 Cisco 中有许多私有的协议,如 EIGRP,BGP 的某些功能只有思科设备上有。
YANG 的结构YANG Module 以层次化树形结构被组织起来,每个模块可以引入外部其他的模块,包含其子模块的数据。
简单来说,就是可以将模块作为参数,引入其他的模块进行使用。
YANG 定义了很多的内置类型,并提供了自定义类型的机制,类似于 C 中的 typedef.
在 YANG 中定义了四种类型,用于将数据模型化:
Leaf Nodes:一个节点用于表示数字或字符串等简单的数据。但只能表示一个值,不能拥有子节点。
YANG 表示:
leaf host-name { type string; description "Hostname for this system"; }xml 表示:
<host-name>my.example.com</host-name>json 表示:
{ "host-name": "my.example.com" } Leaf-List Nodes:表示由 leaf node 构成的列表。
YANG 表示:
leaf-list domain-search { type string; description "List of domain names to search"; }xml 表示:
<domain-search>high.example.com</domain-search> <domain-search>low.example.com</domain-search> <domain-search>everywhere.example.com</domain-search>json 表示:
[ {"domain-search": "high.example.com"}, {"domain-search": "low.example.com"}, {"domain-search": "everywhere.example.com"}, ] Container Nodes:类似于编程语言中的 MAP 形式,将多个 node 组装到一起。一个 container node 可以包含多个任意类型的 node 节点,如 leafs,lists,leaf-lists,及本身 container 的类型。
YANG 表示:
container system { container login { leaf message { type string; description "Message given at start of login session"; } } }xml 表示:
<system> <login> <message>Good morning</message> </login> </system>json 表示:
{"system":{"login": {"message": "Good morning"}}} List Nodes由一个或多个 key leaf 和多个任意类型的子节点组成,类型包括,leafs,
lists, containers 等。
其中 key leaf 用于表示当前 list 的唯一性。
YANG 表示:
list user { key "name"; leaf name { type string; } leaf full-name { type string; } leaf class { type string; } }这里的 name 作为唯一的标识符。
xml 表示:
<user> <name>glocks</name> <full-name>Goldie Locks</full-name> <class>intruder</class> </user> <user> <name>snowey</name> <full-name>Snow White</full-name> <class>free-loader</class> </user> <user> <name>rzell</name> <full-name>Rapun Zell</full-name> <class>tower</class> </user>List Nodes 和 Leaf-List Nodes 的区别就是,Leaf-List Nodes 仅能包含类型是 Leaf Nodes 的节点,而 List Nodes 可以包含任意类型。
YANG 的其他特性对于 YANG 来说,本身支持很多特性:
配置状态数据,对于定义那些不能配置的配置信息。
内置大量的基础类型,binary,bits,boolean 等等。
派生类型,自定义去定义如 binary 等类型。
可重用组,引用通过 grouping 陈述定义的组,用于解耦和封装。
支持 choices,类似于枚举。
使用 augment 对 model 进行约束
提供 RPC 调用
提供通知定义
更多的功能,可以参考 YANG - RFC 文档
PYANG - 更好的浏览 YANG Model在了解 YANG 语言,提供的强大功能后。一般在项目中,会使用由 Python 开发的 Pyang 工具来浏览 YANG 模型.
简单提一下安装方法,目前 Pyang 支持 Python2,Python3.
可以通过 docker 打包 Python 镜像后,作为运行环境:
[root@localhost pyang-env]# ls Dockerfile requirements.txt yang_modules [root@localhost pyang-env]# cat Dockerfile FROM python:3.8.5 ENV MY_PROXY_URL="http://xxx:80" ENV HTTP_PROXY=$MY_PROXY_URL \ HTTPS_PROXY=$MY_PROXY_URL \ FTP_PROXY=$MY_PROXY_URL \ http_proxy=$MY_PROXY_URL \ https_proxy=$MY_PROXY_URL \ ftp_proxy=$MY_PROXY_URL WORKDIR /src COPY ./requirements.txt / RUN pip install --no-cache-dir pyang ENV MY_PROXY_URL= ENV HTTP_PROXY=$MY_PROXY_URL \ HTTPS_PROXY=$MY_PROXY_URL \ FTP_PROXY=$MY_PROXY_URL \ http_proxy=$MY_PROXY_URL \ https_proxy=$MY_PROXY_URL \ ftp_proxy=$MY_PROXY_URL使用 docker run -v /home/xx/pyang-env/yang_modules:/src -it --name pyang-env pyang-image /bin/bash 启动运行环境。
接着去 YANG 的 Github 中,下载由 IETF 或各个厂商开发后的 YANG Module 。这里以 IOS-XE 版本为 633 的 YANG Module 为例。
可以看到有很多类似的 YANG 文件: