forked from TrueCloudLab/frostfs-s3-gw
[#641] Rework CORS bucket behaviour
Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
This commit is contained in:
parent
1fac8e3ef2
commit
9edec7d573
16 changed files with 490 additions and 138 deletions
|
@ -15,9 +15,11 @@ import (
|
|||
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/crdt"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/object"
|
||||
apiobject "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/object"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
|
@ -175,24 +177,42 @@ func (n *Layer) getCORS(ctx context.Context, bkt *data.BucketInfo, decoder func(
|
|||
return cors, nil
|
||||
}
|
||||
|
||||
addr, err := n.treeService.GetBucketCORS(ctx, bkt)
|
||||
objNotFound := errors.Is(err, tree.ErrNodeNotFound)
|
||||
if err != nil && !objNotFound {
|
||||
corsVersions, err := n.getCORSVersions(ctx, bkt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if objNotFound {
|
||||
return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchCORSConfiguration), err.Error())
|
||||
}
|
||||
var (
|
||||
prmAuth frostfs.PrmAuth
|
||||
objID oid.ID
|
||||
corsBkt = bkt
|
||||
lastCORS = corsVersions.GetLast()
|
||||
)
|
||||
|
||||
var prmAuth frostfs.PrmAuth
|
||||
corsBkt := bkt
|
||||
if !addr.Container().Equals(bkt.CID) && !addr.Container().Equals(cid.ID{}) {
|
||||
corsBkt = &data.BucketInfo{CID: addr.Container()}
|
||||
if lastCORS != nil {
|
||||
prmAuth.PrivateKey = &n.gateKey.PrivateKey
|
||||
corsBkt = n.corsCnrInfo
|
||||
objID = lastCORS.ObjID
|
||||
} else {
|
||||
addr, err := n.treeService.GetBucketCORS(ctx, bkt)
|
||||
objNotFound := errors.Is(err, tree.ErrNodeNotFound)
|
||||
if err != nil && !objNotFound {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if objNotFound {
|
||||
return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchCORSConfiguration), err.Error())
|
||||
}
|
||||
|
||||
if !addr.Container().Equals(bkt.CID) && !addr.Container().Equals(cid.ID{}) {
|
||||
corsBkt = &data.BucketInfo{CID: addr.Container()}
|
||||
prmAuth.PrivateKey = &n.gateKey.PrivateKey
|
||||
}
|
||||
|
||||
objID = addr.Object()
|
||||
}
|
||||
|
||||
obj, err := n.objectGetWithAuth(ctx, corsBkt, addr.Object(), prmAuth)
|
||||
obj, err := n.objectGetWithAuth(ctx, corsBkt, objID, prmAuth)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get cors object: %w", err)
|
||||
}
|
||||
|
@ -207,6 +227,56 @@ func (n *Layer) getCORS(ctx context.Context, bkt *data.BucketInfo, decoder func(
|
|||
return cors, nil
|
||||
}
|
||||
|
||||
func (n *Layer) getCORSVersions(ctx context.Context, bkt *data.BucketInfo) (*crdt.ObjectVersions, error) {
|
||||
corsVersions, err := n.frostFS.SearchObjects(ctx, frostfs.PrmObjectSearch{
|
||||
Container: n.corsCnrInfo.CID,
|
||||
ExactAttribute: [2]string{object.AttributeFilePath, bkt.CORSObjectFilePath()},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("search cors objects: %w", err)
|
||||
}
|
||||
|
||||
versions := crdt.NewObjectVersions(bkt.CORSObjectFilePath())
|
||||
versions.SetLessFunc(func(ov1, ov2 *crdt.ObjectVersion) bool {
|
||||
versionID1, versionID2 := ov1.VersionID(), ov2.VersionID()
|
||||
timestamp1, timestamp2 := ov1.Headers[object.AttributeTimestamp], ov2.Headers[object.AttributeTimestamp]
|
||||
|
||||
if ov1.CreationEpoch != ov2.CreationEpoch {
|
||||
return ov1.CreationEpoch < ov2.CreationEpoch
|
||||
}
|
||||
|
||||
if len(timestamp1) > 0 && len(timestamp2) > 0 && timestamp1 != timestamp2 {
|
||||
unixTime1, err := strconv.ParseInt(timestamp1, 10, 64)
|
||||
if err != nil {
|
||||
return versionID1 < versionID2
|
||||
}
|
||||
|
||||
unixTime2, err := strconv.ParseInt(timestamp2, 10, 64)
|
||||
if err != nil {
|
||||
return versionID1 < versionID2
|
||||
}
|
||||
|
||||
return unixTime1 < unixTime2
|
||||
}
|
||||
|
||||
return versionID1 < versionID2
|
||||
})
|
||||
|
||||
for _, id := range corsVersions {
|
||||
objVersion, err := n.frostFS.HeadObject(ctx, frostfs.PrmObjectHead{
|
||||
Container: n.corsCnrInfo.CID,
|
||||
Object: id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("head cors object '%s': %w", id.EncodeToString(), err)
|
||||
}
|
||||
|
||||
versions.AppendVersion(crdt.NewObjectVersion(objVersion))
|
||||
}
|
||||
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
func lockObjectKey(objVersion *data.ObjectVersion) string {
|
||||
// todo reconsider forming name since versionID can be "null" or ""
|
||||
return ".lock." + objVersion.BktInfo.CID.EncodeToString() + "." + objVersion.ObjectName + "." + objVersion.VersionID
|
||||
|
@ -274,7 +344,7 @@ func (n *Layer) attributesFromLock(ctx context.Context, lock *data.ObjectLock) (
|
|||
|
||||
if expEpoch != 0 {
|
||||
result = append(result, [2]string{
|
||||
object.SysAttributeExpEpoch, strconv.FormatUint(expEpoch, 10),
|
||||
apiobject.SysAttributeExpEpoch, strconv.FormatUint(expEpoch, 10),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue