Bump reva deps (#8412)
* bump dependencies Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * bump reva and add config options Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> --------- Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
Generated
Vendored
+4
-6
@@ -22,15 +22,12 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go-micro.dev/v4/util/log"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
v1beta12 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/appctx"
|
||||
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
"github.com/cs3org/reva/v2/pkg/events/stream"
|
||||
@@ -38,6 +35,7 @@ import (
|
||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -190,7 +188,7 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error
|
||||
|
||||
if ev != nil {
|
||||
if err := events.Publish(ctx, publisher, ev); err != nil {
|
||||
log.Error(err)
|
||||
appctx.GetLogger(ctx).Error().Err(err).Interface("event", ev).Msg("publishing event failed")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +209,7 @@ func NewStream() grpc.StreamServerInterceptor {
|
||||
|
||||
// common interface to all responses
|
||||
type su interface {
|
||||
GetStatus() *v1beta12.Status
|
||||
GetStatus() *rpc.Status
|
||||
}
|
||||
|
||||
func isSuccess(res su) bool {
|
||||
|
||||
Generated
Vendored
+24
-2
@@ -55,6 +55,7 @@ type config struct {
|
||||
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
|
||||
GatewayAddr string `mapstructure:"gateway_addr"`
|
||||
AllowedPathsForShares []string `mapstructure:"allowed_paths_for_shares"`
|
||||
DisableResharing bool `mapstructure:"disable_resharing"`
|
||||
}
|
||||
|
||||
func (c *config) init() {
|
||||
@@ -67,6 +68,7 @@ type service struct {
|
||||
sm share.Manager
|
||||
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
||||
allowedPathsForShares []*regexp.Regexp
|
||||
disableResharing bool
|
||||
}
|
||||
|
||||
func getShareManager(c *config) (share.Manager, error) {
|
||||
@@ -127,15 +129,16 @@ func NewDefault(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return New(gatewaySelector, sm, allowedPathsForShares), nil
|
||||
return New(gatewaySelector, sm, allowedPathsForShares, c.DisableResharing), nil
|
||||
}
|
||||
|
||||
// New creates a new user share provider svc
|
||||
func New(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], sm share.Manager, allowedPathsForShares []*regexp.Regexp) rgrpc.Service {
|
||||
func New(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], sm share.Manager, allowedPathsForShares []*regexp.Regexp, disableResharing bool) rgrpc.Service {
|
||||
service := &service{
|
||||
sm: sm,
|
||||
gatewaySelector: gatewaySelector,
|
||||
allowedPathsForShares: allowedPathsForShares,
|
||||
disableResharing: disableResharing,
|
||||
}
|
||||
|
||||
return service
|
||||
@@ -157,6 +160,13 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar
|
||||
log := appctx.GetLogger(ctx)
|
||||
user := ctxpkg.ContextMustGetUser(ctx)
|
||||
|
||||
// when resharing is disabled grants must not allow grant permissions
|
||||
if s.disableResharing && HasGrantPermissions(req.GetGrant().GetPermissions().GetPermissions()) {
|
||||
return &collaboration.CreateShareResponse{
|
||||
Status: status.NewInvalidArg(ctx, "resharing not supported"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
gatewayClient, err := s.gatewaySelector.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -235,6 +245,10 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar
|
||||
}, nil
|
||||
}
|
||||
|
||||
func HasGrantPermissions(p *provider.ResourcePermissions) bool {
|
||||
return p.GetAddGrant() || p.GetUpdateGrant() || p.GetRemoveGrant() || p.GetDenyGrant()
|
||||
}
|
||||
|
||||
func (s *service) RemoveShare(ctx context.Context, req *collaboration.RemoveShareRequest) (*collaboration.RemoveShareResponse, error) {
|
||||
log := appctx.GetLogger(ctx)
|
||||
user := ctxpkg.ContextMustGetUser(ctx)
|
||||
@@ -327,6 +341,14 @@ func (s *service) ListShares(ctx context.Context, req *collaboration.ListSharesR
|
||||
func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShareRequest) (*collaboration.UpdateShareResponse, error) {
|
||||
log := appctx.GetLogger(ctx)
|
||||
user := ctxpkg.ContextMustGetUser(ctx)
|
||||
|
||||
// when resharing is disabled grants must not allow grant permissions
|
||||
if s.disableResharing && HasGrantPermissions(req.GetShare().GetPermissions().GetPermissions()) {
|
||||
return &collaboration.UpdateShareResponse{
|
||||
Status: status.NewInvalidArg(ctx, "resharing not supported"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
gatewayClient, err := s.gatewaySelector.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Generated
Vendored
+20
-200
@@ -50,8 +50,6 @@ func init() {
|
||||
const (
|
||||
// TokenTransportHeader holds the header key for the reva transfer token
|
||||
TokenTransportHeader = "X-Reva-Transfer"
|
||||
// UploadExpiresHeader holds the timestamp for the transport token expiry, defined in https://tus.io/protocols/resumable-upload.html#expiration
|
||||
UploadExpiresHeader = "Upload-Expires"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -133,36 +131,13 @@ func (s *svc) setHandler() {
|
||||
semconv.HTTPURLKey.String(r.URL.String()),
|
||||
)
|
||||
r = r.WithContext(ctx)
|
||||
switch r.Method {
|
||||
case "HEAD":
|
||||
addCorsHeader(w)
|
||||
s.doHead(w, r)
|
||||
return
|
||||
case "GET":
|
||||
s.doGet(w, r)
|
||||
return
|
||||
case "PUT":
|
||||
s.doPut(w, r)
|
||||
return
|
||||
case "PATCH":
|
||||
s.doPatch(w, r)
|
||||
return
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
s.doRequest(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func addCorsHeader(res http.ResponseWriter) {
|
||||
headers := res.Header()
|
||||
headers.Set("Access-Control-Allow-Origin", "*")
|
||||
headers.Set("Access-Control-Allow-Headers", "Content-Type, Origin, Authorization")
|
||||
headers.Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, HEAD")
|
||||
}
|
||||
|
||||
// verify extracts the transfer token from the request
|
||||
// If it is not set as header we assume that it's the last path segment instead.
|
||||
func (s *svc) verify(ctx context.Context, r *http.Request) (*transferClaims, error) {
|
||||
// Extract transfer token from request header. If not existing, assume that it's the last path segment instead.
|
||||
token := r.Header.Get(TokenTransportHeader)
|
||||
if token == "" {
|
||||
token = path.Base(r.URL.Path)
|
||||
@@ -185,112 +160,7 @@ func (s *svc) verify(ctx context.Context, r *http.Request) (*transferClaims, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (s *svc) doHead(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
log := appctx.GetLogger(ctx)
|
||||
|
||||
claims, err := s.verify(ctx, r)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "datagateway: error validating transfer token")
|
||||
log.Error().Err(err).Str("token", r.Header.Get(TokenTransportHeader)).Msg("invalid transfer token")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().Str("target", claims.Target).Msg("sending request to internal data server")
|
||||
|
||||
httpClient := s.client
|
||||
httpReq, err := rhttp.NewRequest(ctx, "HEAD", claims.Target, nil)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("wrong request")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
httpReq.Header = r.Header
|
||||
|
||||
httpRes, err := httpClient.Do(httpReq)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error doing HEAD request to data service")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer httpRes.Body.Close()
|
||||
|
||||
copyHeader(w.Header(), httpRes.Header)
|
||||
|
||||
// add upload expiry / transfer token expiry header for tus https://tus.io/protocols/resumable-upload.html#expiration
|
||||
w.Header().Set(UploadExpiresHeader, time.Unix(claims.ExpiresAt, 0).Format(time.RFC1123))
|
||||
|
||||
if httpRes.StatusCode != http.StatusOK {
|
||||
// swallow the body and set content-length to 0 to prevent reverse proxies from trying to read from it
|
||||
w.Header().Set("Content-Length", "0")
|
||||
w.WriteHeader(httpRes.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (s *svc) doGet(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
log := appctx.GetLogger(ctx)
|
||||
|
||||
claims, err := s.verify(ctx, r)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "datagateway: error validating transfer token")
|
||||
log.Error().Err(err).Str("token", r.Header.Get(TokenTransportHeader)).Msg("invalid transfer token")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().Str("target", claims.Target).Msg("sending request to internal data server")
|
||||
|
||||
httpClient := s.client
|
||||
httpReq, err := rhttp.NewRequest(ctx, "GET", claims.Target, nil)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("wrong request")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
httpReq.Header = r.Header
|
||||
|
||||
httpRes, err := httpClient.Do(httpReq)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error doing GET request to data service")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer httpRes.Body.Close()
|
||||
|
||||
copyHeader(w.Header(), httpRes.Header)
|
||||
switch httpRes.StatusCode {
|
||||
case http.StatusOK:
|
||||
case http.StatusPartialContent:
|
||||
default:
|
||||
// swallow the body and set content-length to 0 to prevent reverse proxies from trying to read from it
|
||||
w.Header().Set("Content-Length", "0")
|
||||
w.WriteHeader(httpRes.StatusCode)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(httpRes.StatusCode)
|
||||
|
||||
var c int64
|
||||
c, err = io.Copy(w, httpRes.Body)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error writing body after headers were sent")
|
||||
}
|
||||
if httpRes.Header.Get("Content-Length") != "" {
|
||||
i, err := strconv.ParseInt(httpRes.Header.Get("Content-Length"), 10, 64)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("content-length", httpRes.Header.Get("Content-Length")).Msg("invalid content length in dataprovider response")
|
||||
}
|
||||
if i != c {
|
||||
log.Error().Int64("content-length", i).Int64("transferred-bytes", c).Msg("content length vs transferred bytes mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *svc) doPut(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *svc) doRequest(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
log := appctx.GetLogger(ctx)
|
||||
|
||||
@@ -314,10 +184,9 @@ func (s *svc) doPut(w http.ResponseWriter, r *http.Request) {
|
||||
targetURL.RawQuery = r.URL.RawQuery
|
||||
target = targetURL.String()
|
||||
|
||||
log.Debug().Str("target", claims.Target).Msg("sending request to internal data server")
|
||||
log.Debug().Str("target", target).Msg("sending request to internal data server")
|
||||
|
||||
httpClient := s.client
|
||||
httpReq, err := rhttp.NewRequest(ctx, "PUT", target, r.Body)
|
||||
httpReq, err := rhttp.NewRequest(ctx, r.Method, target, r.Body)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("wrong request")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
@@ -326,68 +195,9 @@ func (s *svc) doPut(w http.ResponseWriter, r *http.Request) {
|
||||
httpReq.Header = r.Header
|
||||
httpReq.ContentLength = r.ContentLength
|
||||
|
||||
httpRes, err := httpClient.Do(httpReq)
|
||||
httpRes, err := s.client.Do(httpReq)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("error doing PUT request to data service")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer httpRes.Body.Close()
|
||||
|
||||
copyHeader(w.Header(), httpRes.Header)
|
||||
if httpRes.StatusCode != http.StatusOK {
|
||||
// swallow the body and set content-length to 0 to prevent reverse proxies from trying to read from it
|
||||
w.Header().Set("Content-Length", "0")
|
||||
w.WriteHeader(httpRes.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err = io.Copy(w, httpRes.Body)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("error writing body after header were set")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: put and post code is pretty much the same. Should be solved in a nicer way in the long run.
|
||||
func (s *svc) doPatch(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
log := appctx.GetLogger(ctx)
|
||||
|
||||
claims, err := s.verify(ctx, r)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "datagateway: error validating transfer token")
|
||||
log.Err(err).Str("token", r.Header.Get(TokenTransportHeader)).Msg("invalid transfer token")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
target := claims.Target
|
||||
// add query params to target, clients can send checksums and other information.
|
||||
targetURL, err := url.Parse(target)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("datagateway: error parsing target url")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
targetURL.RawQuery = r.URL.RawQuery
|
||||
target = targetURL.String()
|
||||
|
||||
log.Debug().Str("target", claims.Target).Msg("sending request to internal data server")
|
||||
|
||||
httpClient := s.client
|
||||
httpReq, err := rhttp.NewRequest(ctx, "PATCH", target, r.Body)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("wrong request")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
httpReq.Header = r.Header
|
||||
|
||||
httpRes, err := httpClient.Do(httpReq)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("error doing PATCH request to data service")
|
||||
log.Err(err).Msg("error doing " + r.Method + " request to data service")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -400,12 +210,22 @@ func (s *svc) doPatch(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(httpRes.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(httpRes.StatusCode)
|
||||
_, err = io.Copy(w, httpRes.Body)
|
||||
|
||||
var c int64
|
||||
c, err = io.Copy(w, httpRes.Body)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("error writing body after header were set")
|
||||
}
|
||||
if httpRes.Header.Get("Content-Length") != "" {
|
||||
i, err := strconv.ParseInt(httpRes.Header.Get("Content-Length"), 10, 64)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("content-length", httpRes.Header.Get("Content-Length")).Msg("invalid content length in dataprovider response")
|
||||
}
|
||||
if i != c {
|
||||
log.Error().Int64("content-length", i).Int64("transferred-bytes", c).Msg("content length vs transferred bytes mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func copyHeader(dst, src http.Header) {
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -693,7 +693,7 @@ func (h *Handler) GetShare(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if share == nil {
|
||||
sublog.Debug().Msg("no share found with this id")
|
||||
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "share not found", nil)
|
||||
response.WriteOCSError(w, r, response.MetaPathNotFound.StatusCode, "share not found", nil) // MetaNotFount with code 998 would be cleaner, but this is a legacy api
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
oidc "github.com/coreos/go-oidc"
|
||||
oidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
|
||||
+27
-7
@@ -30,6 +30,7 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
"go-micro.dev/v4/broker"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
@@ -50,11 +51,10 @@ type Options struct {
|
||||
FavoriteManager favorite.Manager
|
||||
GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
||||
|
||||
TracingEnabled bool
|
||||
TracingInsecure bool
|
||||
TracingExporter string
|
||||
TracingCollector string
|
||||
TracingEndpoint string
|
||||
TracingEnabled bool
|
||||
TracingInsecure bool
|
||||
TracingEndpoint string
|
||||
TracingTransportCredentials credentials.TransportCredentials
|
||||
|
||||
TraceProvider trace.TracerProvider
|
||||
|
||||
@@ -230,11 +230,25 @@ func LockSystem(val ocdav.LockSystem) Option {
|
||||
}
|
||||
|
||||
// Tracing enables tracing
|
||||
// Deprecated: use WithTracingEndpoint and WithTracingEnabled, Collector is unused
|
||||
func Tracing(endpoint, collector string) Option {
|
||||
return func(o *Options) {
|
||||
o.TracingEnabled = true
|
||||
o.TracingEndpoint = endpoint
|
||||
o.TracingCollector = collector
|
||||
}
|
||||
}
|
||||
|
||||
// WithTracingEnabled option
|
||||
func WithTracingEnabled(enabled bool) Option {
|
||||
return func(o *Options) {
|
||||
o.TracingEnabled = enabled
|
||||
}
|
||||
}
|
||||
|
||||
// WithTracingEndpoint option
|
||||
func WithTracingEndpoint(endpoint string) Option {
|
||||
return func(o *Options) {
|
||||
o.TracingEndpoint = endpoint
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,9 +260,15 @@ func WithTracingInsecure() Option {
|
||||
}
|
||||
|
||||
// WithTracingExporter option
|
||||
// Deprecated: unused
|
||||
func WithTracingExporter(exporter string) Option {
|
||||
return func(o *Options) {}
|
||||
}
|
||||
|
||||
// WithTracingTransportCredentials option
|
||||
func WithTracingTransportCredentials(v credentials.TransportCredentials) Option {
|
||||
return func(o *Options) {
|
||||
o.TracingExporter = exporter
|
||||
o.TracingTransportCredentials = v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -90,9 +90,7 @@ func Service(opts ...Option) (micro.Service, error) {
|
||||
|
||||
if tp == nil {
|
||||
topts := []rtrace.Option{
|
||||
rtrace.WithExporter(sopts.TracingExporter),
|
||||
rtrace.WithEndpoint(sopts.TracingEndpoint),
|
||||
rtrace.WithCollector(sopts.TracingCollector),
|
||||
rtrace.WithServiceName(sopts.Name),
|
||||
}
|
||||
if sopts.TracingEnabled {
|
||||
@@ -101,6 +99,9 @@ func Service(opts ...Option) (micro.Service, error) {
|
||||
if sopts.TracingInsecure {
|
||||
topts = append(topts, rtrace.WithInsecure())
|
||||
}
|
||||
if sopts.TracingTransportCredentials != nil {
|
||||
topts = append(topts, rtrace.WithTransportCredentials(sopts.TracingTransportCredentials))
|
||||
}
|
||||
tp = rtrace.NewTracerProvider(topts...)
|
||||
}
|
||||
if err := useMiddlewares(r, &sopts, revaService, tp); err != nil {
|
||||
|
||||
+3
-8
@@ -326,10 +326,6 @@ func (s *Server) getInterceptors(unprotected []string) ([]grpc.ServerOption, err
|
||||
}
|
||||
|
||||
unaryInterceptors := []grpc.UnaryServerInterceptor{
|
||||
otelgrpc.UnaryServerInterceptor(
|
||||
otelgrpc.WithTracerProvider(s.tracerProvider),
|
||||
otelgrpc.WithPropagators(rtrace.Propagator),
|
||||
),
|
||||
appctx.NewUnary(s.log, s.tracerProvider),
|
||||
token.NewUnary(),
|
||||
useragent.NewUnary(),
|
||||
@@ -372,10 +368,6 @@ func (s *Server) getInterceptors(unprotected []string) ([]grpc.ServerOption, err
|
||||
}
|
||||
|
||||
streamInterceptors := []grpc.StreamServerInterceptor{
|
||||
otelgrpc.StreamServerInterceptor(
|
||||
otelgrpc.WithTracerProvider(s.tracerProvider),
|
||||
otelgrpc.WithPropagators(rtrace.Propagator),
|
||||
),
|
||||
appctx.NewStream(s.log, s.tracerProvider),
|
||||
token.NewStream(),
|
||||
useragent.NewStream(),
|
||||
@@ -391,6 +383,9 @@ func (s *Server) getInterceptors(unprotected []string) ([]grpc.ServerOption, err
|
||||
streamChain := grpc_middleware.ChainStreamServer(streamInterceptors...)
|
||||
|
||||
opts := []grpc.ServerOption{
|
||||
grpc.StatsHandler(otelgrpc.NewServerHandler(
|
||||
otelgrpc.WithTracerProvider(s.tracerProvider),
|
||||
otelgrpc.WithPropagators(rtrace.Propagator))),
|
||||
grpc.UnaryInterceptor(unaryChain),
|
||||
grpc.StreamInterceptor(streamChain),
|
||||
}
|
||||
|
||||
+1
-11
@@ -90,7 +90,7 @@ func NewConn(address string, opts ...Option) (*grpc.ClientConn, error) {
|
||||
grpc.WithDefaultCallOptions(
|
||||
grpc.MaxCallRecvMsgSize(maxRcvMsgSize),
|
||||
),
|
||||
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(
|
||||
grpc.WithStatsHandler(otelgrpc.NewClientHandler(
|
||||
otelgrpc.WithTracerProvider(
|
||||
options.tracerProvider,
|
||||
),
|
||||
@@ -98,16 +98,6 @@ func NewConn(address string, opts ...Option) (*grpc.ClientConn, error) {
|
||||
rtrace.Propagator,
|
||||
),
|
||||
)),
|
||||
grpc.WithUnaryInterceptor(
|
||||
otelgrpc.UnaryClientInterceptor(
|
||||
otelgrpc.WithTracerProvider(
|
||||
options.tracerProvider,
|
||||
),
|
||||
otelgrpc.WithPropagators(
|
||||
rtrace.Propagator,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+33
-4
@@ -23,6 +23,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
tusd "github.com/tus/tusd/pkg/handler"
|
||||
@@ -45,14 +46,25 @@ func init() {
|
||||
registry.Register("tus", New)
|
||||
}
|
||||
|
||||
type TusConfig struct {
|
||||
cache.Config
|
||||
CorsEnabled bool `mapstructure:"cors_enabled"`
|
||||
CorsAllowOrigin string `mapstructure:"cors_allow_origin"`
|
||||
CorsAllowCredentials bool `mapstructure:"cors_allow_credentials"`
|
||||
CorsAllowMethods string `mapstructure:"cors_allow_methods"`
|
||||
CorsAllowHeaders string `mapstructure:"cors_allow_headers"`
|
||||
CorsMaxAge string `mapstructure:"cors_max_age"`
|
||||
CorsExposeHeaders string `mapstructure:"cors_expose_headers"`
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
conf *cache.Config
|
||||
conf *TusConfig
|
||||
publisher events.Publisher
|
||||
statCache cache.StatCache
|
||||
}
|
||||
|
||||
func parseConfig(m map[string]interface{}) (*cache.Config, error) {
|
||||
c := &cache.Config{}
|
||||
func parseConfig(m map[string]interface{}) (*TusConfig, error) {
|
||||
c := &TusConfig{}
|
||||
if err := mapstructure.Decode(m, c); err != nil {
|
||||
err = errors.Wrap(err, "error decoding conf")
|
||||
return nil, err
|
||||
@@ -69,7 +81,7 @@ func New(m map[string]interface{}, publisher events.Publisher) (datatx.DataTX, e
|
||||
return &manager{
|
||||
conf: c,
|
||||
publisher: publisher,
|
||||
statCache: cache.GetStatCache(*c),
|
||||
statCache: cache.GetStatCache(c.Config),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -94,6 +106,23 @@ func (m *manager) Handler(fs storage.FS) (http.Handler, error) {
|
||||
Logger: log.New(appctx.GetLogger(context.Background()), "", 0),
|
||||
}
|
||||
|
||||
if m.conf.CorsEnabled {
|
||||
allowOrigin, err := regexp.Compile(m.conf.CorsAllowOrigin)
|
||||
if m.conf.CorsAllowOrigin != "" && err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config.Cors = &tusd.CorsConfig{
|
||||
Disable: false,
|
||||
AllowOrigin: allowOrigin,
|
||||
AllowCredentials: m.conf.CorsAllowCredentials,
|
||||
AllowMethods: m.conf.CorsAllowMethods,
|
||||
AllowHeaders: m.conf.CorsAllowHeaders,
|
||||
MaxAge: m.conf.CorsMaxAge,
|
||||
ExposeHeaders: m.conf.CorsExposeHeaders,
|
||||
}
|
||||
}
|
||||
|
||||
handler, err := tusd.NewUnroutedHandler(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Generated
Vendored
+7
-3
@@ -202,6 +202,11 @@ func (c *Cache) Add(ctx context.Context, storageID, spaceID, shareID string, sha
|
||||
log.Debug().Msg("precondition failed when persisting added provider share: etag changed. retrying...")
|
||||
// actually, this is the wrong status code and we treat it like errtypes.Aborted because of inconsistencies on the server side
|
||||
// continue with sync below
|
||||
case errtypes.AlreadyExists:
|
||||
log.Debug().Msg("already exists when persisting added provider share. retrying...")
|
||||
// CS3 uses an already exists error instead of precondition failed when using an If-None-Match=* header / IfExists flag in the InitiateFileUpload call.
|
||||
// Thas happens when the cache thinks there is no file.
|
||||
// continue with sync below
|
||||
default:
|
||||
span.SetStatus(codes.Error, fmt.Sprintf("persisting added provider share failed. giving up: %s", err.Error()))
|
||||
log.Error().Err(err).Msg("persisting added provider share failed")
|
||||
@@ -393,10 +398,8 @@ func (c *Cache) Persist(ctx context.Context, storageID, spaceID string) error {
|
||||
// > If the field value is "*", the condition is false if the origin server has a current representation for the target resource.
|
||||
if space.Etag == "" {
|
||||
ur.IfNoneMatch = []string{"*"}
|
||||
log.Debug().Msg("setting IfNoneMatch to *")
|
||||
} else {
|
||||
log.Debug().Msg("setting IfMatchEtag")
|
||||
}
|
||||
|
||||
res, err := c.storage.Upload(ctx, ur)
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
@@ -405,6 +408,7 @@ func (c *Cache) Persist(ctx context.Context, storageID, spaceID string) error {
|
||||
return err
|
||||
}
|
||||
space.Etag = res.Etag
|
||||
|
||||
span.SetStatus(codes.Ok, "")
|
||||
shares := []string{}
|
||||
for _, s := range space.Shares {
|
||||
|
||||
Generated
Vendored
+8
-1
@@ -146,6 +146,11 @@ func (c *Cache) Add(ctx context.Context, userID, spaceID string, rs *collaborati
|
||||
log.Debug().Msg("precondition failed when persisting added received share: etag changed. retrying...")
|
||||
// actually, this is the wrong status code and we treat it like errtypes.Aborted because of inconsistencies on the server side
|
||||
// continue with sync below
|
||||
case errtypes.AlreadyExists:
|
||||
log.Debug().Msg("already exists when persisting added received share. retrying...")
|
||||
// CS3 uses an already exists error instead of precondition failed when using an If-None-Match=* header / IfExists flag in the InitiateFileUpload call.
|
||||
// Thas happens when the cache thinks there is no file.
|
||||
// continue with sync below
|
||||
default:
|
||||
span.SetStatus(codes.Error, fmt.Sprintf("persisting added received share failed. giving up: %s", err.Error()))
|
||||
log.Error().Err(err).Msg("persisting added received share failed")
|
||||
@@ -294,12 +299,14 @@ func (c *Cache) persist(ctx context.Context, userID string) error {
|
||||
ur.IfNoneMatch = []string{"*"}
|
||||
}
|
||||
|
||||
_, err = c.storage.Upload(ctx, ur)
|
||||
res, err := c.storage.Upload(ctx, ur)
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return err
|
||||
}
|
||||
rss.etag = res.Etag
|
||||
|
||||
span.SetStatus(codes.Ok, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
Generated
Vendored
+7
@@ -137,6 +137,11 @@ func (c *Cache) Add(ctx context.Context, userid, shareID string) error {
|
||||
log.Debug().Msg("precondition failed when persisting added share: etag changed. retrying...")
|
||||
// actually, this is the wrong status code and we treat it like errtypes.Aborted because of inconsistencies on the server side
|
||||
// continue with sync below
|
||||
case errtypes.AlreadyExists:
|
||||
log.Debug().Msg("already exists when persisting added share. retrying...")
|
||||
// CS3 uses an already exists error instead of precondition failed when using an If-None-Match=* header / IfExists flag in the InitiateFileUpload call.
|
||||
// Thas happens when the cache thinks there is no file.
|
||||
// continue with sync below
|
||||
default:
|
||||
span.SetStatus(codes.Error, fmt.Sprintf("persisting added share failed. giving up: %s", err.Error()))
|
||||
log.Error().Err(err).Msg("persisting added share failed")
|
||||
@@ -330,6 +335,7 @@ func (c *Cache) Persist(ctx context.Context, userid string) error {
|
||||
if us.Etag == "" {
|
||||
ur.IfNoneMatch = []string{"*"}
|
||||
}
|
||||
|
||||
res, err := c.storage.Upload(ctx, ur)
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
@@ -337,6 +343,7 @@ func (c *Cache) Persist(ctx context.Context, userid string) error {
|
||||
return err
|
||||
}
|
||||
us.Etag = res.Etag
|
||||
|
||||
span.SetStatus(codes.Ok, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
+24
-4
@@ -37,11 +37,22 @@ import (
|
||||
type Blobstore struct {
|
||||
client *minio.Client
|
||||
|
||||
defaultPutOptions Options
|
||||
|
||||
bucket string
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
DisableContentSha256 bool
|
||||
DisableMultipart bool
|
||||
SendContentMd5 bool
|
||||
ConcurrentStreamParts bool
|
||||
NumThreads uint
|
||||
PartSize uint64
|
||||
}
|
||||
|
||||
// New returns a new Blobstore
|
||||
func New(endpoint, region, bucket, accessKey, secretKey string) (*Blobstore, error) {
|
||||
func New(endpoint, region, bucket, accessKey, secretKey string, defaultPutOptions Options) (*Blobstore, error) {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse s3 endpoint")
|
||||
@@ -58,8 +69,9 @@ func New(endpoint, region, bucket, accessKey, secretKey string) (*Blobstore, err
|
||||
}
|
||||
|
||||
return &Blobstore{
|
||||
client: client,
|
||||
bucket: bucket,
|
||||
client: client,
|
||||
bucket: bucket,
|
||||
defaultPutOptions: defaultPutOptions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -71,7 +83,15 @@ func (bs *Blobstore) Upload(node *node.Node, source string) error {
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
_, err = bs.client.PutObject(context.Background(), bs.bucket, bs.path(node), reader, node.Blobsize, minio.PutObjectOptions{ContentType: "application/octet-stream", SendContentMd5: true})
|
||||
_, err = bs.client.PutObject(context.Background(), bs.bucket, bs.path(node), reader, node.Blobsize, minio.PutObjectOptions{
|
||||
ContentType: "application/octet-stream",
|
||||
SendContentMd5: bs.defaultPutOptions.SendContentMd5,
|
||||
ConcurrentStreamParts: bs.defaultPutOptions.ConcurrentStreamParts,
|
||||
NumThreads: bs.defaultPutOptions.NumThreads,
|
||||
PartSize: bs.defaultPutOptions.PartSize,
|
||||
DisableMultipart: bs.defaultPutOptions.DisableMultipart,
|
||||
DisableContentSha256: bs.defaultPutOptions.DisableContentSha256,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not store object '%s' into bucket '%s'", bs.path(node), bs.bucket)
|
||||
|
||||
+29
@@ -43,6 +43,24 @@ type Options struct {
|
||||
|
||||
// Secret key for the s3 blobstore
|
||||
S3SecretKey string `mapstructure:"s3.secret_key"`
|
||||
|
||||
// disable sending content sha256
|
||||
DisableContentSha256 bool `mapstructure:"s3.disable_content_sha254"`
|
||||
|
||||
// disable multipart uploads
|
||||
DisableMultipart bool `mapstructure:"s3.disable_multipart"`
|
||||
|
||||
// enable sending content md5, defaults to true if unset
|
||||
SendContentMd5 bool `mapstructure:"s3.send_content_md5"`
|
||||
|
||||
// use concurrent stream parts
|
||||
ConcurrentStreamParts bool `mapstructure:"s3.concurrent_stream_parts"`
|
||||
|
||||
// number of concurrent uploads
|
||||
NumThreads uint `mapstructure:"s3.num_threads"`
|
||||
|
||||
// part size for concurrent uploads
|
||||
PartSize uint64 `mapstructure:"s3.part_size"`
|
||||
}
|
||||
|
||||
// S3ConfigComplete return true if all required s3 fields are set
|
||||
@@ -60,5 +78,16 @@ func parseConfig(m map[string]interface{}) (*Options, error) {
|
||||
err = errors.Wrap(err, "error decoding conf")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if unset we set these defaults
|
||||
if m["s3.send_content_md5"] == nil {
|
||||
o.SendContentMd5 = true
|
||||
}
|
||||
if m["s3.concurrent_stream_parts"] == nil {
|
||||
o.ConcurrentStreamParts = true
|
||||
}
|
||||
if m["s3.num_threads"] == nil {
|
||||
o.NumThreads = 4
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
+10
-1
@@ -44,7 +44,16 @@ func New(m map[string]interface{}, stream events.Stream) (storage.FS, error) {
|
||||
return nil, fmt.Errorf("S3 configuration incomplete")
|
||||
}
|
||||
|
||||
bs, err := blobstore.New(o.S3Endpoint, o.S3Region, o.S3Bucket, o.S3AccessKey, o.S3SecretKey)
|
||||
defaultPutOptions := blobstore.Options{
|
||||
DisableContentSha256: o.DisableContentSha256,
|
||||
DisableMultipart: o.DisableMultipart,
|
||||
SendContentMd5: o.SendContentMd5,
|
||||
ConcurrentStreamParts: o.ConcurrentStreamParts,
|
||||
NumThreads: o.NumThreads,
|
||||
PartSize: o.PartSize,
|
||||
}
|
||||
|
||||
bs, err := blobstore.New(o.S3Endpoint, o.S3Region, o.S3Bucket, o.S3AccessKey, o.S3SecretKey, defaultPutOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+3
-1
@@ -165,7 +165,9 @@ func (cs3 *CS3) Upload(ctx context.Context, req UploadRequest) (*UploadResponse,
|
||||
}
|
||||
if len(req.IfNoneMatch) > 0 {
|
||||
if req.IfNoneMatch[0] == "*" {
|
||||
ifuReq.Options = &provider.InitiateFileUploadRequest_IfNotExist{}
|
||||
ifuReq.Options = &provider.InitiateFileUploadRequest_IfNotExist{
|
||||
IfNotExist: true,
|
||||
}
|
||||
}
|
||||
// else {
|
||||
// the http upload will carry all if-not-match etags
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
)
|
||||
|
||||
type ctxKey struct{}
|
||||
@@ -43,5 +44,5 @@ func ContextGetTracerProvider(ctx context.Context) trace.TracerProvider {
|
||||
if p, ok := ctx.Value(ctxKey{}).(trace.TracerProvider); ok {
|
||||
return p
|
||||
}
|
||||
return trace.NewNoopTracerProvider()
|
||||
return noop.NewTracerProvider()
|
||||
}
|
||||
|
||||
+9
@@ -24,6 +24,7 @@ func WithEnabled() Option {
|
||||
}
|
||||
|
||||
// WithExporter option
|
||||
// Deprecated: unused
|
||||
func WithExporter(v string) Option {
|
||||
return func(o *Options) {
|
||||
o.Exporter = v
|
||||
@@ -38,6 +39,7 @@ func WithInsecure() Option {
|
||||
}
|
||||
|
||||
// WithCollector option
|
||||
// Deprecated: unused
|
||||
func WithCollector(v string) Option {
|
||||
return func(o *Options) {
|
||||
o.Collector = v
|
||||
@@ -57,3 +59,10 @@ func WithServiceName(v string) Option {
|
||||
o.ServiceName = v
|
||||
}
|
||||
}
|
||||
|
||||
// WithTransportCredentials option
|
||||
func WithTransportCredentials(v credentials.TransportCredentials) Option {
|
||||
return func(o *Options) {
|
||||
o.TransportCredentials = v
|
||||
}
|
||||
}
|
||||
|
||||
+12
-92
@@ -21,25 +21,21 @@ package trace
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/exporters/jaeger"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -66,7 +62,7 @@ func NewTracerProvider(opts ...Option) trace.TracerProvider {
|
||||
}
|
||||
|
||||
if !options.Enabled {
|
||||
return trace.NewNoopTracerProvider()
|
||||
return noop.NewTracerProvider()
|
||||
}
|
||||
|
||||
// default to 'reva' as service name if not set
|
||||
@@ -74,12 +70,7 @@ func NewTracerProvider(opts ...Option) trace.TracerProvider {
|
||||
options.ServiceName = "reva"
|
||||
}
|
||||
|
||||
switch options.Exporter {
|
||||
case "otlp":
|
||||
return getOtlpTracerProvider(options)
|
||||
default:
|
||||
return getJaegerTracerProvider(options)
|
||||
}
|
||||
return getOtlpTracerProvider(options)
|
||||
}
|
||||
|
||||
// SetDefaultTracerProvider sets the default trace provider
|
||||
@@ -97,11 +88,10 @@ func InitDefaultTracerProvider(collector, endpoint string) {
|
||||
defaultProvider.mutex.Lock()
|
||||
defer defaultProvider.mutex.Unlock()
|
||||
if !defaultProvider.initialized {
|
||||
SetDefaultTracerProvider(getJaegerTracerProvider(Options{
|
||||
Enabled: true,
|
||||
Collector: collector,
|
||||
SetDefaultTracerProvider(getOtlpTracerProvider(Options{
|
||||
Endpoint: endpoint,
|
||||
ServiceName: "reva default jaeger provider",
|
||||
ServiceName: "reva default otlp provider",
|
||||
Insecure: true,
|
||||
}))
|
||||
}
|
||||
}
|
||||
@@ -114,89 +104,19 @@ func DefaultProvider() trace.TracerProvider {
|
||||
return otel.GetTracerProvider()
|
||||
}
|
||||
|
||||
// getJaegerTracerProvider returns a new TracerProvider, configure for the specified service
|
||||
func getJaegerTracerProvider(options Options) trace.TracerProvider {
|
||||
var exp *jaeger.Exporter
|
||||
var err error
|
||||
|
||||
if options.Endpoint != "" {
|
||||
var agentHost string
|
||||
var agentPort string
|
||||
|
||||
agentHost, agentPort, err = parseAgentConfig(options.Endpoint)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
exp, err = jaeger.New(
|
||||
jaeger.WithAgentEndpoint(
|
||||
jaeger.WithAgentHost(agentHost),
|
||||
jaeger.WithAgentPort(agentPort),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Collector != "" {
|
||||
exp, err = jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(options.Collector)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return sdktrace.NewTracerProvider(
|
||||
sdktrace.WithBatcher(exp),
|
||||
sdktrace.WithResource(resource.NewWithAttributes(
|
||||
semconv.SchemaURL,
|
||||
semconv.ServiceNameKey.String(options.ServiceName),
|
||||
semconv.HostNameKey.String(hostname),
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
func parseAgentConfig(ae string) (string, string, error) {
|
||||
u, err := url.Parse(ae)
|
||||
// as per url.go:
|
||||
// [...] Trying to parse a hostname and path
|
||||
// without a scheme is invalid but may not necessarily return an
|
||||
// error, due to parsing ambiguities.
|
||||
if err == nil && u.Hostname() != "" && u.Port() != "" {
|
||||
return u.Hostname(), u.Port(), nil
|
||||
}
|
||||
|
||||
p := strings.Split(ae, ":")
|
||||
if len(p) != 2 {
|
||||
return "", "", fmt.Errorf(fmt.Sprintf("invalid agent endpoint `%s`. expected format: `hostname:port`", ae))
|
||||
}
|
||||
|
||||
switch {
|
||||
case p[0] == "" && p[1] == "": // case ae = ":"
|
||||
return "", "", fmt.Errorf(fmt.Sprintf("invalid agent endpoint `%s`. expected format: `hostname:port`", ae))
|
||||
case p[0] == "":
|
||||
return "", "", fmt.Errorf(fmt.Sprintf("invalid agent endpoint `%s`. expected format: `hostname:port`", ae))
|
||||
}
|
||||
return p[0], p[1], nil
|
||||
}
|
||||
|
||||
// getOtelTracerProvider returns a new TracerProvider, configure for the specified service
|
||||
func getOtlpTracerProvider(options Options) trace.TracerProvider {
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
transportCredentials := options.TransportCredentials
|
||||
if options.Insecure {
|
||||
transportCredentials = insecure.NewCredentials()
|
||||
}
|
||||
conn, err := grpc.DialContext(ctx, options.Endpoint,
|
||||
// Note the use of insecure transport here. TLS is recommended in production.
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithBlock(),
|
||||
grpc.WithTransportCredentials(transportCredentials),
|
||||
)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to create gRPC connection to collector: %w", err))
|
||||
panic(fmt.Errorf("failed to create gRPC connection to endpoint: %w", err))
|
||||
}
|
||||
exporter, err := otlptracegrpc.New(
|
||||
context.Background(),
|
||||
|
||||
Reference in New Issue
Block a user