feature/498-make_query_tracing_more_detailed #564

Merged
alexvanin merged 6 commits from r.loginov/frostfs-s3-gw:feature/498-make_query_tracing_more_detailed into master 2025-02-21 09:31:32 +00:00
37 changed files with 524 additions and 118 deletions

View file

@ -161,7 +161,7 @@ func IsStandardContentSHA256(key string) bool {
return ok
}
func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) {
func (c *Center) Authenticate(ctx context.Context, r *http.Request) (*middleware.Box, error) {
var (
err error
authHdr *AuthHeader
@ -216,7 +216,7 @@ func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) {
authHeaderField := r.Header[AuthorizationHdr]
if len(authHeaderField) != 1 {
if strings.HasPrefix(r.Header.Get(ContentTypeHdr), "multipart/form-data") {
return c.checkFormData(r)
return c.checkFormData(ctx, r)
}
return nil, fmt.Errorf("%w: %v", middleware.ErrNoAuthorizationHeader, authHeaderField)
}
@ -242,7 +242,7 @@ func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) {
return nil, err
}
box, attrs, err := c.cli.GetBox(r.Context(), cnrID, authHdr.AccessKeyID)
box, attrs, err := c.cli.GetBox(ctx, cnrID, authHdr.AccessKeyID)
if err != nil {
return nil, fmt.Errorf("get box by access key '%s': %w", authHdr.AccessKeyID, err)
}
@ -315,7 +315,7 @@ func (c Center) checkAccessKeyID(accessKeyID string) error {
return fmt.Errorf("%w: accesskeyID prefix isn't allowed", apierr.GetAPIError(apierr.ErrAccessDenied))
}
func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
func (c *Center) checkFormData(ctx context.Context, r *http.Request) (*middleware.Box, error) {
if err := r.ParseMultipartForm(maxFormSizeMemory); err != nil {
return nil, fmt.Errorf("%w: parse multipart form with max size %d", apierr.GetAPIError(apierr.ErrInvalidArgument), maxFormSizeMemory)
}
@ -347,7 +347,7 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
return nil, err
}
box, attrs, err := c.cli.GetBox(r.Context(), cnrID, accessKeyID)
box, attrs, err := c.cli.GetBox(ctx, cnrID, accessKeyID)
if err != nil {
return nil, fmt.Errorf("get box by accessKeyID '%s': %w", accessKeyID, err)
}

View file

@ -567,7 +567,7 @@ func TestAuthenticate(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
creds := tokens.New(bigConfig)
cntr := New(creds, tc.prefixes, &centerSettingsMock{})
box, err := cntr.Authenticate(tc.request)
box, err := cntr.Authenticate(ctx, tc.request)
if tc.err {
require.Error(t, err)
@ -600,6 +600,7 @@ func TestHTTPPostAuthenticate(t *testing.T) {
region = "default"
)
ctx := context.Background()
key, err := keys.NewPrivateKey()
require.NoError(t, err)
@ -751,7 +752,7 @@ func TestHTTPPostAuthenticate(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
creds := tokens.New(bigConfig)
cntr := New(creds, tc.prefixes, &centerSettingsMock{})
box, err := cntr.Authenticate(tc.request)
box, err := cntr.Authenticate(ctx, tc.request)
if tc.err {
require.Error(t, err)

View file

@ -99,12 +99,14 @@ func TestCheckSign(t *testing.T) {
postReg: NewRegexpMatcher(postPolicyCredentialRegexp),
settings: &centerSettingsMock{},
}
box, err := c.Authenticate(req)
box, err := c.Authenticate(ctx, req)
require.NoError(t, err)
require.EqualValues(t, expBox, box.AccessBox)
}
func TestCheckSignV4a(t *testing.T) {
ctx := context.Background()
var accessKeyAddr oid.Address
err := accessKeyAddr.DecodeString("8N7CYBY74kxZXoyvA5UNdmovaXqFpwNfvEPsqaN81es2/3tDwq5tR8fByrJcyJwyiuYX7Dae8tyDT7pd8oaL1MBto")
require.NoError(t, err)
@ -148,7 +150,7 @@ func TestCheckSignV4a(t *testing.T) {
regV4a: NewRegexpMatcher(AuthorizationFieldV4aRegexp),
postReg: NewRegexpMatcher(postPolicyCredentialRegexp),
}
box, err := c.Authenticate(req)
box, err := c.Authenticate(ctx, req)
require.NoError(t, err)
require.EqualValues(t, expBox, box.AccessBox)
}

View file

@ -11,6 +11,7 @@ import (
"net/http"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -47,7 +48,9 @@ const (
)
func (h *handler) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketACL")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -127,7 +130,9 @@ func getTokenIssuerKey(box *accessbox.Box) (*keys.PublicKey, error) {
}
func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketACL")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -194,7 +199,9 @@ func (h *handler) putBucketACLAPEHandler(w http.ResponseWriter, r *http.Request,
}
func (h *handler) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectACL")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -216,7 +223,9 @@ func (h *handler) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectACL")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
if _, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil {
@ -228,7 +237,9 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketPolicyStatus")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -271,7 +282,9 @@ func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Re
}
func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketPolicy")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -298,7 +311,9 @@ func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
}
func (h *handler) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketPolicy")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -328,7 +343,9 @@ func checkOwner(info *data.BucketInfo, owner string) error {
}
func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketPolicy")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -8,6 +8,7 @@ import (
"strconv"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -70,7 +71,9 @@ var validAttributes = map[string]struct{}{
}
func (h *handler) GetObjectAttributesHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectAttributes")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
params, err := parseGetObjectAttributeArgs(r, h.reqLogger(ctx))

View file

@ -5,6 +5,7 @@ import (
"strconv"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
@ -14,7 +15,9 @@ const maxBucketList = 10000
// ListBucketsHandler handles bucket listing requests.
func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListBuckets")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
params, err := parseListBucketParams(r)

View file

@ -6,6 +6,7 @@ import (
"regexp"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
@ -40,18 +41,19 @@ func path2BucketObject(path string) (string, string, error) {
}
func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CopyObject")
defer span.End()
var (
err error
versionID string
metadata map[string]string
tagSet map[string]string
ctx = r.Context()
reqInfo = middleware.GetReqInfo(ctx)
cannedACLStatus = aclHeadersStatus(r)
)
reqInfo := middleware.GetReqInfo(ctx)
cannedACLStatus := aclHeadersStatus(r)
src := r.Header.Get(api.AmzCopySource)
// Check https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectVersioning.html
// Regardless of whether you have enabled versioning, each object in your bucket

View file

@ -5,6 +5,7 @@ import (
"strconv"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
@ -20,7 +21,9 @@ const (
)
func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketCors")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -42,7 +45,9 @@ func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketCors")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -76,7 +81,9 @@ func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketCors")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -93,6 +100,9 @@ func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request
}
func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) {
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.AppendCORSHeaders")
defer span.End()
if r.Method == http.MethodOptions {
return
}
@ -101,7 +111,6 @@ func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) {
return
}
ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
if reqInfo.BucketName == "" {
return
@ -153,7 +162,9 @@ func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) Preflight(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.Preflight")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketInfo(ctx, reqInfo.BucketName)
if err != nil {

View file

@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
@ -61,7 +62,9 @@ type DeleteObjectsResponse struct {
}
func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteObject")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
versionID := reqInfo.URL.Query().Get(api.QueryVersionID)
versionedObject := []*layer.VersionedObject{{
@ -128,7 +131,9 @@ func isErrObjectLocked(err error) bool {
// DeleteMultipleObjectsHandler handles multiple delete requests.
func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteMultipleObjects")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
// Content-Length is required and should be non-zero
@ -230,7 +235,9 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
}
func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucket")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil {

View file

@ -8,6 +8,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -148,12 +149,11 @@ func writeHeaders(h http.Header, requestHeader http.Header, extendedInfo *data.E
}
func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
var (
params *layer.RangeParams
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObject")
defer span.End()
ctx = r.Context()
reqInfo = middleware.GetReqInfo(ctx)
)
var params *layer.RangeParams
reqInfo := middleware.GetReqInfo(ctx)
conditional := parseConditionalHeaders(r.Header, h.reqLogger(ctx))

View file

@ -4,6 +4,7 @@ import (
"io"
"net/http"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -27,7 +28,9 @@ func getRangeToDetectContentType(maxSize uint64) *layer.RangeParams {
}
func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.HeadObject")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -123,7 +126,9 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.HeadBucket")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -3,11 +3,14 @@ package handler
import (
"net/http"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
)
func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketLocation")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -10,6 +10,7 @@ import (
"net/http"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -27,7 +28,9 @@ const (
)
func (h *handler) GetBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketLifecycle")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -49,10 +52,12 @@ func (h *handler) GetBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque
}
func (h *handler) PutBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) {
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketLifecycle")
defer span.End()
var buf bytes.Buffer
tee := io.TeeReader(r.Body, &buf)
ctx := r.Context()
reqInfo := middleware.GetReqInfo(ctx)
cfg := new(data.LifecycleConfiguration)
@ -115,7 +120,9 @@ func (h *handler) PutBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque
}
func (h *handler) DeleteBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketLifecycle")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -7,6 +7,7 @@ import (
"strconv"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -26,7 +27,9 @@ const (
)
func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketObjectLockConfig")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -74,7 +77,9 @@ func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
}
func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketObjectLockConfig")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -108,7 +113,9 @@ func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt
}
func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectLegalHold")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -161,7 +168,9 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
}
func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectLegalHold")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -199,7 +208,9 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
}
func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectRetention")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -247,7 +258,9 @@ func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
}
func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectRetention")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -10,6 +10,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -104,7 +105,9 @@ const (
)
func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CreateMultipartUpload")
dkirillov marked this conversation as resolved Outdated

