kakkotetsu

ARISTA cEOS-lab で NETCONF を動かす (小ネタ)

小ネタです
twitter で「A社のnetconf動作確認失敗」「マニュアルでは記載あるのに使えない」「たぶん、旧バージョンでは使えていたけど新バージョンで廃止。でドキュメントはメンテしてないのパターンだろう」という噂を見かけたので、実際にどうなのか動かしてみます

結果から先に書くと、2020/03/23 時点でダウンロードできた最新の cEOS-lab 4.23.2F で最低限の動作(<get-config>)は動きました

事前情報

環境情報

ARISTA 公式の Software Download ページ からとってきた 2020/03/23 時点で最新版 の cEOS-lab

localhost>show ver
 cEOSLab
Hardware version:
Serial number:
System MAC address:  0242.ac11.3eb8

Software image version: 4.23.2F
Architecture:           i686
Internal build version: 4.23.2F-15405360.4232F
Internal build ID:      4cde5c53-3642-4934-8bcc-05691ffd79b3

cEOS tools version: 1.1

Uptime:                 7 weeks, 3 days, 4 hours and 33 minutes
Total memory:           2040924 kB
Free memory:            1282940 kB

上記の docker image を動かす母艦

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic


$ uname -a
Linux testvm 4.15.0-76-generic #86-Ubuntu SMP Fri Jan 17 17:24:28 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux


$ docker --version
Docker version 19.03.8, build afacb8b7f0

動作確認

環境準備 (cEOS-lab deploy)

前述の cEOS-lab image ダウンロードページに手順のテキストも置いてあるので、その通りにやっただけです
後ほど、この母艦の外から NETCONF 接続をするので docker create 時に NETCONF のデフォルトTCPポートを突けるように -p 830:830 しておくのが今回の固有ポイント

$ ll
total 391128
drwxrwxr-x 2 kotetsu kotetsu      4096 Mar 23 07:11 ./
drwxrwxr-x 3 kotetsu kotetsu      4096 Mar 23 07:10 ../
-rw-rw-r-- 1 kotetsu kotetsu 400501512 Mar 23 07:11 cEOS-lab-4.23.2F.tar.xz
-rw-rw-r-- 1 kotetsu kotetsu       153 Mar 23 07:11 cEOS-lab-4.23.2F.tar.xz.sha512sum

$ sha512sum cEOS-lab-4.23.2F.tar.xz
40af1a1fa456bb0eb3b99aabddc1905614d032f84fb947070d1818e4cb48b9f655723effbdc03ed782b44461789d01a8935f775684086b28f32bfed65df9b94d  cEOS-lab-4.23.2F.tar.xz


$ docker import cEOS-lab-4.23.2F.tar.xz ceosimage:4.23.2F
sha256:3228be9a009f6931cd07f3867f3f2f5be288f440158412f980d1197fd699dac5

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
ceosimage           4.23.2F             3228be9a009f        About a minute ago   1.74GB


$ docker create --name=ceos1 --privileged -p 830:830 -e INTFTYPE=eth -e ETBA=1 -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e CEOS=1 -e EOS_PLATFORM=ceoslab -e container=docker -i -t ceosimage:4.23.2F /sbin/init systemd.setenv=INTFTYPE=eth systemd.setenv=ETBA=1 systemd.setenv=SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 systemd.setenv=CEOS=1 systemd.setenv=EOS_PLATFORM=ceoslab systemd.setenv=container=docker


$ docker network create net1
fb0cef09267bc7da25ef4394cd80f6333a8433942f8380568b57d15d041b08bf

$ docker network connect net1 ceos1

$ docker start ceos1
ceos1

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
28b52fc3fbde        ceosimage:4.23.2F   "/sbin/init systemd.窶ヲ"   2 minutes ago       Up 9 seconds        0.0.0.0:830->830/tcp   ceos1


$ docker exec -it ceos1 Cli
localhost>

NETCONF 有効化設定 at cEOS-lab

NETCONF で外部から突くために ユーザ作成して NETCONF 有効化

