github.com/argoproj/argo-cd/v3@v3.2.1/reposerver/apiclient/clientset.go (about) 1 package apiclient 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "fmt" 7 "math" 8 "time" 9 10 "github.com/argoproj/argo-cd/v3/common" 11 "github.com/argoproj/argo-cd/v3/util/env" 12 13 grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry" 14 "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/timeout" 15 log "github.com/sirupsen/logrus" 16 "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" 17 "google.golang.org/grpc" 18 "google.golang.org/grpc/credentials" 19 "google.golang.org/grpc/credentials/insecure" 20 21 grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" 22 utilio "github.com/argoproj/argo-cd/v3/util/io" 23 ) 24 25 // MaxGRPCMessageSize contains max grpc message size 26 var MaxGRPCMessageSize = env.ParseNumFromEnv(common.EnvGRPCMaxSizeMB, 100, 0, math.MaxInt32) * 1024 * 1024 27 28 // TLSConfiguration describes parameters for TLS configuration to be used by a repo server API client 29 type TLSConfiguration struct { 30 // Whether to disable TLS for connections 31 DisableTLS bool 32 // Whether to enforce strict validation of TLS certificates 33 StrictValidation bool 34 // List of certificates to validate the peer against (if StrictCerts is true) 35 Certificates *x509.CertPool 36 } 37 38 // Clientset represents repository server api clients 39 type Clientset interface { 40 NewRepoServerClient() (utilio.Closer, RepoServerServiceClient, error) 41 } 42 43 type clientSet struct { 44 address string 45 timeoutSeconds int 46 tlsConfig TLSConfiguration 47 } 48 49 func (c *clientSet) NewRepoServerClient() (utilio.Closer, RepoServerServiceClient, error) { 50 conn, err := NewConnection(c.address, c.timeoutSeconds, &c.tlsConfig) 51 if err != nil { 52 return nil, nil, fmt.Errorf("failed to open a new connection to repo server: %w", err) 53 } 54 return conn, NewRepoServerServiceClient(conn), nil 55 } 56 57 func NewConnection(address string, timeoutSeconds int, tlsConfig *TLSConfiguration) (*grpc.ClientConn, error) { 58 retryOpts := []grpc_retry.CallOption{ 59 grpc_retry.WithMax(3), 60 grpc_retry.WithBackoff(grpc_retry.BackoffLinear(1000 * time.Millisecond)), 61 } 62 unaryInterceptors := []grpc.UnaryClientInterceptor{grpc_retry.UnaryClientInterceptor(retryOpts...)} 63 if timeoutSeconds > 0 { 64 unaryInterceptors = append(unaryInterceptors, timeout.UnaryClientInterceptor(time.Duration(timeoutSeconds)*time.Second)) 65 } 66 opts := []grpc.DialOption{ 67 grpc.WithStreamInterceptor(grpc_util.RetryOnlyForServerStreamInterceptor(retryOpts...)), 68 grpc.WithChainUnaryInterceptor(unaryInterceptors...), 69 grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)), 70 grpc.WithStatsHandler(otelgrpc.NewClientHandler()), 71 } 72 73 tlsC := &tls.Config{} 74 if !tlsConfig.DisableTLS { 75 if !tlsConfig.StrictValidation { 76 tlsC.InsecureSkipVerify = true 77 } else { 78 tlsC.RootCAs = tlsConfig.Certificates 79 } 80 opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tlsC))) 81 } else { 82 opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) 83 } 84 85 conn, err := grpc.NewClient(address, opts...) 86 if err != nil { 87 log.Errorf("Unable to connect to repository service with address %s", address) 88 return nil, err 89 } 90 return conn, nil 91 } 92 93 // NewRepoServerClientset creates new instance of repo server Clientset 94 func NewRepoServerClientset(address string, timeoutSeconds int, tlsConfig TLSConfiguration) Clientset { 95 return &clientSet{address: address, timeoutSeconds: timeoutSeconds, tlsConfig: tlsConfig} 96 }