Skip to content

Commit

Permalink
Update gnmi_cli (#5) (#44)
Browse files Browse the repository at this point in the history
Update gnmi_cli
When configured via args:
    1) Write responses only to a o/p file instead of stdout.
    2) For on change events, filter for a specific event.
    3) Exit upon receiving N responses.
    4) Exit upon timeout.

The above would help use gnmi_cli as tool in scripting environment that does testing.
  • Loading branch information
renukamanavalan authored Oct 10, 2022
1 parent 194ecd0 commit 4f45e3a
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 1 deletion.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ $(GO_DEPS): go.mod $(PATCHES)
patch -d vendor -p0 < patches/gnmi_cli.all.patch
patch -d vendor -p0 < patches/gnmi_set.patch
patch -d vendor -p0 < patches/gnmi_get.patch
git apply patches/0001-Updated-to-filter-and-write-to-file.patch
touch $@

go-deps: $(GO_DEPS)
Expand Down
173 changes: 173 additions & 0 deletions patches/0001-Updated-to-filter-and-write-to-file.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
From 738d4783c75839ec12e373848e9abfe88f0dae47 Mon Sep 17 00:00:00 2001
From: Renuka Manavalan <remanava@microsoft.com>
Date: Sun, 9 Oct 2022 17:05:46 +0000
Subject: [PATCH] Updated to filter and write to file

