github.com/Axway/agent-sdk@v1.1.101/pkg/watchmanager/options.go (about)

     1  package watchmanager
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"net"
     7  	"time"
     8  
     9  	"github.com/Axway/agent-sdk/pkg/agent/events"
    10  	"github.com/Axway/agent-sdk/pkg/harvester"
    11  	"github.com/Axway/agent-sdk/pkg/util"
    12  	"github.com/Axway/agent-sdk/pkg/util/log"
    13  
    14  	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
    15  
    16  	grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
    17  
    18  	"google.golang.org/grpc"
    19  	"google.golang.org/grpc/credentials"
    20  	"google.golang.org/grpc/credentials/insecure"
    21  	"google.golang.org/grpc/keepalive"
    22  
    23  	"github.com/sirupsen/logrus"
    24  )
    25  
    26  // Option configures how we set up the watch connection.
    27  type Option interface {
    28  	apply(*watchOptions)
    29  }
    30  
    31  // funcOption defines a func that receives a watchOptions. Implements the Option interface.
    32  type funcOption func(*watchOptions)
    33  
    34  // apply calls the original func to update the watchOptions.
    35  func (f funcOption) apply(opt *watchOptions) {
    36  	f(opt)
    37  }
    38  
    39  type eventSyncCb func()
    40  
    41  type keepAliveOption struct {
    42  	time    time.Duration
    43  	timeout time.Duration
    44  }
    45  
    46  // watchOptions options to use when creating a stream
    47  type watchOptions struct {
    48  	tlsCfg           *tls.Config
    49  	proxyURL         string
    50  	singleEntryAddr  string
    51  	keepAlive        keepAliveOption
    52  	loggerEntry      *logrus.Entry
    53  	sequence         events.SequenceProvider
    54  	onEventSyncError eventSyncCb
    55  	harvester        harvester.Harvest
    56  }
    57  
    58  // newWatchOptions returns the default watchOptions
    59  func newWatchOptions() *watchOptions {
    60  	return &watchOptions{
    61  		loggerEntry: logrus.NewEntry(log.Get()),
    62  		tlsCfg:      defaultTLSConfig(),
    63  		keepAlive: keepAliveOption{
    64  			time:    util.DefaultKeepAliveInterval,
    65  			timeout: util.DefaultKeepAliveTimeout,
    66  		},
    67  	}
    68  }
    69  
    70  // WithEventSyncError - callback func to invoke when there is an error syncing initial events
    71  func WithEventSyncError(f eventSyncCb) Option {
    72  	return funcOption(func(o *watchOptions) {
    73  		o.onEventSyncError = f
    74  	})
    75  }
    76  
    77  // WithTLSConfig - sets up the TLS credentials or insecure if nil
    78  func WithTLSConfig(tlsCfg *tls.Config) Option {
    79  	return funcOption(func(o *watchOptions) {
    80  		o.tlsCfg = tlsCfg
    81  	})
    82  }
    83  
    84  // WithProxy - sets up the proxy to be used
    85  func WithProxy(proxy string) Option {
    86  	return funcOption(func(o *watchOptions) {
    87  		o.proxyURL = proxy
    88  	})
    89  }
    90  
    91  // WithSingleEntryAddr - sets up the single entry host to be used
    92  func WithSingleEntryAddr(singleEntryAddr string) Option {
    93  	return funcOption(func(o *watchOptions) {
    94  		o.singleEntryAddr = singleEntryAddr
    95  	})
    96  }
    97  
    98  // WithKeepAlive - sets keep alive ping interval and timeout to wait for ping ack
    99  func WithKeepAlive(time, timeout time.Duration) Option {
   100  	return funcOption(func(o *watchOptions) {
   101  		o.keepAlive.time = time
   102  		o.keepAlive.timeout = timeout
   103  	})
   104  }
   105  
   106  // WithLogger sets the logger to be used by the client, overriding the default logger
   107  func WithLogger(loggerEntry *logrus.Entry) Option {
   108  	return funcOption(func(o *watchOptions) {
   109  		o.loggerEntry = loggerEntry
   110  	})
   111  }
   112  
   113  // WithHarvester allows using the harvester client to sync events on watch registration
   114  func WithHarvester(harvester harvester.Harvest, sequence events.SequenceProvider) Option {
   115  	return funcOption(func(o *watchOptions) {
   116  		o.sequence = sequence
   117  		o.harvester = harvester
   118  	})
   119  }
   120  
   121  // withRPCCredentials sets credentials and places auth state on each outbound RPC.
   122  func withRPCCredentials(tenantID string, tokenGetter TokenGetter) grpc.DialOption {
   123  	rpcCredential := newRPCAuth(tenantID, tokenGetter)
   124  	return grpc.WithPerRPCCredentials(rpcCredential)
   125  }
   126  
   127  // withTLSConfig configures connection level security credentials
   128  func withTLSConfig(tlsCfg *tls.Config) grpc.DialOption {
   129  	if tlsCfg != nil {
   130  		return grpc.WithTransportCredentials(credentials.NewTLS(tlsCfg))
   131  	}
   132  	return grpc.WithTransportCredentials(insecure.NewCredentials())
   133  }
   134  
   135  // withKeepaliveParams sets the set keepalive parameters on the client-side
   136  func withKeepaliveParams(time, timeout time.Duration) grpc.DialOption {
   137  	return grpc.WithKeepaliveParams(
   138  		keepalive.ClientParameters{
   139  			PermitWithoutStream: true,
   140  			Time:                time,
   141  			Timeout:             timeout,
   142  		})
   143  }
   144  
   145  // withDialer sets up the proxy dialer
   146  func withDialer(dialer util.Dialer) grpc.DialOption {
   147  	if dialer == nil {
   148  		return &grpc.EmptyDialOption{}
   149  	}
   150  
   151  	return grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
   152  		return dialer.DialContext(ctx, "tcp", addr)
   153  	})
   154  }
   155  
   156  // logrusStreamClientInterceptor returns a new streaming client interceptor that optionally logs the execution of gRPC calls
   157  func logrusStreamClientInterceptor(entry *logrus.Entry) grpc.StreamClientInterceptor {
   158  	opts := []grpc_logrus.Option{
   159  		grpc_logrus.WithLevels(grpc_logrus.DefaultClientCodeToLevel),
   160  		grpc_logrus.WithDurationField(grpc_logrus.DurationToDurationField),
   161  	}
   162  
   163  	return grpc_logrus.StreamClientInterceptor(entry, opts...)
   164  }
   165  
   166  // chainStreamClientInterceptor returns a DialOption that specifies the interceptor for streaming RPCs
   167  func chainStreamClientInterceptor(interceptors ...grpc.StreamClientInterceptor) grpc.DialOption {
   168  	return grpc.WithStreamInterceptor(
   169  		grpc_middleware.ChainStreamClient(interceptors...),
   170  	)
   171  }
   172  
   173  func defaultTLSConfig() *tls.Config {
   174  	return &tls.Config{
   175  		MinVersion: tls.VersionTLS12,
   176  		CipherSuites: []uint16{
   177  			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
   178  			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
   179  			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
   180  			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
   181  			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
   182  			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
   183  			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
   184  			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
   185  		},
   186  	}
   187  }