Git Product home page Git Product logo

gnmi's Introduction

gNMI - gRPC Network Management Interface

This repository contains reference Go implementations for gNMI.

Note: This is not an official Google product.

The implementations include:

  • client library implementation using gnmi.proto
  • CLI for interacting with a gNMI service
  • Caching collector that connects to multiple gNMI targets and makes the data available over a single gNMI Subscribe RPC to clients

Installing

To install the CLI, run

go get -u github.com/openconfig/gnmi/cmd/gnmi_cli

Client libraries

The main entry point for using the client libraries is in github.com/openconfig/gnmi/client.

See godoc pages for documentation and usage examples.

gnmi's People

Contributors

aashaikh avatar dependabot[bot] avatar dplore avatar g-yusufsn avatar gcsl avatar gmacf avatar hellt avatar jxx-gg avatar kidiyoor avatar marcushines avatar mhines01 avatar mkhsueh avatar robshakir avatar vamsipunati avatar wenovus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gnmi's Issues

Have gnmi_cli return error code

Currently I don't think gnmi_cli returns the error code when there is one. It would be useful for it to do so if using gnmi_cli in a script for example. As simple Exit() with the error code at the end of the main function I think should be enough.

Problem with generating the gnmi.proto to javascript files

I wrote script to generate js files from the gnmi.proto file with "grpc_tools_node_protoc",

`#!/usr/bin/env bash
PROTO_IMPORT_DIR="./"
GEN_OUT_DIR="./generated/"

Create the generated output dir if it doesn't exist

if [ ! -d "$GEN_OUT_DIR" ]; then
mkdir -p ${GEN_OUT_DIR}
fi

FILE_PATHS='./*.proto'

Generate JavaScript

grpc_tools_node_protoc
--js_out=import_style=commonjs,binary:${GEN_OUT_DIR}
--grpc_out=${GEN_OUT_DIR}
--plugin=protoc-gen-grpc=which grpc_tools_node_protoc_plugin
-I ${PROTO_IMPORT_DIR}
${FILE_PATHS}`

it generate me those 2 files : gnmi_grpc_pb.js and gnmi_pb.js (one for the service and one for the messages) .

then i wrote a grpc_client, this is part of the code :
`const messages = require('../config/generated/gnmi_pb');
const services = require('../config/generated/gnmi_grpc_pb');

async $init() {

const client = new services.gNMIClient('localhost:50051', grpc.credentials.createInsecure());
const interfaces_counters_path1 = this.get_path("/top/interfaces/interface[name='bundle-1']/oper-items/counters/ethernet-counters/rx-octets");
const interfaces_counters_path2 = this.get_path("/top/interfaces/interface[name='bundle-2']/oper-items/counters/ethernet-counters/rx-octets");
const request = messages.GetRequest({ path: [interfaces_counters_path1, interfaces_counters_path2] });


client.Get(request, function (err, response) {
  console.log('Response:', response);
});

}

get_path(yangXpath: any) {
const elements = [];
const pathX: string[] = yangXpath.split('/');
pathX.forEach(item => {

  item.replace(/"/g, "'");

  if (item.includes('[')) {
    const itemArray = item
        .replace(']', '')
        .replace('\'', '')
        .replace('\'', '')
        .split('[');

    const keyValue = itemArray[1].split('=');
    elements.push(messages.PathElem({ name: itemArray[0], key: { [keyValue[0]]: keyValue[1] } }));
  } else {
    elements.push(messages.PathElem({ name: item }));
  }

});
return messages.Path({ elem: elements });

}`

The problem is that all the values of the elements array get 'undefined' :
elements.push(messages.PathElem({ name: item }));

when i run the same client that i wrote in python that uses the generated files of python you provide in the repository everything is fine .

I suspect that there is something with generating the gnmi.proto to javascript files their must be a problem with missing types or something related .

can someone help or provide a generated files in .js or .ts for the gnmi.proto ?

Thanks.

gnmi_cli does not support gNMI version 0.4 / 0.5

Unfortunately the Path encoding has changed since gNMI version 0.4:
09cf23d#diff-2c94239e729daff1e1db0c192c4d4eda

While repeated string element was used until version 0.3, this attribute is now deprecated. Instead repeated PathElem elem is used. The main difference is, that in the old encoding, the keys have been part of the string - such as "port[port-id=1/1/1]" while now the keys are properly encoded using map <string, string>.

This change impacts compatibility between gNMI servers and client. The current gnmi_cli client produces the following errors when running against a gnmi 0.4/0.5 server (e.g. NOKIA routers running SR OS 15.1).

$ gnmi_cli -a 192.168.33.2:57400 -with_user_pass -ca_crt CAcert.pem -qt s -dt p -pi 10s -q state/port[port-id=1/1/1]/ethernet/statistics/out-utilization
username: grpc
password: ********
E1204 20:32:25.622019   31975 gnmi_cli.go:190] cli.QueryDisplay:
        sendQueryAndDisplay(ctx, {Addrs:[192.168.33.2:57400] Target: Replica:0 UpdatesOnly:false Queries:[[state port[port-id=1/1/1] ethernet statistics out-utilization]] Type:stream Timeout:30s NotificationHandler:<nil> ProtoHandler:<nil> Credentials:0xc42019aa40 TLS:0xc0c9c0 Extra:map[]}, &{PollingInterval:10s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x815710 DisplayPrefix: DisplayIndent:   DisplayType:p DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[]}):
        client had error while displaying results:
        rpc error: code = InvalidArgument desc = MINOR: GMI #2004: / - Invalid path syntax - deprecated path format

I've already changed my Python client accordingly:
https://www.github.com/nokia/pygnmi

How to set DSCP value on gRPC stream in C++?

The gNMI standard has a qos field that is used to mark the DSCP value of the gRPC stream. Does gRPC C++ API support setting DSCP on the stream? Doing it with setsockopt would require us to get the socket file descriptor...

gnmi_cli still does not support Typed value with new gnmi.proto

Continued from last post...
When i used the same gnmi_cli with the different server that is using new proto(0.4.0) i dont receive any reply.
o/p:
./gnmi_cli -a 10.33.81.100:6702 -qt s -dt p -pi 10s -q /hello/system/logical-core-percent[cpu-id=5] -client_types gnmi
subscribe:<subscription:<path:<element:"hello" element:"system" element:"logical-core-percent[cpu-id=5]" > > >

It just sits here and waits.

To verify we used a home grown tool with same server we received this below reply.

