Feature/36 frostfs storage group management #5
25 changed files with 3586 additions and 4 deletions
|
@ -135,6 +135,8 @@ func runTests(ctx context.Context, t *testing.T, key *keys.PrivateKey, version s
|
||||||
t.Run("rest put container eacl "+version, func(t *testing.T) { restContainerEACLPut(ctx, t, clientPool, owner) })
|
t.Run("rest put container eacl "+version, func(t *testing.T) { restContainerEACLPut(ctx, t, clientPool, owner) })
|
||||||
t.Run("rest get container eacl "+version, func(t *testing.T) { restContainerEACLGet(ctx, t, clientPool, cnrID) })
|
t.Run("rest get container eacl "+version, func(t *testing.T) { restContainerEACLGet(ctx, t, clientPool, cnrID) })
|
||||||
t.Run("rest list containers "+version, func(t *testing.T) { restContainerList(ctx, t, clientPool, owner, cnrID) })
|
t.Run("rest list containers "+version, func(t *testing.T) { restContainerList(ctx, t, clientPool, owner, cnrID) })
|
||||||
|
|
||||||
|
t.Run("rest manage storage group "+version, func(t *testing.T) { restManageStorageGroup(ctx, t, clientPool, owner, cnrID) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDockerContainer(ctx context.Context, t *testing.T, image string) testcontainers.Container {
|
func createDockerContainer(ctx context.Context, t *testing.T, image string) testcontainers.Container {
|
||||||
|
@ -443,6 +445,117 @@ func checkGWErrorResponse(t *testing.T, httpClient *http.Client, request *http.R
|
||||||
require.Equal(t, models.ErrorTypeGW, *resp.Type)
|
require.Equal(t, models.ErrorTypeGW, *resp.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func restManageStorageGroup(ctx context.Context, t *testing.T, clientPool *pool.Pool, owner user.ID, cnrID cid.ID) {
|
||||||
|
attributes := map[string]string{object.AttributeFileName: "someFile"}
|
||||||
|
content := []byte("content")
|
||||||
|
objID := createObject(ctx, t, clientPool, &owner, cnrID, attributes, content)
|
||||||
|
|
||||||
|
bearer := &models.Bearer{Object: getAllowedRules()}
|
||||||
|
httpClient := defaultHTTPClient()
|
||||||
|
bearerTokens := makeAuthTokenRequest(ctx, t, []*models.Bearer{bearer}, httpClient)
|
||||||
|
bearerToken := bearerTokens[0]
|
||||||
|
|
||||||
|
query := make(url.Values)
|
||||||
|
query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect))
|
||||||
|
|
||||||
|
var storageGroupAddress models.Address
|
||||||
|
storageGroupName := "my-storage-group"
|
||||||
|
t.Run("put storage group", func(t *testing.T) {
|
||||||
|
req := &models.StorageGroupPutBody{
|
||||||
|
Lifetime: util.NewInteger(10),
|
||||||
|
Members: []string{objID.EncodeToString()},
|
||||||
|
Name: storageGroupName,
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
request, err := http.NewRequest(http.MethodPut, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups?"+query.Encode(), bytes.NewReader(body))
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, &storageGroupAddress)
|
||||||
|
require.Equal(t, cnrID.EncodeToString(), *storageGroupAddress.ContainerID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("list storage groups", func(t *testing.T) {
|
||||||
|
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups?"+query.Encode(), nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
list := &models.StorageGroupList{}
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, list)
|
||||||
|
|
||||||
|
require.Equal(t, int64(1), *list.Size)
|
||||||
|
require.Equal(t, storageGroupAddress.ContainerID, list.StorageGroups[0].Address.ContainerID)
|
||||||
|
require.Equal(t, storageGroupAddress.ObjectID, list.StorageGroups[0].Address.ObjectID)
|
||||||
|
require.Equal(t, storageGroupName, list.StorageGroups[0].Name)
|
||||||
|
require.NotEmpty(t, list.StorageGroups[0].ExpirationEpoch)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("get storage group", func(t *testing.T) {
|
||||||
|
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups/"+*storageGroupAddress.ObjectID+"?"+query.Encode(), nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
group := &models.StorageGroup{}
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, group)
|
||||||
|
|
||||||
|
require.Equal(t, strconv.Itoa(len(content)), *group.Size)
|
||||||
|
require.Equal(t, storageGroupName, group.Name)
|
||||||
|
require.Equal(t, storageGroupAddress.ContainerID, group.Address.ContainerID)
|
||||||
|
require.Equal(t, storageGroupAddress.ObjectID, group.Address.ObjectID)
|
||||||
|
require.NotEmpty(t, *group.ExpirationEpoch)
|
||||||
|
require.Equal(t, []string{objID.EncodeToString()}, group.Members)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("delete storage group", func(t *testing.T) {
|
||||||
|
request, err := http.NewRequest(http.MethodDelete, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups/"+*storageGroupAddress.ObjectID+"?"+query.Encode(), nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
resp := &models.SuccessResponse{}
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, resp)
|
||||||
|
require.True(t, *resp.Success)
|
||||||
|
|
||||||
|
var sgObjID oid.ID
|
||||||
|
err = sgObjID.DecodeString(*storageGroupAddress.ObjectID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var addr oid.Address
|
||||||
|
addr.SetContainer(cnrID)
|
||||||
|
addr.SetObject(sgObjID)
|
||||||
|
|
||||||
|
var prm pool.PrmObjectHead
|
||||||
|
prm.SetAddress(addr)
|
||||||
|
|
||||||
|
_, err = clientPool.HeadObject(ctx, prm)
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllowedRules() []*models.Record {
|
||||||
|
var result []*models.Record
|
||||||
|
|
||||||
|
ops := []models.Operation{models.OperationGET, models.OperationHEAD, models.OperationPUT,
|
||||||
|
models.OperationDELETE, models.OperationSEARCH, models.OperationRANGE, models.OperationRANGEHASH}
|
||||||
|
|
||||||
|
for _, op := range ops {
|
||||||
|
rec := &models.Record{
|
||||||
|
Operation: models.NewOperation(op),
|
||||||
|
Action: models.NewAction(models.ActionALLOW),
|
||||||
|
Filters: []*models.Filter{},
|
||||||
|
Targets: []*models.Target{{
|
||||||
|
Role: models.NewRole(models.RoleOTHERS),
|
||||||
|
Keys: []string{},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
result = append(result, rec)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID) {
|
func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID) {
|
||||||
bearer := &models.Bearer{
|
bearer := &models.Bearer{
|
||||||
Object: []*models.Record{{
|
Object: []*models.Record{{
|
||||||
|
@ -1282,7 +1395,7 @@ func createContainer(ctx context.Context, t *testing.T, clientPool *pool.Pool, o
|
||||||
|
|
||||||
var waitPrm pool.WaitParams
|
var waitPrm pool.WaitParams
|
||||||
waitPrm.SetPollInterval(3 * time.Second)
|
waitPrm.SetPollInterval(3 * time.Second)
|
||||||
waitPrm.SetTimeout(15 * time.Second)
|
waitPrm.SetTimeout(30 * time.Second)
|
||||||
|
|
||||||
var prm pool.PrmContainerPut
|
var prm pool.PrmContainerPut
|
||||||
prm.SetContainer(cnr)
|
prm.SetContainer(cnr)
|
||||||
|
@ -1335,7 +1448,7 @@ func restrictByEACL(ctx context.Context, t *testing.T, clientPool *pool.Pool, cn
|
||||||
|
|
||||||
var waitPrm pool.WaitParams
|
var waitPrm pool.WaitParams
|
||||||
waitPrm.SetPollInterval(3 * time.Second)
|
waitPrm.SetPollInterval(3 * time.Second)
|
||||||
waitPrm.SetTimeout(15 * time.Second)
|
waitPrm.SetTimeout(30 * time.Second)
|
||||||
|
|
||||||
var prm pool.PrmContainerSetEACL
|
var prm pool.PrmContainerSetEACL
|
||||||
prm.SetTable(*table)
|
prm.SetTable(*table)
|
||||||
|
|
166
gen/models/storage_group.go
Normal file
166
gen/models/storage_group.go
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StorageGroup Storage group keeps verification information for Data Audit sessions.
|
||||||
|
// Example: {"address":{"containerId":"5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv","objectId":"9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"},"expirationEpoch":5000,"members":["8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"],"name":"my-storage-group","size":4096}
|
||||||
|
//
|
||||||
|
// swagger:model StorageGroup
|
||||||
|
type StorageGroup struct {
|
||||||
|
|
||||||
|
// Address of storage group object. Set by server.
|
||||||
|
// Required: true
|
||||||
|
// Read Only: true
|
||||||
|
Address *Address `json:"address"`
|
||||||
|
|
||||||
|
// Expiration epoch of storage group.
|
||||||
|
// Required: true
|
||||||
|
ExpirationEpoch *string `json:"expirationEpoch"`
|
||||||
|
|
||||||
|
// Homomorphic hash from the concatenation of the payloads of the storage group members. Empty means hashing is disabled.
|
||||||
|
Hash string `json:"hash,omitempty"`
|
||||||
|
|
||||||
|
// Object identifiers to be placed into storage group. Must be unique.
|
||||||
|
// Required: true
|
||||||
|
Members []string `json:"members"`
|
||||||
|
|
||||||
|
// Name of storage group. It will be the value of the `FileName` attribute in storage group object.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// Total size of the payloads of objects in the storage group.
|
||||||
|
// Required: true
|
||||||
|
Size *string `json:"size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates this storage group
|
||||||
|
func (m *StorageGroup) 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 err := m.validateMembers(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateSize(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StorageGroup) 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 *StorageGroup) validateExpirationEpoch(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("expirationEpoch", "body", m.ExpirationEpoch); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StorageGroup) validateMembers(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("members", "body", m.Members); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StorageGroup) validateSize(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("size", "body", m.Size); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextValidate validate this storage group based on the context it is used
|
||||||
|
func (m *StorageGroup) 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 *StorageGroup) 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 *StorageGroup) MarshalBinary() ([]byte, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return swag.WriteJSON(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary interface implementation
|
||||||
|
func (m *StorageGroup) UnmarshalBinary(b []byte) error {
|
||||||
|
var res StorageGroup
|
||||||
|
if err := swag.ReadJSON(b, &res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = res
|
||||||
|
return nil
|
||||||
|
}
|
128
gen/models/storage_group_base_info.go
Normal file
128
gen/models/storage_group_base_info.go
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
// 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.
|
||||||
|
// Example: {"address":{"containerId":"5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv","objectId":"9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"},"expirationEpoch":5000,"name":"my-storage-group"}
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
}
|
137
gen/models/storage_group_list.go
Normal file
137
gen/models/storage_group_list.go
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// 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.
|
||||||
|
// Example: {"size":1,"storageGroups":[{"address":{"containerId":"5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv","objectId":"9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"},"expirationEpoch":5000,"name":"my-storage-group"}]}
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
}
|
92
gen/models/storage_group_put_body.go
Normal file
92
gen/models/storage_group_put_body.go
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StorageGroupPutBody storage group put body
|
||||||
|
// Example: {"lifetime":100,"members":["8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"],"name":"my-storage-group"}
|
||||||
|
//
|
||||||
|
// swagger:model StorageGroupPutBody
|
||||||
|
type StorageGroupPutBody struct {
|
||||||
|
|
||||||
|
// Lifetime in epochs for storage group.
|
||||||
|
// Required: true
|
||||||
|
Lifetime *int64 `json:"lifetime"`
|
||||||
|
|
||||||
|
// Object identifiers to be placed into storage group. Must be unique.
|
||||||
|
// Required: true
|
||||||
|
Members []string `json:"members"`
|
||||||
|
|
||||||
|
// Name of storage group. It will be the value of the `FileName` attribute in storage group object.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates this storage group put body
|
||||||
|
func (m *StorageGroupPutBody) Validate(formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.validateLifetime(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateMembers(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StorageGroupPutBody) validateLifetime(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("lifetime", "body", m.Lifetime); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StorageGroupPutBody) validateMembers(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("members", "body", m.Members); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextValidate validates this storage group put body based on context it is used
|
||||||
|
func (m *StorageGroupPutBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary interface implementation
|
||||||
|
func (m *StorageGroupPutBody) MarshalBinary() ([]byte, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return swag.WriteJSON(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary interface implementation
|
||||||
|
func (m *StorageGroupPutBody) UnmarshalBinary(b []byte) error {
|
||||||
|
var res StorageGroupPutBody
|
||||||
|
if err := swag.ReadJSON(b, &res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = res
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -523,6 +523,160 @@ 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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/fullBearerToken"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureKeyParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureScheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/fullBearerToken"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Storage group co create.",
|
||||||
|
"name": "storageGroup",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/StorageGroupPutBody"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Address of uploaded storage group.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/containerId"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/containers/{containerId}/storagegroups/{storageGroupId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Get storage group info.",
|
||||||
|
"operationId": "getStorageGroup",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureKeyParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureScheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/fullBearerToken"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Storage group information.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/StorageGroup"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"summary": "Delete storage group from container.",
|
||||||
|
"operationId": "deleteStorageGroup",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureKeyParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureScheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/fullBearerToken"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful deletion.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/SuccessResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/containerId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/storageGroupId"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"/objects": {
|
"/objects": {
|
||||||
"put": {
|
"put": {
|
||||||
"consumes": [
|
"consumes": [
|
||||||
|
@ -1522,6 +1676,148 @@ func init() {
|
||||||
"MatchCommonPrefix"
|
"MatchCommonPrefix"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"StorageGroup": {
|
||||||
|
"description": "Storage group keeps verification information for Data Audit sessions.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"address",
|
||||||
|
"expirationEpoch",
|
||||||
|
"size",
|
||||||
|
"members"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"description": "Address of storage group object. Set by server.",
|
||||||
|
"$ref": "#/definitions/Address",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
"expirationEpoch": {
|
||||||
|
"description": "Expiration epoch of storage group.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"hash": {
|
||||||
|
"description": "Homomorphic hash from the concatenation of the payloads of the storage group members. Empty means hashing is disabled.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"description": "Object identifiers to be placed into storage group. Must be unique.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Name of storage group. It will be the value of the ` + "`" + `FileName` + "`" + ` attribute in storage group object.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"description": "Total size of the payloads of objects in the storage group.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"address": {
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
},
|
||||||
|
"expirationEpoch": 5000,
|
||||||
|
"members": [
|
||||||
|
"8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
],
|
||||||
|
"name": "my-storage-group",
|
||||||
|
"size": 4096
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StorageGroupBaseInfo": {
|
||||||
|
"description": "Storage group info for listing.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"address",
|
||||||
|
"expirationEpoch"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
},
|
||||||
|
"expirationEpoch": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"address": {
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
},
|
||||||
|
"expirationEpoch": 5000,
|
||||||
|
"name": "my-storage-group"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StorageGroupList": {
|
||||||
|
"description": "List of storage groups.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"size",
|
||||||
|
"storageGroups"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"size": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"storageGroups": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/StorageGroupBaseInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"size": 1,
|
||||||
|
"storageGroups": [
|
||||||
|
{
|
||||||
|
"address": {
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
},
|
||||||
|
"expirationEpoch": 5000,
|
||||||
|
"name": "my-storage-group"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StorageGroupPutBody": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"lifetime",
|
||||||
|
"members"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"lifetime": {
|
||||||
|
"description": "Lifetime in epochs for storage group.",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"description": "Object identifiers to be placed into storage group. Must be unique.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Name of storage group. It will be the value of the ` + "`" + `FileName` + "`" + ` attribute in storage group object.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"lifetime": 100,
|
||||||
|
"members": [
|
||||||
|
"8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
],
|
||||||
|
"name": "my-storage-group"
|
||||||
|
}
|
||||||
|
},
|
||||||
"SuccessResponse": {
|
"SuccessResponse": {
|
||||||
"description": "Success response.",
|
"description": "Success response.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -1649,6 +1945,13 @@ func init() {
|
||||||
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
||||||
"name": "walletConnect",
|
"name": "walletConnect",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
"storageGroupId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base58 encoded storage group id.",
|
||||||
|
"name": "storageGroupId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
|
@ -2220,6 +2523,228 @@ 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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Hex encoded the public part of the key that signed the bearer token.",
|
||||||
|
"name": "X-Bearer-Signature-Key",
|
||||||
|
"in": "header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
||||||
|
"name": "walletConnect",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Provided bearer token is final or gate should assemble it using signature.",
|
||||||
|
"name": "fullBearer",
|
||||||
|
"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",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base64 encoded signature for bearer token.",
|
||||||
|
"name": "X-Bearer-Signature",
|
||||||
|
"in": "header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Hex encoded the public part of the key that signed the bearer token.",
|
||||||
|
"name": "X-Bearer-Signature-Key",
|
||||||
|
"in": "header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
||||||
|
"name": "walletConnect",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Provided bearer token is final or gate should assemble it using signature.",
|
||||||
|
"name": "fullBearer",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Storage group co create.",
|
||||||
|
"name": "storageGroup",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/StorageGroupPutBody"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Address of uploaded storage group.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base58 encoded container id.",
|
||||||
|
"name": "containerId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/containers/{containerId}/storagegroups/{storageGroupId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Get storage group info.",
|
||||||
|
"operationId": "getStorageGroup",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base64 encoded signature for bearer token.",
|
||||||
|
"name": "X-Bearer-Signature",
|
||||||
|
"in": "header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Hex encoded the public part of the key that signed the bearer token.",
|
||||||
|
"name": "X-Bearer-Signature-Key",
|
||||||
|
"in": "header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
||||||
|
"name": "walletConnect",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Provided bearer token is final or gate should assemble it using signature.",
|
||||||
|
"name": "fullBearer",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Storage group information.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/StorageGroup"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"summary": "Delete storage group from container.",
|
||||||
|
"operationId": "deleteStorageGroup",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base64 encoded signature for bearer token.",
|
||||||
|
"name": "X-Bearer-Signature",
|
||||||
|
"in": "header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Hex encoded the public part of the key that signed the bearer token.",
|
||||||
|
"name": "X-Bearer-Signature-Key",
|
||||||
|
"in": "header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
||||||
|
"name": "walletConnect",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Provided bearer token is final or gate should assemble it using signature.",
|
||||||
|
"name": "fullBearer",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful deletion.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/SuccessResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base58 encoded container id.",
|
||||||
|
"name": "containerId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base58 encoded storage group id.",
|
||||||
|
"name": "storageGroupId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"/objects": {
|
"/objects": {
|
||||||
"put": {
|
"put": {
|
||||||
"consumes": [
|
"consumes": [
|
||||||
|
@ -3290,6 +3815,148 @@ func init() {
|
||||||
"MatchCommonPrefix"
|
"MatchCommonPrefix"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"StorageGroup": {
|
||||||
|
"description": "Storage group keeps verification information for Data Audit sessions.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"address",
|
||||||
|
"expirationEpoch",
|
||||||
|
"size",
|
||||||
|
"members"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"description": "Address of storage group object. Set by server.",
|
||||||
|
"$ref": "#/definitions/Address",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
"expirationEpoch": {
|
||||||
|
"description": "Expiration epoch of storage group.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"hash": {
|
||||||
|
"description": "Homomorphic hash from the concatenation of the payloads of the storage group members. Empty means hashing is disabled.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"description": "Object identifiers to be placed into storage group. Must be unique.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Name of storage group. It will be the value of the ` + "`" + `FileName` + "`" + ` attribute in storage group object.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"description": "Total size of the payloads of objects in the storage group.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"address": {
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
},
|
||||||
|
"expirationEpoch": 5000,
|
||||||
|
"members": [
|
||||||
|
"8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
],
|
||||||
|
"name": "my-storage-group",
|
||||||
|
"size": 4096
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StorageGroupBaseInfo": {
|
||||||
|
"description": "Storage group info for listing.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"address",
|
||||||
|
"expirationEpoch"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
},
|
||||||
|
"expirationEpoch": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"address": {
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
},
|
||||||
|
"expirationEpoch": 5000,
|
||||||
|
"name": "my-storage-group"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StorageGroupList": {
|
||||||
|
"description": "List of storage groups.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"size",
|
||||||
|
"storageGroups"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"size": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"storageGroups": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/StorageGroupBaseInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"size": 1,
|
||||||
|
"storageGroups": [
|
||||||
|
{
|
||||||
|
"address": {
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
},
|
||||||
|
"expirationEpoch": 5000,
|
||||||
|
"name": "my-storage-group"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StorageGroupPutBody": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"lifetime",
|
||||||
|
"members"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"lifetime": {
|
||||||
|
"description": "Lifetime in epochs for storage group.",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"description": "Object identifiers to be placed into storage group. Must be unique.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Name of storage group. It will be the value of the ` + "`" + `FileName` + "`" + ` attribute in storage group object.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"lifetime": 100,
|
||||||
|
"members": [
|
||||||
|
"8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd"
|
||||||
|
],
|
||||||
|
"name": "my-storage-group"
|
||||||
|
}
|
||||||
|
},
|
||||||
"SuccessResponse": {
|
"SuccessResponse": {
|
||||||
"description": "Success response.",
|
"description": "Success response.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -3417,6 +4084,13 @@ func init() {
|
||||||
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
"description": "Use wallet connect signature scheme or native FrostFS signature.",
|
||||||
"name": "walletConnect",
|
"name": "walletConnect",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
"storageGroupId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base58 encoded storage group id.",
|
||||||
|
"name": "storageGroupId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
|
|
71
gen/restapi/operations/delete_storage_group.go
Normal file
71
gen/restapi/operations/delete_storage_group.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/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteStorageGroupHandlerFunc turns a function with the right signature into a delete storage group handler
|
||||||
|
type DeleteStorageGroupHandlerFunc func(DeleteStorageGroupParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn DeleteStorageGroupHandlerFunc) Handle(params DeleteStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteStorageGroupHandler interface for that can handle valid delete storage group params
|
||||||
|
type DeleteStorageGroupHandler interface {
|
||||||
|
Handle(DeleteStorageGroupParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteStorageGroup creates a new http.Handler for the delete storage group operation
|
||||||
|
func NewDeleteStorageGroup(ctx *middleware.Context, handler DeleteStorageGroupHandler) *DeleteStorageGroup {
|
||||||
|
return &DeleteStorageGroup{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DeleteStorageGroup swagger:route DELETE /containers/{containerId}/storagegroups/{storageGroupId} deleteStorageGroup
|
||||||
|
|
||||||
|
Delete storage group from container.
|
||||||
|
*/
|
||||||
|
type DeleteStorageGroup struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler DeleteStorageGroupHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *DeleteStorageGroup) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
*r = *rCtx
|
||||||
|
}
|
||||||
|
var Params = NewDeleteStorageGroupParams()
|
||||||
|
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)
|
||||||
|
|
||||||
|
}
|
228
gen/restapi/operations/delete_storage_group_parameters.go
Normal file
228
gen/restapi/operations/delete_storage_group_parameters.go
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewDeleteStorageGroupParams creates a new DeleteStorageGroupParams object
|
||||||
|
// with the default values initialized.
|
||||||
|
func NewDeleteStorageGroupParams() DeleteStorageGroupParams {
|
||||||
|
|
||||||
|
var (
|
||||||
|
// initialize parameters with default values
|
||||||
|
|
||||||
|
fullBearerDefault = bool(false)
|
||||||
|
|
||||||
|
walletConnectDefault = bool(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
return DeleteStorageGroupParams{
|
||||||
|
FullBearer: &fullBearerDefault,
|
||||||
|
|
||||||
|
WalletConnect: &walletConnectDefault,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteStorageGroupParams contains all the bound params for the delete storage group operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters deleteStorageGroup
|
||||||
|
type DeleteStorageGroupParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*Base64 encoded signature for bearer token.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignature *string
|
||||||
|
/*Hex encoded the public part of the key that signed the bearer token.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignatureKey *string
|
||||||
|
/*Base58 encoded container id.
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
ContainerID string
|
||||||
|
/*Provided bearer token is final or gate should assemble it using signature.
|
||||||
|
In: query
|
||||||
|
Default: false
|
||||||
|
*/
|
||||||
|
FullBearer *bool
|
||||||
|
/*Base58 encoded storage group id.
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
StorageGroupID string
|
||||||
|
/*Use wallet connect signature scheme or native FrostFS 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 NewDeleteStorageGroupParams() beforehand.
|
||||||
|
func (o *DeleteStorageGroupParams) 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
qFullBearer, qhkFullBearer, _ := qs.GetOK("fullBearer")
|
||||||
|
if err := o.bindFullBearer(qFullBearer, qhkFullBearer, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rStorageGroupID, rhkStorageGroupID, _ := route.Params.GetOK("storageGroupId")
|
||||||
|
if err := o.bindStorageGroupID(rStorageGroupID, rhkStorageGroupID, 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 *DeleteStorageGroupParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
o.XBearerSignature = &raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
|
||||||
|
func (o *DeleteStorageGroupParams) bindXBearerSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
o.XBearerSignatureKey = &raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindContainerID binds and validates parameter ContainerID from path.
|
||||||
|
func (o *DeleteStorageGroupParams) 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindFullBearer binds and validates parameter FullBearer from query.
|
||||||
|
func (o *DeleteStorageGroupParams) bindFullBearer(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 NewDeleteStorageGroupParams()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := swag.ConvertBool(raw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InvalidType("fullBearer", "query", "bool", raw)
|
||||||
|
}
|
||||||
|
o.FullBearer = &value
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindStorageGroupID binds and validates parameter StorageGroupID from path.
|
||||||
|
func (o *DeleteStorageGroupParams) bindStorageGroupID(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.StorageGroupID = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindWalletConnect binds and validates parameter WalletConnect from query.
|
||||||
|
func (o *DeleteStorageGroupParams) 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 NewDeleteStorageGroupParams()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := swag.ConvertBool(raw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InvalidType("walletConnect", "query", "bool", raw)
|
||||||
|
}
|
||||||
|
o.WalletConnect = &value
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
104
gen/restapi/operations/delete_storage_group_responses.go
Normal file
104
gen/restapi/operations/delete_storage_group_responses.go
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// 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/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteStorageGroupOKCode is the HTTP code returned for type DeleteStorageGroupOK
|
||||||
|
const DeleteStorageGroupOKCode int = 200
|
||||||
|
|
||||||
|
/*
|
||||||
|
DeleteStorageGroupOK Successful deletion.
|
||||||
|
|
||||||
|
swagger:response deleteStorageGroupOK
|
||||||
|
*/
|
||||||
|
type DeleteStorageGroupOK struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.SuccessResponse `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteStorageGroupOK creates DeleteStorageGroupOK with default headers values
|
||||||
|
func NewDeleteStorageGroupOK() *DeleteStorageGroupOK {
|
||||||
|
|
||||||
|
return &DeleteStorageGroupOK{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the delete storage group o k response
|
||||||
|
func (o *DeleteStorageGroupOK) WithPayload(payload *models.SuccessResponse) *DeleteStorageGroupOK {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the delete storage group o k response
|
||||||
|
func (o *DeleteStorageGroupOK) SetPayload(payload *models.SuccessResponse) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *DeleteStorageGroupOK) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteStorageGroupBadRequestCode is the HTTP code returned for type DeleteStorageGroupBadRequest
|
||||||
|
const DeleteStorageGroupBadRequestCode int = 400
|
||||||
|
|
||||||
|
/*
|
||||||
|
DeleteStorageGroupBadRequest Bad request.
|
||||||
|
|
||||||
|
swagger:response deleteStorageGroupBadRequest
|
||||||
|
*/
|
||||||
|
type DeleteStorageGroupBadRequest struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.ErrorResponse `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteStorageGroupBadRequest creates DeleteStorageGroupBadRequest with default headers values
|
||||||
|
func NewDeleteStorageGroupBadRequest() *DeleteStorageGroupBadRequest {
|
||||||
|
|
||||||
|
return &DeleteStorageGroupBadRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the delete storage group bad request response
|
||||||
|
func (o *DeleteStorageGroupBadRequest) WithPayload(payload *models.ErrorResponse) *DeleteStorageGroupBadRequest {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the delete storage group bad request response
|
||||||
|
func (o *DeleteStorageGroupBadRequest) SetPayload(payload *models.ErrorResponse) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *DeleteStorageGroupBadRequest) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,6 +53,9 @@ func NewFrostfsRestGwAPI(spec *loads.Document) *FrostfsRestGwAPI {
|
||||||
DeleteObjectHandler: DeleteObjectHandlerFunc(func(params DeleteObjectParams, principal *models.Principal) middleware.Responder {
|
DeleteObjectHandler: DeleteObjectHandlerFunc(func(params DeleteObjectParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation DeleteObject has not yet been implemented")
|
return middleware.NotImplemented("operation DeleteObject has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
DeleteStorageGroupHandler: DeleteStorageGroupHandlerFunc(func(params DeleteStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation DeleteStorageGroup has not yet been implemented")
|
||||||
|
}),
|
||||||
FormBinaryBearerHandler: FormBinaryBearerHandlerFunc(func(params FormBinaryBearerParams, principal *models.Principal) middleware.Responder {
|
FormBinaryBearerHandler: FormBinaryBearerHandlerFunc(func(params FormBinaryBearerParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation FormBinaryBearer has not yet been implemented")
|
return middleware.NotImplemented("operation FormBinaryBearer has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
@ -68,9 +71,15 @@ func NewFrostfsRestGwAPI(spec *loads.Document) *FrostfsRestGwAPI {
|
||||||
GetObjectInfoHandler: GetObjectInfoHandlerFunc(func(params GetObjectInfoParams, principal *models.Principal) middleware.Responder {
|
GetObjectInfoHandler: GetObjectInfoHandlerFunc(func(params GetObjectInfoParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation GetObjectInfo has not yet been implemented")
|
return middleware.NotImplemented("operation GetObjectInfo has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
GetStorageGroupHandler: GetStorageGroupHandlerFunc(func(params GetStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation GetStorageGroup has not yet been implemented")
|
||||||
|
}),
|
||||||
ListContainersHandler: ListContainersHandlerFunc(func(params ListContainersParams) middleware.Responder {
|
ListContainersHandler: ListContainersHandlerFunc(func(params ListContainersParams) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation ListContainers has not yet been implemented")
|
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 {
|
OptionsAuthHandler: OptionsAuthHandlerFunc(func(params OptionsAuthParams) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation OptionsAuth has not yet been implemented")
|
return middleware.NotImplemented("operation OptionsAuth has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
@ -104,6 +113,9 @@ func NewFrostfsRestGwAPI(spec *loads.Document) *FrostfsRestGwAPI {
|
||||||
PutObjectHandler: PutObjectHandlerFunc(func(params PutObjectParams, principal *models.Principal) middleware.Responder {
|
PutObjectHandler: PutObjectHandlerFunc(func(params PutObjectParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation PutObject has not yet been implemented")
|
return middleware.NotImplemented("operation PutObject has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
PutStorageGroupHandler: PutStorageGroupHandlerFunc(func(params PutStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation PutStorageGroup has not yet been implemented")
|
||||||
|
}),
|
||||||
SearchObjectsHandler: SearchObjectsHandlerFunc(func(params SearchObjectsParams, principal *models.Principal) middleware.Responder {
|
SearchObjectsHandler: SearchObjectsHandlerFunc(func(params SearchObjectsParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation SearchObjects has not yet been implemented")
|
return middleware.NotImplemented("operation SearchObjects has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
@ -163,6 +175,8 @@ type FrostfsRestGwAPI struct {
|
||||||
DeleteContainerHandler DeleteContainerHandler
|
DeleteContainerHandler DeleteContainerHandler
|
||||||
// DeleteObjectHandler sets the operation handler for the delete object operation
|
// DeleteObjectHandler sets the operation handler for the delete object operation
|
||||||
DeleteObjectHandler DeleteObjectHandler
|
DeleteObjectHandler DeleteObjectHandler
|
||||||
|
// DeleteStorageGroupHandler sets the operation handler for the delete storage group operation
|
||||||
|
DeleteStorageGroupHandler DeleteStorageGroupHandler
|
||||||
// FormBinaryBearerHandler sets the operation handler for the form binary bearer operation
|
// FormBinaryBearerHandler sets the operation handler for the form binary bearer operation
|
||||||
FormBinaryBearerHandler FormBinaryBearerHandler
|
FormBinaryBearerHandler FormBinaryBearerHandler
|
||||||
// GetBalanceHandler sets the operation handler for the get balance operation
|
// GetBalanceHandler sets the operation handler for the get balance operation
|
||||||
|
@ -173,8 +187,12 @@ type FrostfsRestGwAPI struct {
|
||||||
GetContainerEACLHandler GetContainerEACLHandler
|
GetContainerEACLHandler GetContainerEACLHandler
|
||||||
// GetObjectInfoHandler sets the operation handler for the get object info operation
|
// GetObjectInfoHandler sets the operation handler for the get object info operation
|
||||||
GetObjectInfoHandler GetObjectInfoHandler
|
GetObjectInfoHandler GetObjectInfoHandler
|
||||||
|
// GetStorageGroupHandler sets the operation handler for the get storage group operation
|
||||||
|
GetStorageGroupHandler GetStorageGroupHandler
|
||||||
// ListContainersHandler sets the operation handler for the list containers operation
|
// ListContainersHandler sets the operation handler for the list containers operation
|
||||||
ListContainersHandler ListContainersHandler
|
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 sets the operation handler for the options auth operation
|
||||||
OptionsAuthHandler OptionsAuthHandler
|
OptionsAuthHandler OptionsAuthHandler
|
||||||
// OptionsAuthBearerHandler sets the operation handler for the options auth bearer operation
|
// OptionsAuthBearerHandler sets the operation handler for the options auth bearer operation
|
||||||
|
@ -197,6 +215,8 @@ type FrostfsRestGwAPI struct {
|
||||||
PutContainerEACLHandler PutContainerEACLHandler
|
PutContainerEACLHandler PutContainerEACLHandler
|
||||||
// PutObjectHandler sets the operation handler for the put object operation
|
// PutObjectHandler sets the operation handler for the put object operation
|
||||||
PutObjectHandler PutObjectHandler
|
PutObjectHandler PutObjectHandler
|
||||||
|
// PutStorageGroupHandler sets the operation handler for the put storage group operation
|
||||||
|
PutStorageGroupHandler PutStorageGroupHandler
|
||||||
// SearchObjectsHandler sets the operation handler for the search objects operation
|
// SearchObjectsHandler sets the operation handler for the search objects operation
|
||||||
SearchObjectsHandler SearchObjectsHandler
|
SearchObjectsHandler SearchObjectsHandler
|
||||||
|
|
||||||
|
@ -289,6 +309,9 @@ func (o *FrostfsRestGwAPI) Validate() error {
|
||||||
if o.DeleteObjectHandler == nil {
|
if o.DeleteObjectHandler == nil {
|
||||||
unregistered = append(unregistered, "DeleteObjectHandler")
|
unregistered = append(unregistered, "DeleteObjectHandler")
|
||||||
}
|
}
|
||||||
|
if o.DeleteStorageGroupHandler == nil {
|
||||||
|
unregistered = append(unregistered, "DeleteStorageGroupHandler")
|
||||||
|
}
|
||||||
if o.FormBinaryBearerHandler == nil {
|
if o.FormBinaryBearerHandler == nil {
|
||||||
unregistered = append(unregistered, "FormBinaryBearerHandler")
|
unregistered = append(unregistered, "FormBinaryBearerHandler")
|
||||||
}
|
}
|
||||||
|
@ -304,9 +327,15 @@ func (o *FrostfsRestGwAPI) Validate() error {
|
||||||
if o.GetObjectInfoHandler == nil {
|
if o.GetObjectInfoHandler == nil {
|
||||||
unregistered = append(unregistered, "GetObjectInfoHandler")
|
unregistered = append(unregistered, "GetObjectInfoHandler")
|
||||||
}
|
}
|
||||||
|
if o.GetStorageGroupHandler == nil {
|
||||||
|
unregistered = append(unregistered, "GetStorageGroupHandler")
|
||||||
|
}
|
||||||
if o.ListContainersHandler == nil {
|
if o.ListContainersHandler == nil {
|
||||||
unregistered = append(unregistered, "ListContainersHandler")
|
unregistered = append(unregistered, "ListContainersHandler")
|
||||||
}
|
}
|
||||||
|
if o.ListStorageGroupsHandler == nil {
|
||||||
|
unregistered = append(unregistered, "ListStorageGroupsHandler")
|
||||||
|
}
|
||||||
if o.OptionsAuthHandler == nil {
|
if o.OptionsAuthHandler == nil {
|
||||||
unregistered = append(unregistered, "OptionsAuthHandler")
|
unregistered = append(unregistered, "OptionsAuthHandler")
|
||||||
}
|
}
|
||||||
|
@ -340,6 +369,9 @@ func (o *FrostfsRestGwAPI) Validate() error {
|
||||||
if o.PutObjectHandler == nil {
|
if o.PutObjectHandler == nil {
|
||||||
unregistered = append(unregistered, "PutObjectHandler")
|
unregistered = append(unregistered, "PutObjectHandler")
|
||||||
}
|
}
|
||||||
|
if o.PutStorageGroupHandler == nil {
|
||||||
|
unregistered = append(unregistered, "PutStorageGroupHandler")
|
||||||
|
}
|
||||||
if o.SearchObjectsHandler == nil {
|
if o.SearchObjectsHandler == nil {
|
||||||
unregistered = append(unregistered, "SearchObjectsHandler")
|
unregistered = append(unregistered, "SearchObjectsHandler")
|
||||||
}
|
}
|
||||||
|
@ -454,6 +486,10 @@ func (o *FrostfsRestGwAPI) initHandlerCache() {
|
||||||
o.handlers["DELETE"] = make(map[string]http.Handler)
|
o.handlers["DELETE"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
o.handlers["DELETE"]["/objects/{containerId}/{objectId}"] = NewDeleteObject(o.context, o.DeleteObjectHandler)
|
o.handlers["DELETE"]["/objects/{containerId}/{objectId}"] = NewDeleteObject(o.context, o.DeleteObjectHandler)
|
||||||
|
if o.handlers["DELETE"] == nil {
|
||||||
|
o.handlers["DELETE"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
|
o.handlers["DELETE"]["/containers/{containerId}/storagegroups/{storageGroupId}"] = NewDeleteStorageGroup(o.context, o.DeleteStorageGroupHandler)
|
||||||
if o.handlers["GET"] == nil {
|
if o.handlers["GET"] == nil {
|
||||||
o.handlers["GET"] = make(map[string]http.Handler)
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
|
@ -477,7 +513,15 @@ func (o *FrostfsRestGwAPI) initHandlerCache() {
|
||||||
if o.handlers["GET"] == nil {
|
if o.handlers["GET"] == nil {
|
||||||
o.handlers["GET"] = make(map[string]http.Handler)
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
|
o.handlers["GET"]["/containers/{containerId}/storagegroups/{storageGroupId}"] = NewGetStorageGroup(o.context, o.GetStorageGroupHandler)
|
||||||
|
if o.handlers["GET"] == nil {
|
||||||
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
o.handlers["GET"]["/containers"] = NewListContainers(o.context, o.ListContainersHandler)
|
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 {
|
if o.handlers["OPTIONS"] == nil {
|
||||||
o.handlers["OPTIONS"] = make(map[string]http.Handler)
|
o.handlers["OPTIONS"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
|
@ -522,6 +566,10 @@ func (o *FrostfsRestGwAPI) initHandlerCache() {
|
||||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
o.handlers["PUT"]["/objects"] = NewPutObject(o.context, o.PutObjectHandler)
|
o.handlers["PUT"]["/objects"] = NewPutObject(o.context, o.PutObjectHandler)
|
||||||
|
if o.handlers["PUT"] == nil {
|
||||||
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
|
o.handlers["PUT"]["/containers/{containerId}/storagegroups"] = NewPutStorageGroup(o.context, o.PutStorageGroupHandler)
|
||||||
if o.handlers["POST"] == nil {
|
if o.handlers["POST"] == nil {
|
||||||
o.handlers["POST"] = make(map[string]http.Handler)
|
o.handlers["POST"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
|
|
71
gen/restapi/operations/get_storage_group.go
Normal file
71
gen/restapi/operations/get_storage_group.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/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetStorageGroupHandlerFunc turns a function with the right signature into a get storage group handler
|
||||||
|
type GetStorageGroupHandlerFunc func(GetStorageGroupParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn GetStorageGroupHandlerFunc) Handle(params GetStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStorageGroupHandler interface for that can handle valid get storage group params
|
||||||
|
type GetStorageGroupHandler interface {
|
||||||
|
Handle(GetStorageGroupParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetStorageGroup creates a new http.Handler for the get storage group operation
|
||||||
|
func NewGetStorageGroup(ctx *middleware.Context, handler GetStorageGroupHandler) *GetStorageGroup {
|
||||||
|
return &GetStorageGroup{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GetStorageGroup swagger:route GET /containers/{containerId}/storagegroups/{storageGroupId} getStorageGroup
|
||||||
|
|
||||||
|
Get storage group info.
|
||||||
|
*/
|
||||||
|
type GetStorageGroup struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler GetStorageGroupHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *GetStorageGroup) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
*r = *rCtx
|
||||||
|
}
|
||||||
|
var Params = NewGetStorageGroupParams()
|
||||||
|
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)
|
||||||
|
|
||||||
|
}
|
228
gen/restapi/operations/get_storage_group_parameters.go
Normal file
228
gen/restapi/operations/get_storage_group_parameters.go
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGetStorageGroupParams creates a new GetStorageGroupParams object
|
||||||
|
// with the default values initialized.
|
||||||
|
func NewGetStorageGroupParams() GetStorageGroupParams {
|
||||||
|
|
||||||
|
var (
|
||||||
|
// initialize parameters with default values
|
||||||
|
|
||||||
|
fullBearerDefault = bool(false)
|
||||||
|
|
||||||
|
walletConnectDefault = bool(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
return GetStorageGroupParams{
|
||||||
|
FullBearer: &fullBearerDefault,
|
||||||
|
|
||||||
|
WalletConnect: &walletConnectDefault,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStorageGroupParams contains all the bound params for the get storage group operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters getStorageGroup
|
||||||
|
type GetStorageGroupParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*Base64 encoded signature for bearer token.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignature *string
|
||||||
|
/*Hex encoded the public part of the key that signed the bearer token.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignatureKey *string
|
||||||
|
/*Base58 encoded container id.
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
ContainerID string
|
||||||
|
/*Provided bearer token is final or gate should assemble it using signature.
|
||||||
|
In: query
|
||||||
|
Default: false
|
||||||
|
*/
|
||||||
|
FullBearer *bool
|
||||||
|
/*Base58 encoded storage group id.
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
StorageGroupID string
|
||||||
|
/*Use wallet connect signature scheme or native FrostFS 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 NewGetStorageGroupParams() beforehand.
|
||||||
|
func (o *GetStorageGroupParams) 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
qFullBearer, qhkFullBearer, _ := qs.GetOK("fullBearer")
|
||||||
|
if err := o.bindFullBearer(qFullBearer, qhkFullBearer, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rStorageGroupID, rhkStorageGroupID, _ := route.Params.GetOK("storageGroupId")
|
||||||
|
if err := o.bindStorageGroupID(rStorageGroupID, rhkStorageGroupID, 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 *GetStorageGroupParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
o.XBearerSignature = &raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
|
||||||
|
func (o *GetStorageGroupParams) bindXBearerSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
o.XBearerSignatureKey = &raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindContainerID binds and validates parameter ContainerID from path.
|
||||||
|
func (o *GetStorageGroupParams) 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindFullBearer binds and validates parameter FullBearer from query.
|
||||||
|
func (o *GetStorageGroupParams) bindFullBearer(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 NewGetStorageGroupParams()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := swag.ConvertBool(raw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InvalidType("fullBearer", "query", "bool", raw)
|
||||||
|
}
|
||||||
|
o.FullBearer = &value
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindStorageGroupID binds and validates parameter StorageGroupID from path.
|
||||||
|
func (o *GetStorageGroupParams) bindStorageGroupID(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.StorageGroupID = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindWalletConnect binds and validates parameter WalletConnect from query.
|
||||||
|
func (o *GetStorageGroupParams) 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 NewGetStorageGroupParams()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := swag.ConvertBool(raw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InvalidType("walletConnect", "query", "bool", raw)
|
||||||
|
}
|
||||||
|
o.WalletConnect = &value
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
104
gen/restapi/operations/get_storage_group_responses.go
Normal file
104
gen/restapi/operations/get_storage_group_responses.go
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// 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/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetStorageGroupOKCode is the HTTP code returned for type GetStorageGroupOK
|
||||||
|
const GetStorageGroupOKCode int = 200
|
||||||
|
|
||||||
|
/*
|
||||||
|
GetStorageGroupOK Storage group information.
|
||||||
|
|
||||||
|
swagger:response getStorageGroupOK
|
||||||
|
*/
|
||||||
|
type GetStorageGroupOK struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.StorageGroup `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetStorageGroupOK creates GetStorageGroupOK with default headers values
|
||||||
|
func NewGetStorageGroupOK() *GetStorageGroupOK {
|
||||||
|
|
||||||
|
return &GetStorageGroupOK{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the get storage group o k response
|
||||||
|
func (o *GetStorageGroupOK) WithPayload(payload *models.StorageGroup) *GetStorageGroupOK {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the get storage group o k response
|
||||||
|
func (o *GetStorageGroupOK) SetPayload(payload *models.StorageGroup) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *GetStorageGroupOK) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStorageGroupBadRequestCode is the HTTP code returned for type GetStorageGroupBadRequest
|
||||||
|
const GetStorageGroupBadRequestCode int = 400
|
||||||
|
|
||||||
|
/*
|
||||||
|
GetStorageGroupBadRequest Bad request.
|
||||||
|
|
||||||
|
swagger:response getStorageGroupBadRequest
|
||||||
|
*/
|
||||||
|
type GetStorageGroupBadRequest struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.ErrorResponse `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetStorageGroupBadRequest creates GetStorageGroupBadRequest with default headers values
|
||||||
|
func NewGetStorageGroupBadRequest() *GetStorageGroupBadRequest {
|
||||||
|
|
||||||
|
return &GetStorageGroupBadRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the get storage group bad request response
|
||||||
|
func (o *GetStorageGroupBadRequest) WithPayload(payload *models.ErrorResponse) *GetStorageGroupBadRequest {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the get storage group bad request response
|
||||||
|
func (o *GetStorageGroupBadRequest) SetPayload(payload *models.ErrorResponse) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *GetStorageGroupBadRequest) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
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/TrueCloudLab/frostfs-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)
|
||||||
|
|
||||||
|
}
|
203
gen/restapi/operations/list_storage_groups_parameters.go
Normal file
203
gen/restapi/operations/list_storage_groups_parameters.go
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewListStorageGroupsParams creates a new ListStorageGroupsParams object
|
||||||
|
// with the default values initialized.
|
||||||
|
func NewListStorageGroupsParams() ListStorageGroupsParams {
|
||||||
|
|
||||||
|
var (
|
||||||
|
// initialize parameters with default values
|
||||||
|
|
||||||
|
fullBearerDefault = bool(false)
|
||||||
|
walletConnectDefault = bool(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
return ListStorageGroupsParams{
|
||||||
|
FullBearer: &fullBearerDefault,
|
||||||
|
|
||||||
|
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.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignature *string
|
||||||
|
/*Hex encoded the public part of the key that signed the bearer token.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignatureKey *string
|
||||||
|
/*Base58 encoded container id.
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
ContainerID string
|
||||||
|
/*Provided bearer token is final or gate should assemble it using signature.
|
||||||
|
In: query
|
||||||
|
Default: false
|
||||||
|
*/
|
||||||
|
FullBearer *bool
|
||||||
|
/*Use wallet connect signature scheme or native FrostFS 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
qFullBearer, qhkFullBearer, _ := qs.GetOK("fullBearer")
|
||||||
|
if err := o.bindFullBearer(qFullBearer, qhkFullBearer, 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 {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindFullBearer binds and validates parameter FullBearer from query.
|
||||||
|
func (o *ListStorageGroupsParams) bindFullBearer(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("fullBearer", "query", "bool", raw)
|
||||||
|
}
|
||||||
|
o.FullBearer = &value
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
104
gen/restapi/operations/list_storage_groups_responses.go
Normal file
104
gen/restapi/operations/list_storage_groups_responses.go
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// 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/TrueCloudLab/frostfs-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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
71
gen/restapi/operations/put_storage_group.go
Normal file
71
gen/restapi/operations/put_storage_group.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/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PutStorageGroupHandlerFunc turns a function with the right signature into a put storage group handler
|
||||||
|
type PutStorageGroupHandlerFunc func(PutStorageGroupParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn PutStorageGroupHandlerFunc) Handle(params PutStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutStorageGroupHandler interface for that can handle valid put storage group params
|
||||||
|
type PutStorageGroupHandler interface {
|
||||||
|
Handle(PutStorageGroupParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPutStorageGroup creates a new http.Handler for the put storage group operation
|
||||||
|
func NewPutStorageGroup(ctx *middleware.Context, handler PutStorageGroupHandler) *PutStorageGroup {
|
||||||
|
return &PutStorageGroup{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
PutStorageGroup swagger:route PUT /containers/{containerId}/storagegroups putStorageGroup
|
||||||
|
|
||||||
|
Create a new storage group in container.
|
||||||
|
*/
|
||||||
|
type PutStorageGroup struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler PutStorageGroupHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *PutStorageGroup) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
*r = *rCtx
|
||||||
|
}
|
||||||
|
var Params = NewPutStorageGroupParams()
|
||||||
|
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)
|
||||||
|
|
||||||
|
}
|
242
gen/restapi/operations/put_storage_group_parameters.go
Normal file
242
gen/restapi/operations/put_storage_group_parameters.go
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"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"
|
||||||
|
|
||||||
|
"github.com/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewPutStorageGroupParams creates a new PutStorageGroupParams object
|
||||||
|
// with the default values initialized.
|
||||||
|
func NewPutStorageGroupParams() PutStorageGroupParams {
|
||||||
|
|
||||||
|
var (
|
||||||
|
// initialize parameters with default values
|
||||||
|
|
||||||
|
fullBearerDefault = bool(false)
|
||||||
|
|
||||||
|
walletConnectDefault = bool(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
return PutStorageGroupParams{
|
||||||
|
FullBearer: &fullBearerDefault,
|
||||||
|
|
||||||
|
WalletConnect: &walletConnectDefault,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutStorageGroupParams contains all the bound params for the put storage group operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters putStorageGroup
|
||||||
|
type PutStorageGroupParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*Base64 encoded signature for bearer token.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignature *string
|
||||||
|
/*Hex encoded the public part of the key that signed the bearer token.
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XBearerSignatureKey *string
|
||||||
|
/*Base58 encoded container id.
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
ContainerID string
|
||||||
|
/*Provided bearer token is final or gate should assemble it using signature.
|
||||||
|
In: query
|
||||||
|
Default: false
|
||||||
|
*/
|
||||||
|
FullBearer *bool
|
||||||
|
/*Storage group co create.
|
||||||
|
Required: true
|
||||||
|
In: body
|
||||||
|
*/
|
||||||
|
StorageGroup *models.StorageGroupPutBody
|
||||||
|
/*Use wallet connect signature scheme or native FrostFS 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 NewPutStorageGroupParams() beforehand.
|
||||||
|
func (o *PutStorageGroupParams) 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
qFullBearer, qhkFullBearer, _ := qs.GetOK("fullBearer")
|
||||||
|
if err := o.bindFullBearer(qFullBearer, qhkFullBearer, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtime.HasBody(r) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
var body models.StorageGroupPutBody
|
||||||
|
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
res = append(res, errors.Required("storageGroup", "body", ""))
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.NewParseError("storageGroup", "body", "", err))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// validate body object
|
||||||
|
if err := body.Validate(route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := validate.WithOperationRequest(context.Background())
|
||||||
|
if err := body.ContextValidate(ctx, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) == 0 {
|
||||||
|
o.StorageGroup = &body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.Required("storageGroup", "body", ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
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 *PutStorageGroupParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
o.XBearerSignature = &raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
|
||||||
|
func (o *PutStorageGroupParams) bindXBearerSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: false
|
||||||
|
|
||||||
|
if raw == "" { // empty values pass all other validations
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
o.XBearerSignatureKey = &raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindContainerID binds and validates parameter ContainerID from path.
|
||||||
|
func (o *PutStorageGroupParams) 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindFullBearer binds and validates parameter FullBearer from query.
|
||||||
|
func (o *PutStorageGroupParams) bindFullBearer(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 NewPutStorageGroupParams()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := swag.ConvertBool(raw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InvalidType("fullBearer", "query", "bool", raw)
|
||||||
|
}
|
||||||
|
o.FullBearer = &value
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindWalletConnect binds and validates parameter WalletConnect from query.
|
||||||
|
func (o *PutStorageGroupParams) 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 NewPutStorageGroupParams()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := swag.ConvertBool(raw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InvalidType("walletConnect", "query", "bool", raw)
|
||||||
|
}
|
||||||
|
o.WalletConnect = &value
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
104
gen/restapi/operations/put_storage_group_responses.go
Normal file
104
gen/restapi/operations/put_storage_group_responses.go
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// 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/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PutStorageGroupOKCode is the HTTP code returned for type PutStorageGroupOK
|
||||||
|
const PutStorageGroupOKCode int = 200
|
||||||
|
|
||||||
|
/*
|
||||||
|
PutStorageGroupOK Address of uploaded storage group.
|
||||||
|
|
||||||
|
swagger:response putStorageGroupOK
|
||||||
|
*/
|
||||||
|
type PutStorageGroupOK struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.Address `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPutStorageGroupOK creates PutStorageGroupOK with default headers values
|
||||||
|
func NewPutStorageGroupOK() *PutStorageGroupOK {
|
||||||
|
|
||||||
|
return &PutStorageGroupOK{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the put storage group o k response
|
||||||
|
func (o *PutStorageGroupOK) WithPayload(payload *models.Address) *PutStorageGroupOK {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the put storage group o k response
|
||||||
|
func (o *PutStorageGroupOK) SetPayload(payload *models.Address) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *PutStorageGroupOK) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutStorageGroupBadRequestCode is the HTTP code returned for type PutStorageGroupBadRequest
|
||||||
|
const PutStorageGroupBadRequestCode int = 400
|
||||||
|
|
||||||
|
/*
|
||||||
|
PutStorageGroupBadRequest Bad request.
|
||||||
|
|
||||||
|
swagger:response putStorageGroupBadRequest
|
||||||
|
*/
|
||||||
|
type PutStorageGroupBadRequest struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.ErrorResponse `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPutStorageGroupBadRequest creates PutStorageGroupBadRequest with default headers values
|
||||||
|
func NewPutStorageGroupBadRequest() *PutStorageGroupBadRequest {
|
||||||
|
|
||||||
|
return &PutStorageGroupBadRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the put storage group bad request response
|
||||||
|
func (o *PutStorageGroupBadRequest) WithPayload(payload *models.ErrorResponse) *PutStorageGroupBadRequest {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the put storage group bad request response
|
||||||
|
func (o *PutStorageGroupBadRequest) SetPayload(payload *models.ErrorResponse) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *PutStorageGroupBadRequest) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
go.mod
4
go.mod
|
@ -4,7 +4,9 @@ go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/TrueCloudLab/frostfs-api-go/v2 v2.0.0-20221212144048-1351b6656d68
|
github.com/TrueCloudLab/frostfs-api-go/v2 v2.0.0-20221212144048-1351b6656d68
|
||||||
|
github.com/TrueCloudLab/frostfs-crypto v0.5.0
|
||||||
github.com/TrueCloudLab/frostfs-sdk-go v0.0.0-20221214065929-4c779423f556
|
github.com/TrueCloudLab/frostfs-sdk-go v0.0.0-20221214065929-4c779423f556
|
||||||
|
github.com/TrueCloudLab/tzhash v1.7.0
|
||||||
github.com/go-openapi/errors v0.20.2
|
github.com/go-openapi/errors v0.20.2
|
||||||
github.com/go-openapi/loads v0.21.1
|
github.com/go-openapi/loads v0.21.1
|
||||||
github.com/go-openapi/runtime v0.23.3
|
github.com/go-openapi/runtime v0.23.3
|
||||||
|
@ -27,10 +29,8 @@ require (
|
||||||
github.com/Microsoft/hcsshim v0.8.23 // indirect
|
github.com/Microsoft/hcsshim v0.8.23 // indirect
|
||||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||||
github.com/TrueCloudLab/frostfs-crypto v0.5.0
|
|
||||||
github.com/TrueCloudLab/hrw v1.1.0 // indirect
|
github.com/TrueCloudLab/hrw v1.1.0 // indirect
|
||||||
github.com/TrueCloudLab/rfc6979 v0.3.0 // indirect
|
github.com/TrueCloudLab/rfc6979 v0.3.0 // indirect
|
||||||
github.com/TrueCloudLab/tzhash v1.7.0 // indirect
|
|
||||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
|
|
@ -126,6 +126,12 @@ func (a *API) Configure(api *operations.FrostfsRestGwAPI) http.Handler {
|
||||||
api.OptionsContainersEACLHandler = operations.OptionsContainersEACLHandlerFunc(a.OptionsContainersEACL)
|
api.OptionsContainersEACLHandler = operations.OptionsContainersEACLHandlerFunc(a.OptionsContainersEACL)
|
||||||
api.PutContainerEACLHandler = operations.PutContainerEACLHandlerFunc(a.PutContainerEACL)
|
api.PutContainerEACLHandler = operations.PutContainerEACLHandlerFunc(a.PutContainerEACL)
|
||||||
api.GetContainerEACLHandler = operations.GetContainerEACLHandlerFunc(a.GetContainerEACL)
|
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.GetStorageGroupHandler = operations.GetStorageGroupHandlerFunc(a.GetStorageGroup)
|
||||||
|
api.DeleteStorageGroupHandler = operations.DeleteStorageGroupHandlerFunc(a.DeleteStorageGroup)
|
||||||
|
|
||||||
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
||||||
if !strings.HasPrefix(s, BearerPrefix) {
|
if !strings.HasPrefix(s, BearerPrefix) {
|
||||||
|
|
|
@ -413,6 +413,10 @@ func createContainer(ctx context.Context, p *pool.Pool, stoken session.Container
|
||||||
container.WriteDomain(&cnr, domain)
|
container.WriteDomain(&cnr, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = pool.SyncContainerWithNetwork(ctx, &cnr, p); err != nil {
|
||||||
|
return cid.ID{}, fmt.Errorf("sync container with network: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
var prm pool.PrmContainerPut
|
var prm pool.PrmContainerPut
|
||||||
prm.SetContainer(cnr)
|
prm.SetContainer(cnr)
|
||||||
prm.WithinSession(stoken)
|
prm.WithinSession(stoken)
|
||||||
|
|
403
handlers/storagegroup.go
Normal file
403
handlers/storagegroup.go
Normal file
|
@ -0,0 +1,403 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
objectv2 "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
|
"github.com/TrueCloudLab/frostfs-rest-gw/gen/models"
|
||||||
|
"github.com/TrueCloudLab/frostfs-rest-gw/gen/restapi/operations"
|
||||||
|
"github.com/TrueCloudLab/frostfs-rest-gw/internal/util"
|
||||||
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
|
"github.com/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||||
|
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
"github.com/TrueCloudLab/frostfs-sdk-go/pool"
|
||||||
|
"github.com/TrueCloudLab/frostfs-sdk-go/storagegroup"
|
||||||
|
"github.com/TrueCloudLab/tzhash/tz"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PutStorageGroup handler that create a new storage group.
|
||||||
|
func (a *API) PutStorageGroup(params operations.PutStorageGroupParams, 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.NewPutStorageGroupBadRequest().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect, *params.FullBearer)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("invalid bearer token", err)
|
||||||
|
return operations.NewPutStorageGroupBadRequest().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
sg, err := a.formStorageGroup(ctx, cnrID, btoken, params.StorageGroup)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("form storage group", err)
|
||||||
|
return operations.NewPutStorageGroupBadRequest().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
objID, err := a.putStorageGroupObject(ctx, cnrID, btoken, params.StorageGroup.Name, *sg)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("put storage group", err)
|
||||||
|
return operations.NewPutStorageGroupBadRequest().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp models.Address
|
||||||
|
resp.ContainerID = util.NewString(params.ContainerID)
|
||||||
|
resp.ObjectID = util.NewString(objID.String())
|
||||||
|
|
||||||
|
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, *params.FullBearer)
|
||||||
|
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)
|
||||||
|
attachBearer(&prm, 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)
|
||||||
|
attachBearer(&prm, 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteStorageGroup handler that removes storage group from NeoFS.
|
||||||
|
func (a *API) DeleteStorageGroup(params operations.DeleteStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
ctx := params.HTTPRequest.Context()
|
||||||
|
|
||||||
|
addr, err := parseAddress(params.ContainerID, params.StorageGroupID)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("invalid address", err)
|
||||||
|
return operations.NewDeleteStorageGroupBadRequest().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect, *params.FullBearer)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("failed to get bearer token", err)
|
||||||
|
return operations.NewDeleteStorageGroupBadRequest().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var prm pool.PrmObjectDelete
|
||||||
|
prm.SetAddress(addr)
|
||||||
|
attachBearer(&prm, btoken)
|
||||||
|
|
||||||
|
if err = a.pool.DeleteObject(ctx, prm); err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("failed to delete storage group", err)
|
||||||
|
return operations.NewDeleteStorageGroupBadRequest().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
return operations.NewDeleteStorageGroupOK().WithPayload(util.NewSuccessResponse())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStorageGroup handler that get storage group info.
|
||||||
|
func (a *API) GetStorageGroup(params operations.GetStorageGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
|
errorResponse := operations.NewGetObjectInfoBadRequest()
|
||||||
|
ctx := params.HTTPRequest.Context()
|
||||||
|
|
||||||
|
addr, err := parseAddress(params.ContainerID, params.StorageGroupID)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("invalid address", err)
|
||||||
|
return errorResponse.WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect, *params.FullBearer)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("get bearer token", err)
|
||||||
|
return errorResponse.WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var prm pool.PrmObjectGet
|
||||||
|
prm.SetAddress(addr)
|
||||||
|
attachBearer(&prm, btoken)
|
||||||
|
|
||||||
|
objRes, err := a.pool.GetObject(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("get storage group object", err)
|
||||||
|
return errorResponse.WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
sb, err := a.readStorageGroup(objRes)
|
||||||
|
if err != nil {
|
||||||
|
resp := a.logAndGetErrorResponse("read storage group", err)
|
||||||
|
return errorResponse.WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var sbHash string
|
||||||
|
cs, ok := sb.ValidationDataHash()
|
||||||
|
if ok {
|
||||||
|
sbHash = hex.EncodeToString(cs.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
members := make([]string, len(sb.Members()))
|
||||||
|
for i, objID := range sb.Members() {
|
||||||
|
members[i] = objID.EncodeToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := &models.StorageGroup{
|
||||||
|
Address: &models.Address{
|
||||||
|
ContainerID: util.NewString(addr.Container().String()),
|
||||||
|
ObjectID: util.NewString(addr.Object().String()),
|
||||||
|
},
|
||||||
|
ExpirationEpoch: util.NewString(strconv.FormatUint(sb.ExpirationEpoch(), 10)),
|
||||||
|
Size: util.NewString(strconv.FormatUint(sb.ValidationDataSize(), 10)),
|
||||||
|
Hash: sbHash,
|
||||||
|
Members: members,
|
||||||
|
Name: getStorageGroupName(objRes.Header),
|
||||||
|
}
|
||||||
|
|
||||||
|
return operations.NewGetStorageGroupOK().WithPayload(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStorageGroupName(obj object.Object) string {
|
||||||
|
for _, attribute := range obj.Attributes() {
|
||||||
|
if attribute.Key() == object.AttributeFileName {
|
||||||
|
return attribute.Value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) readStorageGroup(objRes pool.ResGetObject) (*storagegroup.StorageGroup, error) {
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
if _, err := io.Copy(buf, objRes.Payload); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to copy storage group payload: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj := objRes.Header
|
||||||
|
obj.SetPayload(buf.Bytes())
|
||||||
|
|
||||||
|
var sb storagegroup.StorageGroup
|
||||||
|
if err := storagegroup.ReadFromObject(&sb, obj); err != nil {
|
||||||
|
return nil, fmt.Errorf("read storage group from object: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &sb, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) formStorageGroup(ctx context.Context, cnrID cid.ID, btoken *bearer.Token, storageGroup *models.StorageGroupPutBody) (*storagegroup.StorageGroup, error) {
|
||||||
|
members, err := a.parseStorageGroupMembers(storageGroup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parse storage group members: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hashDisabled, err := isHomomorphicHashingDisabled(ctx, a.pool, cnrID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("check if homomorphic hash disabled: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sgSize, cs, err := a.getStorageGroupSizeAndHash(ctx, cnrID, btoken, members, !hashDisabled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get storage group size: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
networkInfo, err := a.pool.NetworkInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get network info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var sg storagegroup.StorageGroup
|
||||||
|
sg.SetMembers(members)
|
||||||
|
sg.SetValidationDataSize(sgSize)
|
||||||
|
sg.SetExpirationEpoch(networkInfo.CurrentEpoch() + uint64(*storageGroup.Lifetime))
|
||||||
|
|
||||||
|
if !hashDisabled {
|
||||||
|
sg.SetValidationDataHash(*cs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &sg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) putStorageGroupObject(ctx context.Context, cnrID cid.ID, btoken *bearer.Token, fileName string, sg storagegroup.StorageGroup) (*oid.ID, error) {
|
||||||
|
var attrFileName object.Attribute
|
||||||
|
attrFileName.SetKey(object.AttributeFileName)
|
||||||
|
attrFileName.SetValue(fileName)
|
||||||
|
|
||||||
|
obj := object.New()
|
||||||
|
obj.SetContainerID(cnrID)
|
||||||
|
attachOwner(obj, btoken)
|
||||||
|
obj.SetAttributes(attrFileName)
|
||||||
|
|
||||||
|
storagegroup.WriteToObject(sg, obj)
|
||||||
|
|
||||||
|
var prmPut pool.PrmObjectPut
|
||||||
|
prmPut.SetHeader(*obj)
|
||||||
|
attachBearer(&prmPut, btoken)
|
||||||
|
|
||||||
|
objID, err := a.pool.PutObject(ctx, prmPut)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("put object: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &objID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) getStorageGroupSizeAndHash(ctx context.Context, cnrID cid.ID, btoken *bearer.Token, members []oid.ID, needCalcHash bool) (uint64, *checksum.Checksum, error) {
|
||||||
|
var (
|
||||||
|
sgSize uint64
|
||||||
|
objHashes [][]byte
|
||||||
|
addr oid.Address
|
||||||
|
prm pool.PrmObjectHead
|
||||||
|
)
|
||||||
|
|
||||||
|
addr.SetContainer(cnrID)
|
||||||
|
attachBearer(&prm, btoken)
|
||||||
|
|
||||||
|
for _, objID := range members {
|
||||||
|
addr.SetObject(objID)
|
||||||
|
prm.SetAddress(addr)
|
||||||
|
|
||||||
|
objInfo, err := a.pool.HeadObject(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, fmt.Errorf("chead object from storage group members, id '%s': %w", objID.EncodeToString(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sgSize += objInfo.PayloadSize()
|
||||||
|
|
||||||
|
if needCalcHash {
|
||||||
|
cs, _ := objInfo.PayloadHomomorphicHash()
|
||||||
|
objHashes = append(objHashes, cs.Value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if needCalcHash {
|
||||||
|
sumHash, err := tz.Concat(objHashes)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, fmt.Errorf("concat tz hashes: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cs checksum.Checksum
|
||||||
|
tzHash := [64]byte{}
|
||||||
|
copy(tzHash[:], sumHash)
|
||||||
|
cs.SetTillichZemor(tzHash)
|
||||||
|
|
||||||
|
return sgSize, &cs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return sgSize, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) parseStorageGroupMembers(storageGroup *models.StorageGroupPutBody) ([]oid.ID, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
members := make([]oid.ID, len(storageGroup.Members))
|
||||||
|
uniqueFilter := make(map[oid.ID]struct{}, len(members))
|
||||||
|
|
||||||
|
for i, objIDStr := range storageGroup.Members {
|
||||||
|
if err = members[i].DecodeString(objIDStr); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid object id '%s': %w", objIDStr, err)
|
||||||
|
}
|
||||||
|
if _, ok := uniqueFilter[members[i]]; ok {
|
||||||
|
return nil, fmt.Errorf("invalid storage group members: duplicate id '%s': %w", objIDStr, err)
|
||||||
|
}
|
||||||
|
uniqueFilter[members[i]] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return members, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isHomomorphicHashingDisabled(ctx context.Context, p *pool.Pool, cnrID cid.ID) (bool, error) {
|
||||||
|
var prm pool.PrmContainerGet
|
||||||
|
prm.SetContainerID(cnrID)
|
||||||
|
|
||||||
|
cnr, err := p.GetContainer(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("get container: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return container.IsHomomorphicHashingDisabled(cnr), nil
|
||||||
|
}
|
190
spec/rest.yaml
190
spec/rest.yaml
|
@ -56,6 +56,12 @@ parameters:
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
description: Base58 encoded object id.
|
description: Base58 encoded object id.
|
||||||
|
storageGroupId:
|
||||||
|
in: path
|
||||||
|
name: storageGroupId
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: Base58 encoded storage group id.
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/auth:
|
/auth:
|
||||||
|
@ -557,6 +563,89 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/ErrorResponse'
|
$ref: '#/definitions/ErrorResponse'
|
||||||
|
|
||||||
|
/containers/{containerId}/storagegroups:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/containerId'
|
||||||
|
put:
|
||||||
|
operationId: putStorageGroup
|
||||||
|
summary: Create a new storage group in container.
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/signatureParam'
|
||||||
|
- $ref: '#/parameters/signatureKeyParam'
|
||||||
|
- $ref: '#/parameters/signatureScheme'
|
||||||
|
- $ref: '#/parameters/fullBearerToken'
|
||||||
|
- in: body
|
||||||
|
name: storageGroup
|
||||||
|
required: true
|
||||||
|
description: Storage group co create.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/StorageGroupPutBody'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Address of uploaded storage group.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Address'
|
||||||
|
400:
|
||||||
|
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'
|
||||||
|
- $ref: '#/parameters/fullBearerToken'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: List of storage groups.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/StorageGroupList'
|
||||||
|
400:
|
||||||
|
description: Bad request.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ErrorResponse'
|
||||||
|
|
||||||
|
/containers/{containerId}/storagegroups/{storageGroupId}:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/containerId'
|
||||||
|
- $ref: '#/parameters/storageGroupId'
|
||||||
|
get:
|
||||||
|
operationId: getStorageGroup
|
||||||
|
summary: Get storage group info.
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/signatureParam'
|
||||||
|
- $ref: '#/parameters/signatureKeyParam'
|
||||||
|
- $ref: '#/parameters/signatureScheme'
|
||||||
|
- $ref: '#/parameters/fullBearerToken'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Storage group information.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/StorageGroup'
|
||||||
|
400:
|
||||||
|
description: Bad request.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ErrorResponse'
|
||||||
|
delete:
|
||||||
|
operationId: deleteStorageGroup
|
||||||
|
summary: Delete storage group from container.
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/signatureParam'
|
||||||
|
- $ref: '#/parameters/signatureKeyParam'
|
||||||
|
- $ref: '#/parameters/signatureScheme'
|
||||||
|
- $ref: '#/parameters/fullBearerToken'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Successful deletion.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/SuccessResponse'
|
||||||
|
400:
|
||||||
|
description: Bad request.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ErrorResponse'
|
||||||
|
|
||||||
definitions:
|
definitions:
|
||||||
BinaryBearer:
|
BinaryBearer:
|
||||||
description: Bearer token for object operations that is represented in binary form.
|
description: Bearer token for object operations that is represented in binary form.
|
||||||
|
@ -1030,6 +1119,107 @@ definitions:
|
||||||
value: myfile
|
value: myfile
|
||||||
targets:
|
targets:
|
||||||
- role: OTHERS
|
- role: OTHERS
|
||||||
|
StorageGroupPutBody:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name of storage group. It will be the value of the `FileName` attribute in storage group object.
|
||||||
|
type: string
|
||||||
|
lifetime:
|
||||||
|
description: Lifetime in epochs for storage group.
|
||||||
|
type: integer
|
||||||
|
members:
|
||||||
|
description: Object identifiers to be placed into storage group. Must be unique.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- lifetime
|
||||||
|
- members
|
||||||
|
example:
|
||||||
|
name: my-storage-group
|
||||||
|
lifetime: 100
|
||||||
|
members:
|
||||||
|
- 8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd
|
||||||
|
StorageGroup:
|
||||||
|
description: Storage group keeps verification information for Data Audit sessions.
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name of storage group. It will be the value of the `FileName` attribute in storage group object.
|
||||||
|
type: string
|
||||||
|
address:
|
||||||
|
description: Address of storage group object. Set by server.
|
||||||
|
readOnly: true
|
||||||
|
$ref: '#/definitions/Address'
|
||||||
|
expirationEpoch:
|
||||||
|
description: Expiration epoch of storage group.
|
||||||
|
type: string
|
||||||
|
hash:
|
||||||
|
description: Homomorphic hash from the concatenation of the payloads of the storage group members. Empty means hashing is disabled.
|
||||||
|
type: string
|
||||||
|
size:
|
||||||
|
description: Total size of the payloads of objects in the storage group.
|
||||||
|
type: string
|
||||||
|
members:
|
||||||
|
description: Object identifiers to be placed into storage group. Must be unique.
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- address
|
||||||
|
- expirationEpoch
|
||||||
|
- size
|
||||||
|
- members
|
||||||
|
example:
|
||||||
|
name: my-storage-group
|
||||||
|
address:
|
||||||
|
objectId: 9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd
|
||||||
|
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
||||||
|
expirationEpoch: 5000
|
||||||
|
size: 4096
|
||||||
|
members:
|
||||||
|
- 8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd
|
||||||
|
StorageGroupBaseInfo:
|
||||||
|
description: Storage group info for listing.
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
address:
|
||||||
|
$ref: '#/definitions/Address'
|
||||||
|
expirationEpoch:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- address
|
||||||
|
- expirationEpoch
|
||||||
|
example:
|
||||||
|
name: my-storage-group
|
||||||
|
address:
|
||||||
|
objectId: 9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd
|
||||||
|
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
||||||
|
expirationEpoch: 5000
|
||||||
|
StorageGroupList:
|
||||||
|
description: List of storage groups.
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
size:
|
||||||
|
type: integer
|
||||||
|
storageGroups:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/StorageGroupBaseInfo'
|
||||||
|
required:
|
||||||
|
- size
|
||||||
|
- storageGroups
|
||||||
|
example:
|
||||||
|
size: 1
|
||||||
|
storageGroups:
|
||||||
|
- name: my-storage-group
|
||||||
|
address:
|
||||||
|
objectId: 9N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd
|
||||||
|
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
||||||
|
expirationEpoch: 5000
|
||||||
Attribute:
|
Attribute:
|
||||||
description: Attribute is a pair of strings that can be attached to a container or an object.
|
description: Attribute is a pair of strings that can be attached to a container or an object.
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -75,4 +75,24 @@ Also, you can use this attribute to further object searching.
|
||||||
More about FrostFS status code you can
|
More about FrostFS status code you can
|
||||||
find [here](https://github.com/nspcc-dev/neofs-spec/blob/master/20-api-v2/status.md).
|
find [here](https://github.com/nspcc-dev/neofs-spec/blob/master/20-api-v2/status.md).
|
||||||
|
|
||||||
|
### Storage groups
|
||||||
|
|
||||||
|
The concept of a storage group has been introduced to reduce the dependence of the complexity of
|
||||||
|
the check on the number of stored objects in the system.
|
||||||
|
|
||||||
|
The consistency and availability of multiple objects on the network are achieved by validating the
|
||||||
|
storage group without saving meta information and performing validation on each object.
|
||||||
|
|
||||||
|
`StorageGroup` keeps verification information for Data Audit sessions. Objects that require paid storage
|
||||||
|
guaranties are gathered in `StorageGroups` with additional information used for proof of storage
|
||||||
|
checks. A `StorageGroup` can be created only for objects from the same container.
|
||||||
|
|
||||||
|
A `StorageGroup` are objects of a special type with the payload containing the serialized protobuf
|
||||||
|
structure. For the details on the format please refer to the [API specification](https://github.com/nspcc-dev/neofs-spec/blob/master/20-api-v2/storagegroup.md) in the corresponding section.
|
||||||
|
|
||||||
|
StorageGroup structure has information about:
|
||||||
|
* Total size of the payloads of objects in the storage group
|
||||||
|
* Homomorphic hash from the concatenation of the payloads of the storage group members. The order of concatenation is the same as the order of the members in the members field.
|
||||||
|
|
||||||
|
* Last NeoFS epoch number of the storage group lifetime
|
||||||
|
* Alpha-numerically sorted list of member objects
|
||||||
|
|
Reference in a new issue