美文网首页
基于ncclient的Netconf协议实践

基于ncclient的Netconf协议实践

作者: 九净 | 来源:发表于2020-05-10 20:09 被阅读0次

    原文:https://mp.weixin.qq.com/s?__biz=MzI4ODgwNDUzNA==&mid=2247483688&idx=1&sn=afc178b85bbd739f4aa068af303a0444&chksm=ec399af1db4e13e7df60661f90a222357deedc9acd37350cf95e93a01912d1b662bf292da6b4&token=1804173027&lang=zh_CN#rd

    Netconf协议与YANG Model我们在上一期已经分享过。

    我们也举了一些Netconf的例子,比如get,get-config,edit-config等等。

    这些例子都是还原了交互的报文,在实际生产中,我们肯定只要用程序去实现这些报文的发送处理,包括将我们想要的数据封装成xml。

    这篇的分享我会保姆级的讲解如何用一个Python的Netconf协议工具包Ncclient。

    看这篇文章,建议有一定的python基础,如果没有请去我的系列课程学习去吧。https://gitee.com/feifeiflight/netdevops 看看前两节课掌握基础的python知识,也可以去看其他视频,我这个就是稍微精简了一下,看完了可以上手写点。后续我也会在公众号里添加一些短平快而又实用的python教程。

    准备工作

    本文的环境

    python版本

    python请务必选择3.X ,个人建议3.7及以上。本文使用3.7.3

    python软件包

    用到了以下两个包,可以安装最新版本,不一定用以下版本。

    ncclient==0.6.7
    xmltodict==0.12.0
    

    交换机

    本文使用的是一台思科devnet的nxos系列的N9K交换机(感觉是虚拟化出来的资源),软件版本9.3(3),感谢思科devnet!也希望国内的厂家有人组局创建一个国内的NetDevOps社区,并给予一定的设备支持,虚拟化就行: ),方便大家交流实验分享代码等等。

    动手写代码

    建链,交换capabilities

    from ncclient import manager
    #核心用到的是manager
    if __name__ == '__main__':
        nexus9k_info = dict(username='XX',
                            password='XX',
                            host='XX',
                            # ip or hostname
                            hostkey_verify=False,
                            # 关闭hostkey_verify是ssh验证
                            port=10000,
                            # Netconf的协议端口,默认830,实验环境做了NAT
                            manager_params={'timeout': 180}
                             # manager的一些参数,比如timeout
                            )
        with manager.connect(**nexus9k_info) as m:
            # 用with 最后会关闭session
            server_capabilities =m.server_capabilities
            client_capabilities = m.client_capabilities
    
            print('server_capabilities are:')
            for i in server_capabilities:
                print(i)
            print('client_capabilities are:')
            for i in client_capabilities:
                print(i)
    

    这里面server是网络设备,你可以这样理解,它代表的是网络设备里的Netconf服务器,client是我们的程序。这也是网上很多图用的左侧是server(网络设备),右侧是agent(脚本或者程序)。

    我们非常开心的看到了,这台N9K支持以下capability,划重点,Openconfig,happy~

    网络设备支持以下:

    image

    网络设备端着重描述支持Netconf的版本及操作,以及,划重点,它所支持的YANG Model,很开心看到一堆的openconfig。

    脚本client端支持以下:

    image

    client端着重描述的是支持的Netconf版本及操作。因为它并不提供服务,只索取~

    这个N9K实际上它还支持很多思科私有(native)的YANG Model,它并未给我们返回回来。但是实际是可以调用的。 比如我们用命令行可以找到命令行对应的Netconf报文,如下图“{{命令行}}|xmlin”

    image image

    对于nexus系列,我从来不吝惜对它在网络可编程支持的赞美!

    这种sao操作,我在国产设备上还没试验出来,也许有但是我没找到,欢迎大家提供给我操作方法!如果没有,也强烈建议广大国产厂商对标此功能!

    提一点,Netconf协议最后会以]]>]]>表示报文的结束,前面是xml报文。以上ncclient会自动帮我们处理,我们关注于xml报文即可。

    这段代码是我们用来获取网络设备支持的yang,方便后续编写,实际上如果我们知道yang的情况下,直接就可以get get-config edit-config等了。

    接下来我们就演示一下

    get

    获取running的配置和state数据。

    我们把设备信息写到一个py文件里。命名device.py。和此脚本同目录。

    device.py的代码

    nexus9k_info = dict(username='XX',
                            password='XX',
                            host='XX',
                            # ip or hostname
                            hostkey_verify=False,
                            # 关闭hostkey_verify是ssh验证
                            port=10000,
                            # Netconf的协议端口,默认830,实验环境做了NAT
                            manager_params={'timeout': 180}
                             # manager的一些参数,比如timeout
                            )
    

    主体代码

    # 我们的Netconf的代码,这是另一个文件了。
    # 用于xml转python的dict
    import xmltodict
    from ncclient import manager
    import pprint
    from device import nexus9k_info
    
    
    if __name__ == '__main__':
        # NETCONF filter to use 用于过滤get的信息
        # 比如如下,我们过滤的是interfaces的interface中名称为eth1/1的信息
        # get 获取的是配置及运行态信息
        # xmlns 是xml的命名空间,简单理解,我们用到的是openconfig的yang模型
        # 中的interfacces
        netconf_filter = '''
        <filter>
            <interfaces xmlns="http://openconfig.net/yang/interfaces">
                <interface><name>eth1/1</name></interface>
            </interfaces>
        </filter>
        '''
        with manager.connect(**nexus9k_info) as m:
            # Get Configuration and State Info for Interface
            # manager支持Netconf协议中的各类operation
            #  我们展示的是get直接调用get即可
            # 参数中传入我们的过滤用的filter xml报文
            # ncclient会帮我们去处理rpc等的封装以及底层的一些建链的交互
            # 所以这里显得非常干净利索
            netconf_reply = m.get(netconf_filter)
            intf_details = xmltodict.parse(netconf_reply.xml)
            pprint.pprint(intf_details)
    

    返回的报文,我们debug可以看到,结构化非常好,data中返回了过滤后的数据,interfaces,看到了eth1/1的详细配置,在字典中层次优美,信息丰富。是不是比用正则解析cli的show内容要简单很多:)

    插播一下,后续也会分享给大家如何快速简单的提取cli show出来的数据。请订阅关注分享!


    image

    get-config

    获取配置

    我们看看ncclient的源代码,看注释,获取某配置的全部或者部分。请注意,这是“渔”,请掌握本技能。后续的很多operation就可以自己结合Netconf的协议与ncclient的各种operation类去实现自己想要的操作了。

    第一个参数是source,比如是running的,startup的还是某candidate的。我们按需,一般是在running和starup中找自己想要的配置


    image

    第二个参数就是filter了,如果不填写默认是None,那就是拿到所有配置了,等同于备份了。不过devnet的环境问题,我们还是加上filter,不然会超时。

    代码走你

    
    import xmltodict
    from ncclient import manager
    import pprint
    from device import nexus9k_info
    
    
    if __name__ == '__main__':
        # NETCONF filter to use
        netconf_filter = '''<filter>
            <interfaces xmlns="http://openconfig.net/yang/interfaces">
                <interface><name>eth1/1</name></interface>
            </interfaces>
        </filter>'''
        with manager.connect(**nexus9k_info) as m:
            ## 这个config 也可以用add_interface_native  私有的yang 去配置3
            netconf_reply = m.get_config('running', netconf_filter)
            intf_details = dict(xmltodict.parse(netconf_reply.xml))
            print(intf_details)
    

    静待一会

    image

    和get的区别是,这次只返回了配置相关的,没有state数据了。

    edit-config

    接下来我们讲讲配置,我们用一个native的,然后用了刚才投机取巧的办法,快速生成对应的xml报文,然后摘取一段。

    
    import xmltodict
    from ncclient import manager
    
    from device import nexus9k_info
    
    
    if __name__ == '__main__':
        add_interface_native = '''
      <config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
        <System xmlns="http://cisco.com/ns/yang/cisco-nx-os-device">
          <intf-items>
            <svi-items>
               <If-list nc:operation="create">
                   <id>vlan119</id>
               </If-list>
            </svi-items>
          </intf-items>
        </System>
       </config>'''
        with manager.connect(**nexus9k_info) as m:
            # Get Configuration and State Info for Interface  
            ## 这个config 也可以用add_interface_native  私有的yang 去配置
            netconf_reply = m.edit_config(config=add_interface_native ,target='running')
    
            # Process the XML and store in useful dictionaries
            intf_details = dict(xmltodict.parse(netconf_reply.xml))
            print(intf_details)
    

    由于是配置,配置只需要告诉我们成功与否,如果失败,原因是什么。

    很幸运,我们的端口配置成功了。看那个ok。

    image

    我们也附上一段openconfig的端口配置的代码

    <config>
       <interfaces xmlns="http://openconfig.net/yang/interfaces">
            <interface>
              <name>eth1/50</name>
              <config>
                <mtu>9216</mtu>
                <description>configured with openconfig 20200505</description>
                <enabled>true</enabled>
              </config>
            </interface>
    </interfaces>
    </config>
    

    同样也可以成功,我们不附设备上的配置了,请相信我!

    更多operation

    我们可以参考Netconf协议与ncclient的api。如下,在manager里我们看到各类操作与其工具类,描述的非常清楚。

    我们就不凑齐七颗龙珠一一演示了,大家可以去尝试一下。


    image

    比上一篇讲的基础的operation相比,我们发现了新大陆,很多操作,比如va验证配置、订阅、重启等等。相信通过对应的对象初始化参数可以非常容易的搞定。

    个人推荐一下订阅(我说的是Netconf里的订阅,如果你没订阅本公众号,也请订阅:) ),我们设想一下,我filter路由或者一些重要端口,如果数据发生变化会立刻发给我消息,那我的脚本可以通过对接短信平台、微信接口、或者syslog发出告警或者触发修复等等。我只是抛个转,大家可以根据自己的场景和经验,把脑洞再开大一点。NetDevOps最终还是要落地场景的嘛,不然就是空中楼阁。

    以上代码均在实际环境中通过,保姆级水准的代码。code与讲解水乳交融,你能百度到的ncclient的代码里,我觉得这应该是最易于掌握的了~

    再补充一些:

    • SDN网络控制器下发配置,绝大部分是通过Netconf去实现的。

    • 查看native的yang model,请去官网。

    • Netconf 配置数据时如果报错,支持一些回滚操作,详细请看Netconf的官方文档

    • 呼吁国内厂商,能够奋起直追,对标一些优秀的设计,多看看别人家孩子。国产化给了好的机会,咱们也要端住自己的碗,与君共勉!

    • 我们在实际编写脚本或者程序时,可以把xml里的数据参数化,这样可以让代码符合DRY(Don't Repeat Yourself),可以复用。再向上抽象,封装,面向我们的运维场景,你吹吹牛都可以说是IBN(基于意图的网络)了。

    • 分享Netconf,是希望大家看清趋势,知道有一些新的东西可以让我们工作的可能更轻松,不代表Netconf可以搞定你的一切。NetDevOps要因地制宜,在本地扎根后,持续生长,这样才有生命力。比如你的环境老旧设备 非SDN设备历史存量多,那还是选择CLI,但是需要因地制宜,合理设计,非SDN网络可以做到like SDN网络,在使用上,无限接近SDN网络。

    相关文章

      网友评论

          本文标题:基于ncclient的Netconf协议实践

          本文链接:https://www.haomeiwen.com/subject/pilsnhtx.html