$ ./gnmic
Server address: 10.33.81.100
Server port: 6702
Enter sensor names...
system logical-core-percent[cpu-id=5]
subscribe { prefix { origin: "caxv-gmathur-01" elem { name: "hello" } } subscription { path { origin: "OriginHello" elem { name: "system" } elem { name: "logical-core-percent" key { key: "cpu-id" value: "5" } } } mode: SAMPLE sample_interval: 2000 heartbeat_interval: 10000 } }

update {
timestamp: 1508267372968000000
prefix {
origin: "Hello"
elem { name: "hello" }
elem { name: "system" }
elem { name: "logical-core-percent" key { key: "cpu-id" value: "5" } } }
update {
path {
origin: "Hello"
elem { name: "cpu-idle" }
}
val { float_val: 100 }
}
}

Examples for JSON-encoded and protobuf.Any oneof value

Doing test with the fake_server and gnmi_cli, and also taking the current code as implementation reference. With fake.proto, there are examples for the native scalar protobuf types.

Probably I'm asking too much, it will be great if examples for structured data type like JSON and Proto could be added to oneof vaule in fake.proto. The distribution for them might be optional. Thanks!

Sample Interval datatype and range

The datatype of sample interval for Subscribe RPC is uint64. This translates to huge range, which doesn't have any practical purpose. Is there any guidance for the vendors for the max interval range that should be supported?

Need help on mutual authentication

I am using mutual authentication but always get the following failures from server side.
Can I get some help here how to fix it?

root@yangtze:/hfzhang/tinyjpg# gnmi_cli -a 1.100.0.4:10162 -query_type s -display_type p -query "/components/" -ca_crt ./CA/RootCA.crt -client_crt ./client/client.crt -client_key ./client/client.key
E0718 11:48:55.392003 21595 gnmi_cli.go:180] sendQueryAndDisplay(ctx, {Addrs:[1.100.0.4:10162] Target: Replica:0 UpdatesOnly:false Queries:[[components]] Type:stream Timeout:30s NotificationHandler: ProtoHandler: Credentials: TLS:0xc70aa0 Extra:map[] SubReq:}, &{PollingInterval:30s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x83cee0 DisplayPrefix: DisplayIndent: DisplayType:p DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[gnmi]}):
client had error while displaying results:
client "gnmi" : client "gnmi" : Dialer(1.100.0.4:10162, 30s): context deadline exceeded
root@yangtze:
/hfzhang/tinyjpg#

From server side:

Jul 18 11:48:40 ssl_transport_security.c:939: Handshake failed with fatal error SSL_ERROR_SSL: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate.
Jul 18 11:48:40 chttp2_server.c:83: Handshaking failed: {"created":"@1531939720.978903477","description":"Handshake failed","file":"../../../../../../../../src/dist/grpc/src/core/lib/security/transport/security_handshaker.c","file_line":276,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}
Jul 18 11:48:49 ssl_transport_security.c:193: ssl_info_callback: error occured.

Jul 18 11:48:49 ssl_transport_security.c:939: Handshake failed with fatal error SSL_ERROR_SSL: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate.
Jul 18 11:48:49 chttp2_server.c:83: Handshaking failed: {"created":"@1531939729.854758554","description":"Handshake failed","file":"../../../../../../../../src/dist/grpc/src/core/lib/security/transport/security_handshaker.c","file_line":276,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}

gnmi_cli display_type single or group return display error

I am using the latest version of gnmi_cli against my gNMI server (using spec v0.3.1). When trying to set the display type to single or group, I am getting a displaying error:

# gnmi_cli -a pe1:57400 -with_user_pass -ca_crt CAcert.pem -qt s -dt s -pi 10s -q state/port[port-id=1/1/1]/ethernet/statistics/out-utilization
username: grpc
password: E0919 13:53:47.398923    5101 gnmi_cli.go:186] cli.QueryDisplay:
        sendQueryAndDisplay(ctx, {Addrs:[pe1:57400] Target: Replica:0 Discard:false Queries:[[state port[port-id=1/1/1] ethernet statistics out-utilization]] Type:stream Timeout:30s NotificationHandler:<nil> ProtoHandler:<nil> Credentials:0xc420152460 TLS:0xb78020 Extra:map[]}, &{PollingInterval:10s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x7c6040 DisplayPrefix: DisplayIndent:   DisplayType:s DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[]}):
        client had error while displaying results:
        non-scalar type &{JsonVal:[48]}

As long I am using proto everything works without problems:

#  gnmi_cli -a pe1:57400 -with_user_pass -ca_crt CAcert.pem -qt s -dt p -pi 10s -q state/port[port-id=1/1/1]/ethernet/statistics/out-utilization
username: grpc
password: update: <
  timestamp: 1505822251599627652
  prefix: <
    element: "state"
    element: "port[port-id=1/1/1]"
    element: "ethernet"
    element: "statistics"
  >
  update: <
    path: <
      element: "out-utilization"
    >
    val: <
      json_val: "0"
    >
  >
>

sync_response: true

gnmi_cli is not framing path elem correctly for a given query in SetRequest

When the key is specified in an update/replace query for SetRequest, the key field is not populating the path elem of SetRequest. I am able to see key and value fields properly for the same query in case of SubscribeRequest.

Can please point me how to get the key and value fields properly in case of SetRequest?

Following is the SetRequest update/replace request that gnmi server received from the gnmi GO client.

update SetRequest:

gnmi_cli --address localhost:50051 --ca_crt=/home/ca-bundle.crt --client_crt=/home/client.crt --client_key= /home/client.key -set -update "/eqpt/shelf[shelfId='1']/type=up"

Server Received:
update {
path {
element: "eqpt"
element: "shelfId"
elem {
name: "eqpt"
}
elem {
name: "shelfId"
}
}
value {
value: ""'1']/type=up""
}
val {
json_val: ""'1']/type=up""
}
}

replace SetRequest:

gnmi_cli --address localhost:50051 --ca_crt=/home/ca-bundle.crt --client_crt=/home/client.crt --client_key= /home/client.key -set -replace "/eqpt/shelf[shelfId='1']/type=up"

Server Received:
replace {
path {
element: "eqpt"
element: "shelfId"
elem {
name: "eqpt"
}
elem {
name: "shelfId"
}
}
value {
value: ""'1']/type=up""
}
val {
json_val: ""'1']/type=up""
}
}

SubscribeRequest:

gnmi_cli --address localhost:50051 --ca_crt=/home/ca-bundle.crt --client_crt=/home/client.crt --client_key= /home/client.key --q "/eqpt/shelf[shelfId='1']/type" --qt=p -pi=10s --c=1

Server Received:

subscribe {
prefix {
}
subscription {
path {
element: "eqpt"
element: "shelf[shelfId='1']"
element: "type"
elem {
name: "eqpt"
}
elem {
name: "shelf"
key {
key: "shelfId"
value: "'1'"
}
}
elem {
name: "type"
}
}
}
mode: POLL
}

