[#301] Implement GetBucketLocation

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-01-11 15:33:09 +03:00 committed by Stanislav Bogatyrev
parent 9b14340816
commit b9f77b3d96
6 changed files with 43 additions and 21 deletions

View file

@ -17,11 +17,12 @@ const (
type (
// BucketInfo stores basic bucket data.
BucketInfo struct {
Name string
CID *cid.ID
Owner *owner.ID
Created time.Time
BasicACL uint32
Name string
CID *cid.ID
Owner *owner.ID
Created time.Time
BasicACL uint32
LocationConstraint string
}
// ObjectInfo holds S3 object data.

View file

@ -9,12 +9,18 @@ import (
func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context())
if _, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err)
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
if err != nil {
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
return
}
if err := api.EncodeToResponse(w, LocationResponse{Location: ""}); err != nil {
h.logAndSendError(w, "something went wrong", reqInfo, err)
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
return
}
if err = api.EncodeToResponse(w, LocationResponse{Location: bktInfo.LocationConstraint}); err != nil {
h.logAndSendError(w, "couldn't encode bucket location response", reqInfo, err)
}
}

View file

@ -549,6 +549,7 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
for _, placementPolicy := range policies {
if placementPolicy.LocationConstraint == createParams.LocationConstraint {
p.Policy = placementPolicy.Policy
p.LocationConstraint = createParams.LocationConstraint
break
}
}

View file

@ -26,6 +26,8 @@ type (
}
)
const locationConstraintAttr = ".s3-location-constraint"
func (n *layer) containerInfo(ctx context.Context, cid *cid.ID) (*data.BucketInfo, error) {
var (
err error
@ -70,6 +72,8 @@ func (n *layer) containerInfo(ctx context.Context, cid *cid.ID) (*data.BucketInf
}
info.Created = time.Unix(unix, 0)
case locationConstraintAttr:
info.LocationConstraint = val
}
}
@ -117,16 +121,25 @@ func (n *layer) containerList(ctx context.Context) ([]*data.BucketInfo, error) {
func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*cid.ID, error) {
var err error
bktInfo := &data.BucketInfo{
Name: p.Name,
Owner: n.Owner(ctx),
Created: time.Now(),
BasicACL: p.ACL,
Name: p.Name,
Owner: n.Owner(ctx),
Created: time.Now(),
BasicACL: p.ACL,
LocationConstraint: p.LocationConstraint,
}
cnr := container.New(
options := []container.Option{
container.WithPolicy(p.Policy),
container.WithCustomBasicACL(p.ACL),
container.WithAttribute(container.AttributeName, p.Name),
container.WithAttribute(container.AttributeTimestamp, strconv.FormatInt(bktInfo.Created.Unix(), 10)))
container.WithAttribute(container.AttributeTimestamp, strconv.FormatInt(bktInfo.Created.Unix(), 10)),
}
if p.LocationConstraint != "" {
options = append(options, container.WithAttribute(locationConstraintAttr, p.LocationConstraint))
}
cnr := container.New(options...)
container.SetNativeName(cnr, p.Name)
cnr.SetSessionToken(p.SessionToken)

View file

@ -131,11 +131,12 @@ type (
}
// CreateBucketParams stores bucket create request parameters.
CreateBucketParams struct {
Name string
ACL uint32
Policy *netmap.PlacementPolicy
EACL *eacl.Table
SessionToken *session.Token
Name string
ACL uint32
Policy *netmap.PlacementPolicy
EACL *eacl.Table
SessionToken *session.Token
LocationConstraint string
}
// PutBucketACLParams stores put bucket acl request parameters.
PutBucketACLParams struct {

View file

@ -87,7 +87,7 @@ See also `GetObject` and other method parameters.
|----|----------------------|-----------|
| 🟢 | CreateBucket | PutBucket |
| 🟢 | DeleteBucket | |
| 🔵 | GetBucketLocation | |
| 🟢 | GetBucketLocation | |
| 🟢 | HeadBucket | |
| 🟢 | ListBuckets | |
| 🔵 | PutPublicAccessBlock | |