github.com/argoproj/argo-cd/v3@v3.2.1/reposerver/server.go (about) 1 package reposerver 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "os" 7 "path/filepath" 8 9 grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" 10 "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" 11 "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" 12 log "github.com/sirupsen/logrus" 13 "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" 14 "google.golang.org/grpc" 15 "google.golang.org/grpc/credentials" 16 "google.golang.org/grpc/health" 17 "google.golang.org/grpc/health/grpc_health_v1" 18 "google.golang.org/grpc/keepalive" 19 "google.golang.org/grpc/reflection" 20 21 "github.com/argoproj/argo-cd/v3/common" 22 versionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/version" 23 "github.com/argoproj/argo-cd/v3/reposerver/apiclient" 24 reposervercache "github.com/argoproj/argo-cd/v3/reposerver/cache" 25 "github.com/argoproj/argo-cd/v3/reposerver/metrics" 26 "github.com/argoproj/argo-cd/v3/reposerver/repository" 27 "github.com/argoproj/argo-cd/v3/server/version" 28 "github.com/argoproj/argo-cd/v3/util/env" 29 "github.com/argoproj/argo-cd/v3/util/git" 30 grpc_util "github.com/argoproj/argo-cd/v3/util/grpc" 31 tlsutil "github.com/argoproj/argo-cd/v3/util/tls" 32 ) 33 34 // ArgoCDRepoServer is the repo server implementation 35 type ArgoCDRepoServer struct { 36 repoService *repository.Service 37 opts []grpc.ServerOption 38 } 39 40 // The hostnames to generate self-signed issues with 41 var tlsHostList = []string{"localhost", "reposerver"} 42 43 // NewServer returns a new instance of the Argo CD Repo server 44 func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cache, tlsConfCustomizer tlsutil.ConfigCustomizer, initConstants repository.RepoServerInitConstants, gitCredsStore git.CredsStore) (*ArgoCDRepoServer, error) { 45 var tlsConfig *tls.Config 46 47 // Generate or load TLS server certificates to use with this instance of 48 // repository server. 49 if tlsConfCustomizer != nil { 50 var err error 51 certPath := env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath) + "/reposerver/tls/tls.crt" 52 keyPath := env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath) + "/reposerver/tls/tls.key" 53 tlsConfig, err = tlsutil.CreateServerTLSConfig(certPath, keyPath, tlsHostList) 54 if err != nil { 55 return nil, fmt.Errorf("error creating server TLS config: %w", err) 56 } 57 tlsConfCustomizer(tlsConfig) 58 } 59 60 var serverMetricsOptions []grpc_prometheus.ServerMetricsOption 61 if os.Getenv(common.EnvEnableGRPCTimeHistogramEnv) == "true" { 62 serverMetricsOptions = append(serverMetricsOptions, grpc_prometheus.WithServerHandlingTimeHistogram()) 63 } 64 serverMetrics := grpc_prometheus.NewServerMetrics(serverMetricsOptions...) 65 metricsServer.PrometheusRegistry.MustRegister(serverMetrics) 66 67 serverLog := log.NewEntry(log.StandardLogger()) 68 streamInterceptors := []grpc.StreamServerInterceptor{ 69 logging.StreamServerInterceptor(grpc_util.InterceptorLogger(serverLog)), 70 serverMetrics.StreamServerInterceptor(), 71 recovery.StreamServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(serverLog))), 72 } 73 unaryInterceptors := []grpc.UnaryServerInterceptor{ 74 logging.UnaryServerInterceptor(grpc_util.InterceptorLogger(serverLog)), 75 serverMetrics.UnaryServerInterceptor(), 76 recovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpc_util.LoggerRecoveryHandler(serverLog))), 77 grpc_util.ErrorSanitizerUnaryServerInterceptor(), 78 } 79 80 serverOpts := []grpc.ServerOption{ 81 grpc.ChainUnaryInterceptor(unaryInterceptors...), 82 grpc.ChainStreamInterceptor(streamInterceptors...), 83 grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize), 84 grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize), 85 grpc.KeepaliveEnforcementPolicy( 86 keepalive.EnforcementPolicy{ 87 MinTime: common.GetGRPCKeepAliveEnforcementMinimum(), 88 }, 89 ), 90 grpc.StatsHandler(otelgrpc.NewServerHandler()), 91 } 92 93 // We do allow for non-TLS servers to be created, in case of mTLS will be 94 // implemented by e.g. a sidecar container. 95 if tlsConfig != nil { 96 serverOpts = append(serverOpts, grpc.Creds(credentials.NewTLS(tlsConfig))) 97 } 98 repoService := repository.NewService(metricsServer, cache, initConstants, gitCredsStore, filepath.Join(os.TempDir(), "_argocd-repo")) 99 if err := repoService.Init(); err != nil { 100 return nil, fmt.Errorf("failed to initialize the repo service: %w", err) 101 } 102 103 return &ArgoCDRepoServer{ 104 opts: serverOpts, 105 repoService: repoService, 106 }, nil 107 } 108 109 // CreateGRPC creates new configured grpc server 110 func (a *ArgoCDRepoServer) CreateGRPC() *grpc.Server { 111 server := grpc.NewServer(a.opts...) 112 versionpkg.RegisterVersionServiceServer(server, version.NewServer(nil, func() (bool, error) { 113 return true, nil 114 })) 115 apiclient.RegisterRepoServerServiceServer(server, a.repoService) 116 117 healthService := health.NewServer() 118 grpc_health_v1.RegisterHealthServer(server, healthService) 119 120 // Register reflection service on gRPC server. 121 reflection.Register(server) 122 123 return server 124 }