gnmi_cli command line proto setup example

#23

the xpath /eqpt is a valid xpath and when i set this path elem name to gnmi.GetRequest proto (path<elemname:"eqpt">), getting invalid string error from gnmi_cli parser. Can please point me what is wrong in the proto setup? Please provide some examples reference.

E0702 00:45:24.484458 12144 gnmi_cli.go:180] unable to parse gnmi.GetRequest from "pathelemname:eqpt" : line 1.15: invalid string: eqpt

Question:some minor questions about gnmi.proto

  1. The gnmi.proto file is using proto3, why the generated file named with gnmi_pb2.py and gnmi_pb2_grpc.py?
    syntax = "proto3";

  2. What's the difference bwtween gnmi_pb2.py and gnmi_pb2_grpc.py? I think gnmi_pb2.py is enough,
    why we need gnmi_pb2_grpc.py?

Add generated python gnmi file

Would you mind including the gnmi_pb2.py file in this repo and keeping it updated with gnmi.proto changes? This would make it easier for Python projects using gnmi.

gNmi Subscribe, gNmi gnxi

Is there a plan to combine gnmi subscribe of this repo and the gnxi implementation.

I you would start to implement an gnmi target, would you start at gnxi or at gnmi subscribe and add the rest?

Is there a way to use the YANG models for validation before they are stored in the cache?
Can me someone point to the right direction?

gnmi_cli still does not support PathElem field of message Path from gnmi.proto v4

In this gnmi_cli i was thinking it supports TypedValue val i.e. added in new gnmi.proto 0.4.0 but when i used this client i see this
o/p:
./gnmi_cli -a 10.33.101.170:6702 -qt s -dt p -pi 10s -q /hello/system/logical-core-percent[cpu-id=5] -client_types gnmi
subscribe:<subscription:<path:<element:"hello" element:"system" element:"logical-core-percent[cpu-id=5]" > > >
update: <
timestamp: 1508251414
prefix: <
element: "hello"
element: "system"
element: "logical-core-percent[cpu-id=5]"
origin: "Hello"

update: <
path: <
element: "cpu-idle"
origin: "Hello"
>
value: <
value: "100"
>

Am i missing something here? or not using the client in the right way?

How do i disable TLS in gnmi_cli as tls is not implemented in server side.

How do i disable TLS in gnmi_cli as tls is not implemented on our telemetry server side yet.
I see this error:

./gnmi_cli --address=10.33.83.104:6702 --query state/port[port-id=*]/statistics -qt s -insecure

E0928 14:27:45.630926 5471 gnmi_cli.go:186] cli.QueryDisplay: sendQueryAndDisplay(ctx, {Addrs:[10.33.83.104:6702] Target: Replica:0 Discard:false Queries:[[state port[port-id=*] statistics]] Type:stream Timeout:30s NotificationHandler: ProtoHandler: Credentials: TLS:0xad55c0 Extra:map[]}, &{PollingInterval:30s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x403ae0 DisplayPrefix: DisplayIndent: DisplayType:group DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[]}): client "gnmi" : Dialer(10.33.83.104:6702, 30s): tls: first record does not look like a TLS handshake client "openconfig" : Dialer(10.33.83.104:6702, 30s): tls: first record does not look like a TLS handshake

gnmi_cli with ca_cert option not working

Hi,

I am trying to use gnmi_cli command, where server is started with following option
creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)

however when i run the client i am getting the timeout error consistently. For now i have made changes to validate only the server side certificate as per following sample code:
server.go
https://github.com/grpc/grpc-go/blob/master/examples/route_guide/server/server.go

./gnmi_cli -alsologtostderr -ca_crt /bldimg/fusion/dlakshma/myca_ca.cert.pem -address 10.37.18.172:50052 -get -proto 'prefix:<elem:<name:"interfaces" > elem:<name:"interface" key:<key:"name" value:"interface ethernet 1/1" > > > '
addres:[10.37.18.172:50052]
Target:
Timeout:30s
Credentials:
TLS:&{ [] map[] 0xc0001158c0 [] 0 false [] false false [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0 0 [] false 0 {0 {0 0}} {{0 0} 0 0 0 0} []}

E0122 04:12:21.114742 59705 gnmi_cli.go:189] could not create a gNMI client: Dialer(10.37.18.172:50052, 30s): context deadline exceeded

Can you please let me know if i am missing anything here

Thanks.

Send initial state in POLL subscriptions?

When a client makes a POLL subscription to the target, what is the expected behavior from the target as a result of that? From reading the gNMI specification, there is some ambiguity in what happens:

  1. Client needs to send the poll message to retrieve the current state ($3.5.1.5.3)
  2. If updates_only is set, then only a sync_response is sent ($3.5.2.3). Does that imply that the initial state shall be sent if the flag updates_only is cleared?

Below is a sequence diagram for alternative 1.

  1. Client invokes Subscribe, sending the SubscribeRequest to target.

  2. Client sends an empty poll message on gRPC stream.

  3. Server streams the data to the client

  4. Server finishes operation by sending sync_response message

                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”                            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”          
                 โ”‚gNMI  โ”‚                            โ”‚gNMI  โ”‚          
                 โ”‚clientโ”‚                            โ”‚serverโ”‚          
                 โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜                            โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜          
                    โ”‚        [1] Subscribe, POLL        โ”‚              
                    โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>              
                    โ”‚                                   โ”‚              
                    โ”‚     [2] stream->Write(), poll     โ”‚              
                    โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>              
                    โ”‚                                   โ”‚              
                    โ”‚                                   โ”‚              
       โ•”โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
       โ•‘ LOOP  โ”‚  for each leaf                         โ”‚             โ•‘
       โ•Ÿโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚                                   โ”‚             โ•‘
       โ•‘            โ”‚    [3] stream->Write(), update    โ”‚             โ•‘
       โ•‘            โ”‚ <โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€             โ•‘
       โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
                    โ”‚                                   โ”‚              
                    โ”‚ [4] stream->Write(), sync_responseโ”‚              
                    โ”‚ <โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€              
                 โ”Œโ”€โ”€โ”ดโ”€โ”€โ”€โ”                            โ”Œโ”€โ”€โ”ดโ”€โ”€โ”€โ”          
                 โ”‚gNMI  โ”‚                            โ”‚gNMI  โ”‚          
                 โ”‚clientโ”‚                            โ”‚serverโ”‚          
                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          
    

OPENSSL_internal:BAD_DECRYPT error

