karimra / gnmic

gNMIc is a gNMI CLI client and collector
https://gnmic.kmrd.dev
Apache License 2.0
217 stars 32 forks source link

How can I pass several EOS commands with gNMIc and SET RPC and the origin cli? #399

Closed ksator closed 3 years ago

ksator commented 3 years ago

Hello

arista-cli.yang is https://github.com/aristanetworks/yang/blob/master/EOS-4.26.0F/experimental/eos/models/arista-cli.yang

gnmic -a 10.73.1.107:6030 -u arista -p arista --insecure capabilities | grep arista-cli

I can use the GET RPC with origin cli:

gnmic -a 10.73.1.107:6030 -u arista -p arista --insecure get --path "cli:/show version"

I can use the SET RPC using origin cli if there is one single EOS command:

gnmic -a 10.73.1.105:6030 -u ansible -p ansible --encoding ASCII --insecure set --update-path "cli:"  --update-value "vlan 101"

How can I use several EOS commands with gNMIc and SET RPC and the origin cli?

I am able to do it with gRPCurl and SET RPC and the origin cli:

ksator commented 3 years ago

With OpenConfig data model, we can use a file with the SET RPC:

gnmic -a 10.73.1.107:6030 --insecure -u arista -p arista set --update-path "/interfaces/interface[name=Ethernet1]/config/description" --update-value "gnmi-example"
gnmic -a 10.73.1.107:6030 --insecure -u arista -p arista set --update  "/interfaces/interface[name=Ethernet3]/config/enabled:::bool:::false"
gnmic -a 10.73.1.117:6030 --insecure -u arista -p arista set --replace-path '/network-instances/network-instance[name=default]/protocols/protocol[name=BGP]/bgp' --replace-file test.json

Can we use also use a file with gNMIc and SET RPC and the origin cli?

karimra commented 3 years ago

Hi,

You can use the --update-path and --update-value multiple times.

gnmic set --update-path /path1 --update-value val1 \
          --update-path /path2 --update-value val2

The same statement is valid for the pairs:

What you cannot do is mixing --update-value and --update-file or mixing --replace-value and --replace-file in the same command.

About using a file with the origin cli:

I see that the encoding used is ASCII, can you use JSON or `JSON_IETF ?

The --update-file and --replace-file flags are supported when the encoding is either JSON or JSON_IETF

karimra commented 3 years ago

For the origin cli, you can also look into using the flag --request-file https://gnmic.kmrd.dev/cmd/set/#template-format

ksator commented 3 years ago

Thank you!

Example with:

interface Ethernet 3
description 12345
vlan 304
name test 
gnmic -a 10.73.1.105:6030 -u ansible -p ansible --encoding ASCII --insecure set --update-path "cli:"  --update-value "interface Ethernet 3" --update-path "cli:"  --update-value "description 12345" --update-path "cli:"  --update-value "vlan 304"  --update-path "cli:"  --update-value "name test"
{
  "timestamp": 1622895568311760499,
  "time": "2021-06-05T12:19:28.311760499Z",
  "results": [
    {
      "operation": "UPDATE",
      "path": "cli:"
    },
    {
      "operation": "UPDATE",
      "path": "cli:"
    },
    {
      "operation": "UPDATE",
      "path": "cli:"
    },
    {
      "operation": "UPDATE",
      "path": "cli:"
    }
  ]
}
DC1-LEAF1A(config)#sh vlan 304
VLAN  Name                             Status    Ports
----- -------------------------------- --------- -------------------------------
304   test                             active   

DC1-LEAF1A(config)#sh int et3 desc
Interface                      Status         Protocol           Description
Et3                            admin down     down               12345
DC1-LEAF1A(config)#

So this is working. Great!

ksator commented 3 years ago

I tried using one single --update-path and one single --update-value that has all the eos commands (splitted with \n) as shown above in the grpcurl example but it did not work with gnmic ... so I have to use one --update-path --update-value pair per eos command ...

ksator commented 3 years ago

CLI origin encoding should be ASCII ...

gnmic -a 10.73.1.105:6030 -u ansible -p ansible --encoding ascii --insecure set --update-path "cli:"  --update-value "vlan 101"
{
  "timestamp": 1622896807893292172,
  "time": "2021-06-05T12:40:07.893292172Z",
  "results": [
    {
      "operation": "UPDATE",
      "path": "cli:"
    }
  ]
}
$ gnmic -a 10.73.1.105:6030 -u ansible -p ansible --encoding json_ietf --insecure set --update-path "cli:"  --update-value "vlan 101"
target "10.73.1.105:6030" set request failed: failed sending SetRequest to '10.73.1.105:6030': rpc error: code = InvalidArgument desc = CLI origin encoding should be ASCII
Error: one or more requests failed
$ gnmic -a 10.73.1.105:6030 -u ansible -p ansible --encoding json --insecure set --update-path "cli:"  --update-value "vlan 101"
target "10.73.1.105:6030" set request failed: failed sending SetRequest to '10.73.1.105:6030': rpc error: code = InvalidArgument desc = CLI origin encoding should be ASCII
Error: one or more requests failed
$ gnmic -a 10.73.1.105:6030 -u ansible -p ansible --insecure set --update-path "cli:"  --update-value "vlan 101"
target "10.73.1.105:6030" set request failed: failed sending SetRequest to '10.73.1.105:6030': rpc error: code = InvalidArgument desc = CLI origin encoding should be ASCII
Error: one or more requests failed

so I can not currently use the flag --update-file ...

karimra commented 3 years ago

Let me try to build the same example with the --request-file flag

karimra commented 3 years ago

I found an issue with the ascii value encoding when using --request-file, which is fixed in #401 I will release v0.14.3 with the fix when gh container registry will be out of maintenance: https://www.githubstatus.com/

So you will be able to use a file that looks like this:

cat req.yaml
updates:
  - path: "cli:"
    value: interface Ethernet 1
    encoding: ascii
  - path: "cli:"
    value: description 12345
    encoding: ascii
  - path: "cli:"
    value: vlan 304
    encoding: ascii
  - path: "cli:"
    value: name test
    encoding: ascii

Or the same in json

cat req.json
{
  "updates": [
    {
      "path": "cli:",
      "value": "interface Ethernet 1",
      "encoding": "ascii"
    },
    {
      "path": "cli:",
      "value": "description 12345",
      "encoding": "ascii"
    },
    {
      "path": "cli:",
      "value": "vlan 304",
      "encoding": "ascii"
    },
    {
      "path": "cli:",
      "value": "name test",
      "encoding": "ascii"
    }
  ]
}

and run: gnmic -a x.x.x.x set --request-file req.yaml or gnmic -a x.x.x.x set --request-file req.json

ksator commented 3 years ago

@karimra awesome! I will upgrade to v0.14.3 and test it. Thanks!!

karimra commented 3 years ago

released! let me know how it goes.

btw, you can omit the encoding from the file and set it using the --encoding flag

updates:
  - path: "cli:"
    value: interface Ethernet 1
  - path: "cli:"
    value: description 12345
  - path: "cli:"
    value: vlan 304
  - path: "cli:"
    value: name test
gnmic -a x.x.x.x set -e ascii --request-file req.yaml
ksator commented 3 years ago

Hello @karimra It works well! This is awseome. Thank you so much for your help!