项目作者: arista-netdevops-community

项目描述 :
gNOI demo with Arista
高级语言:
项目地址: git://github.com/arista-netdevops-community/gNOI_demo_with_Arista.git
创建时间: 2021-06-20T17:09:44Z
项目社区:https://github.com/arista-netdevops-community/gNOI_demo_with_Arista

开源协议:Apache License 2.0

下载


About this repository

This repository shows gNOI demo with Arista.
It includes examples using gNOIc and gRPCurl.

About gRPC

gRPC - Google Remote Procedure Call

gRPC uses protobuf and HTTP/2

About gNOI

gNOI - gRPC Network Operations Interface

gNOI defines a set of gRPC-based microservices for executing operational commands on network devices.

gNOI repository https://github.com/openconfig/gnoi

As example, this gNOI proto file https://github.com/openconfig/gnoi/blob/master/system/system.proto defines the service System with the RPC Traceroute and Ping

  • Ping executes the ping command on the target and streams back the results
  • Traceroute executes the traceroute command on the target and streams back the results
  • As you can see in the proto file, the field VRF is not defined for these messages

About gNOI support on EOS

https://eos.arista.com/eos-4-24-2f/gnoi/

Examples:

EOS

EOS switch configuration:

  1. hostname DC1-L2LEAF2A
  2. ip name-server vrf MGMT 8.8.8.8
  3. interface Management1
  4. description oob_management
  5. vrf MGMT
  6. ip address 10.73.1.118/24
  7. username arista secret 0 arista
  8. management api gnmi
  9. transport grpc def
  10. vrf MGMT

Before to use gNOI ping and traceroute, lets run these commands locally:

  1. $ ssh arista@10.73.1.118
  2. Password:
  3. Last login: Thu Jun 3 12:06:25 2021 from 10.73.1.3
  4. DC1-L2LEAF2A>en
  5. DC1-L2LEAF2A#bash
  6. Arista Networks EOS shell
  7. [arista@DC1-L2LEAF2A ~]$ ping 172.31.255.0 -c 2
  8. PING 172.31.255.0 (172.31.255.0) 56(84) bytes of data.
  9. 64 bytes from 172.31.255.0: icmp_seq=1 ttl=63 time=24.6 ms
  10. 64 bytes from 172.31.255.0: icmp_seq=2 ttl=63 time=18.8 ms
  11. --- 172.31.255.0 ping statistics ---
  12. 2 packets transmitted, 2 received, 0% packet loss, time 1001ms
  13. rtt min/avg/max/mdev = 18.861/21.738/24.616/2.881 ms
  14. [arista@DC1-L2LEAF2A ~]$
  15. [arista@DC1-L2LEAF2A ~]$ traceroute -A 172.31.255.0
  16. traceroute to 172.31.255.0 (172.31.255.0), 30 hops max, 60 byte packets
  17. 1 10.90.90.1 (10.90.90.1) [!!] 26.636 ms 29.420 ms 32.113 ms
  18. 2 172.31.255.0 (172.31.255.0) [!!] 52.764 ms 53.881 ms 63.213 ms
  19. [arista@DC1-L2LEAF2A ~]$
  20. [arista@DC1-L2LEAF2A ~]$ exit
  21. logout
  22. DC1-L2LEAF2A#exit
  23. Connection to 10.73.1.118 closed.

gNOI demo with Arista using gNOIc

About gNOIc

gNOIc is a gNOI CLI client
https://github.com/karimra/gnoic

Install gNOIc

  1. bash -c "$(curl -sL https://get-gnoic.kmrd.dev)"
  1. $ gnoic version
  2. version : 0.0.5
  3. commit : 26c6248
  4. date : 2021-05-12T10:12:55Z
  5. gitURL : https://github.com/karimra/gnoic
  6. docs : https://gnoic.kmrd.dev

Use gNOIc

gNOI Ping

  1. $ gnoic -a 10.73.1.118:6030 -u arista -p arista --insecure system ping --destination 172.31.255.0 --count 2 --do-not-resolve
  2. WARN[0000] "10.73.1.118:6030" could not lookup hostname: lookup 118.1.73.10.in-addr.arpa. on 127.0.0.53:53: no such host
  3. source: "172.31.255.0"
  4. time: 31200000
  5. bytes: 64
  6. sequence: 1
  7. ttl: 63
  8. source: "172.31.255.0"
  9. time: 33900000
  10. bytes: 64
  11. sequence: 2
  12. ttl: 63
  13. source: "172.31.255.0"
  14. time: 1001000000
  15. sent: 2
  16. received: 2
  17. min_time: 31251000
  18. avg_time: 32590000
  19. max_time: 33930000
  20. std_dev: 1351000