I suggest write "handler.CreateMultipartUpload" instead of "handler.CreateMultipartUploadHandler"

I suggest write `"handler.CreateMultipartUpload"` instead of `"handler.CreateMultipartUploadHandler"`
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
uploadID := uuid.New()
cannedACLStatus := aclHeadersStatus(r)
@ -174,7 +177,9 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re
}
func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.UploadPart")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -247,15 +252,16 @@ func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
var (
versionID string
ctx = r.Context()
reqInfo = middleware.GetReqInfo(ctx)
queryValues = reqInfo.URL.Query()
uploadID = queryValues.Get(uploadIDHeaderName)
partNumStr = queryValues.Get(partNumberHeaderName)
additional = []zap.Field{zap.String("uploadID", uploadID), zap.String("partNumber", partNumStr)}
)
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.UploadPartCopy")
defer span.End()
var versionID string
reqInfo := middleware.GetReqInfo(ctx)
queryValues := reqInfo.URL.Query()
uploadID := queryValues.Get(uploadIDHeaderName)
partNumStr := queryValues.Get(partNumberHeaderName)
additional := []zap.Field{zap.String("uploadID", uploadID), zap.String("partNumber", partNumStr)}
partNumber, err := strconv.Atoi(partNumStr)
if err != nil || partNumber < layer.UploadMinPartNumber || partNumber > layer.UploadMaxPartNumber {
@ -381,7 +387,9 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CompleteMultipartUpload")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -508,7 +516,9 @@ func (h *handler) completeMultipartUpload(r *http.Request, c *layer.CompleteMult
}
func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListMultipartUploads")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -559,7 +569,9 @@ func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Req
}
func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListParts")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -623,7 +635,9 @@ func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.AbortMultipartUpload")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -7,6 +7,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -19,7 +20,9 @@ const maxObjectList = 1000 // Limit number of objects in a listObjectsResponse/l
// ListObjectsV1Handler handles objects listing requests for API version 1.
func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListObjectsV1")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
params, err := parseListObjectsArgsV1(reqInfo)
if err != nil {
@ -64,7 +67,9 @@ func (h *handler) encodeV1(p *layer.ListObjectsParamsV1, list *layer.ListObjects
// ListObjectsV2Handler handles objects listing requests for API version 2.
func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListObjectsV2")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
params, err := parseListObjectsArgsV2(reqInfo)
if err != nil {
@ -223,7 +228,9 @@ func fillContents(src []*data.ExtendedNodeVersion, encode string, fetchOwner, md
}
func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListBucketObjectVersions")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
p, err := parseListObjectVersionsRequest(reqInfo)
if err != nil {

View file

@ -7,6 +7,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -19,7 +20,9 @@ import (
const maxPatchSize = 5 * 1024 * 1024 * 1024 // 5GB
func (h *handler) PatchObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PatchObject")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
if _, ok := r.Header[api.ContentRange]; !ok {

View file

@ -18,6 +18,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
@ -196,12 +197,13 @@ type createBucketParams struct {
}
func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
var (
err error
cannedACLStatus = aclHeadersStatus(r)
ctx = r.Context()
reqInfo = middleware.GetReqInfo(ctx)
)
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObject")
defer span.End()
var err error
cannedACLStatus := aclHeadersStatus(r)
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
if err != nil {
@ -486,12 +488,13 @@ func (h *handler) isTLSCheckRequired(r *http.Request) bool {
}
func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
var (
tagSet map[string]string
ctx = r.Context()
reqInfo = middleware.GetReqInfo(ctx)
metadata = make(map[string]string)
)
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PostObject")
defer span.End()
var tagSet map[string]string
reqInfo := middleware.GetReqInfo(ctx)
metadata := make(map[string]string)
policy, err := checkPostPolicy(r, reqInfo, metadata)
if err != nil {
@ -776,7 +779,10 @@ func parseCannedACL(header http.Header) (string, error) {
}
func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
h.createBucketHandlerPolicy(w, r)
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CreateBucket")
defer span.End()
h.createBucketHandlerPolicy(w, r.WithContext(ctx))
}
func (h *handler) parseCommonCreateBucketParams(reqInfo *middleware.ReqInfo, boxData *accessbox.Box, r *http.Request) (*keys.PublicKey, *layer.CreateBucketParams, error) {

View file

@ -6,6 +6,7 @@ import (
"strings"
"unicode"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -21,7 +22,9 @@ const (
)
func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectTagging")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
tagSet, err := h.readTagSet(reqInfo.Tagging)
@ -54,7 +57,9 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request
}
func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectTagging")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -92,7 +97,9 @@ func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request
}
func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteObjectTagging")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -116,7 +123,9 @@ func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
}
func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketTagging")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
tagSet, err := h.readTagSet(reqInfo.Tagging)
@ -138,7 +147,9 @@ func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request
}
func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketTagging")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
@ -160,7 +171,9 @@ func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request
}
func (h *handler) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketTagging")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -3,6 +3,7 @@ package handler
import (
"net/http"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
@ -10,7 +11,9 @@ import (
)
func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketVersioning")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
configuration := new(VersioningConfiguration)
@ -57,7 +60,9 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
// GetBucketVersioningHandler implements bucket versioning getter handler.
func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketVersioning")
defer span.End()
reqInfo := middleware.GetReqInfo(ctx)
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)

View file

@ -5,12 +5,16 @@ import (
"errors"
"fmt"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
)
func (n *Layer) GetObjectTaggingAndLock(ctx context.Context, objVersion *data.ObjectVersion, nodeVersion *data.NodeVersion) (map[string]string, data.LockInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObjectTaggingAndLock")
defer span.End()
var err error
owner := n.BearerOwner(ctx)

View file

@ -8,6 +8,7 @@ import (
"fmt"
"io"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
@ -23,6 +24,9 @@ const wildcard = "*"
var supportedMethods = map[string]struct{}{"GET": {}, "HEAD": {}, "POST": {}, "PUT": {}, "DELETE": {}}
func (n *Layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketCORS")
defer span.End()
var (
buf bytes.Buffer
tee = io.TeeReader(p.Reader, &buf)
@ -98,6 +102,9 @@ func (n *Layer) deleteCORSObject(ctx context.Context, bktInfo *data.BucketInfo,
}
func (n *Layer) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, decoder func(io.Reader, string) *xml.Decoder) (*data.CORSConfiguration, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketCORS")
defer span.End()
cors, err := n.getCORS(ctx, bktInfo, decoder)
if err != nil {
return nil, err
@ -107,6 +114,9 @@ func (n *Layer) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, dec
}
func (n *Layer) DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucketCORS")
defer span.End()
objs, err := n.treeService.DeleteBucketCORS(ctx, bktInfo)
objNotFound := errors.Is(err, tree.ErrNoNodeToRemove)
if err != nil && !objNotFound {

View file

@ -15,6 +15,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -336,6 +337,9 @@ func (n *Layer) prepareAuthParameters(ctx context.Context, prm *frostfs.PrmAuth,
// GetBucketInfo returns bucket info by name.
func (n *Layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketInfo")
defer span.End()
name, err := url.QueryUnescape(name)
if err != nil {
return nil, fmt.Errorf("unescape bucket name: %w", err)
@ -384,6 +388,9 @@ func (n *Layer) ResolveCID(ctx context.Context, name string) (cid.ID, error) {
// ListBuckets returns all user containers. The name of the bucket is a container
// id. Timestamp is omitted since it is not saved in frostfs container.
func (n *Layer) ListBuckets(ctx context.Context, params ListBucketsParams) (ListBucketsResult, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListBuckets")
defer span.End()
var result ListBucketsResult
var err error
@ -405,6 +412,9 @@ func (n *Layer) ListBuckets(ctx context.Context, params ListBucketsParams) (List
// GetObject from storage.
func (n *Layer) GetObject(ctx context.Context, p *GetObjectParams) (*ObjectPayload, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObject")
defer span.End()
var params getParams
params.objInfo = p.ObjectInfo
@ -519,6 +529,9 @@ func getDecrypter(p *GetObjectParams) (*encryption.Decrypter, error) {
// GetObjectInfo returns meta information about the object.
func (n *Layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ObjectInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObjectInfo")
defer span.End()
extendedObjectInfo, err := n.GetExtendedObjectInfo(ctx, p)
if err != nil {
return nil, err
@ -529,8 +542,13 @@ func (n *Layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.O
// GetExtendedObjectInfo returns meta information and corresponding info from the tree service about the object.
func (n *Layer) GetExtendedObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ExtendedObjectInfo, error) {
var objInfo *data.ExtendedObjectInfo
var err error
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetExtendedObjectInfo")
defer span.End()
var (
objInfo *data.ExtendedObjectInfo
err error
)
if p.Versioned() {
objInfo, err = n.headVersion(ctx, p.BktInfo, p)
@ -552,6 +570,9 @@ func (n *Layer) GetExtendedObjectInfo(ctx context.Context, p *HeadObjectParams)
// CopyObject from one bucket into another bucket.
func (n *Layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*data.ExtendedObjectInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.CopyObject")
defer span.End()
objPayload, err := n.GetObject(ctx, &GetObjectParams{
ObjectInfo: p.SrcObject,
Versioned: p.SrcVersioned,
@ -820,6 +841,9 @@ func (n *Layer) removeCombinedObject(ctx context.Context, bkt *data.BucketInfo,
// DeleteObjects from the storage.
func (n *Layer) DeleteObjects(ctx context.Context, p *DeleteObjectParams) []*VersionedObject {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteObjects")
defer span.End()
for i, obj := range p.Objects {
p.Objects[i] = n.deleteObject(ctx, p.BktInfo, p.Settings, obj, p.NetworkInfo)
if p.IsMultiple && p.Objects[i].Error != nil {
@ -831,6 +855,9 @@ func (n *Layer) DeleteObjects(ctx context.Context, p *DeleteObjectParams) []*Ver
}
func (n *Layer) CreateBucket(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.CreateBucket")
defer span.End()
bktInfo, err := n.GetBucketInfo(ctx, p.Name)
if err != nil {
if apierr.IsS3Error(err, apierr.ErrNoSuchBucket) {
@ -860,6 +887,9 @@ func (n *Layer) ResolveBucket(ctx context.Context, zone, name string) (cid.ID, e
}
func (n *Layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucket")
defer span.End()
if !p.SkipCheck {
res, _, err := n.getAllObjectsVersions(ctx, commonVersionsListingParams{
BktInfo: p.BktInfo,
@ -903,6 +933,9 @@ func (n *Layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
}
func (n *Layer) DeleteContainer(ctx context.Context, p *DeleteBucketParams) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteContainer")
defer span.End()
n.cache.DeleteBucket(p.BktInfo)
if err := n.frostFS.DeleteContainer(ctx, p.BktInfo.CID, p.SessionToken); err != nil {
return fmt.Errorf("delete container: %w", err)
@ -911,6 +944,9 @@ func (n *Layer) DeleteContainer(ctx context.Context, p *DeleteBucketParams) erro
}
func (n *Layer) GetNetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetNetworkInfo")
defer span.End()
cachedInfo := n.cache.GetNetworkInfo()
if cachedInfo != nil {
return *cachedInfo, nil

View file

@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
@ -23,6 +24,9 @@ type PutBucketLifecycleParams struct {
}
func (n *Layer) PutBucketLifecycleConfiguration(ctx context.Context, p *PutBucketLifecycleParams) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketLifecycleConfiguration")
defer span.End()
cfgBytes, err := xml.Marshal(p.LifecycleCfg)
if err != nil {
return fmt.Errorf("marshal lifecycle configuration: %w", err)
@ -86,6 +90,9 @@ func (n *Layer) deleteLifecycleObject(ctx context.Context, bktInfo *data.BucketI
}
func (n *Layer) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) (*data.LifecycleConfiguration, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketLifecycleConfiguration")
defer span.End()
owner := n.BearerOwner(ctx)
if cfg := n.cache.GetLifecycleConfiguration(owner, bktInfo); cfg != nil {
return cfg, nil
@ -131,6 +138,9 @@ func (n *Layer) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *da
}
func (n *Layer) DeleteBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucketLifecycleConfiguration")
defer span.End()
objs, err := n.treeService.DeleteBucketLifecycleConfiguration(ctx, bktInfo)
objsNotFound := errors.Is(err, tree.ErrNoNodeToRemove)
if err != nil && !objsNotFound {

View file

@ -9,6 +9,7 @@ import (
"strings"
"sync"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -97,6 +98,9 @@ const (
// ListObjectsV1 returns objects in a bucket for requests of Version 1.
func (n *Layer) ListObjectsV1(ctx context.Context, p *ListObjectsParamsV1) (*ListObjectsInfoV1, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListObjectsV1")
defer span.End()
var result ListObjectsInfoV1
prm := commonLatestVersionsListingParams{
@ -128,6 +132,9 @@ func (n *Layer) ListObjectsV1(ctx context.Context, p *ListObjectsParamsV1) (*Lis
// ListObjectsV2 returns objects in a bucket for requests of Version 2.
func (n *Layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*ListObjectsInfoV2, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListObjectsV2")
defer span.End()
var result ListObjectsInfoV2
prm := commonLatestVersionsListingParams{
@ -158,6 +165,9 @@ func (n *Layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*Lis
}
func (n *Layer) ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListObjectVersions")
defer span.End()
prm := commonVersionsListingParams{
BktInfo: p.BktInfo,
Delimiter: p.Delimiter,

View file

@ -15,6 +15,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
@ -151,6 +152,9 @@ type (
)
func (n *Layer) CreateMultipartUpload(ctx context.Context, p *CreateMultipartParams) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.CreateMultipartUpload")
defer span.End()
metaSize := len(p.Header)
if p.Data != nil {
metaSize += len(p.Data.TagSet)
@ -190,6 +194,9 @@ func (n *Layer) CreateMultipartUpload(ctx context.Context, p *CreateMultipartPar
}
func (n *Layer) UploadPart(ctx context.Context, p *UploadPartParams) (string, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.UploadPart")
defer span.End()
multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID)
if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) {
@ -342,6 +349,9 @@ func (n *Layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf
}
func (n *Layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.ObjectInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.UploadPartCopy")
defer span.End()
multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID)
if err != nil {
if errors.Is(err, tree.ErrNodeNotFound) {
@ -391,6 +401,9 @@ func (n *Layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.
}
func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipartParams) (*UploadData, *data.ExtendedObjectInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.CompleteMultipartUpload")
defer span.End()
for i := 1; i < len(p.Parts); i++ {
if p.Parts[i].PartNumber <= p.Parts[i-1].PartNumber {
return nil, nil, apierr.GetAPIError(apierr.ErrInvalidPartOrder)
@ -513,6 +526,9 @@ func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
}
func (n *Layer) ListMultipartUploads(ctx context.Context, p *ListMultipartUploadsParams) (*ListMultipartUploadsInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListMultipartUploads")
defer span.End()
var result ListMultipartUploadsInfo
if p.MaxUploads == 0 {
return &result, nil
@ -573,6 +589,9 @@ func (n *Layer) ListMultipartUploads(ctx context.Context, p *ListMultipartUpload
}
func (n *Layer) AbortMultipartUpload(ctx context.Context, p *UploadInfoParams) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.AbortMultipartUpload")
defer span.End()
multipartInfo, parts, err := n.getUploadParts(ctx, p)
if err != nil {
return err
@ -610,6 +629,9 @@ func (n *Layer) deleteUploadedParts(ctx context.Context, bkt *data.BucketInfo, p
}
func (n *Layer) ListParts(ctx context.Context, p *ListPartsParams) (*ListPartsInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListParts")
defer span.End()
var res ListPartsInfo
multipartInfo, partsInfo, err := n.getUploadParts(ctx, p.Info)
if err != nil {

View file

@ -17,6 +17,7 @@ import (
"strconv"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
@ -227,6 +228,9 @@ func ParseCompletedPartHeader(hdr string) (*Part, error) {
// PutObject stores object into FrostFS, took payload from io.Reader.
func (n *Layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ExtendedObjectInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutObject")
defer span.End()
bktSettings, err := n.GetBucketSettings(ctx, p.BktInfo)
if err != nil {
return nil, fmt.Errorf("couldn't get versioning settings object: %w", err)

View file

@ -10,6 +10,7 @@ import (
"strconv"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
@ -25,6 +26,9 @@ type PatchObjectParams struct {
}
func (n *Layer) PatchObject(ctx context.Context, p *PatchObjectParams) (*data.ExtendedObjectInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PatchObject")
defer span.End()
if p.Object.ObjectInfo.Headers[AttributeDecryptedSize] != "" {
return nil, fmt.Errorf("patch encrypted object")
}

View file

@ -10,6 +10,7 @@ import (
"strconv"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
@ -32,6 +33,9 @@ type PutLockInfoParams struct {
}
func (n *Layer) PutLockInfo(ctx context.Context, p *PutLockInfoParams) (err error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutLockInfo")
defer span.End()
newLock := p.NewLock
versionNode := p.NodeVersion
// sometimes node version can be provided from executing context
@ -139,6 +143,9 @@ func (n *Layer) putLockObject(ctx context.Context, bktInfo *data.BucketInfo, obj
}
func (n *Layer) GetLockInfo(ctx context.Context, objVersion *data.ObjectVersion) (*data.LockInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetLockInfo")
defer span.End()
owner := n.BearerOwner(ctx)
if lockInfo := n.cache.GetLockInfo(owner, lockObjectKey(objVersion)); lockInfo != nil {
return lockInfo, nil
@ -206,6 +213,9 @@ func lockObjectKey(objVersion *data.ObjectVersion) string {
}
func (n *Layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketSettings")
defer span.End()
owner := n.BearerOwner(ctx)
if settings := n.cache.GetSettings(owner, bktInfo); settings != nil {
return settings, nil
@ -226,6 +236,9 @@ func (n *Layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo)
}
func (n *Layer) PutBucketSettings(ctx context.Context, p *PutSettingsParams) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketSettings")
defer span.End()
if err := n.treeService.PutSettingsNode(ctx, p.BktInfo, p.Settings); err != nil {
return fmt.Errorf("failed to get settings node: %w", err)
}

View file

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
@ -16,6 +17,9 @@ import (
)
func (n *Layer) GetObjectTagging(ctx context.Context, p *data.GetObjectTaggingParams) (string, map[string]string, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObjectTagging")
defer span.End()
var err error
owner := n.BearerOwner(ctx)
@ -52,6 +56,9 @@ func (n *Layer) GetObjectTagging(ctx context.Context, p *data.GetObjectTaggingPa
}
func (n *Layer) PutObjectTagging(ctx context.Context, p *data.PutObjectTaggingParams) (err error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutObjectTagging")
defer span.End()
nodeVersion := p.NodeVersion
if nodeVersion == nil {
nodeVersion, err = n.getNodeVersionFromCacheOrFrostfs(ctx, p.ObjectVersion)
@ -75,6 +82,9 @@ func (n *Layer) PutObjectTagging(ctx context.Context, p *data.PutObjectTaggingPa
}
func (n *Layer) DeleteObjectTagging(ctx context.Context, p *data.ObjectVersion) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteObjectTagging")
defer span.End()
version, err := n.getNodeVersion(ctx, p)
if err != nil {
return err
@ -96,6 +106,9 @@ func (n *Layer) DeleteObjectTagging(ctx context.Context, p *data.ObjectVersion)
}
func (n *Layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketTagging")
defer span.End()
owner := n.BearerOwner(ctx)
if tags := n.cache.GetTagging(owner, bucketTaggingCacheKey(bktInfo.CID)); tags != nil {
@ -113,6 +126,9 @@ func (n *Layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo)
}
func (n *Layer) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, tagSet map[string]string) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketTagging")
defer span.End()
if err := n.treeService.PutBucketTagging(ctx, bktInfo, tagSet); err != nil {
return err
}
@ -123,6 +139,9 @@ func (n *Layer) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo,
}
func (n *Layer) DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error {
ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucketTagging")
defer span.End()
n.cache.DeleteTagging(bucketTaggingCacheKey(bktInfo.CID))
return n.treeService.DeleteBucketTagging(ctx, bktInfo)

View file

@ -1,12 +1,14 @@
package middleware
import (
"context"
"crypto/elliptic"
"errors"
"fmt"
"net/http"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
@ -30,7 +32,9 @@ type (
Center interface {
// Authenticate validate and authenticate request.
// Must return ErrNoAuthorizationHeader if auth header is missed.
Authenticate(request *http.Request) (*Box, error)
// Authenticate uses a separate context so that the authorization
// span middleware does not contain all subsequent spans.
Authenticate(ctx context.Context, request *http.Request) (*Box, error)
}
//nolint:revive
@ -47,34 +51,38 @@ var ErrNoAuthorizationHeader = errors.New("no authorization header")
func Auth(center Center, log *zap.Logger) Func {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dkirillov marked this conversation as resolved Outdated

Typo, must be middleware.Auth

Typo, must be `middleware.Auth`
ctx := r.Context()
reqInfo := GetReqInfo(ctx)
reqCtx := r.Context()
ctx, span := tracing.StartSpanFromContext(reqCtx, "middleware.Auth")
reqInfo := GetReqInfo(reqCtx)
reqInfo.User = "anon"
box, err := center.Authenticate(r)
box, err := center.Authenticate(ctx, r)
if err != nil {
if errors.Is(err, ErrNoAuthorizationHeader) {
reqLogOrDefault(ctx, log).Debug(logs.CouldntReceiveAccessBoxForGateKeyRandomKeyWillBeUsed, zap.Error(err), logs.TagField(logs.TagDatapath))
reqLogOrDefault(reqCtx, log).Debug(logs.CouldntReceiveAccessBoxForGateKeyRandomKeyWillBeUsed, zap.Error(err), logs.TagField(logs.TagDatapath))
alexvanin marked this conversation as resolved Outdated

Is there a reason why we can't use ctx created from span? I would like to avoid multiple contexts in the function if possible.

Is there a reason why we can't use `ctx` created from span? I would like to avoid multiple contexts in the function if possible.

Specifically, in the reqLogOrDefault functions we can actually use the usual context. I made it so that it would be clearly visible where the context with the information about the span for racing is transmitted, and where the information about the tracing is not needed and the usual context is transmitted. If you think it's worth making the most of ctx with spawn, then I'll correct you.

However, it will not be possible to completely get rid of the reqCtx context in the function, because when we insert the context into the request, we should not have information about the span.

For example, if all of them use ctx:

h.ServeHTTP(w, r.WithContext(ctx))

As a result, there will be incorrect nesting of spans (See Auth and ListBuckets)
Screenshot from 2025-02-21 11-12-11.png

And if you use the context as it is done now, then the nesting of the spans is correct:
Screenshot from 2025-02-21 11-14-12.png

Specifically, in the `reqLogOrDefault` functions we can actually use the usual context. I made it so that it would be clearly visible where the context with the information about the span for racing is transmitted, and where the information about the tracing is not needed and the usual context is transmitted. If you think it's worth making the most of `ctx` with spawn, then I'll correct you. However, it will not be possible to completely get rid of the `reqCtx` context in the function, because when we insert the context [into the request](https://git.frostfs.info/r.loginov/frostfs-s3-gw/src/branch/feature/498-make_query_tracing_more_detailed/api/middleware/auth.go#L85), we should not have information about the span. For example, if all of them use `ctx`: ```go h.ServeHTTP(w, r.WithContext(ctx)) ``` As a result, there will be incorrect nesting of spans (See `Auth` and `ListBuckets`) ![Screenshot from 2025-02-21 11-12-11.png](/attachments/8fbe1b99-6be9-4d1e-827d-a3048d22228d) And if you use the context as it is done now, then the nesting of the spans is correct: ![Screenshot from 2025-02-21 11-14-12.png](/attachments/6ec88f22-bead-4213-bf43-6a88550d002f)

Oh I see. Then it makes sense.

Oh I see. Then it makes sense.
} else {
reqLogOrDefault(ctx, log).Error(logs.FailedToPassAuthentication, zap.Error(err), logs.TagField(logs.TagDatapath))
reqLogOrDefault(reqCtx, log).Error(logs.FailedToPassAuthentication, zap.Error(err), logs.TagField(logs.TagDatapath))
err = apierr.TransformToS3Error(err)
if err.(apierr.Error).ErrCode == apierr.ErrInternalError {
err = apierr.GetAPIError(apierr.ErrAccessDenied)
}
if _, wrErr := WriteErrorResponse(w, GetReqInfo(r.Context()), err); wrErr != nil {
reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr), logs.TagField(logs.TagDatapath))
reqLogOrDefault(reqCtx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr), logs.TagField(logs.TagDatapath))
}
span.End()
return
}
} else {
ctx = SetBox(ctx, box)
reqCtx = SetBox(reqCtx, box)
if box.AccessBox.Gate.BearerToken != nil {
reqInfo.User = bearer.ResolveIssuer(*box.AccessBox.Gate.BearerToken).String()
}
reqLogOrDefault(ctx, log).Debug(logs.SuccessfulAuth, zap.String("accessKeyID", box.AuthHeaders.AccessKeyID), logs.TagField(logs.TagDatapath))
reqLogOrDefault(reqCtx, log).Debug(logs.SuccessfulAuth, zap.String("accessKeyID", box.AuthHeaders.AccessKeyID), logs.TagField(logs.TagDatapath))
}
h.ServeHTTP(w, r.WithContext(ctx))
span.End()
h.ServeHTTP(w, r.WithContext(reqCtx))
})
}
}
@ -86,22 +94,26 @@ type FrostFSIDValidator interface {
func FrostfsIDValidation(frostfsID FrostFSIDValidator, log *zap.Logger) Func {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, span := tracing.StartSpanFromContext(r.Context(), "middleware.FrostfsIDValidation")
bd, err := GetBoxData(ctx)
if err != nil || bd.Gate.BearerToken == nil {
reqLogOrDefault(ctx, log).Debug(logs.AnonRequestSkipFrostfsIDValidation, logs.TagField(logs.TagDatapath))
span.End()
h.ServeHTTP(w, r)
return
}
if err = validateBearerToken(frostfsID, bd.Gate.BearerToken); err != nil {
reqLogOrDefault(ctx, log).Error(logs.FrostfsIDValidationFailed, zap.Error(err), logs.TagField(logs.TagDatapath))
if _, wrErr := WriteErrorResponse(w, GetReqInfo(r.Context()), err); wrErr != nil {
if _, wrErr := WriteErrorResponse(w, GetReqInfo(ctx), err); wrErr != nil {
r.loginov marked this conversation as resolved Outdated

Shouldn't r.Context() be used here and in policy check? Like in Auth middleware

Shouldn't `r.Context()` be used here and in policy check? Like in Auth middleware

In middleware.auth context is eventually modified and added to http.Request, which is why there should be a separation between the use of the request context and the container with information about span. In the case of middleware.Frost fs ID Validation context is not saved further in http.Request and therefore it will not affect further spans in any way. In the middleware.PolicyCheck the situation is the same.

In `middleware.auth` context is eventually modified and [added](https://git.frostfs.info/TrueCloudLab/frostfs-s3-gw/src/branch/master/api/middleware/auth.go#L77) to `http.Request`, which is why there should be a separation between the use of the request context and the container with information about span. In the case of `middleware.Frost fs ID Validation` context is not saved further in `http.Request` and therefore it will not affect further spans in any way. In the `middleware.PolicyCheck` the situation is the same.
reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr), logs.TagField(logs.TagDatapath))
}
span.End()
return
}
span.End()
h.ServeHTTP(w, r)
})
}

View file

@ -10,6 +10,7 @@ import (
"net/url"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
@ -88,32 +89,35 @@ type PolicyConfig struct {
func PolicyCheck(cfg PolicyConfig) Func {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := policyCheck(r, cfg); err != nil {
ctx, span := tracing.StartSpanFromContext(r.Context(), "middleware.PolicyCheck")
if err := policyCheck(ctx, r, cfg); err != nil {
reqLogOrDefault(ctx, cfg.Log).Error(logs.PolicyValidationFailed, zap.Error(err), logs.TagField(logs.TagDatapath))
err = apierr.TransformToS3Error(err)
if _, wrErr := WriteErrorResponse(w, GetReqInfo(ctx), err); wrErr != nil {
reqLogOrDefault(ctx, cfg.Log).Error(logs.FailedToWriteResponse, zap.Error(wrErr), logs.TagField(logs.TagDatapath))
}
span.End()
return
}
span.End()
h.ServeHTTP(w, r)
})
}
r.loginov marked this conversation as resolved Outdated

Maybe we should also use span context in determineResourceTags?

Maybe we should also use span context in `determineResourceTags`?

Yes, you are right, because there may be requests in storage.

Yes, you are right, because there may be requests in storage.
}
func policyCheck(r *http.Request, cfg PolicyConfig) error {
reqInfo := GetReqInfo(r.Context())
func policyCheck(ctx context.Context, r *http.Request, cfg PolicyConfig) error {
reqInfo := GetReqInfo(ctx)
req, userKey, userGroups, err := getPolicyRequest(r, cfg, reqInfo.RequestType, reqInfo.BucketName, reqInfo.ObjectName)
req, userKey, userGroups, err := getPolicyRequest(ctx, r, cfg, reqInfo.RequestType, reqInfo.BucketName, reqInfo.ObjectName)
if err != nil {
return err
}
var bktInfo *data.BucketInfo
if reqInfo.RequestType != noneType && !strings.HasSuffix(req.Operation(), CreateBucketOperation) {
bktInfo, err = cfg.BucketResolver(r.Context(), reqInfo.BucketName)
bktInfo, err = cfg.BucketResolver(ctx, reqInfo.BucketName)
if err != nil {
return err
}
@ -161,7 +165,7 @@ func policyCheck(r *http.Request, cfg PolicyConfig) error {
return nil
}
func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktName string, objName string) (*testutil.Request, *keys.PublicKey, []string, error) {
func getPolicyRequest(ctx context.Context, r *http.Request, cfg PolicyConfig, reqType ReqType, bktName string, objName string) (*testutil.Request, *keys.PublicKey, []string, error) {
var (
owner string
groups []string
@ -169,7 +173,6 @@ func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktNam
pk *keys.PublicKey
)
ctx := r.Context()
bd, err := GetBoxData(ctx)
if err == nil && bd.Gate.BearerToken != nil {
alexvanin marked this conversation as resolved Outdated

And also here, do we really need to take box data out of request context instead of using regular context?

And also here, do we really need to take box data out of request context instead of using regular context?

It's really not necessary to use the context of the request here, I corrected it.

It's really not necessary to use the context of the request here, I corrected it.
pk, err = keys.NewPublicKeyFromBytes(bd.Gate.BearerToken.SigningKeyBytes(), elliptic.P256())
@ -193,7 +196,7 @@ func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktNam
res = fmt.Sprintf(s3.ResourceFormatS3Bucket, bktName)
}
requestProps, resourceProps, err := determineProperties(r, cfg.Decoder, cfg.BucketResolver, cfg.Tagging, reqType, op, bktName, objName, owner, groups, tags)
requestProps, resourceProps, err := determineProperties(ctx, r, cfg.Decoder, cfg.BucketResolver, cfg.Tagging, reqType, op, bktName, objName, owner, groups, tags)
if err != nil {
return nil, nil, nil, fmt.Errorf("determine properties: %w", err)
}
@ -420,7 +423,7 @@ func determineGeneralOperation(r *http.Request) string {
return "UnmatchedOperation"
}
func determineProperties(r *http.Request, decoder XMLDecoder, resolver BucketResolveFunc, tagging ResourceTagging, reqType ReqType,
func determineProperties(ctx context.Context, r *http.Request, decoder XMLDecoder, resolver BucketResolveFunc, tagging ResourceTagging, reqType ReqType,
op, bktName, objName, owner string, groups []string, userClaims map[string]string) (requestProperties map[string]string, resourceProperties map[string]string, err error) {
requestProperties = map[string]string{
s3.PropertyKeyOwner: owner,
@ -468,7 +471,7 @@ func determineProperties(r *http.Request, decoder XMLDecoder, resolver BucketRes
requestProperties[k] = v
}
resourceProperties, err = determineResourceTags(r.Context(), reqType, op, bktName, objName, queries.Get(QueryVersionID), resolver, tagging)
resourceProperties, err = determineResourceTags(ctx, reqType, op, bktName, objName, queries.Get(QueryVersionID), resolver, tagging)
if err != nil {
return nil, nil, fmt.Errorf("determine resource tags: %w", err)
}

View file

@ -45,7 +45,7 @@ type centerMock struct {
key *keys.PrivateKey
}
func (c *centerMock) Authenticate(*http.Request) (*middleware.Box, error) {
func (c *centerMock) Authenticate(context.Context, *http.Request) (*middleware.Box, error) {
if c.noAuthHeader {
return nil, middleware.ErrNoAuthorizationHeader
}

2
go.mod
View file

@ -4,7 +4,7 @@ go 1.22
require (
git.frostfs.info/TrueCloudLab/frostfs-contract v0.20.1-0.20241022094040-5f956751d48b
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241125133852-37bd75821121
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250130095343-593dd77d841a
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240822104152-a3bc3099bd5b

4
go.sum
View file

@ -40,10 +40,10 @@ git.frostfs.info/TrueCloudLab/frostfs-contract v0.20.1-0.20241022094040-5f956751
git.frostfs.info/TrueCloudLab/frostfs-contract v0.20.1-0.20241022094040-5f956751d48b/go.mod h1:5fSm/l5xSjGWqsPUffSdboiGFUHa7y/1S0fvxzQowN8=
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSVCB8JNSfPG7Uk4r2oSk=
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0/go.mod h1:RUIKZATQLJ+TaYQa60X2fTDwfuhMfm8Ar60bQ5fr+vU=
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88 h1:9bvBDLApbbO5sXBKdODpE9tzy3HV99nXxkDWNn22rdI=
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88/go.mod h1:kbwB4v2o6RyOfCo9kEFeUDZIX3LKhmS0yXPrtvzkQ1g=
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250130095343-593dd77d841a h1:Ud+3zz4WP9HPxEQxDPJZPpiPdm30nDNSKucsWP9L54M=
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250130095343-593dd77d841a/go.mod h1:aQpPWfG8oyfJ2X+FenPTJpSRWZjwcP5/RAtkW+/VEX8=
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241125133852-37bd75821121 h1:/Z8DfbLZXp7exUQWUKoG/9tbFdI9d5lV1qSReaYoG8I=
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241125133852-37bd75821121/go.mod h1:kbwB4v2o6RyOfCo9kEFeUDZIX3LKhmS0yXPrtvzkQ1g=
git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc=
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972 h1:/960fWeyn2AFHwQUwDsWB3sbP6lTEnFnMzLMM6tx6N8=

View file

@ -9,6 +9,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/util"
@ -57,6 +58,9 @@ func NewFrostFS(p *pool.Pool, key *keys.PrivateKey) *FrostFS {
// TimeToEpoch implements layer.FrostFS interface method.
func (x *FrostFS) TimeToEpoch(ctx context.Context, now, futureTime time.Time) (uint64, uint64, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.TimeToEpoch")
defer span.End()
if futureTime.Before(now) {
return 0, 0, fmt.Errorf("time '%s' must be in the future (after %s)",
futureTime.Format(time.RFC3339), now.Format(time.RFC3339))
@ -77,6 +81,9 @@ func (x *FrostFS) TimeToEpoch(ctx context.Context, now, futureTime time.Time) (u
// Container implements layer.FrostFS interface method.
func (x *FrostFS) Container(ctx context.Context, layerPrm frostfs.PrmContainer) (*container.Container, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.Container")
defer span.End()
prm := pool.PrmContainerGet{
ContainerID: layerPrm.ContainerID,
Session: layerPrm.SessionToken,
@ -92,6 +99,9 @@ func (x *FrostFS) Container(ctx context.Context, layerPrm frostfs.PrmContainer)
// CreateContainer implements layer.FrostFS interface method.
func (x *FrostFS) CreateContainer(ctx context.Context, prm frostfs.PrmContainerCreate) (*frostfs.ContainerCreateResult, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.CreateContainer")
defer span.End()
var cnr container.Container
cnr.Init()
cnr.SetPlacementPolicy(prm.Policy)
@ -139,6 +149,9 @@ func (x *FrostFS) CreateContainer(ctx context.Context, prm frostfs.PrmContainerC
// AddContainerPolicyChain implements frostfs.FrostFS interface method.
func (x *FrostFS) AddContainerPolicyChain(ctx context.Context, prm frostfs.PrmAddContainerPolicyChain) error {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.AddContainerPolicyChain")
defer span.End()
data, err := prm.Chain.MarshalBinary()
if err != nil {
return err
@ -158,6 +171,9 @@ func (x *FrostFS) AddContainerPolicyChain(ctx context.Context, prm frostfs.PrmAd
// UserContainers implements layer.FrostFS interface method.
func (x *FrostFS) UserContainers(ctx context.Context, layerPrm frostfs.PrmUserContainers) ([]cid.ID, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.UserContainers")
defer span.End()
prm := pool.PrmContainerList{
OwnerID: layerPrm.UserID,
Session: layerPrm.SessionToken,
@ -169,6 +185,9 @@ func (x *FrostFS) UserContainers(ctx context.Context, layerPrm frostfs.PrmUserCo
// DeleteContainer implements layer.FrostFS interface method.
func (x *FrostFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.Container) error {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.DeleteContainer")
defer span.End()
prm := pool.PrmContainerDelete{ContainerID: id, Session: token, WaitParams: &x.await}
err := x.pool.DeleteContainer(ctx, prm)
@ -177,6 +196,9 @@ func (x *FrostFS) DeleteContainer(ctx context.Context, id cid.ID, token *session
// CreateObject implements layer.FrostFS interface method.
func (x *FrostFS) CreateObject(ctx context.Context, prm frostfs.PrmObjectCreate) (*frostfs.CreateObjectResult, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.CreateObject")
defer span.End()
attrNum := len(prm.Attributes) + 1 // + creation time
if prm.Filepath != "" {
@ -271,6 +293,9 @@ func (x payloadReader) Read(p []byte) (int, error) {
// HeadObject implements layer.FrostFS interface method.
func (x *FrostFS) HeadObject(ctx context.Context, prm frostfs.PrmObjectHead) (*object.Object, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.HeadObject")
defer span.End()
var addr oid.Address
addr.SetContainer(prm.Container)
addr.SetObject(prm.Object)
@ -294,6 +319,9 @@ func (x *FrostFS) HeadObject(ctx context.Context, prm frostfs.PrmObjectHead) (*o
// GetObject implements layer.FrostFS interface method.
func (x *FrostFS) GetObject(ctx context.Context, prm frostfs.PrmObjectGet) (*frostfs.Object, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.GetObject")
defer span.End()
var addr oid.Address
addr.SetContainer(prm.Container)
addr.SetObject(prm.Object)
@ -320,6 +348,9 @@ func (x *FrostFS) GetObject(ctx context.Context, prm frostfs.PrmObjectGet) (*fro
// RangeObject implements layer.FrostFS interface method.
func (x *FrostFS) RangeObject(ctx context.Context, prm frostfs.PrmObjectRange) (io.ReadCloser, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.RangeObject")
defer span.End()
var addr oid.Address
addr.SetContainer(prm.Container)
addr.SetObject(prm.Object)
@ -345,6 +376,9 @@ func (x *FrostFS) RangeObject(ctx context.Context, prm frostfs.PrmObjectRange) (
// DeleteObject implements layer.FrostFS interface method.
func (x *FrostFS) DeleteObject(ctx context.Context, prm frostfs.PrmObjectDelete) error {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.DeleteObject")
defer span.End()
var addr oid.Address
addr.SetContainer(prm.Container)
addr.SetObject(prm.Object)
@ -364,6 +398,9 @@ func (x *FrostFS) DeleteObject(ctx context.Context, prm frostfs.PrmObjectDelete)
// SearchObjects implements layer.FrostFS interface method.
func (x *FrostFS) SearchObjects(ctx context.Context, prm frostfs.PrmObjectSearch) ([]oid.ID, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.SearchObjects")
defer span.End()
filters := object.NewSearchFilters()
filters.AddRootFilter()
@ -401,6 +438,9 @@ func (x *FrostFS) SearchObjects(ctx context.Context, prm frostfs.PrmObjectSearch
// NetworkInfo implements layer.FrostFS interface method.
func (x *FrostFS) NetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.NetworkInfo")
defer span.End()
ni, err := x.pool.NetworkInfo(ctx)
if err != nil {
return ni, handleObjectError("get network info via connection pool", err)
@ -410,6 +450,9 @@ func (x *FrostFS) NetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) {
}
func (x *FrostFS) NetmapSnapshot(ctx context.Context) (netmap.NetMap, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.NetmapSnapshot")
defer span.End()
netmapSnapshot, err := x.pool.NetMapSnapshot(ctx)
if err != nil {
return netmapSnapshot, handleObjectError("get netmap via connection pool", err)
@ -419,6 +462,9 @@ func (x *FrostFS) NetmapSnapshot(ctx context.Context) (netmap.NetMap, error) {
}
func (x *FrostFS) PatchObject(ctx context.Context, prm frostfs.PrmObjectPatch) (oid.ID, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.PatchObject")
defer span.End()
var addr oid.Address
addr.SetContainer(prm.Container)
addr.SetObject(prm.Object)
@ -467,6 +513,9 @@ func NewResolverFrostFS(p *pool.Pool) *ResolverFrostFS {
// SystemDNS implements resolver.FrostFS interface method.
func (x *ResolverFrostFS) SystemDNS(ctx context.Context) (string, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.SystemDNS")
defer span.End()
networkInfo, err := x.pool.NetworkInfo(ctx)
if err != nil {
return "", handleObjectError("read network info via client", err)

View file

@ -11,6 +11,7 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
@ -493,6 +494,9 @@ func newPartInfo(node NodeResponse) (*data.PartInfoExtended, error) {
}
func (c *Tree) GetSettingsNode(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetSettingsNode")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, settingsFileName)
if err != nil {
return nil, fmt.Errorf("couldn't get node: %w", err)
@ -523,6 +527,9 @@ func (c *Tree) GetSettingsNode(ctx context.Context, bktInfo *data.BucketInfo) (*
}
func (c *Tree) PutSettingsNode(ctx context.Context, bktInfo *data.BucketInfo, settings *data.BucketSettings) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutSettingsNode")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, settingsFileName)
isErrNotFound := errors.Is(err, tree.ErrNodeNotFound)
if err != nil && !isErrNotFound {
@ -552,6 +559,9 @@ func (c *Tree) PutSettingsNode(ctx context.Context, bktInfo *data.BucketInfo, se
}
func (c *Tree) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.Address, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetBucketCORS")
defer span.End()
node, err := c.getSystemNode(ctx, bktInfo, corsFilename)
if err != nil {
return oid.Address{}, err
@ -561,6 +571,9 @@ func (c *Tree) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid
}
func (c *Tree) PutBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, addr oid.Address) ([]oid.Address, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutBucketCORS")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, corsFilename)
isErrNotFound := errors.Is(err, tree.ErrNodeNotFound)
if err != nil && !isErrNotFound {
@ -601,6 +614,9 @@ func (c *Tree) PutBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, addr
}
func (c *Tree) DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) ([]oid.Address, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteBucketCORS")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, corsFilename)
isErrNotFound := errors.Is(err, tree.ErrNodeNotFound)
if err != nil && !isErrNotFound {
@ -658,6 +674,9 @@ func (c *Tree) cleanOldNodes(ctx context.Context, nodes []*treeNode, bktInfo *da
}
func (c *Tree) GetObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion) (map[string]string, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetObjectTagging")
defer span.End()
tagNode, err := c.getTreeNode(ctx, bktInfo, objVersion.ID, isTagKV)
if err != nil {
return nil, err
@ -683,6 +702,9 @@ func getObjectTagging(tagNode *treeNode) map[string]string {
}
func (c *Tree) PutObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion, tagSet map[string]string) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutObjectTagging")
defer span.End()
tagNode, err := c.getTreeNode(ctx, bktInfo, objVersion.ID, isTagKV)
if err != nil {
return err
@ -709,10 +731,16 @@ func (c *Tree) PutObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, o
}
func (c *Tree) DeleteObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteObjectTagging")
r.loginov marked this conversation as resolved Outdated

tree.DeleteObjectTagging

`tree.DeleteObjectTagging`
defer span.End()
return c.PutObjectTagging(ctx, bktInfo, objVersion, nil)
}
func (c *Tree) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetBucketTagging")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, bucketTaggingFilename)
if err != nil {
return nil, err
@ -730,6 +758,9 @@ func (c *Tree) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (
}
func (c *Tree) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, tagSet map[string]string) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutBucketTagging")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, bucketTaggingFilename)
isErrNotFound := errors.Is(err, tree.ErrNodeNotFound)
if err != nil && !isErrNotFound {
@ -764,6 +795,9 @@ func (c *Tree) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, t
}
func (c *Tree) DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteBucketTagging")
defer span.End()
return c.PutBucketTagging(ctx, bktInfo, nil)
}
@ -807,10 +841,16 @@ func (c *Tree) getTreeNodes(ctx context.Context, bktInfo *data.BucketInfo, nodeI
}
func (c *Tree) GetVersions(ctx context.Context, bktInfo *data.BucketInfo, filepath string) ([]*data.NodeVersion, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetVersions")
defer span.End()
return c.getVersions(ctx, bktInfo, versionTree, filepath, false)
}
func (c *Tree) GetLatestVersion(ctx context.Context, bktInfo *data.BucketInfo, objectName string) (*data.NodeVersion, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetLatestVersion")
defer span.End()
meta := []string{oidKV, isCombinedKV, isUnversionedKV, isDeleteMarkerKV, etagKV, sizeKV, md5KV, creationEpochKV}
path := pathFromName(objectName)
@ -1080,6 +1120,9 @@ func (s *VersionsByPrefixStreamImpl) parseNodeResponse(node NodeResponse) (res *
}
func (c *Tree) InitVersionsByPrefixStream(ctx context.Context, bktInfo *data.BucketInfo, prefix string, latestOnly bool) (data.VersionsStream, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.InitVersionsByPrefixStream")
defer span.End()
mainStream, tailPrefix, rootID, err := c.getSubTreeByPrefixMainStream(ctx, bktInfo, versionTree, prefix)
if err != nil {
if errors.Is(err, io.EOF) {
@ -1272,6 +1315,9 @@ func formLatestNodeKey(parentID uint64, fileName string) string {
}
func (c *Tree) GetUnversioned(ctx context.Context, bktInfo *data.BucketInfo, filepath string) (*data.NodeVersion, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetUnversioned")
defer span.End()
return c.getUnversioned(ctx, bktInfo, versionTree, filepath)
}
@ -1300,14 +1346,23 @@ func (c *Tree) getUnversioned(ctx context.Context, bktInfo *data.BucketInfo, tre
}
func (c *Tree) AddVersion(ctx context.Context, bktInfo *data.BucketInfo, version *data.NodeVersion) (uint64, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.AddVersion")
defer span.End()
return c.addVersion(ctx, bktInfo, versionTree, version)
}
func (c *Tree) RemoveVersion(ctx context.Context, bktInfo *data.BucketInfo, id uint64) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.RemoveVersion")
defer span.End()
return c.service.RemoveNode(ctx, bktInfo, versionTree, id)
}
func (c *Tree) CreateMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, info *data.MultipartInfo) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.CreateMultipartUpload")
defer span.End()
path := pathFromName(info.Key)
meta := metaFromMultipart(info, path[len(path)-1])
_, err := c.service.AddNodeByPath(ctx, bktInfo, systemTree, path[:len(path)-1], meta)
@ -1316,6 +1371,9 @@ func (c *Tree) CreateMultipartUpload(ctx context.Context, bktInfo *data.BucketIn
}
func (c *Tree) GetMultipartUploadsByPrefix(ctx context.Context, bktInfo *data.BucketInfo, prefix string) ([]*data.MultipartInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetMultipartUploadsByPrefix")
defer span.End()
subTreeNodes, headPrefix, err := c.getSubTreeByPrefix(ctx, bktInfo, systemTree, prefix, false)
if err != nil {
return nil, err
@ -1396,6 +1454,9 @@ func (c *Tree) getSubTreeMultipartUploads(ctx context.Context, bktInfo *data.Buc
}
func (c *Tree) GetMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, objectName, uploadID string) (*data.MultipartInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetMultipartUpload")
defer span.End()
path := pathFromName(objectName)
p := &GetNodesParams{
BktInfo: bktInfo,
@ -1427,6 +1488,9 @@ func (c *Tree) GetMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo,
}
func (c *Tree) AddPart(ctx context.Context, bktInfo *data.BucketInfo, multipartNodeID uint64, info *data.PartInfo) (oldObjIDsToDelete []oid.ID, err error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.AddPart")
defer span.End()
parts, err := c.service.GetSubTree(ctx, bktInfo, systemTree, []uint64{multipartNodeID}, 2, false)
if err != nil {
return nil, err
@ -1507,6 +1571,9 @@ func (c *Tree) AddPart(ctx context.Context, bktInfo *data.BucketInfo, multipartN
}
func (c *Tree) GetParts(ctx context.Context, bktInfo *data.BucketInfo, multipartNodeID uint64) ([]*data.PartInfoExtended, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetParts")
defer span.End()
parts, err := c.service.GetSubTree(ctx, bktInfo, systemTree, []uint64{multipartNodeID}, 2, false)
if err != nil {
return nil, err
@ -1541,6 +1608,9 @@ func (c *Tree) GetParts(ctx context.Context, bktInfo *data.BucketInfo, multipart
}
func (c *Tree) PutBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo, addr oid.Address) ([]oid.Address, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutBucketLifecycleConfiguration")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, bucketLifecycleFilename)
isErrNotFound := errors.Is(err, tree.ErrNodeNotFound)
if err != nil && !isErrNotFound {
@ -1581,6 +1651,9 @@ func (c *Tree) PutBucketLifecycleConfiguration(ctx context.Context, bktInfo *dat
}
func (c *Tree) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) (oid.Address, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetBucketLifecycleConfiguration")
defer span.End()
node, err := c.getSystemNode(ctx, bktInfo, bucketLifecycleFilename)
if err != nil {
return oid.Address{}, fmt.Errorf("get lifecycle node: %w", err)
@ -1590,6 +1663,9 @@ func (c *Tree) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *dat
}
func (c *Tree) DeleteBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) ([]oid.Address, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteBucketLifecycleConfiguration")
defer span.End()
multiNode, err := c.getSystemNode(ctx, bktInfo, bucketLifecycleFilename)
isErrNotFound := errors.Is(err, tree.ErrNodeNotFound)
if err != nil && !isErrNotFound {
@ -1609,6 +1685,9 @@ func (c *Tree) DeleteBucketLifecycleConfiguration(ctx context.Context, bktInfo *
}
func (c *Tree) DeleteMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, multipartInfo *data.MultipartInfo) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteMultipartUpload")
defer span.End()
err := c.service.RemoveNode(ctx, bktInfo, systemTree, multipartInfo.ID)
if err != nil {
return err
@ -1620,6 +1699,9 @@ func (c *Tree) DeleteMultipartUpload(ctx context.Context, bktInfo *data.BucketIn
}
func (c *Tree) PutLock(ctx context.Context, bktInfo *data.BucketInfo, nodeID uint64, lock *data.LockInfo) error {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutLock")
defer span.End()
meta := map[string]string{isLockKV: "true"}
if lock.IsLegalHoldSet() {
@ -1642,6 +1724,9 @@ func (c *Tree) PutLock(ctx context.Context, bktInfo *data.BucketInfo, nodeID uin
}
func (c *Tree) GetLock(ctx context.Context, bktInfo *data.BucketInfo, nodeID uint64) (*data.LockInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetLock")
defer span.End()
lockNode, err := c.getTreeNode(ctx, bktInfo, nodeID, isLockKV)
if err != nil {
return nil, err
@ -1681,6 +1766,9 @@ func getLock(lockNode *treeNode) (*data.LockInfo, error) {
}
func (c *Tree) GetObjectTaggingAndLock(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion) (map[string]string, *data.LockInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetObjectTaggingAndLock")
defer span.End()
nodes, err := c.getTreeNodes(ctx, bktInfo, objVersion.ID, isTagKV, isLockKV)
if err != nil {
return nil, nil, err