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  }