ARISTA EOS Central / OpenConfig 4.20.2.1F Release Notes / NETCONF Transport を参考に
(なお、このリリースノートが twitter 上では「マニュアルでは記載あるのに使えない」として画面キャプされてました)

localhost#conf t
localhost(config)#username kotetsu role network-admin secret kotetsu
localhost(config)#
localhost(config)#management api ?
  external-services  Configure the external(customer specific) web services on HTTP server
  gnmi               Configure GNMI
  gribi              Configure gRIBI
  http-commands      Configure the HTTP Commands API
  netconf            Configure NETCONF
  openconfig         Configure OpenConfig
  restconf           Configure RESTCONF

localhost(config)#management api netconf ?
  <cr>

localhost(config)#management api netconf
localhost(config-mgmt-api-netconf)#transport ?
  ssh  Configure SSH transport for NETCONF

localhost(config-mgmt-api-netconf)#transport ssh ?
  WORD  Transport name

localhost(config-mgmt-api-netconf)#transport ssh TEST-NETCONF ?
  WORD  Transport name
  <cr>

localhost(config-mgmt-api-netconf)#transport ssh TEST-NETCONF
localhost(config-netconf-transport-TEST-NETCONF)#end
localhost#
localhost#show management api netconf
Enabled:            Yes
Server:             running on port 830, in default VRF
localhost#show run
! Command: show running-config
! device: localhost (cEOSLab, EOS-4.23.2F)
!
transceiver qsfp default-mode 4x10G
!
agent Bfd shutdown
agent PowerManager shutdown
agent LedPolicy shutdown
agent Thermostat shutdown
agent PowerFuse shutdown
agent StandbyCpld shutdown
agent LicenseManager shutdown
!
spanning-tree mode mstp
!
no aaa root
!
username kotetsu role network-admin secret sha512 $6$Esck1TwFdZfKszo6$K54/xPLQguinpmY2q4S9IxOg1TZASNdnJYZzhs3FkUujs6uccGJbiYR6w.yOW/ML.G2CowJrFFoU7EtpCpmJe/
!
interface Ethernet1
!
no ip routing
!
management api netconf
   transport ssh TEST-NETCONF
!
end

動作確認 (via remote ssh)

とりあえず外部から ssh で突いてみると、hello メッセージで capability リストを教えてくれてきています
長いので途中で切ってますが...
ちな、ここで <rpc>...</rpc> とか貼っていけばやりとりできます

$ ssh -l kotetsu <docker母艦のIPアドレス> -p 830 -s netconf
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability><capability>urn:ietf:params:netconf:base:1.1</capability><capability>urn:ietf:params:xml:ns:netconf:base:1.0</capability><capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</capability><capability>urn:ietf:params:netconf:capability:writable-running:1.0</capability><capability>urn:ietf:params:netconf:capability:candidate:1.0</capability><capability>http://arista.com/yang/openconfig/policy/augments?module=arista-rpol-augments&amp;revision=2018-04-12</capability><capability>http://arista.com/yang/openconfig/isis/deviations?module=arista-isis-deviations&amp;revision=2019-05-14</capability><capability>http://openconfig.net/yang/hercules/qos?module=openconfig-hercules-qos&amp;revision=2018-06-01</capability><capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2013-07-15</capability><capability>http://openconfig.net/yang/openconfig-types?module=openconfig-types&amp;revision=2019-04-16</capability><capability>http://openconfig.net/yang/lacp?module=openconfig-lacp&amp;revision=2018-11-21</capability><capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability><capability>http://openconfig.net/yang/aft?module=openconfig-aft&amp;revision=2019-08-01</capability><capability>http://openconfig.net/yang/system/logging?module=openconfig-system-logging&amp;revision=2018-11-21</capability><capability>http://arista.com/yang/openconfig/acl/deviations?module=arista-acl-deviations&amp;revision=2019-06-17</capability><capability>http://openconfig.net/yang/ospf-types?module=openconfig-ospf-types&amp;revision=2018-11-21</capability><capability>http://openconfig.net/yang/interfaces/ip?module=openconfig-if-ip&amp;revision=2019-01-08</capability><capability>http://arista.com/yang/openconfig/relay-agent/deviations?module=arista-relay-agent-deviations&amp;revision=2016-11-21</capability><capability>http://openconfig.net/yang/platform/fan?module=openconfig-platform-fan&amp;revision=2018-11-21</capability><capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&amp;revision=2011-06-01</capability><capability>http://openconfig.net/yang/routing-policy?module=openconfig-routing-policy&amp;revision=2018-11-21</capability><capability>http://openconfig.net/yang/network-instance-l3?module=openconfig-network-instance-l3&amp;revision=2018-11-21</capability><capability>http://openconfig.net/yang/vlan-types?module=openconfig-vlan-types&amp;revision=2019-01-31</capability><capability>http://arista.com/yang/openconfig/local-routing/deviations?module=arista-local-routing-deviations&amp;revision=2017-11-22</capability><capability>http://arista.com/yang/experimental/eos/eos-types?module=arista-eos-types&amp;revision=2016-10-14</capability><capability>http://openconfig.net/yang/system/terminal?module=openconfig-system-terminal&amp;revision=2018-11-21</capability>

