github.com/aristanetworks/goarista@v0.0.0-20240514173732-cca2755bbd44/openconfig/client/flags.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
     6  
     7  import (
     8  	"crypto/tls"
     9  	"crypto/x509"
    10  	"flag"
    11  	"io/ioutil"
    12  	"os"
    13  	"strings"
    14  
    15  	"github.com/aristanetworks/glog"
    16  	"google.golang.org/grpc"
    17  	"google.golang.org/grpc/credentials"
    18  )
    19  
    20  const (
    21  	// HostnameArg is the value to be replaced by the actual hostname
    22  	HostnameArg = "HOSTNAME"
    23  )
    24  
    25  // ParseHostnames parses a comma-separated list of names and replaces HOSTNAME with the current
    26  // hostname in it
    27  func ParseHostnames(list string) ([]string, error) {
    28  	items := strings.Split(list, ",")
    29  	hostname, err := os.Hostname()
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	names := make([]string, len(items))
    34  	for i, name := range items {
    35  		if name == HostnameArg {
    36  			name = hostname
    37  		}
    38  		names[i] = name
    39  	}
    40  	return names, nil
    41  }
    42  
    43  // ParseFlags registers some additional common flags,
    44  // parses the flags, and returns the resulting gRPC options,
    45  // and other settings to connect to the gRPC interface.
    46  func ParseFlags() (username string, password string, subscriptions, addrs []string,
    47  	opts []grpc.DialOption) {
    48  
    49  	var (
    50  		addrsFlag = flag.String("addrs", "localhost:6030",
    51  			"Comma-separated list of addresses of OpenConfig gRPC servers. The address 'HOSTNAME' "+
    52  				"is replaced by the current hostname.")
    53  
    54  		caFileFlag = flag.String("cafile", "",
    55  			"Path to server TLS certificate file")
    56  
    57  		certFileFlag = flag.String("certfile", "",
    58  			"Path to client TLS certificate file")
    59  
    60  		keyFileFlag = flag.String("keyfile", "",
    61  			"Path to client TLS private key file")
    62  
    63  		passwordFlag = flag.String("password", "",
    64  			"Password to authenticate with")
    65  
    66  		subscribeFlag = flag.String("subscribe", "",
    67  			"Comma-separated list of paths to subscribe to upon connecting to the server")
    68  
    69  		usernameFlag = flag.String("username", "",
    70  			"Username to authenticate with")
    71  
    72  		tlsFlag = flag.Bool("tls", false,
    73  			"Enable TLS")
    74  	)
    75  
    76  	flag.Parse()
    77  	if *tlsFlag || *caFileFlag != "" || *certFileFlag != "" {
    78  		config := &tls.Config{}
    79  		if *caFileFlag != "" {
    80  			b, err := ioutil.ReadFile(*caFileFlag)
    81  			if err != nil {
    82  				glog.Fatal(err)
    83  			}
    84  			cp := x509.NewCertPool()
    85  			if !cp.AppendCertsFromPEM(b) {
    86  				glog.Fatalf("credentials: failed to append certificates")
    87  			}
    88  			config.RootCAs = cp
    89  		} else {
    90  			config.InsecureSkipVerify = true
    91  		}
    92  		if *certFileFlag != "" {
    93  			if *keyFileFlag == "" {
    94  				glog.Fatalf("Please provide both -certfile and -keyfile")
    95  			}
    96  			cert, err := tls.LoadX509KeyPair(*certFileFlag, *keyFileFlag)
    97  			if err != nil {
    98  				glog.Fatal(err)
    99  			}
   100  			config.Certificates = []tls.Certificate{cert}
   101  		}
   102  		opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(config)))
   103  	} else {
   104  		opts = append(opts, grpc.WithInsecure())
   105  	}
   106  	var err error
   107  	addrs, err = ParseHostnames(*addrsFlag)
   108  	if err != nil {
   109  		glog.Fatal(err)
   110  	}
   111  	subscriptions = strings.Split(*subscribeFlag, ",")
   112  	return *usernameFlag, *passwordFlag, subscriptions, addrs, opts
   113  }