293dd2e848
* Add vendor dir so builds dont require dep * Pin specific version go-eth version
121 lines
2.9 KiB
Go
121 lines
2.9 KiB
Go
// Copyright (c) 2017 Arista Networks, Inc.
|
|
// Use of this source code is governed by the Apache License 2.0
|
|
// that can be found in the COPYING file.
|
|
|
|
package gnmi
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"io/ioutil"
|
|
"strings"
|
|
|
|
"github.com/aristanetworks/glog"
|
|
pb "github.com/openconfig/gnmi/proto/gnmi"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
"google.golang.org/grpc/metadata"
|
|
)
|
|
|
|
const (
|
|
defaultPort = "6042"
|
|
)
|
|
|
|
// Config is the gnmi.Client config
|
|
type Config struct {
|
|
Addr string
|
|
CAFile string
|
|
CertFile string
|
|
KeyFile string
|
|
Password string
|
|
Username string
|
|
TLS bool
|
|
}
|
|
|
|
// Dial connects to a gnmi service and returns a client
|
|
func Dial(cfg *Config) pb.GNMIClient {
|
|
var opts []grpc.DialOption
|
|
if cfg.TLS || cfg.CAFile != "" || cfg.CertFile != "" {
|
|
tlsConfig := &tls.Config{}
|
|
if cfg.CAFile != "" {
|
|
b, err := ioutil.ReadFile(cfg.CAFile)
|
|
if err != nil {
|
|
glog.Fatal(err)
|
|
}
|
|
cp := x509.NewCertPool()
|
|
if !cp.AppendCertsFromPEM(b) {
|
|
glog.Fatalf("credentials: failed to append certificates")
|
|
}
|
|
tlsConfig.RootCAs = cp
|
|
} else {
|
|
tlsConfig.InsecureSkipVerify = true
|
|
}
|
|
if cfg.CertFile != "" {
|
|
if cfg.KeyFile == "" {
|
|
glog.Fatalf("Please provide both -certfile and -keyfile")
|
|
}
|
|
cert, err := tls.LoadX509KeyPair(cfg.CertFile, cfg.KeyFile)
|
|
if err != nil {
|
|
glog.Fatal(err)
|
|
}
|
|
tlsConfig.Certificates = []tls.Certificate{cert}
|
|
}
|
|
opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
|
|
} else {
|
|
opts = append(opts, grpc.WithInsecure())
|
|
}
|
|
|
|
if !strings.ContainsRune(cfg.Addr, ':') {
|
|
cfg.Addr += ":" + defaultPort
|
|
}
|
|
conn, err := grpc.Dial(cfg.Addr, opts...)
|
|
if err != nil {
|
|
glog.Fatalf("Failed to dial: %s", err)
|
|
}
|
|
|
|
return pb.NewGNMIClient(conn)
|
|
}
|
|
|
|
// NewContext returns a new context with username and password
|
|
// metadata if they are set in cfg.
|
|
func NewContext(ctx context.Context, cfg *Config) context.Context {
|
|
if cfg.Username != "" {
|
|
ctx = metadata.NewOutgoingContext(ctx, metadata.Pairs(
|
|
"username", cfg.Username,
|
|
"password", cfg.Password))
|
|
}
|
|
return ctx
|
|
}
|
|
|
|
// NewGetRequest returns a GetRequest for the given paths
|
|
func NewGetRequest(paths [][]string) (*pb.GetRequest, error) {
|
|
req := &pb.GetRequest{
|
|
Path: make([]*pb.Path, len(paths)),
|
|
}
|
|
for i, p := range paths {
|
|
gnmiPath, err := ParseGNMIElements(p)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Path[i] = gnmiPath
|
|
}
|
|
return req, nil
|
|
}
|
|
|
|
// NewSubscribeRequest returns a SubscribeRequest for the given paths
|
|
func NewSubscribeRequest(paths [][]string) (*pb.SubscribeRequest, error) {
|
|
subList := &pb.SubscriptionList{
|
|
Subscription: make([]*pb.Subscription, len(paths)),
|
|
}
|
|
for i, p := range paths {
|
|
gnmiPath, err := ParseGNMIElements(p)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
subList.Subscription[i] = &pb.Subscription{Path: gnmiPath}
|
|
}
|
|
return &pb.SubscribeRequest{
|
|
Request: &pb.SubscribeRequest_Subscribe{Subscribe: subList}}, nil
|
|
}
|