github.com/argoproj/argo-cd/v2@v2.10.9/reposerver/server.go (about)

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