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