1. YANG 概念
YANG (Yet Another Next Generation) 是网络配置建模语言:
- 用于定义网络设备的配置和状态数据结构
- 支持 NETCONF/RESTCONF 协议的数据操作
- 提供数据约束和验证规则
- 广泛应用于 SDN、网络自动化和设备管理
核心价值:使网络配置标准化、可验证、自动化
2. YANG 核心原理
- 树状结构:数据组织为层次化树形结构
- 强类型系统:定义严格的数据类型
- 约束规范:通过 must/when 定义业务规则
- RPC支持:定义远程过程调用接口
- 通知机制:支持事件通知模型
- 模块化设计:支持模块复用和扩展
3. YANG 语法规范
基本结构
module example-system {
namespace "urn:ietf:params:xml:ns:yang:example-system";
prefix sys;
container system {
leaf hostname {
type string;
description "Device hostname";
}
list interface {
key "name";
leaf name {
type string;
}
leaf ip-address {
type inet:ip-address;
}
}
}
}
核心元素
元素 | 功能 | 示例 |
---|---|---|
module | 定义模块 | module network { ... } |
container | 容器节点 | container interfaces { ... } |
leaf | 叶子节点 | leaf hostname { type string; } |
list | 列表节点 | list interface { key "name"; ... } |
leaf-list | 叶子列表 | leaf-list dns-server { type inet:ip-address; } |
choice | 选择分支 | choice protocol { case tcp; case udp; } |
typedef | 类型定义 | typedef port-number { type uint16 { range 1..65535; } } |
rpc | 远程调用 | rpc reboot { input { ... } output { ... } } |
notification | 事件通知 | notification interface-down { ... } |
数据类型
类型 | 描述 | 示例 |
---|---|---|
string | 字符串 | type string; |
uint8/16/32/64 | 无符号整数 | type uint16; |
int8/16/32/64 | 有符号整数 | type int32; |
boolean | 布尔值 | type boolean; |
enumeration | 枚举值 | type enumeration { enum up; enum down; } |
identityref | 身份引用 | type identityref { base interface-type; } |
leafref | 叶子引用 | type leafref { path "/interfaces/interface/name"; } |
4. Python YANG 处理工具
主要工具
- pyang:YANG 验证和转换工具
- ncclient:NETCONF 客户端库
- yangson:纯 Python YANG 数据模型处理器
- pyangbind:从 YANG 生成 Python 绑定
安装
pip install pyang ncclient
5. YANG 处理流程
6. 应用示例
示例1:创建YANG模型
输入 (network.yang):
module network {
namespace "urn:ietf:params:xml:ns:yang:network";
prefix net;
container devices {
list device {
key "name";
leaf name {
type string;
}
leaf ip-address {
type inet:ip-address;
mandatory true;
}
leaf status {
type enumeration {
enum up;
enum down;
enum testing;
}
default up;
}
}
}
rpc reboot {
input {
leaf device-name {
type leafref {
path "/devices/device/name";
}
}
}
output {
leaf result {
type string;
}
}
}
}
示例2:使用pyang验证模型
# 验证语法
pyang network.yang
# 生成树形图
pyang -f tree network.yang
树形图输出:
module: network
+--rw devices
+--rw device* [name]
+--rw name string
+--rw ip-address inet:ip-address
+--rw status? enumeration
+---x reboot
+---w input
| +---w device-name -> /devices/device/name
+--ro output
+--ro result? string
示例3:使用ncclient配置设备
Python 配置代码:
from ncclient import manager
# 连接设备
with manager.connect(
host='192.168.1.1',
port=830,
username='admin',
password='secret',
hostkey_verify=False
) as m:
# 构建配置XML
config = """
<config>
<devices xmlns="urn:ietf:params:xml:ns:yang:network">
<device>
<name>router01</name>
<ip-address>192.168.1.1</ip-address>
<status>up</status>
</device>
</devices>
</config>
"""
# 发送配置
m.edit_config(target='running', config=config)
# 调用RPC
rpc = """
<reboot xmlns="urn:ietf:params:xml:ns:yang:network">
<device-name>router01</device-name>
</reboot>
"""
response = m.dispatch(rpc)
print(response.xml)
RPC响应:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<result xmlns="urn:ietf:params:xml:ns:yang:network">Reboot initiated</result>
</rpc-reply>
示例4:查询设备状态
Python 查询代码:
# 继续使用上面的连接
# 构建查询
filter = """
<devices xmlns="urn:ietf:params:xml:ns:yang:network">
<device>
<name>router01</name>
</device>
</devices>
"""
# 发送查询
response = m.get_config(source='running', filter=('subtree', filter))
print(response.xml)
查询结果:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<data>
<devices xmlns="urn:ietf:params:xml:ns:yang:network">
<device>
<name>router01</name>
<ip-address>192.168.1.1</ip-address>
<status>up</status>
</device>
</devices>
</data>
</rpc-reply>
示例5:使用pyangbind处理数据
from pyangbind.lib.serialise import pybindJSONDecoder
import json
# 加载YANG模型(需先编译)
# pyang --plugindir $PWD/pyangbind/plugin -f pybind -o network.py network.yang
from network import network
# 创建模型实例
model = network()
# 添加设备
device = model.devices.device.add("router01")
device.ip_address = "192.168.1.1"
device.status = "up"
# 序列化为JSON
json_data = model.devices.device["router01"].get(filter=True)
print(json.dumps(json_data, indent=2))
# 反序列化
new_device = {
"name": "switch01",
"ip-address": "10.0.0.1",
"status": "down"
}
pybindJSONDecoder.load_ietf_json(
new_device,
None, None,
obj=model.devices.device.add("switch01")
)
print("添加的设备:", model.devices.device["switch01"].name)
输出:
{
"name": "router01",
"ip-address": "192.168.1.1",
"status": "up"
}
添加的设备: switch01
7. YANG 在自动化运维中的典型应用
1. 网络设备配置管理
module cisco-ios {
container interfaces {
list interface {
key "name";
leaf name {
type string;
}
leaf description {
type string;
}
leaf enabled {
type boolean;
default true;
}
}
}
}
2. 服务配置建模
module vpn-service {
container vpn {
list instance {
key "name";
leaf name {
type string;
}
leaf type {
type enumeration {
enum site-to-site;
enum remote-access;
}
}
leaf-list endpoints {
type inet:ip-address;
}
}
}
}
3. 监控数据模型
module system-monitoring {
container metrics {
leaf cpu-usage {
type percentage;
config false; // 状态数据,不可配置
}
leaf memory-usage {
type percentage;
config false;
}
notification high-usage {
leaf resource {
type enumeration {
enum cpu;
enum memory;
}
}
leaf value {
type percentage;
}
}
}
}
8. 最佳实践
-
模块化设计:
module network-base { // 基础类型和分组 } module network-devices { import network-base { prefix base; } // 设备特定扩展 }
-
命名规范:
- 模块名:小写加连字符 (
acme-network
) - 叶子名:小写驼峰 (
ipAddress
) - 容器名:单数名词 (
device
)
- 模块名:小写加连字符 (
-
数据验证:
leaf mtu { type uint16 { range 68..9216; } must ". >= 1500" { error-message "MTU must be at least 1500"; } }
-
文档注释:
leaf ospf-enabled { type boolean; default true; description "Enable OSPF routing protocol"; reference "RFC 2328 - OSPF Version 2"; }
-
版本控制:
revision 2023-11-15 { description "Added BGP support"; }
9. 工具生态系统
工具 | 用途 | 示例命令 |
---|---|---|
pyang | 模型验证/转换 | pyang -f tree model.yang |
yanglint | 高级验证 | yanglint model.yang |
gnmic | gNMI 客户端 | gnmic get --path /interfaces |
confd | 配置引擎 | confd --yangpath ./yang |
sysrepo | YANG 运行时 | sysrepoctl -i model.yang |
10. YANG 与其他格式对比
特性 | YANG | JSON Schema | XSD |
---|---|---|---|
主要用途 | 网络配置 | API数据验证 | XML验证 |
协议支持 | NETCONF/RESTCONF | HTTP/REST | SOAP |
数据类型 | 网络专用类型 | 基础类型 | XML类型 |
扩展性 | 强(分组/继承) | 有限 | 中等 |
工具生态 | 网络设备专用 | 通用 | 通用 |
总结
YANG 是现代网络自动化的核心技术:
- 标准化建模:统一网络设备配置接口
- 强约束验证:确保配置正确性
- 自动化支持:与 NETCONF/RESTCONF 完美集成
- 跨厂商兼容:支持多厂商设备统一管理
核心应用场景:
- 网络设备配置管理
- SDN控制器数据建模
- 网络服务编排
- 配置审计和验证
- 网络状态监控
通过 Python 工具链(pyang + ncclient):
- 可以轻松实现 YANG 模型的验证和处理
- 与网络设备进行配置交互
- 构建网络自动化流水线
掌握 YANG 是成为高级网络自动化工程师的关键技能,能够显著提升网络运维的效率和质量。