github.com/Psiphon-Inc/goarista@v0.0.0-20160825065156-d002785f4c67/openconfig/client/client.go (about) 1 // Copyright (C) 2016 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 // Package client provides helper functions for OpenConfig CLI tools. 6 package client 7 8 import ( 9 "io" 10 "strings" 11 "sync" 12 13 "github.com/aristanetworks/glog" 14 "github.com/aristanetworks/goarista/openconfig" 15 "golang.org/x/net/context" 16 "google.golang.org/grpc" 17 "google.golang.org/grpc/metadata" 18 ) 19 20 const defaultPort = "6042" 21 22 // Run creates a new gRPC client, sends subscriptions, and consumes responses. 23 // The given publish function is used to publish SubscribeResponses received 24 // for the given subscriptions, when connected to the given host, with the 25 // given user/pass pair, or the client-side cert specified in the gRPC opts. 26 // This function does not normally return so it should probably be run in its 27 // own goroutine. When this function returns, the given WaitGroup is marked 28 // as done. 29 func Run(publish func(*openconfig.SubscribeResponse), wg *sync.WaitGroup, 30 username, password, addr string, subscriptions []string, 31 opts []grpc.DialOption) { 32 33 defer wg.Done() 34 if !strings.ContainsRune(addr, ':') { 35 addr += ":" + defaultPort 36 } 37 conn, err := grpc.Dial(addr, opts...) 38 if err != nil { 39 glog.Fatalf("fail to dial: %s", err) 40 } 41 glog.Infof("Connected to %s", addr) 42 defer conn.Close() 43 client := openconfig.NewOpenConfigClient(conn) 44 45 ctx := context.Background() 46 if username != "" { 47 ctx = metadata.NewContext(ctx, metadata.Pairs( 48 "username", username, 49 "password", password)) 50 } 51 52 stream, err := client.Subscribe(ctx) 53 if err != nil { 54 glog.Fatalf("Subscribe failed: %s", err) 55 } 56 defer stream.CloseSend() 57 58 for _, path := range subscriptions { 59 sub := &openconfig.SubscribeRequest{ 60 Request: &openconfig.SubscribeRequest_Subscribe{ 61 Subscribe: &openconfig.SubscriptionList{ 62 Subscription: []*openconfig.Subscription{ 63 &openconfig.Subscription{ 64 Path: &openconfig.Path{Element: strings.Split(path, "/")}, 65 }, 66 }, 67 }, 68 }, 69 } 70 71 glog.Infof("Sending subscribe request: %s", sub) 72 err = stream.Send(sub) 73 if err != nil { 74 glog.Fatalf("Failed to subscribe: %s", err) 75 } 76 } 77 78 for { 79 resp, err := stream.Recv() 80 if err != nil { 81 if err != io.EOF { 82 glog.Fatalf("Error received from the server: %s", err) 83 } 84 return 85 } 86 glog.V(3).Info(resp) 87 publish(resp) 88 } 89 }