---
vendor/github.com/openconfig/gnmi/cli/cli.go | 13 +++-
.../openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go | 67 +++++++++++++++++--
2 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/vendor/github.com/openconfig/gnmi/cli/cli.go b/vendor/github.com/openconfig/gnmi/cli/cli.go
index 81a8704..ca0a383 100644
--- a/vendor/github.com/openconfig/gnmi/cli/cli.go
+++ b/vendor/github.com/openconfig/gnmi/cli/cli.go
@@ -22,6 +22,7 @@ import (
"context"
"encoding/json"
"fmt"
+ "reflect"
"strings"
"time"

@@ -286,7 +287,8 @@ func displayPollingResults(ctx context.Context, query client.Query, cfg *Config)
// subsequent individual updates as they arrive.
func displayStreamingResults(ctx context.Context, query client.Query, cfg *Config) error {
c := client.New()
- complete := false
+ onChange := query.Streaming_type == gpb.SubscriptionMode(1)
+ complete := onChange
display := func(path []string, ts time.Time, val interface{}) {
if !complete {
return
@@ -295,8 +297,15 @@ func displayStreamingResults(ctx context.Context, query client.Query, cfg *Confi
if cfg.Timestamp != "" {
b.add(append(path, "timestamp"), ts)
b.add(append(path, "value"), val)
- } else {
+ } else if !onChange {
b.add(path, val)
+ } else {
+ v := reflect.ValueOf(val)
+ if v.Kind() == reflect.String {
+ json.Unmarshal([]byte(v.String()), &b)
+ } else {
+ b.add(path, val)
+ }
}
result, err := json.MarshalIndent(b, cfg.DisplayPrefix, cfg.DisplayIndent)
if err != nil {
diff --git a/vendor/github.com/openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go b/vendor/github.com/openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go
index e851a4b..6d04a74 100644
--- a/vendor/github.com/openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go
+++ b/vendor/github.com/openconfig/gnmi/cmd/gnmi_cli/gnmi_cli.go
@@ -27,6 +27,7 @@ import (
"context"
"crypto/tls"
"crypto/x509"
+ "encoding/json"
"errors"
"fmt"
"io/ioutil"
@@ -39,24 +40,48 @@ import (

"flag"

- log "github.com/golang/glog"
"golang.org/x/crypto/ssh/terminal"
"github.com/golang/protobuf/proto"
"github.com/openconfig/gnmi/cli"
"github.com/openconfig/gnmi/client"
"github.com/openconfig/gnmi/client/flags"
gclient "github.com/openconfig/gnmi/client/gnmi"
+ log "github.com/golang/glog"

gpb "github.com/openconfig/gnmi/proto/gnmi"
)

var (
+ displayHandle = os.Stdout
+ prefix = []byte("[\n")
+ rcvd_cnt uint = 0
+ term = make(chan string, 1)
q = client.Query{TLS: &tls.Config{}}
mu sync.Mutex
cfg = cli.Config{Display: func(b []byte) {
- defer mu.Unlock()
- mu.Lock()
- os.Stdout.Write(append(b, '\n'))
+ found := len(*expected_event) == 0
+ if !found {
+ var fvp map[string]interface{}
+
+ json.Unmarshal(b, &fvp)
+ _, found = fvp[*expected_event]
+ }
+ if found {
+ defer mu.Unlock()
+ mu.Lock()
+
+ if *expected_cnt > 0 {
+ rcvd_cnt += 1
+ if *expected_cnt <= rcvd_cnt {
+ s := fmt.Sprintf("Received all. expected:%d rcvd:%d", *expected_cnt, rcvd_cnt)
+ log.V(7).Infof("Writing to terminate: %v", s)
+ term <- s
+ }
+ }
+ displayHandle.Write(prefix)
+ displayHandle.Write(b)
+ prefix = []byte(",\n")
+ }
}}

clientTypes = flags.NewStringList(&cfg.ClientTypes, []string{gclient.Type})
@@ -81,6 +106,10 @@ var (
streaming_sample_int = flag.Uint("streaming_sample_interval", 0, "Streaming sample inteval seconds, 0 means lowest supported.")
heartbeat_int = flag.Uint("heartbeat_interval", 0, "Heartbeat inteval seconds.")
suppress_redundant = flag.Bool("suppress_redundant", false, "Suppress Redundant Subscription Updates")
+ output_file = flag.String("output_file", "", "Output file to write the response")
+ expected_cnt = flag.Uint("expected_count", 0, "End upon receiving the count of responses.")
+ expected_event = flag.String("expected_event", "", "Event to capture")
+ streaming_timeout = flag.Uint("streaming_timeout", 0, "Exits after this time.")
)

func init() {
@@ -125,7 +154,21 @@ func init() {
func main() {
flag.Parse()

+ defer func() {
+ displayHandle.Write([]byte("\n]\n"))
+ displayHandle.Close()
+ }()
+
+ if len(*output_file) != 0 {
+ var err error
+ displayHandle, err = os.OpenFile(*output_file, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ log.Error(fmt.Printf("unable to create output file(%v) err=%v\n", *output_file, err))
+ return
+ }
+ }
ctx, cancel := context.WithCancel(context.Background())
+
// Terminate immediately on Ctrl+C, skipping lame-duck mode.
go func() {
c := make(chan os.Signal, 1)
@@ -134,6 +177,22 @@ func main() {
cancel()
}()

+ go func() {
+ if *streaming_timeout > 0 {
+ time.Sleep(time.Duration(*streaming_timeout) * time.Second)
+ s := fmt.Sprintf("Timeout %d Secs", *streaming_timeout)
+ log.V(7).Infof("Writing to terminate: %v", s)
+ term <- s
+ }
+ }()
+
+ go func() {
+ // Terminate when indicated.
+ m := <-term
+ log.V(1).Infof("Terminating due to %v", m)
+ cancel()
+ }()
+
if len(q.Addrs) == 0 {
log.Exit("--address must be set")
}
--
2.17.1

1 change: 0 additions & 1 deletion sonic_data_client/events_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ func get_events(evtc *EventClient) {
for {

rc, evt := C_recv_evt(evtc.subs_handle)
log.V(7).Infof("C.event_receive_wrap rc=%d evt:%s", rc, (*C.char)(str_ptr))

if rc == 0 {
evtc.counters[MISSED] += (uint64)(evt.Missed_cnt)
Expand Down

0 comments on commit 4f45e3a

Please sign in to comment.