gNOI Traceroute

  1. $ gnoic -a 10.73.1.118:6030 -u arista -p arista --insecure system traceroute --destination 172.31.255.0 --do-not-resolve
  2. WARN[0000] "10.73.1.118:6030" could not lookup hostname: lookup 118.1.73.10.in-addr.arpa. on 127.0.0.53:53: no such host
  3. destination_name: "172.31.255.0"
  4. destination_address: "172.31.255.0"
  5. hops: 30
  6. packet_size: 60
  7. hop: 1
  8. address: "10.90.90.1"
  9. rtt: 21440000
  10. hop: 1
  11. address: "10.90.90.1"
  12. rtt: 23011000
  13. hop: 1
  14. address: "10.90.90.1"
  15. rtt: 31135000
  16. hop: 2
  17. address: "172.31.255.0"
  18. rtt: 62216000
  19. hop: 2
  20. address: "172.31.255.0"
  21. rtt: 63213000
  22. hop: 2
  23. address: "172.31.255.0"
  24. rtt: 71079000

gNOI Cert

  1. $ gnoic -a 10.73.1.118:6030 -u arista -p arista --insecure cert can-generate-csr
  2. WARN[0000] "10.73.1.118:6030" could not lookup hostname: lookup 118.1.73.10.in-addr.arpa. on 127.0.0.53:53: no such host
  3. INFO[0000] "10.73.1.118:6030" key-type=KT_RSA, cert-type=CT_X509, key-size=2048: can_generate: true
  4. +------------------+------------------+
  5. | Target Name | Can Generate CSR |
  6. +------------------+------------------+
  7. | 10.73.1.118:6030 | true |
  8. +------------------+------------------+

Upgrading EOS using gNOI

EOS supports gNOI OS Install/Activate/Verification (4.24.2F+) and gNOI System Reboot/Reboot/RebootStatus (4.27.0F+)
that can be used to upload the EOS image, activate that image (set the boot-config) so that it boots with it next time,
verify the image activation was successful and lastly to reboot the device to perform the upgrade.

gNOI OS Install

To upload an EOS SWI image to a switch we can use the gnoi.os.OS/Installation RPC:

  1. gnoic -a 192.0.2.1:6030 --insecure --gzip -u admin -p admin \
  2. os install \
  3. --version 4.29.1F \
  4. --pkg EOS.swi

Output:

  1. INFO[0000] starting install RPC
  2. INFO[0000] target "192.0.2.1:6030": starting Install stream
  3. INFO[0003] target "192.0.2.1:6030": TransferProgress bytes_received:5242880
  4. INFO[0003] target "192.0.2.1:6030": TransferProgress bytes_received:10485760
  5. ...
  6. INFO[0411] target "192.0.2.1:6030": TransferProgress bytes_received:1030750208
  7. INFO[0413] target "192.0.2.1:6030": sending TransferEnd
  8. INFO[0413] target "192.0.2.1:6030": TransferProgress bytes_received:1035993088
  9. INFO[0413] target "192.0.2.1:6030": TransferContent done...
gNOI OS Activate

To activate the new EOS image (equivalent to running boot system flash:EOS.swi on the CLI) we can use the
/gnoi.os.OS/Activation RPC:

  1. gnoic -a 192.0.2.1:6030 --insecure --gzip -u admin -p admin \
  2. os activate \
  3. --version 4.29.1F \
  4. --no-reboot

Output:

  1. INFO[0034] target "192.0.2.1:6030" activate response "activate_ok:{}"
gNOI OS Verify
  1. gnoic -a 192.0.2.1:6030 --insecure --gzip -u admin -p admin os verify

Output:

  1. +-------------------+---------+---------------------+
  2. | Target Name | Version | Activation Fail Msg |
  3. +-------------------+---------+---------------------+
  4. | 192.0.2.1:6030 | 4.29.1F | |
  5. +-------------------+---------+---------------------+
gNOI System Reboot

