akarneliuk / pygnmi

The pure Python implementation of the gNMI client.
https://training.karneliuk.com
BSD 3-Clause "New" or "Revised" License
129 stars 44 forks source link

gnmi history extension #68

Closed ksator closed 2 years ago

ksator commented 2 years ago

Hello I would like to use pygnmi with these 2 diff use cases https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-history.md

but I dont see these options. Is it already supported? Many thanks in advance for your help!

ksator commented 2 years ago

The Arista gNMI command line client is published on the GH org aristanetworks.
It supports 3 flags for these 2 options https://github.com/aristanetworks/goarista/blob/master/gnmi/client/client.go#L81-L89

Examples using the Arista gNMI command line client, to query a database (-addr) about a device (target):

ability to request historical data from the server there are two kinds:

Get interfaces status of a device at a specific time

gnmi -addr=192.0.2.100:443 -token=`cat token.tok` -mode=once -history_snapshot=2021-07-13T09:47:00Z subscribe origin=openconfig target=JPE17471508 "/interfaces/interface[name=Ethernet47]/state/admin-status"
[2021-07-13T09:33:41.479506009Z] (JPE17471508) /interfaces/interface[name=Ethernet47]/state/admin-status = DOWN

Get interface status of a device at a specified time range


gnmi -addr=192.0.2.100:443 -token=`cat token.tok` -mode=stream -history_start=2021-07-13T09:47:00Z -history_end=2021-07-13T09:51:00Z subscribe origin=openconfig target=JPE17471508 "/interfaces/interface[name=Ethernet47]/state/admin-status"
[2021-07-13T09:47:34.67759454Z] (JPE17471508) /interfaces/interface[name=Ethernet47]/state/admin-status = DOWN
[2021-07-13T09:47:31.195992481Z] (JPE17471508) /interfaces/interface[name=Ethernet47]/state/admin-status = UP
[2021-07-13T09:33:41.479506009Z] (JPE17471508) /interfaces/interface[name=Ethernet47]/state/admin-status = DOWN```
ksator commented 2 years ago

Examples using gNMIc and CVP:

Get interfaces counters of a device at a specific time

gnmic -a [192.168.0.5:443](http://192.168.0.5:443/) subscribe \
    --path "openconfig:/interfaces/interface/state/counters" \
    --token=`cat token.tok` --mode=once --target=spine1 \
    --skip-verify  --history-snapshot=2022-07-17T12:56:00Z

Get interface counters of a device at a specified time range

gnmic -a [192.168.0.5:443](http://192.168.0.5:443/) subscribe \
    --path "openconfig:/interfaces/interface/state/counters" \
    --token=`cat token.tok` --mode=stream --target=spine1 --skip-verify\
    --history-start=2022-07-17T12:53:00Z  --history-end=2022-07-17T12:55:00Z 
akarneliuk commented 2 years ago

Hey @ksator ,

I figured out you provided a link in gnmic. I will take a look how to get that implemented, it is a bit more complicated that all previous request. I will keep you updates.

Best, Anton

akarneliuk commented 2 years ago

Hey @ksator ,

This feature is implemented in #82 and available in the latest pygnmi=0.8.2 release. I will update examples later, but you can try it like that:

TELEMETRY_REQUEST = {
                        'subscription': [
                            {
                                'path': 'openconfig:/interfaces/interface/state/counters',
                                'mode': 'target_defined'
                            }
                        ],
                        'mode': 'stream',
                        'encoding': 'proto'
                    }

# For snapshot_time
EXTENSION1 = {
                'history': {
                    'snapshot_time': '2021-07-13T09:47:00Z'
                }
            }

# For range
EXTENSION2 = {
                'history': {
                    'range': {
                        'start': '2021-07-13T09:47:00Z',
                        'end': '2021-07-13T09:51:00Z'
                    }
                }
            }

with gNMIclient(target=(ENV_HOSTNAME, ENV_PORT),
                username=ENV_USERNAME,
                password=ENV_PASSWORD,
                skip_verify=True) as gconn:
    for item in gconn.subscribe2(subscribe=TELEMETRY_REQUEST, target="something", extension=EXTENSION1):
        print(item)

Please, let me know if that worked for you.

Best, Anton

ksator commented 2 years ago

Thank you @akarneliuk I will test it and let you know.

Just 2 comments before:

https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-history.md

pyGNMI 0.8.2 brokes my scripts that were working with 0.7.5 so I created the issue #83

ksator commented 2 years ago

The range is working

arista@devbox:~$ pip freeze | grep pygn
pygnmi==0.8.2
from pygnmi.client import gNMIclient

TELEMETRY_REQUEST2 = {
                        'subscription': [
                            {
                                'path': 'openconfig:/interfaces/interface/state/counters',
                                'mode': 'target_defined'
                            }
                        ],
                        'mode': 'stream',
                        'encoding': 'proto'
                    }

# For range
EXTENSION2 = {
                'history': {
                    'range': {
                        'start': '2022-07-23T09:47:00Z',
                        'end': '2022-07-24T8:57:00Z'
                    }
                }
            }

with open("token.tok") as f:
    TOKEN = f.read().strip('\n')

with gNMIclient(target=('192.168.0.5', '443'), token=TOKEN, skip_verify=True) as gconn:
    for item in gconn.subscribe2(subscribe=TELEMETRY_REQUEST2, target="leaf1", extension=EXTENSION2):
        print(item)
ksator commented 2 years ago

The snaspshot is working

arista@devbox:~$ pip freeze | grep pygn
pygnmi==0.8.2

below using "once" as indicated in the spec

from pygnmi.client import gNMIclient

TELEMETRY_REQUEST1 = {
                        'subscription': [
                            {
                                'path': 'openconfig:/interfaces/interface[name=Ethernet2]/state/counters',
                                'mode': 'target_defined'
                            }
                        ],
                        'mode': 'once',
                        'encoding': 'proto'
                    }

# For snapshot_time
EXTENSION1 = {
                'history': {
                    'snapshot_time': '2022-07-24T8:57:00Z'
                }
            }

with open("token.tok") as f:
    TOKEN = f.read().strip('\n')

with gNMIclient(target=('192.168.0.5', '443'), token=TOKEN, skip_verify=True) as gconn:
    for item in gconn.subscribe2(subscribe=TELEMETRY_REQUEST1, target="leaf1", extension=EXTENSION1):
        print(item)
akarneliuk commented 2 years ago

Hey @ksator ,

Thanks for testing. You are right on once/stream. I will add it to documentation. Shall we close this one?

ksator commented 2 years ago

Hello @akarneliuk yep you can close it.
Many thanks but please this 0.8 release broke scripts that was working with 0.7.5 (issue #83)

akarneliuk commented 2 years ago

Hey @ksator,

fixed by #84 and in published release pygnmi==0.8.3

Best, Anton