We build the gnmi GO client (gnmi_cli) using go1.10.4.linux-amd64.tar.gz.

When we use this gnmi_cli from x86_64 architecture to connect to gNMI Server running on a ppc64 machine using openssl certificates, we are seeing following error. When the same certificates are working fine when gNMI server is running on x86_64 or armv7l machine. There is not much info on BAD_DECRYPT error. Can we use gnmi_cli build using one architecture on another architecture server? What could be the reason for BAD_DECRYPT error when the same certificates are working on different architecture?

E0901 13:59:46.484633290 25656 ssl_transport_security.cc:976] Handshake failed with fatal error SSL_ERROR_SSL: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT.

$ openssl version
OpenSSL 1.1.0e 16 Feb 201
$
$ uname -a
Linux fujitsu 3.12.19-rt30-4.0_2+g6619b8b #1 SMP Fri Aug 31 14:09:57 CDT 2018 ppc64 GNU/Linux
$

Certificate Generation commands:

client_openssl.txt

openssl genrsa -passout pass:1234 -des3 -out googleca.key 4096
openssl req -passin pass:1234 -new -x509 -days 365 -key googleca.key -out googleca.crt -subj "/C=SP/ST=Spain/L=Valdepenias/O=Test/OU=Test/CN=Root CA"

openssl genrsa -passout pass:1234 -des3 -out client.key 4096
openssl req -passin pass:1234 -new -key client.key -out client.csr -subj "/C=SP/ST=Spain/L=Valdepenias/O=Test/OU=Client/CN=gNMIClientKoti"
openssl x509 -passin pass:1234 -req -days 365 -in client.csr -extfile ./client_openssl.cnf -extensions v3_ca -CA googleca.crt -CAkey googleca.key -set_serial 01 -out client.crt
openssl rsa -passin pass:1234 -in client.key -out client.key

openssl x509 -in googleca.crt -text >> roots.pem

openssl genrsa -passout pass:1234 -des3 -out fujitsuca.key 4096
openssl req -passin pass:1234 -new -x509 -days 365 -key fujitsuca.key -out fujitsuca.crt -subj "/C=SP/ST=Spain/L=Valdepenias/O=Test/OU=Test/CN=Root CA"
openssl genrsa -passout pass:1234 -des3 -out server.key 4096
openssl req -passin pass:1234 -new -key server.key -out server.csr -subj "/C=SP/ST=Spain/L=Valdepenias/O=Test/OU=Server/CN=gNMIServerKoti"
openssl x509 -req -passin pass:1234 -days 365 -in server.csr -extfile ./client_openssl.cnf -extensions v3_ca -CA fujitsuca.crt -CAkey fujitsuca.key -set_serial 01 -out server.crt

touch ca-bundle.crt
chmod 777 ca-bundle.crt
openssl x509 -in fujitsuca.crt -text >> ca-bundle.crt
openssl rsa -passin pass:1234 -in server.key -out server.key
cat server.key server.crt > server.pem

gnmi_cli improve help on command line options

It would be good to provide help for the usage of some command line options:

  -count uint
        Number of polling/streaming events (0 is infinite).
  -display_indent string
        Output line, per nesting-level indent. (default "  ")
  -display_prefix string
        Per output line prefix.
  -display_size
        Display the total size of query response.
  -display_type string
        Display output type (g, group, s, single, p, proto). (default "group")
  -latency
        Display the latency for receiving each update (Now - update timestamp).
  -v value
        log level for V logs
  -vmodule value
        comma-separated list of pattern=N settings for file-filtered logging

Most of these options does not work at all in my test environment, so usage examples are welcome. Following command works for me:

# gnmi_cli -a pe1:57400 -with_user_pass -ca_crt CAcert.pem -qt s -dt p -pi 10s -q state/port[port-id=1/1/1]/ethernet/statistics/out-utilization

Expactation would be, that by adding the parameter -count 1 I would only see the first response. But in my setup it still streams forever.

target_defined mode in gnmi_cli client

Is target_defined mode implemented in gnmi_cli decoder?

Target Defined (TARGET_DEFINED) - when a client creates a subscription specifying the target defined mode, the target MUST determine the best type of subscription to be created on a per-leaf basis. That is to say, if the path specified within the message refers to some leaves which are event driven (e.g., the changing of state of an entity based on an external trigger) then an ON_CHANGE subscription may be created, whereas if other data represents counter values, a SAMPLE subscription may be created.

I don't see any knobs to enable this mode:
root@yangtze:~/hfzhang/gnmi# gnmi_cli --help
Usage of gnmi_cli:
-a value
Short for address.
-address value
Address of the GNMI target to query.
-alsologtostderr
log to standard error as well as files
-c uint
Short for count.
-ca_crt string
CA certificate file. Used to verify server TLS certificate.
-capabilities
When set, CLI will perform a Capabilities request. Usage: gnmi_cli -capabilities [-proto <gnmi.CapabilityRequest>] -address

[other flags ...]
-client_crt string
Client certificate file. Used for client certificate-based authentication.
-client_key string
Client private key file. Used for client certificate-based authentication.
-client_types value
List of explicit client types to attempt, one of: gnmi. (default gnmi)
-count uint
Number of polling/streaming events (0 is infinite).
-d string
Short for delimiter. (default "/")
-delimiter string
Delimiter between path nodes in query. Must be a single UTF-8 code point. (default "/")
-display_indent string
Output line, per nesting-level indent. (default " ")
-display_prefix string
Per output line prefix.
-display_size
Display the total size of query response.
-display_type string
Display output type (g, group, s, single, p, proto). (default "group")
-ds
Short for display_size.
-dt string
Short for display_type. (default "group")
-get
When set, CLI will perform a Get request. Usage: gnmi_cli -get -proto <gnmi.GetRequest> -address [other flags ...]
-insecure
When set, CLI will not verify the server certificate during TLS handshake.
-l Short for latency.
-latency
Display the latency for receiving each update (Now - update timestamp).
-log_backtrace_at value
when logging hits line file:N, emit a stack trace
-log_dir string
If non-empty, write log files in this directory
-logtostderr
log to standard error instead of files
-p string
Short for request proto.
-pi duration
Short for polling_interval. (default 30s)
-polling_interval duration
Interval at which to poll in seconds if polling is specified for query_type. (default 30s)
-proto string
Text proto for gNMI request.
-q value
Short for query.
-qt string
Short for query_type. (default "once")
-query value
Comma separated list of queries. Each query is a delimited list of OpenConfig path nodes which may also be specified as a glob (*). The delimeter can be specified with the --delimiter flag.
-query_type string
Type of result, one of: (o, once, p, polling, s, streaming). (default "once")
-sd duration
Short for streaming_duration.
-server_name string
When set, CLI will use this hostname to verify server certificate during TLS handshake.
-set
When set, CLI will perform a Set request. Usage: gnmi_cli -set -proto <gnmi.SetRequest> -address [other flags ...]
-stderrthreshold value
logs at or above this threshold go to stderr
-streaming_duration duration
Length of time to collect streaming queries (0 is infinite).
-t string
Short for target.
-target string
Name of the gNMI target.
-timeout duration
Terminate query if no RPC is established within the timeout duration. (default 30s)
-timestamp string
Specify timestamp formatting in output. One of (, on, raw, ) where is disabled, on is human readable, raw is int64 nanos since epoch, and is according to golang time.Format()
-ts string
Short for timestamp.
-u Short for updates_only.
-updates_only
Only stream updates, not the initial sync. Setting this flag for once or polling queries will cause nothing to be returned.
-v value
log level for V logs
-vmodule value
comma-separated list of pattern=N settings for file-filtered logging
-with_user_pass
When set, CLI will prompt for username/password to use when connecting to a target.