To reboot the device we can use gnoi.system.System/Reboot RPC and the COLD method:

  1. gnoic -a 192.0.2.1:6030 --insecure --gzip -u admin -p admin \
  2. system reboot \
  3. --method COLD

Note on older EOS versions you may get the following error message:

  1. ERRO[0009] "192.0.2.1:6030" System Reboot failed: rpc error: code = Unavailable desc = error reading from server: EOF
  2. Error: there was 1 error(s)

gNOI demo with Arista using gRPCurl

About gRPCurl

gRPCurl is a command-line tool that lets you interact with gRPC servers.

Install GO

  1. $ go version
  2. go version go1.16.4 linux/amd64
  1. $ go env | grep 'GOROOT\|GOPATH'
  1. $ echo $HOME
  2. $ echo $GOROOT
  3. $ echo $GOPATH
  4. $ echo $PATH
  5. $ export GOROOT=/usr/local/go
  6. $ export GOPATH=$HOME/go
  7. $ export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

Get gNOI repository

  1. $ mkdir -p $GOPATH/src/github.com/openconfig
  2. $ git clone https://github.com/openconfig/gnoi.git $GOPATH/src/github.com/openconfig/gnoi
  1. $ ls $GOPATH/src/github.com/openconfig
  2. gnoi

Install gRPCurl

  1. $ go get github.com/fullstorydev/grpcurl
  1. $ ls $GOPATH/pkg/mod/github.com/fullstorydev/
  2. grpcurl@v1.8.1
  1. $ go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
  1. ls $GOPATH/bin/
  2. grpcurl

Use gRPCurl

Describe from a proto file

  1. $ grpcurl --plaintext --import-path ${GOPATH}/src --proto github.com/openconfig/gnoi/system/system.proto describe gnoi.system.System.CancelReboot
  2. gnoi.system.System.CancelReboot is a method:
  3. // CancelReboot cancels any pending reboot request.
  4. rpc CancelReboot ( .gnoi.system.CancelRebootRequest ) returns ( .gnoi.system.CancelRebootResponse );
  1. $ grpcurl --plaintext --import-path ${GOPATH}/src --proto github.com/openconfig/gnoi/system/system.proto describe gnoi.system.System
  2. gnoi.system.System is a service:
  3. // The gNOI service is a collection of operational RPC's that allow for the
  4. // management of a target outside of the configuration and telemetry pipeline.
  5. service System {
  6. // CancelReboot cancels any pending reboot request.
  7. rpc CancelReboot ( .gnoi.system.CancelRebootRequest ) returns ( .gnoi.system.CancelRebootResponse );
  8. // Ping executes the ping command on the target and streams back
  9. // the results. Some targets may not stream any results until all
  10. // results are in. If a packet count is not explicitly provided,
  11. // 5 is used.
  12. rpc Ping ( .gnoi.system.PingRequest ) returns ( stream .gnoi.system.PingResponse );
  13. // Reboot causes the target to reboot, possibly at some point in the future.
  14. // If the method of reboot is not supported then the Reboot RPC will fail.
  15. // If the reboot is immediate the command will block until the subcomponents
  16. // have restarted.
  17. // If a reboot on the active control processor is pending the service must
  18. // reject all other reboot requests.
  19. // If a reboot request for active control processor is initiated with other
  20. // pending reboot requests it must be rejected.
  21. rpc Reboot ( .gnoi.system.RebootRequest ) returns ( .gnoi.system.RebootResponse );
  22. // RebootStatus returns the status of reboot for the target.
  23. rpc RebootStatus ( .gnoi.system.RebootStatusRequest ) returns ( .gnoi.system.RebootStatusResponse );
  24. // SetPackage places a software package (possibly including bootable images)
  25. // on the target. The file is sent in sequential messages, each message
  26. // up to 64KB of data. A final message must be sent that includes the hash
  27. // of the data sent. An error is returned if the location does not exist or
  28. // there is an error writing the data. If no checksum is received, the target
  29. // must assume the operation is incomplete and remove the partially
  30. // transmitted file. The target should initially write the file to a temporary
  31. // location so a failure does not destroy the original file.
  32. rpc SetPackage ( stream .gnoi.system.SetPackageRequest ) returns ( .gnoi.system.SetPackageResponse );
  33. // SwitchControlProcessor will switch from the current route processor to the
  34. // provided route processor. If the current route processor is the same as the
  35. // one provided it is a NOOP. If the target does not exist an error is
  36. // returned.
  37. rpc SwitchControlProcessor ( .gnoi.system.SwitchControlProcessorRequest ) returns ( .gnoi.system.SwitchControlProcessorResponse );
  38. // Time returns the current time on the target. Time is typically used to
  39. // test if a target is actually responding.
  40. rpc Time ( .gnoi.system.TimeRequest ) returns ( .gnoi.system.TimeResponse );
  41. // Traceroute executes the traceroute command on the target and streams back
  42. // the results. Some targets may not stream any results until all
  43. // results are in. If a hop count is not explicitly provided,
  44. // 30 is used.
  45. rpc Traceroute ( .gnoi.system.TracerouteRequest ) returns ( stream .gnoi.system.TracerouteResponse );
  46. }

