params.go raw

   1  package endpoints
   2  
   3  import (
   4  	"crypto/tls"
   5  
   6  	"google.golang.org/grpc"
   7  	"google.golang.org/grpc/credentials"
   8  	"google.golang.org/grpc/credentials/insecure"
   9  	"google.golang.org/grpc/keepalive"
  10  )
  11  
  12  // EndpointParams represents the parameters required to configure an endpoint, including its address and options.
  13  type EndpointParams struct {
  14  	Addr    string
  15  	Options []EndpointOption
  16  }
  17  
  18  // NewEndpointParams creates a new EndpointParams instance with the specified address and optional EndpointOptions.
  19  func NewEndpointParams(addr string, opts ...EndpointOption) *EndpointParams {
  20  	return &EndpointParams{Addr: addr, Options: opts}
  21  }
  22  
  23  // Append adds one or more EndpointOption instances to the Options slice and returns the updated EndpointParams.
  24  func (ep *EndpointParams) Append(opts ...EndpointOption) *EndpointParams {
  25  	ep.Options = append(ep.Options, opts...)
  26  	return ep
  27  }
  28  
  29  // Build constructs an Endpoint using the provided address and dial options from the EndpointParams configuration.
  30  func (ep *EndpointParams) Build() *Endpoint {
  31  	var creds grpc.DialOption
  32  	dialOptions := make([]grpc.DialOption, 0, len(ep.Options)+1)
  33  
  34  	// Separate transport credentials from other options.
  35  	for _, opt := range ep.Options {
  36  		if tco, ok := opt.(TransportCredentialEndpointOption); ok {
  37  			// Always use the last-specified transport credential option.
  38  			creds = tco.DialOption()
  39  		} else {
  40  			dialOptions = append(dialOptions, opt.DialOption())
  41  		}
  42  	}
  43  
  44  	// Use default TLS credentials if none provided.
  45  	if creds == nil {
  46  		// grpc.DialOption for TLS using the default system roots.
  47  		creds = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))
  48  	}
  49  	// Prepend the transport credentials.
  50  	dialOptions = append([]grpc.DialOption{creds}, dialOptions...)
  51  
  52  	return &Endpoint{
  53  		Addr:        ep.Addr,
  54  		DialOptions: dialOptions,
  55  	}
  56  }
  57  
  58  // EndpointOption is an interface that represents a configurable option for creating a gRPC endpoint connection.
  59  type EndpointOption interface {
  60  	DialOption() grpc.DialOption
  61  }
  62  
  63  // TransportCredentialEndpointOption defines an interface for specifying transport-layer security options for an endpoint.
  64  type TransportCredentialEndpointOption interface {
  65  	EndpointOption
  66  	isTransportCredential()
  67  }
  68  
  69  func Plaintext() TransportCredentialEndpointOption { return plaintextOption{} }
  70  
  71  // SkipTLSVerify returns a TransportCredentialEndpointOption that disables TLS certificate verification for secure connections.
  72  func SkipTLSVerify() TransportCredentialEndpointOption { return skipTLSVerifyOption{} }
  73  
  74  // Keepalive configures client-side keepalive parameters for gRPC connections using the provided parameters.
  75  func Keepalive(params keepalive.ClientParameters) EndpointOption {
  76  	return keepaliveOption(params)
  77  }
  78  
  79  // plaintextOption is a struct type used to configure plaintext transport credentials for gRPC connections.
  80  type plaintextOption struct{}
  81  
  82  // skipTLSVerifyOption is a type that represents an option to skip TLS certificate verification during a transport.
  83  type skipTLSVerifyOption struct{}
  84  
  85  // keepaliveOption is a type alias for keepalive.ClientParameters, used to configure keepalive settings in gRPC clients.
  86  type keepaliveOption keepalive.ClientParameters
  87  
  88  // isTransportCredential marks plaintextOption as a type that satisfies the transport credentials interface.
  89  func (plaintextOption) isTransportCredential() {}
  90  
  91  // isTransportCredential marks skipTLSVerifyOption as a credential option for transport security use.
  92  func (skipTLSVerifyOption) isTransportCredential() {}
  93  
  94  // DialOption returns a grpc.DialOption configured with insecure transport credentials.
  95  func (plaintextOption) DialOption() grpc.DialOption {
  96  	return grpc.WithTransportCredentials(insecure.NewCredentials())
  97  }
  98  
  99  // DialOption returns a gRPC DialOption that configures the transport credentials to skip TLS verification.
 100  func (skipTLSVerifyOption) DialOption() grpc.DialOption {
 101  	return grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
 102  		InsecureSkipVerify: true,
 103  	}))
 104  }
 105  
 106  // DialOption returns a grpc.DialOption configured with the keepalive parameters from the keepaliveOption receiver.
 107  func (kp keepaliveOption) DialOption() grpc.DialOption {
 108  	return grpc.WithKeepaliveParams(keepalive.ClientParameters(kp))
 109  }
 110