Question:What's the function of 'key' in PathElem define?

Hi all, I want to ask a question, I think a string is enough in PathElem define , why we need map<string, string> key = 2 ? could give me an example? Thanks.

message PathElem {
  string name = 1;                    // The name of the element in the path.
  map<string, string> key = 2;        // Map of key (attribute) name to value.
}

gNMI dial in vs dial out

As I understand both are supported from gNMI/gRPC standard point of view. Right ?

*** Which forum such questions should be asked ? ***

I know this is forum for pure issue reporting and wrong place. So, apologize for it.

Questions: Design about ModelData Message

Hi Google teams,

I think ModelData is a good design within the SubscribeReqeust and GetRequest, and it can avoid any collisions in path or pathElem which published by different organizations.
Why not apply it in SetRequest?
Is there any special consideration for that?
looking forward for your reply.

ModelData
// ModelData is used to describe a set of schema modules. It can be used in a
// CapabilityResponse where a target reports the set of modules that it
// supports, and within the SubscribeRequest and GetRequest messages to specify
// the set of models from which data tree elements should be reported.

rpc/Suscribe
// The set of schemas that define the elements of the data tree that should
// be sent by the target.
repeated ModelData use_models = 7;

rpc/Get
repeated ModelData use_models = 6; // The schema models to be used.

Errors are often not displayed correctly

Using latest version of gnmi_cli against my server which is running gnmi v0.3.1.
If using wrong username/password I often get the following response:

#  gnmi_cli -a pe1:57400 -with_user_pass -ca_crt CAcert.pem -qt s -dt p -pi 10s -q state/port[port-id=1/1/1]/ethernet/statistics/out-utilization
username: wrong
password: E0919 14:00:31.086602    5194 gnmi_cli.go:186] cli.QueryDisplay:
        sendQueryAndDisplay(ctx, {Addrs:[pe1:57400] Target: Replica:0 Discard:false Queries:[[state port[port-id=1/1/1] ethernet statistics out-utilization]] Type:stream Timeout:30s NotificationHandler:<nil> ProtoHandler:<nil> Credentials:0xc420152460 TLS:0xb78020 Extra:map[]}, &{PollingInterval:10s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x7c6040 DisplayPrefix: DisplayIndent:   DisplayType:p DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[]}):
        client had error while displaying results:
        rpc error: code = Unimplemented desc =

But sometime the error display is correct:

#  gnmi_cli -a pe1:57400 -with_user_pass -ca_crt CAcert.pem -qt s -dt p -pi 10s -q state/port[port-id=1/1/1]/ethernet/statistics/out-utilization
username: wrong
password: E0919 14:00:13.705036    5187 gnmi_cli.go:186] cli.QueryDisplay:
        sendQueryAndDisplay(ctx, {Addrs:[pe1:57400] Target: Replica:0 Discard:false Queries:[[state port[port-id=1/1/1] ethernet statistics out-utilization]] Type:stream Timeout:30s NotificationHandler:<nil> ProtoHandler:<nil> Credentials:0xc420152460 TLS:0xb78020 Extra:map[]}, &{PollingInterval:10s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x7c6040 DisplayPrefix: DisplayIndent:   DisplayType:p DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[]}):
        client had error while displaying results:
        rpc error: code = Unauthenticated desc = Invalid username or password

Unclear, why this is. Is there any way to check, if this is a server or client issues.
In addition I am confused why getting the message "client had error while displaying results".

Update firmware on switch?

I am wondering if I have to update firmware on a switch that supports gRPC, how would I do that? I don't see gNMI nor gNOI support such an operation. I wanted to know if there is any known interface for such a task or does one hack with protobuf with a binary blob of data and also have the switch understand the blob?

Serialization method for gnmi_ext.registered_ext.msg

The gnmi_ext.proto file mentions the following for msg attribute:
"The binary-marshalled protobuf extension payload."
As there are quite a few methods to serialize a message e.g SerializeToString or SerializeToArray, which one should the server choose to serialize the message? If the message is serialized using SerializeToArray, then on the client side, the collector will need to know the actual size of the array to deserialize. Moreover, AFAIK, there is no method to deserialize array in Python. Also, in Go, we have Marshall and UnMarshall methods. Can you please suggest the best way to populate the extension payload on the server side?

gnmi_cli returns an error, when delimiter is contained in key value

Example:

# go run gnmi_cli.go -a pe1:57400 -with_user_pass -qt s -dt p -insecure -q state/port[port-id=1/1/1]/ethernet/statistics/out-utilization
username: grpc
password: ********
E0913 20:32:05.785297   20625 gnmi_cli.go:180] cli.QueryDisplay:
        sendQueryAndDisplay(ctx, {Addrs:[pe1:57400] Target: Replica:0 Discard:false Queries:[[state port[port-id=1 1 1] ethernet statistics out-utilization]] Type:stream Timeout:30s NotificationHandler:<nil> ProtoHandler:<nil> Credentials:0xc420150440 TLS:0xb75d60 Extra:map[]}, &{PollingInterval:30s StreamingDuration:0s Count:0 countExhausted:false Delimiter:/ Display:0x7c56f0 DisplayPrefix: DisplayIndent:   DisplayType:p DisplayPeer:false Timestamp: DisplaySize:false Latency:false ClientTypes:[]}):
        client had error while displaying results:
        rpc error: code = Unimplemented desc =

While this one is working nicely:

# go run gnmi_cli.go -a pe1:57400 -with_user_pass -qt s -dt p -insecure -q state_port[port-id=1/1/1]_ethernet_statistics_out-utilization -d _
username: grpc
password: ********

