forked from TrueCloudLab/frostfs-s3-gw
Merge pull request #1 from nspcc-dev/NFSSVC-27
NFSSVC-27 Simplify ListBuckets handler
This commit is contained in:
commit
feaa52ae81
4 changed files with 49 additions and 73 deletions
1
go.mod
1
go.mod
|
@ -9,7 +9,6 @@ require (
|
||||||
github.com/Shopify/sarama v1.24.1
|
github.com/Shopify/sarama v1.24.1
|
||||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||||
github.com/alecthomas/participle v0.2.1
|
github.com/alecthomas/participle v0.2.1
|
||||||
github.com/aws/aws-sdk-go v1.33.8
|
|
||||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2
|
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2
|
||||||
github.com/beevik/ntp v0.2.0
|
github.com/beevik/ntp v0.2.0
|
||||||
github.com/cespare/xxhash/v2 v2.1.1
|
github.com/cespare/xxhash/v2 v2.1.1
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -47,8 +47,6 @@ github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQh
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310 h1:t+qxRrRtwNiUYA+Xh2jSXhoG2grnMCMKX4Fg6lx9X1U=
|
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310 h1:t+qxRrRtwNiUYA+Xh2jSXhoG2grnMCMKX4Fg6lx9X1U=
|
||||||
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
|
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
|
||||||
github.com/aws/aws-sdk-go v1.33.8 h1:2/sOfb9oPHTRZ0lxinoaTPDcYwNa1H/SpKP4nVRBwmg=
|
|
||||||
github.com/aws/aws-sdk-go v1.33.8/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
|
||||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2 h1:M+TYzBcNIRyzPRg66ndEqUMd7oWDmhvdQmaPC6EZNwM=
|
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2 h1:M+TYzBcNIRyzPRg66ndEqUMd7oWDmhvdQmaPC6EZNwM=
|
||||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2/go.mod h1:RDu/qcrnpEdJC/p8tx34+YBFqqX71lB7dOX9QE+ZC4M=
|
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2/go.mod h1:RDu/qcrnpEdJC/p8tx34+YBFqqX71lB7dOX9QE+ZC4M=
|
||||||
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
||||||
|
@ -261,8 +259,6 @@ github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7V
|
||||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
||||||
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03 h1:FUwcHNlEqkqLjLBdCp5PRlCFijNjvcYANOZXzCfXwCM=
|
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03 h1:FUwcHNlEqkqLjLBdCp5PRlCFijNjvcYANOZXzCfXwCM=
|
||||||
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
|
||||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
|
||||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
@ -401,7 +397,6 @@ github.com/nspcc-dev/hrw v1.0.8 h1:vwRuJXZXgkMvf473vFzeWGCfY1WBVeSHAEHvR4u3/Cg=
|
||||||
github.com/nspcc-dev/hrw v1.0.8/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
|
github.com/nspcc-dev/hrw v1.0.8/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
|
||||||
github.com/nspcc-dev/neofs-api-go v1.2.0 h1:8vovd8hvnoWS4qkSa6rhyMFLFvjLtNKar5vYRodf+y4=
|
github.com/nspcc-dev/neofs-api-go v1.2.0 h1:8vovd8hvnoWS4qkSa6rhyMFLFvjLtNKar5vYRodf+y4=
|
||||||
github.com/nspcc-dev/neofs-api-go v1.2.0/go.mod h1:2tf31g2Ns/Z2ev5d8LZ/9f1VHIeY5LHpDbq4EsDhYM0=
|
github.com/nspcc-dev/neofs-api-go v1.2.0/go.mod h1:2tf31g2Ns/Z2ev5d8LZ/9f1VHIeY5LHpDbq4EsDhYM0=
|
||||||
github.com/nspcc-dev/neofs-api-go v1.3.0 h1:w0wYIXzPJIElwhqahnQw/1NKiHxjRZKJhDUMSbEHmdk=
|
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
|
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
||||||
github.com/nspcc-dev/netmap v1.7.0 h1:ak64xn/gPdgYw4tsqSSF7kAGQGbEpeuJEF3XwBX4L9Y=
|
github.com/nspcc-dev/netmap v1.7.0 h1:ak64xn/gPdgYw4tsqSSF7kAGQGbEpeuJEF3XwBX4L9Y=
|
||||||
|
@ -604,7 +599,6 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
|
|
@ -25,6 +25,7 @@ type (
|
||||||
|
|
||||||
// Bucket container for bucket metadata
|
// Bucket container for bucket metadata
|
||||||
Bucket struct {
|
Bucket struct {
|
||||||
|
CID refs.CID `xml:"-"` // ignored by response
|
||||||
Name string
|
Name string
|
||||||
CreationDate string // time string of format "2006-01-02T15:04:05.000Z"
|
CreationDate string // time string of format "2006-01-02T15:04:05.000Z"
|
||||||
}
|
}
|
||||||
|
@ -43,7 +44,6 @@ type (
|
||||||
|
|
||||||
cnrInfoParams struct {
|
cnrInfoParams struct {
|
||||||
cid refs.CID
|
cid refs.CID
|
||||||
con *grpc.ClientConn
|
|
||||||
tkn *service.BearerTokenMsg
|
tkn *service.BearerTokenMsg
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -51,6 +51,7 @@ type (
|
||||||
func (h *handler) getContainerInfo(ctx context.Context, p cnrInfoParams) (*Bucket, error) {
|
func (h *handler) getContainerInfo(ctx context.Context, p cnrInfoParams) (*Bucket, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
con *grpc.ClientConn
|
||||||
res *container.GetResponse
|
res *container.GetResponse
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -59,9 +60,11 @@ func (h *handler) getContainerInfo(ctx context.Context, p cnrInfoParams) (*Bucke
|
||||||
req.SetTTL(service.SingleForwardingTTL)
|
req.SetTTL(service.SingleForwardingTTL)
|
||||||
req.SetBearer(p.tkn)
|
req.SetBearer(p.tkn)
|
||||||
|
|
||||||
if err = service.SignRequestData(h.key, req); err != nil {
|
if con, err = h.cli.GetConnection(ctx); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not fetch connection")
|
||||||
|
} else if err = service.SignRequestData(h.key, req); err != nil {
|
||||||
return nil, errors.Wrap(err, "could not sign container info request")
|
return nil, errors.Wrap(err, "could not sign container info request")
|
||||||
} else if res, err = container.NewServiceClient(p.con).Get(ctx, req); err != nil {
|
} else if res, err = container.NewServiceClient(con).Get(ctx, req); err != nil {
|
||||||
return nil, errors.Wrap(err, "could not fetch container info")
|
return nil, errors.Wrap(err, "could not fetch container info")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,18 +73,52 @@ func (h *handler) getContainerInfo(ctx context.Context, p cnrInfoParams) (*Bucke
|
||||||
_ = res
|
_ = res
|
||||||
|
|
||||||
return &Bucket{
|
return &Bucket{
|
||||||
|
CID: p.cid,
|
||||||
Name: p.cid.String(),
|
Name: p.cid.String(),
|
||||||
CreationDate: new(time.Time).Format(time.RFC3339),
|
CreationDate: new(time.Time).Format(time.RFC3339),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
|
func (h *handler) getContainerList(ctx context.Context, tkn *service.BearerTokenMsg) ([]*Bucket, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
uid = h.uid
|
|
||||||
inf *Bucket
|
inf *Bucket
|
||||||
con *grpc.ClientConn
|
con *grpc.ClientConn
|
||||||
res *container.ListResponse
|
res *container.ListResponse
|
||||||
|
)
|
||||||
|
|
||||||
|
req := new(container.ListRequest)
|
||||||
|
req.OwnerID = tkn.OwnerID
|
||||||
|
req.SetTTL(service.SingleForwardingTTL)
|
||||||
|
req.SetBearer(tkn)
|
||||||
|
|
||||||
|
if con, err = h.cli.GetConnection(ctx); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not fetch connection")
|
||||||
|
} else if err = service.SignRequestData(h.key, req); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not sign request")
|
||||||
|
} else if res, err = container.NewServiceClient(con).List(ctx, req); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not fetch list containers")
|
||||||
|
}
|
||||||
|
|
||||||
|
params := cnrInfoParams{tkn: tkn}
|
||||||
|
result := make([]*Bucket, 0, len(res.CID))
|
||||||
|
|
||||||
|
for _, cid := range res.CID {
|
||||||
|
params.cid = cid
|
||||||
|
if inf, err = h.getContainerInfo(ctx, params); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not fetch container info")
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, inf)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
lst []*Bucket
|
||||||
tkn *service.BearerTokenMsg
|
tkn *service.BearerTokenMsg
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -102,43 +139,11 @@ func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}, r.URL)
|
}, r.URL)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
} else if lst, err = h.getContainerList(ctx, tkn); err != nil {
|
||||||
|
h.log.Error("could not fetch bearer token",
|
||||||
req := new(container.ListRequest)
|
|
||||||
req.OwnerID = uid
|
|
||||||
req.SetTTL(service.SingleForwardingTTL)
|
|
||||||
req.SetBearer(tkn)
|
|
||||||
// req.SetVersion(APIVersion) ??
|
|
||||||
|
|
||||||
if con, err = h.cli.GetConnection(ctx); err != nil {
|
|
||||||
h.log.Error("could not get connection",
|
|
||||||
zap.Error(err))
|
zap.Error(err))
|
||||||
|
|
||||||
e := api.GetAPIError(api.ErrInternalError)
|
// TODO check that error isn't gRPC error
|
||||||
|
|
||||||
api.WriteErrorResponse(ctx, w, api.Error{
|
|
||||||
Code: e.Code,
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: e.HTTPStatusCode,
|
|
||||||
}, r.URL)
|
|
||||||
|
|
||||||
return
|
|
||||||
} else if err = service.SignRequestData(h.key, req); err != nil {
|
|
||||||
h.log.Error("could not prepare request",
|
|
||||||
zap.Error(err))
|
|
||||||
|
|
||||||
e := api.GetAPIError(api.ErrInternalError)
|
|
||||||
|
|
||||||
api.WriteErrorResponse(ctx, w, api.Error{
|
|
||||||
Code: e.Code,
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: e.HTTPStatusCode,
|
|
||||||
}, r.URL)
|
|
||||||
|
|
||||||
return
|
|
||||||
} else if res, err = container.NewServiceClient(con).List(ctx, req); err != nil {
|
|
||||||
h.log.Error("could not list buckets",
|
|
||||||
zap.Error(err))
|
|
||||||
|
|
||||||
e := api.GetAPIError(api.ErrInternalError)
|
e := api.GetAPIError(api.ErrInternalError)
|
||||||
|
|
||||||
|
@ -152,33 +157,11 @@ func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &ListBucketsResponse{Owner: Owner{
|
result := &ListBucketsResponse{Owner: Owner{
|
||||||
ID: uid.String(),
|
ID: tkn.OwnerID.String(),
|
||||||
DisplayName: uid.String(),
|
DisplayName: tkn.OwnerID.String(),
|
||||||
}}
|
}}
|
||||||
|
|
||||||
params := cnrInfoParams{con: con, tkn: tkn}
|
result.Buckets.Buckets = lst
|
||||||
|
|
||||||
for _, cid := range res.CID {
|
|
||||||
// should receive each container info (??):
|
|
||||||
params.cid = cid
|
|
||||||
|
|
||||||
if inf, err = h.getContainerInfo(ctx, params); err != nil {
|
|
||||||
h.log.Error("could not fetch bucket info",
|
|
||||||
zap.Error(err))
|
|
||||||
|
|
||||||
e := api.GetAPIError(api.ErrInternalError)
|
|
||||||
|
|
||||||
api.WriteErrorResponse(ctx, w, api.Error{
|
|
||||||
Code: e.Code,
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: e.HTTPStatusCode,
|
|
||||||
}, r.URL)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Buckets.Buckets = append(result.Buckets.Buckets, inf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate response.
|
// Generate response.
|
||||||
encodedSuccessResponse := api.EncodeResponse(result)
|
encodedSuccessResponse := api.EncodeResponse(result)
|
||||||
|
|
|
@ -14,7 +14,7 @@ func AttachUserAuth(router *mux.Router, center *auth.Center, log *zap.Logger) {
|
||||||
bearerToken, err := center.AuthenticationPassed(r)
|
bearerToken, err := center.AuthenticationPassed(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to pass authentication", zap.Error(err))
|
log.Error("failed to pass authentication", zap.Error(err))
|
||||||
WriteErrorResponse(r.Context(), w, getAPIError(ErrAccessDenied), r.URL)
|
WriteErrorResponse(r.Context(), w, GetAPIError(ErrAccessDenied), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.ServeHTTP(w, r.WithContext(auth.SetBearerToken(r.Context(), bearerToken)))
|
h.ServeHTTP(w, r.WithContext(auth.SetBearerToken(r.Context(), bearerToken)))
|
||||||
|
|
Loading…
Reference in a new issue