forked from TrueCloudLab/frostfs-rest-gw
[#36] Add route to list storage groups
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
e5b9fd5f5a
commit
c20eed98f9
10 changed files with 913 additions and 0 deletions
127
gen/models/storage_group_base_info.go
Normal file
127
gen/models/storage_group_base_info.go
Normal file
|
@ -0,0 +1,127 @@
|
|||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// StorageGroupBaseInfo Storage group info for listing.
|
||||
//
|
||||
// swagger:model StorageGroupBaseInfo
|
||||
type StorageGroupBaseInfo struct {
|
||||
|
||||
// address
|
||||
// Required: true
|
||||
Address *Address `json:"address"`
|
||||
|
||||
// expiration epoch
|
||||
// Required: true
|
||||
ExpirationEpoch *string `json:"expirationEpoch"`
|
||||
|
||||
// name
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this storage group base info
|
||||
func (m *StorageGroupBaseInfo) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateAddress(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateExpirationEpoch(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StorageGroupBaseInfo) validateAddress(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("address", "body", m.Address); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Address != nil {
|
||||
if err := m.Address.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("address")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("address")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StorageGroupBaseInfo) validateExpirationEpoch(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("expirationEpoch", "body", m.ExpirationEpoch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this storage group base info based on the context it is used
|
||||
func (m *StorageGroupBaseInfo) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateAddress(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StorageGroupBaseInfo) contextValidateAddress(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Address != nil {
|
||||
if err := m.Address.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("address")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("address")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *StorageGroupBaseInfo) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *StorageGroupBaseInfo) UnmarshalBinary(b []byte) error {
|
||||
var res StorageGroupBaseInfo
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
136
gen/models/storage_group_list.go
Normal file
136
gen/models/storage_group_list.go
Normal file
|
@ -0,0 +1,136 @@
|
|||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// StorageGroupList List of storage groups.
|
||||
//
|
||||
// swagger:model StorageGroupList
|
||||
type StorageGroupList struct {
|
||||
|
||||
// size
|
||||
// Required: true
|
||||
Size *int64 `json:"size"`
|
||||
|
||||
// storage groups
|
||||
// Required: true
|
||||
StorageGroups []*StorageGroupBaseInfo `json:"storageGroups"`
|
||||
}
|
||||
|
||||
// Validate validates this storage group list
|
||||
func (m *StorageGroupList) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateSize(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateStorageGroups(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StorageGroupList) validateSize(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("size", "body", m.Size); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StorageGroupList) validateStorageGroups(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("storageGroups", "body", m.StorageGroups); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.StorageGroups); i++ {
|
||||
if swag.IsZero(m.StorageGroups[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.StorageGroups[i] != nil {
|
||||
if err := m.StorageGroups[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("storageGroups" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("storageGroups" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this storage group list based on the context it is used
|
||||
func (m *StorageGroupList) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateStorageGroups(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StorageGroupList) contextValidateStorageGroups(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.StorageGroups); i++ {
|
||||
|
||||
if m.StorageGroups[i] != nil {
|
||||
if err := m.StorageGroups[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("storageGroups" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("storageGroups" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *StorageGroupList) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *StorageGroupList) UnmarshalBinary(b []byte) error {
|
||||
var res StorageGroupList
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
|
@ -524,6 +524,35 @@ func init() {
|
|||
]
|
||||
},
|
||||
"/containers/{containerId}/storagegroups": {
|
||||
"get": {
|
||||
"summary": "Find all storage groups in container.",
|
||||
"operationId": "listStorageGroups",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/signatureParam"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/signatureKeyParam"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/signatureScheme"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of storage groups.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/StorageGroupList"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"summary": "Create a new storage group in container.",
|
||||
"operationId": "putStorageGroup",
|
||||
|
@ -1602,6 +1631,44 @@ func init() {
|
|||
}
|
||||
}
|
||||
},
|
||||
"StorageGroupBaseInfo": {
|
||||
"description": "Storage group info for listing.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"address",
|
||||
"expirationEpoch"
|
||||
],
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "#/definitions/Address"
|
||||
},
|
||||
"expirationEpoch": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"StorageGroupList": {
|
||||
"description": "List of storage groups.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"size",
|
||||
"storageGroups"
|
||||
],
|
||||
"properties": {
|
||||
"size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"storageGroups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/StorageGroupBaseInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"SuccessResponse": {
|
||||
"description": "Success response.",
|
||||
"type": "object",
|
||||
|
@ -2301,6 +2368,47 @@ func init() {
|
|||
]
|
||||
},
|
||||
"/containers/{containerId}/storagegroups": {
|
||||
"get": {
|
||||
"summary": "Find all storage groups in container.",
|
||||
"operationId": "listStorageGroups",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Base64 encoded signature for bearer token.",
|
||||
"name": "X-Bearer-Signature",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Hex encoded the public part of the key that signed the bearer token.",
|
||||
"name": "X-Bearer-Signature-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use wallet connect signature scheme or native NeoFS signature.",
|
||||
"name": "walletConnect",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of storage groups.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/StorageGroupList"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"summary": "Create a new storage group in container.",
|
||||
"operationId": "putStorageGroup",
|
||||
|
@ -3466,6 +3574,44 @@ func init() {
|
|||
}
|
||||
}
|
||||
},
|
||||
"StorageGroupBaseInfo": {
|
||||
"description": "Storage group info for listing.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"address",
|
||||
"expirationEpoch"
|
||||
],
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "#/definitions/Address"
|
||||
},
|
||||
"expirationEpoch": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"StorageGroupList": {
|
||||
"description": "List of storage groups.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"size",
|
||||
"storageGroups"
|
||||
],
|
||||
"properties": {
|
||||
"size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"storageGroups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/StorageGroupBaseInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"SuccessResponse": {
|
||||
"description": "Success response.",
|
||||
"type": "object",
|
||||
|
|
|
@ -71,6 +71,9 @@ func NewFrostfsRestGwAPI(spec *loads.Document) *FrostfsRestGwAPI {
|
|||
ListContainersHandler: ListContainersHandlerFunc(func(params ListContainersParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation ListContainers has not yet been implemented")
|
||||
}),
|
||||
ListStorageGroupsHandler: ListStorageGroupsHandlerFunc(func(params ListStorageGroupsParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation ListStorageGroups has not yet been implemented")
|
||||
}),
|
||||
OptionsAuthHandler: OptionsAuthHandlerFunc(func(params OptionsAuthParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation OptionsAuth has not yet been implemented")
|
||||
}),
|
||||
|
@ -178,6 +181,8 @@ type FrostfsRestGwAPI struct {
|
|||
GetObjectInfoHandler GetObjectInfoHandler
|
||||
// ListContainersHandler sets the operation handler for the list containers operation
|
||||
ListContainersHandler ListContainersHandler
|
||||
// ListStorageGroupsHandler sets the operation handler for the list storage groups operation
|
||||
ListStorageGroupsHandler ListStorageGroupsHandler
|
||||
// OptionsAuthHandler sets the operation handler for the options auth operation
|
||||
OptionsAuthHandler OptionsAuthHandler
|
||||
// OptionsAuthBearerHandler sets the operation handler for the options auth bearer operation
|
||||
|
@ -312,6 +317,9 @@ func (o *FrostfsRestGwAPI) Validate() error {
|
|||
if o.ListContainersHandler == nil {
|
||||
unregistered = append(unregistered, "ListContainersHandler")
|
||||
}
|
||||
if o.ListStorageGroupsHandler == nil {
|
||||
unregistered = append(unregistered, "ListStorageGroupsHandler")
|
||||
}
|
||||
if o.OptionsAuthHandler == nil {
|
||||
unregistered = append(unregistered, "OptionsAuthHandler")
|
||||
}
|
||||
|
@ -486,6 +494,10 @@ func (o *FrostfsRestGwAPI) initHandlerCache() {
|
|||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/containers"] = NewListContainers(o.context, o.ListContainersHandler)
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/containers/{containerId}/storagegroups"] = NewListStorageGroups(o.context, o.ListStorageGroupsHandler)
|
||||
if o.handlers["OPTIONS"] == nil {
|
||||
o.handlers["OPTIONS"] = make(map[string]http.Handler)
|
||||
}
|
||||
|
|
71
gen/restapi/operations/list_storage_groups.go
Normal file
71
gen/restapi/operations/list_storage_groups.go
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package operations
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
|
||||
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||
)
|
||||
|
||||
// ListStorageGroupsHandlerFunc turns a function with the right signature into a list storage groups handler
|
||||
type ListStorageGroupsHandlerFunc func(ListStorageGroupsParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn ListStorageGroupsHandlerFunc) Handle(params ListStorageGroupsParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// ListStorageGroupsHandler interface for that can handle valid list storage groups params
|
||||
type ListStorageGroupsHandler interface {
|
||||
Handle(ListStorageGroupsParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewListStorageGroups creates a new http.Handler for the list storage groups operation
|
||||
func NewListStorageGroups(ctx *middleware.Context, handler ListStorageGroupsHandler) *ListStorageGroups {
|
||||
return &ListStorageGroups{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/* ListStorageGroups swagger:route GET /containers/{containerId}/storagegroups listStorageGroups
|
||||
|
||||
Find all storage groups in container.
|
||||
|
||||
*/
|
||||
type ListStorageGroups struct {
|
||||
Context *middleware.Context
|
||||
Handler ListStorageGroupsHandler
|
||||
}
|
||||
|
||||
func (o *ListStorageGroups) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
*r = *rCtx
|
||||
}
|
||||
var Params = NewListStorageGroupsParams()
|
||||
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||
if err != nil {
|
||||
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||
return
|
||||
}
|
||||
if aCtx != nil {
|
||||
*r = *aCtx
|
||||
}
|
||||
var principal *models.Principal
|
||||
if uprinc != nil {
|
||||
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||
}
|
||||
|
||||
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||
return
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
175
gen/restapi/operations/list_storage_groups_parameters.go
Normal file
175
gen/restapi/operations/list_storage_groups_parameters.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package operations
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// NewListStorageGroupsParams creates a new ListStorageGroupsParams object
|
||||
// with the default values initialized.
|
||||
func NewListStorageGroupsParams() ListStorageGroupsParams {
|
||||
|
||||
var (
|
||||
// initialize parameters with default values
|
||||
|
||||
walletConnectDefault = bool(false)
|
||||
)
|
||||
|
||||
return ListStorageGroupsParams{
|
||||
WalletConnect: &walletConnectDefault,
|
||||
}
|
||||
}
|
||||
|
||||
// ListStorageGroupsParams contains all the bound params for the list storage groups operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters listStorageGroups
|
||||
type ListStorageGroupsParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*Base64 encoded signature for bearer token.
|
||||
Required: true
|
||||
In: header
|
||||
*/
|
||||
XBearerSignature string
|
||||
/*Hex encoded the public part of the key that signed the bearer token.
|
||||
Required: true
|
||||
In: header
|
||||
*/
|
||||
XBearerSignatureKey string
|
||||
/*Base58 encoded container id.
|
||||
Required: true
|
||||
In: path
|
||||
*/
|
||||
ContainerID string
|
||||
/*Use wallet connect signature scheme or native NeoFS signature.
|
||||
In: query
|
||||
Default: false
|
||||
*/
|
||||
WalletConnect *bool
|
||||
}
|
||||
|
||||
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||
// for simple values it will use straight method calls.
|
||||
//
|
||||
// To ensure default values, the struct must have been initialized with NewListStorageGroupsParams() beforehand.
|
||||
func (o *ListStorageGroupsParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
qs := runtime.Values(r.URL.Query())
|
||||
|
||||
if err := o.bindXBearerSignature(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature")], true, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := o.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature-Key")], true, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
rContainerID, rhkContainerID, _ := route.Params.GetOK("containerId")
|
||||
if err := o.bindContainerID(rContainerID, rhkContainerID, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
qWalletConnect, qhkWalletConnect, _ := qs.GetOK("walletConnect")
|
||||
if err := o.bindWalletConnect(qWalletConnect, qhkWalletConnect, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindXBearerSignature binds and validates parameter XBearerSignature from header.
|
||||
func (o *ListStorageGroupsParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||
if !hasKey {
|
||||
return errors.Required("X-Bearer-Signature", "header", rawData)
|
||||
}
|
||||
var raw string
|
||||
if len(rawData) > 0 {
|
||||
raw = rawData[len(rawData)-1]
|
||||
}
|
||||
|
||||
// Required: true
|
||||
|
||||
if err := validate.RequiredString("X-Bearer-Signature", "header", raw); err != nil {
|
||||
return err
|
||||
}
|
||||
o.XBearerSignature = raw
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
|
||||
func (o *ListStorageGroupsParams) bindXBearerSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||
if !hasKey {
|
||||
return errors.Required("X-Bearer-Signature-Key", "header", rawData)
|
||||
}
|
||||
var raw string
|
||||
if len(rawData) > 0 {
|
||||
raw = rawData[len(rawData)-1]
|
||||
}
|
||||
|
||||
// Required: true
|
||||
|
||||
if err := validate.RequiredString("X-Bearer-Signature-Key", "header", raw); err != nil {
|
||||
return err
|
||||
}
|
||||
o.XBearerSignatureKey = raw
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindContainerID binds and validates parameter ContainerID from path.
|
||||
func (o *ListStorageGroupsParams) bindContainerID(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||
var raw string
|
||||
if len(rawData) > 0 {
|
||||
raw = rawData[len(rawData)-1]
|
||||
}
|
||||
|
||||
// Required: true
|
||||
// Parameter is provided by construction from the route
|
||||
o.ContainerID = raw
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindWalletConnect binds and validates parameter WalletConnect from query.
|
||||
func (o *ListStorageGroupsParams) bindWalletConnect(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||
var raw string
|
||||
if len(rawData) > 0 {
|
||||
raw = rawData[len(rawData)-1]
|
||||
}
|
||||
|
||||
// Required: false
|
||||
// AllowEmptyValue: false
|
||||
|
||||
if raw == "" { // empty values pass all other validations
|
||||
// Default values have been previously initialized by NewListStorageGroupsParams()
|
||||
return nil
|
||||
}
|
||||
|
||||
value, err := swag.ConvertBool(raw)
|
||||
if err != nil {
|
||||
return errors.InvalidType("walletConnect", "query", "bool", raw)
|
||||
}
|
||||
o.WalletConnect = &value
|
||||
|
||||
return nil
|
||||
}
|
102
gen/restapi/operations/list_storage_groups_responses.go
Normal file
102
gen/restapi/operations/list_storage_groups_responses.go
Normal file
|
@ -0,0 +1,102 @@
|
|||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package operations
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
|
||||
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||
)
|
||||
|
||||
// ListStorageGroupsOKCode is the HTTP code returned for type ListStorageGroupsOK
|
||||
const ListStorageGroupsOKCode int = 200
|
||||
|
||||
/*ListStorageGroupsOK List of storage groups.
|
||||
|
||||
swagger:response listStorageGroupsOK
|
||||
*/
|
||||
type ListStorageGroupsOK struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.StorageGroupList `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewListStorageGroupsOK creates ListStorageGroupsOK with default headers values
|
||||
func NewListStorageGroupsOK() *ListStorageGroupsOK {
|
||||
|
||||
return &ListStorageGroupsOK{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the list storage groups o k response
|
||||
func (o *ListStorageGroupsOK) WithPayload(payload *models.StorageGroupList) *ListStorageGroupsOK {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the list storage groups o k response
|
||||
func (o *ListStorageGroupsOK) SetPayload(payload *models.StorageGroupList) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *ListStorageGroupsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(200)
|
||||
if o.Payload != nil {
|
||||
payload := o.Payload
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ListStorageGroupsBadRequestCode is the HTTP code returned for type ListStorageGroupsBadRequest
|
||||
const ListStorageGroupsBadRequestCode int = 400
|
||||
|
||||
/*ListStorageGroupsBadRequest Bad request.
|
||||
|
||||
swagger:response listStorageGroupsBadRequest
|
||||
*/
|
||||
type ListStorageGroupsBadRequest struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.ErrorResponse `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewListStorageGroupsBadRequest creates ListStorageGroupsBadRequest with default headers values
|
||||
func NewListStorageGroupsBadRequest() *ListStorageGroupsBadRequest {
|
||||
|
||||
return &ListStorageGroupsBadRequest{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the list storage groups bad request response
|
||||
func (o *ListStorageGroupsBadRequest) WithPayload(payload *models.ErrorResponse) *ListStorageGroupsBadRequest {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the list storage groups bad request response
|
||||
func (o *ListStorageGroupsBadRequest) SetPayload(payload *models.ErrorResponse) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *ListStorageGroupsBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(400)
|
||||
if o.Payload != nil {
|
||||
payload := o.Payload
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
}
|
||||
}
|
||||
}
|
|
@ -127,7 +127,9 @@ func (a *API) Configure(api *operations.FrostfsRestGwAPI) http.Handler {
|
|||
api.PutContainerEACLHandler = operations.PutContainerEACLHandlerFunc(a.PutContainerEACL)
|
||||
api.GetContainerEACLHandler = operations.GetContainerEACLHandlerFunc(a.GetContainerEACL)
|
||||
api.ListContainersHandler = operations.ListContainersHandlerFunc(a.ListContainer)
|
||||
|
||||
api.PutStorageGroupHandler = operations.PutStorageGroupHandlerFunc(a.PutStorageGroup)
|
||||
api.ListStorageGroupsHandler = operations.ListStorageGroupsHandlerFunc(a.ListStorageGroups)
|
||||
|
||||
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
||||
if !strings.HasPrefix(s, BearerPrefix) {
|
||||
|
|
|
@ -3,8 +3,10 @@ package handlers
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
objectv2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||
"github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations"
|
||||
"github.com/nspcc-dev/neofs-rest-gw/internal/util"
|
||||
|
@ -54,6 +56,103 @@ func (a *API) PutStorageGroup(params operations.PutStorageGroupParams, principal
|
|||
return operations.NewPutStorageGroupOK().WithPayload(&resp)
|
||||
}
|
||||
|
||||
// ListStorageGroups handler that create a new storage group.
|
||||
func (a *API) ListStorageGroups(params operations.ListStorageGroupsParams, principal *models.Principal) middleware.Responder {
|
||||
ctx := params.HTTPRequest.Context()
|
||||
|
||||
cnrID, err := parseContainerID(params.ContainerID)
|
||||
if err != nil {
|
||||
resp := a.logAndGetErrorResponse("invalid container id", err)
|
||||
return operations.NewListStorageGroupsBadRequest().WithPayload(resp)
|
||||
}
|
||||
|
||||
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect)
|
||||
if err != nil {
|
||||
resp := a.logAndGetErrorResponse("invalid bearer token", err)
|
||||
return operations.NewListStorageGroupsBadRequest().WithPayload(resp)
|
||||
}
|
||||
|
||||
var filters object.SearchFilters
|
||||
filters.AddTypeFilter(object.MatchStringEqual, object.TypeStorageGroup)
|
||||
|
||||
var prm pool.PrmObjectSearch
|
||||
prm.SetContainerID(cnrID)
|
||||
prm.UseBearer(btoken)
|
||||
prm.SetFilters(filters)
|
||||
|
||||
resSearch, err := a.pool.SearchObjects(ctx, prm)
|
||||
if err != nil {
|
||||
resp := a.logAndGetErrorResponse("failed to search objects", err)
|
||||
return operations.NewListStorageGroupsBadRequest().WithPayload(resp)
|
||||
}
|
||||
|
||||
var iterateErr error
|
||||
var sgInfo *models.StorageGroupBaseInfo
|
||||
var storageGroups []*models.StorageGroupBaseInfo
|
||||
|
||||
err = resSearch.Iterate(func(id oid.ID) bool {
|
||||
if sgInfo, iterateErr = headObjectStorageGroupBaseInfo(ctx, a.pool, cnrID, id, btoken); iterateErr != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
storageGroups = append(storageGroups, sgInfo)
|
||||
return false
|
||||
})
|
||||
if err == nil {
|
||||
err = iterateErr
|
||||
}
|
||||
if err != nil {
|
||||
resp := a.logAndGetErrorResponse("failed to search storage groups", err)
|
||||
return operations.NewListStorageGroupsBadRequest().WithPayload(resp)
|
||||
}
|
||||
|
||||
resp := &models.StorageGroupList{
|
||||
Size: util.NewInteger(int64(len(storageGroups))),
|
||||
StorageGroups: storageGroups,
|
||||
}
|
||||
|
||||
return operations.NewListStorageGroupsOK().WithPayload(resp)
|
||||
}
|
||||
|
||||
func headObjectStorageGroupBaseInfo(ctx context.Context, p *pool.Pool, cnrID cid.ID, objID oid.ID, btoken bearer.Token) (*models.StorageGroupBaseInfo, error) {
|
||||
var addr oid.Address
|
||||
addr.SetContainer(cnrID)
|
||||
addr.SetObject(objID)
|
||||
|
||||
var prm pool.PrmObjectHead
|
||||
prm.SetAddress(addr)
|
||||
prm.UseBearer(btoken)
|
||||
|
||||
objInfo, err := p.HeadObject(ctx, prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("head object '%s': %w", objID.EncodeToString(), err)
|
||||
}
|
||||
|
||||
resp := &models.StorageGroupBaseInfo{
|
||||
Address: &models.Address{
|
||||
ContainerID: util.NewString(cnrID.String()),
|
||||
ObjectID: util.NewString(objID.String()),
|
||||
},
|
||||
}
|
||||
|
||||
expEpoch := "0"
|
||||
for _, attr := range objInfo.Attributes() {
|
||||
switch attr.Key() {
|
||||
case object.AttributeFileName:
|
||||
resp.Name = attr.Value()
|
||||
case objectv2.SysAttributeExpEpoch:
|
||||
if _, err = strconv.ParseUint(attr.Value(), 10, 64); err != nil {
|
||||
return nil, fmt.Errorf("invalid expiration epoch '%s': %w", attr.Value(), err)
|
||||
}
|
||||
expEpoch = attr.Value()
|
||||
}
|
||||
}
|
||||
|
||||
resp.ExpirationEpoch = &expEpoch
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (a *API) formStorageGroup(ctx context.Context, cnrID cid.ID, btoken bearer.Token, storageGroup *models.StorageGroup) (*storagegroup.StorageGroup, error) {
|
||||
members, err := a.parseStorageGroupMembers(storageGroup)
|
||||
if err != nil {
|
||||
|
|
|
@ -556,6 +556,7 @@ paths:
|
|||
description: Bad request.
|
||||
schema:
|
||||
$ref: '#/definitions/ErrorResponse'
|
||||
|
||||
/containers/{containerId}/storagegroups:
|
||||
parameters:
|
||||
- $ref: '#/parameters/containerId'
|
||||
|
@ -581,6 +582,22 @@ paths:
|
|||
description: Bad request.
|
||||
schema:
|
||||
$ref: '#/definitions/ErrorResponse'
|
||||
get:
|
||||
operationId: listStorageGroups
|
||||
summary: Find all storage groups in container.
|
||||
parameters:
|
||||
- $ref: '#/parameters/signatureParam'
|
||||
- $ref: '#/parameters/signatureKeyParam'
|
||||
- $ref: '#/parameters/signatureScheme'
|
||||
responses:
|
||||
200:
|
||||
description: List of storage groups.
|
||||
schema:
|
||||
$ref: '#/definitions/StorageGroupList'
|
||||
400:
|
||||
description: Bad request.
|
||||
schema:
|
||||
$ref: '#/definitions/ErrorResponse'
|
||||
|
||||
definitions:
|
||||
BinaryBearer:
|
||||
|
@ -1081,6 +1098,32 @@ definitions:
|
|||
required:
|
||||
- lifetime
|
||||
- members
|
||||
StorageGroupBaseInfo:
|
||||
description: Storage group info for listing.
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
address:
|
||||
$ref: '#/definitions/Address'
|
||||
expirationEpoch:
|
||||
type: string
|
||||
required:
|
||||
- address
|
||||
- expirationEpoch
|
||||
StorageGroupList:
|
||||
description: List of storage groups.
|
||||
type: object
|
||||
properties:
|
||||
size:
|
||||
type: integer
|
||||
storageGroups:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/StorageGroupBaseInfo'
|
||||
required:
|
||||
- size
|
||||
- storageGroups
|
||||
Attribute:
|
||||
description: Attribute is a pair of strings that can be attached to a container or an object.
|
||||
type: object
|
||||
|
|
Loading…
Reference in a new issue