update: <
  timestamp: 1505327998773031795
  prefix: <
    element: "state"
    element: "port[port-id=1/1/1]"
    element: "ethernet"
    element: "statistics"
  >
  update: <
    path: <
      element: "out-utilization"
    >
    val: <
      json_val: "0"
    >
  >
>

sync_response: true

It would be desired, if the any slash characters "/" within square brackets "[...]" are not used as delimiter.

gnmi_cli requires client key/crt for self-signed certificates

Unclear, how to use gnmi_cli with self-signed server certificates.

Testing with CAcert.pem returns an error:

# go run ./src/github.com/openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go --address pe1:57400 --query state/port[port-id=*]/statistics --with_user_pass -qt s -dt p --ca_crt CAcert.pem
username: grpc
password: ********
F0913 20:06:35.706205   16165 gnmi_cli.go:157] --ca_crt --client_crt and --client_key must be set with file locations
exit status 1

Two ways to work around this issue:

# go run ./src/github.com/openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go --address pe1:57400 --query state/port[port-id=*]/statistics --with_user_pass -qt s -dt p --ca_crt CAcert.pem --client_crt cert.pem --client_key key.pem
username: grpc
password: ********

update: <
  timestamp: 1505326055483137479
  prefix: <
    element: "state"
    element: "port[port-id=1/1/1]"
    element: "statistics"

or

# go run ./src/github.com/openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go --address pe1:57400 --query state/port[port-id=*]/statistics --with_user_pass -qt s -dt p -insecure
username: grpc
password: ********

update: <
  timestamp: 1505326230813076769
  prefix: <
    element: "state"
    element: "port[port-id=1/1/1]"
    element: "statistics"
  >
  update: <
    path: <

The first workaround is bad, as it requires to provide client certificate/key - but I am using just username and password authentication in my setup. So to generate and provide the client certificate is meaningless.
The second workaround is not good either, as I am disabling TLS security completely. So basically the server certificate is accepted without being checked against my CA certificate.

In general, I would recommend to allow users just to provide the CA certificate without making the client certificate mandatory. The other option is to provide a documentation, how to install additional CA certificates on system-level (unclear, what cert pool is used by default by the golang gRPC implementation).

Question:how to fill the mode field of Subscription if the mode is ONCE or POLL?

Hi, all, I have a question. According to the specification, there are three type subscriptions, ONCE, STREAM and POLL. When using STREAM mode, the mode field of Subscription must be specified with one of the following modes: ON_CHANGE, SAMPLE and TARGET_DEFINED, I want to know if I use ONCE or POLL mode, how to fill the mode field of Subscription? I didn't find any explain in the specification. Thanks.
https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md

message SubscriptionList {
    Path prefix = 1;                          // Prefix used for paths.
    repeated Subscription subscription = 2;   // Set of subscriptions to create.
  ...
  enum Mode {
      STREAM = 0; // Values streamed by the target (Sec. 3.5.1.5.2).
      ONCE = 1;   // Values sent once-off by the target (Sec. 3.5.1.5.1).
      POLL = 2;   // Values sent in response to a poll request (Sec. 3.5.1.5.3).
  }
  Mode mode = 5;
  ...
}

message Subscription {
  Path path = 1;                    // The data tree path.
  SubscriptionMode mode = 2;        // Subscription mode to be used.
  uint64 sample_interval = 3;       // ns between samples in SAMPLE mode.
  ...
}

enum SubscriptionMode {
  TARGET_DEFINED = 0;  // The target selects the relevant mode for each element.
  ON_CHANGE      = 1;  // The target sends an update on element value change.
  SAMPLE         = 2;  // The target samples values according to the interval.
}

gnmi_cli is not displaying subscribeResponse

I am still in the initial phase of setting up server and gnmi_cli (go) communication. When the following subscribeReuqest is initiated from the gnmi_cli, my server is receiving the request and able to parse the query string. And am filling the subscribeResponse as needed. This response is not getting displayed on gnmi_cli session and the session just hangs . Can please point me what did I miss in filling the SubscribeResponse message? And also point me how to enable debug verbose in gnmi_cli?

gnmi_cli subscribeRequest:

./gnmi_cli --address rtxscplp124:50051 --ca_crt server.crt --q /system/services -qt "once" --logtostderr

Server SubscribeResponse data:

('subscribe_res', update {
timestamp: 1234567
update {
path {
origin: "Koti"
elem {
name: "system"
}
elem {
name: "services"
}
}
val {
json_val: "{\n "system:services": {\n "ssh-server": {\n "ssh-server-enabled": true,\n "ssh-server-port": 22,\n "algorithms": {\n "mac": ["hmac-md5", "hmac-sha1", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1-96", "hmac-md5-96"],\n "encryption": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-cbc", "aes256-cbc", "3des-cbc"]\n }\n },\n "web-server": {\n "webgui-enabled": true,\n "webgui-timeout": "PT30M",\n "rest": {\n "rest-enabled": true\n },\n "http": {\n "http-port": 80\n }\n },\n "ftp": {\n "ftp-server": {\n "ftp-server-enabled": false,\n "ftp-server-port": 21\n }\n },\n "sftp": {\n "sftp-server": {\n "sftp-server-enabled": false,\n "sftp-server-port": 2202,\n "algorithms": {\n "allowed-mac": ["hmac-md5", "hmac-sha1", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1-96", "hmac-md5-96"],\n "allowed-encryption": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-cbc", "aes256-cbc", "3des-cbc"]\n }\n }\n },\n "telnet": {\n "telnet-enabled": false,\n "telnet-port": 23\n },\n "netconf": {\n "netconf-enabled": true,\n "netconf-port": 830,\n "netconf-timeout": "PT30M"\n },\n "snmp": {\n "snmp-enabled": true,\n "snmp-port": 161,\n "snmp-ip": "0.0.0.0",\n "system-snmp:authFailureTrap": "enabled",\n "system-snmp:alarm-trap": "enabled",\n "system-snmp:event-trap": "enabled",\n "system-snmp:tca-trap": "enabled"\n }\n }\n}\n"
}
}
}
)

Question: about message Update/duplicates

Hi,

I'm not sure how to use the filed duplicates in the message Update.
can anybody describe some user scenarios?
thanks.

==
message Update {
Path path = 1; // The path (key) for the update.
Value value = 2 [deprecated=true]; // The value (value) for the update.
TypedValue val = 3; // The explicitly typed update value.
uint32 duplicates = 4; // Number of coalesced duplicates.
}

Need gnmi_cli set request example

I am getting following error when used "-set" to trigger SetRequest from gnmi_cli. What would be the SetRequest syntax for gnmi_cli?

