package grpc import ( "crypto/tls" "crypto/x509" "errors" "os" mgrpcc "github.com/go-micro/plugins/v4/client/grpc" mbreaker "github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker" mtracer "github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry" "github.com/owncloud/ocis/v2/ocis-pkg/registry" "github.com/owncloud/ocis/v2/ocis-pkg/shared" "go-micro.dev/v4/client" "go.opentelemetry.io/otel/trace" ) // ClientOptions represent options (e.g. tls settings) for the grpc clients type ClientOptions struct { tlsMode string caCert string tp trace.TracerProvider } // Option is used to pass client options type ClientOption func(opts *ClientOptions) // WithTLSMode allows setting the TLSMode option for grpc clients func WithTLSMode(v string) ClientOption { return func(o *ClientOptions) { o.tlsMode = v } } // WithTLSCACert allows setting the CA Certificate for grpc clients func WithTLSCACert(v string) ClientOption { return func(o *ClientOptions) { o.caCert = v } } // WithTraceProvider allows to set the trace Provider for grpc clients func WithTraceProvider(tp trace.TracerProvider) ClientOption { return func(o *ClientOptions) { if tp != nil { o.tp = tp } else { o.tp = trace.NewNoopTracerProvider() } } } func GetClientOptions(t *shared.GRPCClientTLS) []ClientOption { opts := []ClientOption{ WithTLSMode(t.Mode), WithTLSCACert(t.CACert), } return opts } func NewClient(opts ...ClientOption) (client.Client, error) { var options ClientOptions for _, opt := range opts { opt(&options) } reg := registry.GetRegistry() var tlsConfig *tls.Config cOpts := []client.Option{ client.Registry(reg), client.Wrap(mbreaker.NewClientWrapper()), client.Wrap(mtracer.NewClientWrapper( mtracer.WithTraceProvider(options.tp), )), } switch options.tlsMode { case "insecure": tlsConfig = &tls.Config{ InsecureSkipVerify: true, } cOpts = append(cOpts, mgrpcc.AuthTLS(tlsConfig)) case "on": tlsConfig = &tls.Config{} // Note: If caCert is empty we use the system's default set of trusted CAs if options.caCert != "" { certs := x509.NewCertPool() pemData, err := os.ReadFile(options.caCert) if err != nil { return nil, err } if !certs.AppendCertsFromPEM(pemData) { return nil, errors.New("could not initialize client, adding CA cert failed") } tlsConfig.RootCAs = certs } cOpts = append(cOpts, mgrpcc.AuthTLS(tlsConfig)) // case "off": // default: } return mgrpcc.NewClient(cOpts...), nil }