List

List from a proto file
  1. $ grpcurl --plaintext --import-path ${GOPATH}/src --proto github.com/openconfig/gnoi/system/system.proto list
  2. gnoi.system.System
  1. $ grpcurl --plaintext --import-path ${GOPATH}/src --proto github.com/openconfig/gnoi/system/system.proto list gnoi.system.System
  2. gnoi.system.System.CancelReboot
  3. gnoi.system.System.Ping
  4. gnoi.system.System.Reboot
  5. gnoi.system.System.RebootStatus
  6. gnoi.system.System.SetPackage
  7. gnoi.system.System.SwitchControlProcessor
  8. gnoi.system.System.Time
  9. gnoi.system.System.Traceroute
  1. $ grpcurl --plaintext --import-path ${GOPATH}/src --proto github.com/openconfig/gnoi/os/os.proto list gnoi.os.OS
  2. gnoi.os.OS.Activate
  3. gnoi.os.OS.Install
  4. gnoi.os.OS.Verify
List from a gRPC server (EOS device)
  1. $ grpcurl --plaintext 10.73.1.105:6030 list
  2. gnmi.gNMI
  3. gnoi.certificate.CertificateManagement
  4. gnoi.system.System
  5. grpc.reflection.v1alpha.ServerReflection

Execute gNOI RPC with EOS

  1. $ grpcurl -H 'username: arista' -H 'password: arista' -d '{"destination": "172.31.255.0", "count": 2, "do_not_resolve":true}' -import-path ${GOPATH}/src -proto github.com/openconfig/gnoi/system/system.proto -plaintext 10.73.1.118:6030 gnoi.system.System/Ping
  2. {
  3. "source": "172.31.255.0",
  4. "time": "29800000",
  5. "bytes": 64,
  6. "sequence": 1,
  7. "ttl": 63
  8. }
  9. {
  10. "source": "172.31.255.0",
  11. "time": "25200000",
  12. "bytes": 64,
  13. "sequence": 2,
  14. "ttl": 63
  15. }
  16. {
  17. "source": "172.31.255.0",
  18. "time": "1001000000",
  19. "sent": 2,
  20. "received": 2,
  21. "minTime": "25210000",
  22. "avgTime": "27510000",
  23. "maxTime": "29810000",
  24. "stdDev": "2300000"
  25. }
  1. $ grpcurl -H 'username: arista' -H 'password: arista' -d '{"destination": "172.31.255.0", "max_ttl": 50, "do_not_resolve":true}' -import-path ${GOPATH}/src -proto github.com/openconfig/gnoi/system/system.proto -plaintext 10.73.1.118:6030 gnoi.system.System/Traceroute
  2. {
  3. "destinationName": "172.31.255.0",
  4. "destinationAddress": "172.31.255.0",
  5. "hops": 50,
  6. "packetSize": 60
  7. }
  8. {
  9. "hop": 1,
  10. "address": "10.90.90.1",
  11. "rtt": "16589000"
  12. }
  13. {
  14. "hop": 1,
  15. "address": "10.90.90.1",
  16. "rtt": "17886000"
  17. }
  18. {
  19. "hop": 1,
  20. "address": "10.90.90.1",
  21. "rtt": "23219000"
  22. }
  23. {
  24. "hop": 2,
  25. "address": "172.31.255.0",
  26. "rtt": "46537000"
  27. }
  28. {
  29. "hop": 2,
  30. "address": "172.31.255.0",
  31. "rtt": "47873000"
  32. }
  33. {
  34. "hop": 2,
  35. "address": "172.31.255.0",
  36. "rtt": "55376000"
  37. }