./gnmi_cli -address myServer:5000 -ca_crt /data/users/server.crt -set "/eqpt/shelf/1/admin-status" -update "down" -timeout 10s
E1026 23:43:21.831747 37571 gnmi_cli.go:141] Set failed: Query() must be called before any operations on client

broken import in proto/gnmi/gnmi.pb.go ?

Hi,

My apologies if this report is not very clear, I'm not very familiar with either go or protobuf. But I'm trying to build a project which dependends on openconfig/gnmi, that started failing after 084de23

../../build/debug/third_party/go/src/github.com/openconfig/gnmi/proto/gnmi/gnmi.pb.go:22:8: no Go files in /build/debug/third_party/go/src/github.com/openconfig/gnmi/proto/gnmi_ext

It seems that openconfig/gnmi/proto/gnmi_ext does not contain any go file, so this import fails (at least that's my guess, but again, I don't know much about Go or this project in particular).

Thanks for your time.

gNMI SET example

Folks-
This is not a bug report. But, I didn't know where to get my thought validated. I want to check if I'm using the right SET command and comply with gNMI. We are using the "protobuf.any" (structured data types mentioned in section 2.3.3 of the gNMI spec) encoding for the data.
Eg: Setting interface properties for interface "ethernet1/1/1":

SET request : update {
  path {
    elem {
      name: "interfaces"
    }
    elem {
      name: "interface"
      key {
        key: "name"
        value: "ethernet1/1/1"
      }
    }
  }
  val {
    any_val {
      type_url: "type.googleapis.com/openconfig.openconfig_interfaces.Interfaces.Interface"
      value: "\332\246\343\372\t&\352\366\377\215\001\002\b\001\332\201\317\305\001\017\n\rethernet1/1/1\262\272\220\233\v\003\b\376\v"
    }
  }

Another example, for setting up a BGP Neighbor:

SetRequest: replace {
  path {
    elem {
      name: "bgp"
    }
    elem {
      name: "neighbors"
    }
    elem {
      name: "neighbor"
      key {
        key: "neighbor-address"
        value: "192.168.3.1"
      }
    }
    elem {
      name: "config"
    }
  }
  val {
    any_val {
      type_url: "type.googleapis.com/openconfig.openconfig_bgp.Bgp.Neighbors.Neighbor.Config"
      value: "\202\277\260!\r\n\v192.168.3.1\302\362\321\205\v\002\b\001\222\261\275\214\v\004\b\331\370\003\272\231\366\265\016\004\b\200\370\003"
    }
  }
}

Could someone confirm if I'm doing this right?
Thanks for your time.

Coverage extent of 'path' for Get/Subscribe request

Given the Openconfig data-model, are there any set guide-lines forpath variable to be used in gNMI Get or Subscribe requests ? Please note that, I am not looking for syntactical guidelines here, which are already specified with greater length of details; Instead, what am looking for is more to do with semantic coverage of given a path and how much the path's coverage should be ? Below questions are applicable to both Get & Subscribe requests.

  1. For larger data sets, it is suggested to use Subscribe than Get, so that data can be streamed per section 3.5. Can a client specify a high-level path something like '/' (root) and expect all of the data tree to be streamed ? Such an operation can become quite resource intensive on the target, though it is streaming.
  2. Similar question for SubscriptionRequest as well. Can a client subscribe for high-level path e.g., /network-instances/network-instance and expect to receive Updates per the request made, whenever any change happens in any of the sub-trees which could go upto multi-levels e.g., /network-instances/network-instance/protocols/protocol/bgp/... ? This could pose potential performance issues when it comes to tracking of highly scaled state information such as routes learnt of a particular network-instance. To add to this, such information can also be very dynamic in nature.

As a greedy/lazy gNMI client application, it might be easy to ask for everything by specifying a high-level path which covers a majority of the state data, but actually may be interested in very minor percent of such data. This could keep the gNMI server busy with tracking and publishing state information when the network is busy. So, in such cases, having rules to limit the data coverage or forcing to ask specific/explicit sub-set of information will help keep things under control.

Example cmd/gnmi_cli directly uses a package that says you shouldn't use it directly

github.com/openconfig/gnmi/client/gnmi says "Note: this package should not be used directly. Use github.com/openconfig/gnmi/client instead."

Yet the example gnmi_cli uses it directly (here). And (maybe I'm missing it) I see no other way to do a Capabilities, or regular Get or Set calls.

Quite possibly I'm missing something. I'm new to gNMI.

As a side note, that package resides in .../gnmi/client/gnmi but is actually called package client, which is weird.

cache, gnmi update, suppressed duplicate value prevents all other updates

Hi,
I identified following problem:
If I update the cache with multiple Updates in one gNmi Notification, and one Notification has the same value as the old one, than on the following line an error is generated:

return nil, errors.New("suppressed duplicate value")

and here the loop is aborted.

gnmi/cache/cache.go

Lines 349 to 352 in 33a1865

nd, err := t.gnmiUpdate(noti)
if err != nil {
return err
}

I think that is not correct.

Extension of Subscription message

I would like to ask for an extension in Subscription message allowing to define a "filter criteria". In case the collector subscribes to large tables, it would be beneficial to define a filter criteria in order to limit number of notifications sent by the target.
For instance, in case of subscribing to forwarding table, it is sometimes required to subscribe only to routes form certain subnets iso of all forwarding entries. Similarly, only routes originated by a particular protocol (e.g. isis) could be filtered out.
Also other tables, (e.g. subscriber-hosts) which are typically large and experience relatively high number of changes would benefit possibility to filter outgoing notifiactions.
In Nokia we have currently the server implementation which allows to filter subscription to a forwarding table based on the prefix, but this is based on using proprietary "keyword" in the path.
In order to make it more generic, applicable to more use cases, it would be better to have ability to define generic filter in Subscription message.

How to fill Subscription attributes in SubscribeRequest using gnmi_cli

We are able to fill very few attributes of SubscribeRequest-->SubscriptionList attribute like mode using --qt in gnmi_cli.

gnmi_cli help is not displaying options (I may be missing from the list of displayed options) to fill other SubscribeRequest attributes like poll, aliases, prefix, use_aliases, qos, encoding, sample_interval, suppress_redundant, heartbeat_interval etc...

Can Please point me some examples how to fill SubscribeRequest fields using gnmi_cli client.

Need help with subscribe example: Error "received bogus greeting from client"

Hi,

I am having trouble running the GNMI client/sever example. I tried to trace the issue: The details are below. It seems I am missing something.

I am looking for sample commands for client and server to go with the uploaded example-config.pb.txt

Please see below what I have been trying, the issue I am seeing, and related debugging.
Please help to share if you have any general suggestions in this regard.

Many Thanks for your time and help!
Best Regards,
Nilesh

Here are two versions of example-configs I have been trying to get working
$ cat example-config.pb.txt
target: "foo"
client_type: GRPC_GNMI

$ cat example-config-cred.pb.txt
target: "foo"
client_type: GRPC_GNMI
credentials: {username: "grpc", password: "grpc"}

I run server as follows:
./cmd --config=example-config.pb.txt --text --port=57400
./cmd --config=example-config.pb.txt --text --port=57400 --server_key ~/z/keys/server.key --server_crt ~/z/keys/server.crt --ca_crt ~/z/keys/ca.crt
[I am new to golang; I did 'go install' in directory server.go; the binary in the $GOPATH/bin is cmd.]

I tried running client in several ways
./gnmi_cli --address localhost:57400 --query state/port[port-id=]/statistics --with_user_pass -qt s -dt p -insecure
./gnmi_cli --address localhost:57400 --query state/port[port-id=
]/statistics --with_user_pass -qt s -dt p --ca_crt ~/z/keys/ca.crt --client_crt ~/z/keys/client.crt --client_key ~/z/keys/client.key

For client, I tried changing query to everything:
./gnmi_cli --address localhost:57400 --query * --with_user_pass -qt s -dt p -insecure

Here is what issue the code is running into with the above config-files, server commands, client commands:
./cmd --config=example-config.pb.txt --text --port=57400
./gnmi_cli --address localhost:57400 --query state/port[port-id=*]/statistics --with_user_pass -qt s -dt p -insecure

  1. The client is able to connect to the server.
    Under wireshark I do see packets being exchanged between the client and server.

  2. I have not been able to get the verbose logs working. (a side question is how to enable verbose logs?) so I added several debug prints in the GNMI and underlying GRPC source code.
    I am attaching a file, if you would like to see the trace with my debug-prints.
    Summarizing, under GRPC, it goes inside serveHTTP2Transport() from grpc/server.go and then calls serveStreams(), and then HandleStreams() from http2_server.go
    In here, it closes the connection from the condition preface != clientPreface
    errorf("transport: http2Server.HandleStreams received bogus greeting from client: %q", preface)

  3. Under Wireshark, I see that the server is resetting the two (Guess, one connection is for GNMI based channel and other one is Openconfig based channel as mentioned in client documentation) connections.

Next, I used the second config file with credentials as well, and there is no change in behavior.

Next, I used certificates, the server is closing the connection
./cmd --config=example-config.pb.txt --text --port=57400 --server_key ~/z/keys/server.key --server_crt ~/z/keys/server.crt --ca_crt ~/z/keys/ca.crt
./gnmi_cli --address localhost:57400 --query state/port[port-id=*]/statistics --with_user_pass -qt s -dt p --ca_crt ~/z/keys/ca.crt --client_crt ~/z/keys/client.crt --client_key ~/z/keys/client.key

In this case, the handleRawConn() returns with error (from the very first if condition which says Handshake failed) from grpc/server.go

Again, I think, I may be missing something very basic and if I could get an example

  1. sample config file
  2. what parameters to pass to server
  3. what parameters to pass to client
    to get the GitHub code working on my local PC working, it would be great!! Really appreciate your help and time!

Thanks,
Best Regards,
Nilesh

grpc_client_server_connection_errors.txt

TypedVal float_val only allows float32

TypedValue in gnmi.proto has a float_val member whose type is float. This translates to a 32-bit floating point in generated code, eg. a float32 in Go. The intention based on the gNMI Specification seems to have been for this to be a double which translates to a 64-bit floating point, eg. float64 in Go.

From the gNMI Specification:

float in the float_val field, used to store floating-point values (i.e., float32, float64).

Unfortunately, this type can't be changed to double without breaking backwards compatibility. A new double field could be introduced in TypedValue, and possibly the float field could be deprecated. Or, it could be advised to encode float64 values as JSON.

gnmi_cli is stripping double quotes in TypedValue

I am using the latest gnmi_cli in which Set & Get are taking proto directly. I am seeing a behavior with the json_val or json_ietf_val fields. The quotes(") are stripping by gnmi_cli and server is receiving the json values are as type str. Is there any way we can avoid removing the quotes(") specified in the gnmi_cli's SetRequest and can server receives the same with quotes? (if gnmi_cli is not sending the json val in json format instead sending as string).

When single quote is used around the names in json_val or json_ietf_val, gnmi_cli is reporting a parsing error "unknown field name in gnmi.TypedValue"

When the escape character is used before quotes("), gnmi_cli is sending the request as it is (")

With Double quotes in json_val or json_ietf_val:

For the below gnmi_cli SetRequest update,

./gnmi_cli --address rtxscplp124:20175 --ca_crt /home/kboyapa1/crt/ca-bundle.crt --client_crt /home/kboyapa1/crt/client.crt --client_key /home/kboyapa1/crt/client.key --d="#" --set --proto "update<path<elemname:'eqpt' elem<name:'shelf' key<key:'shelfId' value:'1'>>> val<json_ietf_val:'{"slot":[{"slotID":"FAN1","admin-status":"up"}]}'>>" --with_user_pass

The server is receiving the SetRequest as
Received SetRequest = update {
path {
elem {
name: "eqpt"
}
elem {
name: "shelf"
key {
key: "shelfId"
value: "1"
}
}
}
val {
json_ietf_val: "{slot:[{slotID:FAN1,admin-status:up}]}"
}
}

I am expecting json_ietf_val: '{"slot":[{"slotID":"FAN1","admin-status":"up"}]}' as showed in gnmi specification.

With Single quote in json_val or json_ietf_val:

./gnmi_cli --address rtxscplp124:20175 --ca_crt /home/kboyapa1/crt/ca-bundle.crt --client_crt /home/kboyapa1/crt/client.crt --client_key /home/kboyapa1/crt/client.key --d="#" --set --proto "update<path<elemname:'eqpt' elem<name:'shelf' key<key:'shelfId' value:'1'>>> val<json_ietf_val:'{'slot':[{'slotID':'FAN1','admin-status':'up'}]}'>>" --with_user_pass
username: fujitsu
password: E0704 01:34:14.738653 5057 gnmi_cli.go:180] unable to parse gnmi.SetRequest from "update<path<elemname:'eqpt' elem<name:'shelf' key<key:'shelfId' value:'1'>>> val<json_ietf_val:'{'slot':[{'slotID':'FAN1','admin-status':'up'}]}'>>" : line 1.100: unknown field name "slot" in gnmi.TypedValue

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.