...snip

動作確認 (via Python ncclient)

有名どころの NETCONF クライアントライブラリを使って <get-config> くらいまでは見ておきましょーか

以下のような NETCONF クライアント用の Python venv 環境を用意して

$ pip list --format=columns
Package       Version
------------- -------
bcrypt        3.1.7
cffi          1.14.0
cryptography  2.8
lxml          4.5.0
ncclient      0.6.7
paramiko      2.7.1
pip           9.0.1
pkg-resources 0.0.0
pycparser     2.20
PyNaCl        1.3.0
setuptools    39.0.1
six           1.14.0


$ python3 --version
Python 3.6.9

NETCONF で cEOS-lab に <get-config> して xml を標準出力するだけの簡易スクリプトを用意して

#!/usr/bin/env python3
from ncclient import manager
import xml.dom.minidom

with manager.connect(host='<docker母艦のIPアドレス>', port=830, username='kotetsu', password='kotetsu', hostkey_verify=False) as m:
    c = m.get_config(source='running').data_xml
    print(xml.dom.minidom.parseString(c).toprettyxml())
$ ./nc-test.py > result.log

Gist / ceos-lab_4.23.2F_netconf_get-config.xml にカットなしのモノは置きましたが、以下が出力の一部です

<?xml version="1.0" ?>
<data time-modified="2020-03-23T08:03:36.805590273Z" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
        <acl xmlns="http://openconfig.net/yang/acl"/>
        <arista xmlns="http://arista.com/yang/experimental/eos">
                <eos>
                        <bridging xmlns="http://arista.com/yang/experimental/igmpsnooping">
                                <igmpsnooping>
                                        <config/>
                                </igmpsnooping>
                        </bridging>
                        <mlag xmlns="urn:aristanetworks:yang:experimental:eos">
                                <config>
                                        <dual-primary-action>action-none</dual-primary-action>
                                        <enabled>true</enabled>
                                        <heartbeat-interval>4000</heartbeat-interval>
                                        <heartbeat-peer-address>
                                                <address>0.0.0.0</address>
                                                <vrf/>
                                        </heartbeat-peer-address>
                                        <lacp-standby>false</lacp-standby>
                                </config>
                        </mlag>
                        <qos xmlns="http://arista.com/yang/experimental/eos/qos">
                                <acl xmlns="http://arista.com/yang/experimental/eos/qos/acl">
                                        <input>
                                                <cli>


...snip


                                <input xmlns="http://arista.com/yang/experimental/eos/qos/config">
                                        <config>
                                                <cli>
                                                        <servicePolicyConfig>
                                                                <key-direction>input</key-direction>
                                                                <key-pmapName>copp-system-policy</key-pmapName>
                                                                <key-type>mapControlPlane</key-type>
                                                        </servicePolicyConfig>
                                                </cli>
                                        </config>
                                </input>
                        </qos>
                        <routing xmlns="http://arista.com/yang/experimental/multicast">
                                <multicast>
                                        <routeconfig>
                                                <static>
                                                        <vrfConfig>
                                                                <vrfName>default</vrfName>
                                                        </vrfConfig>
                                                </static>
                                        </routeconfig>
                                </multicast>
                        </routing>
                </eos>
        </arista>

...snip

        <interfaces xmlns="http://openconfig.net/yang/interfaces">
                <interface>
                        <name>Ethernet1</name>
                        <config>
                                <description/>
                                <enabled>true</enabled>
                                <load-interval xmlns="http://arista.com/yang/openconfig/interfaces/augments">300</load-interval>
                                <loopback-mode>false</loopback-mode>
                                <mtu>0</mtu>
                                <name>Ethernet1</name>
                                <tpid xmlns="http://openconfig.net/yang/vlan" xmlns:oc-vlan-types="http://openconfig.net/yang/vlan-types">oc-vlan-types:TPID_0X8100</tpid>
                                <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
                        </config>
                        <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet">
                                <config>
                                        <fec-encoding xmlns="http://arista.com/yang/openconfig/interfaces/augments">
                                                <disabled>false</disabled>
                                                <fire-code>false</fire-code>
                                                <reed-solomon>false</reed-solomon>
                                                <reed-solomon544>false</reed-solomon544>
                                        </fec-encoding>
                                        <forwarding-viable xmlns="http://openconfig.net/yang/hercules/interfaces">true</forwarding-viable>
                                        <mac-address>00:00:00:00:00:00</mac-address>
                                        <port-speed>SPEED_UNKNOWN</port-speed>
                                        <sfp-1000base-t xmlns="http://arista.com/yang/openconfig/interfaces/augments">false</sfp-1000base-t>
                                </config>
                        </ethernet>
                        <hold-time>
                                <config>
                                        <down>0</down>
                                        <up>0</up>
                                </config>
                        </hold-time>
                        <subinterfaces>
                                <subinterface>
                                        <index>0</index>
                                        <config>
                                                <description/>
                                                <enabled>true</enabled>
                                                <index>0</index>
                                        </config>
                                        <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip">
                                                <config>
                                                        <dhcp-client>false</dhcp-client>
                                                        <enabled>false</enabled>
                                                        <mtu>1500</mtu>
                                                </config>
                                        </ipv4>
                                        <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip">
                                                <config>
                                                        <dhcp-client>false</dhcp-client>
                                                        <dup-addr-detect-transmits>1</dup-addr-detect-transmits>
                                                        <enabled>false</enabled>
                                                        <mtu>1500</mtu>
                                                </config>
                                        </ipv6>
                                </subinterface>
                        </subinterfaces>

...snip

                </interface>
        </interfaces>

...snip

        <lldp xmlns="http://openconfig.net/yang/lldp">
                <config>
                        <enabled>true</enabled>
                        <hello-timer>30</hello-timer>
                        <management-address xmlns="http://arista.com/yang/openconfig/lldp/augments">
                                <interface/>
                                <network-instance>default</network-instance>
                                <transmit-mode>BEST</transmit-mode>
                        </management-address>
                </config>
                <interfaces>
                        <interface>
                                <name>Ethernet1</name>
                                <config>
                                        <enabled>true</enabled>
                                </config>
                        </interface>
                </interfaces>
        </lldp>

        </system>
</data>

おしまい

最低限の動作を見ただけですが、以下まとめ/所感

  • cEOS-lab 4.23.2F で NETCONF <get-config> までは動くことを確認できた
  • 実際に生で NETCONF を使う人がいるかどうかは知らんけど(ARISTA の API としては古くから eAPI という結構良い感じのがあるし )、ARISTA のマニュアル構造的には YANG, OpenConfig のサポートのために動くようにしているのかな...
  • こういうちょっとしたコントロール系動作だけなら cEOS-lab は軽くて良さげ