Feature/2 rebranding deep #4
42 changed files with 336 additions and 336 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,7 +3,7 @@
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
# Tree service
|
# Tree service
|
||||||
internal/neofs/services/tree/
|
internal/frostfs/services/tree/
|
||||||
|
|
||||||
# Vendoring
|
# Vendoring
|
||||||
vendor
|
vendor
|
||||||
|
|
|
@ -92,9 +92,9 @@ func (p prs) Seek(_ int64, _ int) (int64, error) {
|
||||||
var _ io.ReadSeeker = prs(0)
|
var _ io.ReadSeeker = prs(0)
|
||||||
|
|
||||||
// New creates an instance of AuthCenter.
|
// New creates an instance of AuthCenter.
|
||||||
func New(neoFS tokens.NeoFS, key *keys.PrivateKey, prefixes []string, config *cache.Config) Center {
|
func New(frostFS tokens.FrostFS, key *keys.PrivateKey, prefixes []string, config *cache.Config) Center {
|
||||||
return ¢er{
|
return ¢er{
|
||||||
cli: tokens.New(neoFS, key, config),
|
cli: tokens.New(frostFS, key, config),
|
||||||
reg: NewRegexpMatcher(authorizationFieldRegexp),
|
reg: NewRegexpMatcher(authorizationFieldRegexp),
|
||||||
postReg: NewRegexpMatcher(postPolicyCredentialRegexp),
|
postReg: NewRegexpMatcher(postPolicyCredentialRegexp),
|
||||||
allowedAccessKeyIDPrefixes: prefixes,
|
allowedAccessKeyIDPrefixes: prefixes,
|
||||||
|
|
2
api/cache/objectslist.go
vendored
2
api/cache/objectslist.go
vendored
|
@ -20,7 +20,7 @@ import (
|
||||||
After putting a record, it lives for a while (default value is 60 seconds).
|
After putting a record, it lives for a while (default value is 60 seconds).
|
||||||
|
|
||||||
When we receive a request from a user, we try to find the suitable and non-expired cache entry, go through the list
|
When we receive a request from a user, we try to find the suitable and non-expired cache entry, go through the list
|
||||||
and get ObjectInfos from common object cache or with a request to NeoFS.
|
and get ObjectInfos from common object cache or with a request to FrostFS.
|
||||||
|
|
||||||
When we put an object into a container, we invalidate entries with prefixes that are prefixes of the object's name.
|
When we put an object into a container, we invalidate entries with prefixes that are prefixes of the object's name.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,7 +25,7 @@ func (v NodeVersion) IsDeleteMarker() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMarkerInfo is used to save object info if node in the tree service is delete marker.
|
// DeleteMarkerInfo is used to save object info if node in the tree service is delete marker.
|
||||||
// We need this information because the "delete marker" object is no longer stored in NeoFS.
|
// We need this information because the "delete marker" object is no longer stored in FrostFS.
|
||||||
type DeleteMarkerInfo struct {
|
type DeleteMarkerInfo struct {
|
||||||
Created time.Time
|
Created time.Time
|
||||||
Owner user.ID
|
Owner user.ID
|
||||||
|
|
|
@ -986,7 +986,7 @@ var errorCodes = errorCodeMap{
|
||||||
ErrNotSupported: {
|
ErrNotSupported: {
|
||||||
ErrCode: ErrNotSupported,
|
ErrCode: ErrNotSupported,
|
||||||
Code: "BadRequest",
|
Code: "BadRequest",
|
||||||
Description: "Not supported by NeoFS S3 Gateway",
|
Description: "Not supported by FrostFS S3 Gateway",
|
||||||
HTTPStatusCode: http.StatusNotImplemented,
|
HTTPStatusCode: http.StatusNotImplemented,
|
||||||
},
|
},
|
||||||
ErrInvalidEncryptionMethod: {
|
ErrInvalidEncryptionMethod: {
|
||||||
|
|
|
@ -38,7 +38,7 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultPolicy is a default policy of placing containers in NeoFS if it's not set at the request.
|
// DefaultPolicy is a default policy of placing containers in FrostFS if it's not set at the request.
|
||||||
DefaultPolicy = "REP 3"
|
DefaultPolicy = "REP 3"
|
||||||
// DefaultCopiesNumber is a default number of object copies that is enough to consider put successful if it's not set in config.
|
// DefaultCopiesNumber is a default number of object copies that is enough to consider put successful if it's not set in config.
|
||||||
DefaultCopiesNumber uint32 = 0
|
DefaultCopiesNumber uint32 = 0
|
||||||
|
@ -50,7 +50,7 @@ var _ api.Handler = (*handler)(nil)
|
||||||
func New(log *zap.Logger, obj layer.Client, notificator Notificator, cfg *Config) (api.Handler, error) {
|
func New(log *zap.Logger, obj layer.Client, notificator Notificator, cfg *Config) (api.Handler, error) {
|
||||||
switch {
|
switch {
|
||||||
case obj == nil:
|
case obj == nil:
|
||||||
return nil, errors.New("empty NeoFS Object Layer")
|
return nil, errors.New("empty FrostFS Object Layer")
|
||||||
case log == nil:
|
case log == nil:
|
||||||
return nil, errors.New("empty logger")
|
return nil, errors.New("empty logger")
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ func TestDeleteObject(t *testing.T) {
|
||||||
deleteObject(t, tc, bktName, objName, emptyVersion)
|
deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||||
checkNotFound(t, tc, bktName, objName, emptyVersion)
|
checkNotFound(t, tc, bktName, objName, emptyVersion)
|
||||||
|
|
||||||
require.False(t, existInMockedNeoFS(tc, bktInfo, objInfo))
|
require.False(t, existInMockedFrostFS(tc, bktInfo, objInfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteObjectFromSuspended(t *testing.T) {
|
func TestDeleteObjectFromSuspended(t *testing.T) {
|
||||||
|
@ -109,7 +109,7 @@ func TestDeleteObjectVersioned(t *testing.T) {
|
||||||
deleteObject(t, tc, bktName, objName, objInfo.VersionID())
|
deleteObject(t, tc, bktName, objName, objInfo.VersionID())
|
||||||
checkNotFound(t, tc, bktName, objName, objInfo.VersionID())
|
checkNotFound(t, tc, bktName, objName, objInfo.VersionID())
|
||||||
|
|
||||||
require.False(t, existInMockedNeoFS(tc, bktInfo, objInfo), "object exists but shouldn't")
|
require.False(t, existInMockedFrostFS(tc, bktInfo, objInfo), "object exists but shouldn't")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteObjectUnversioned(t *testing.T) {
|
func TestDeleteObjectUnversioned(t *testing.T) {
|
||||||
|
@ -126,7 +126,7 @@ func TestDeleteObjectUnversioned(t *testing.T) {
|
||||||
require.Len(t, versions.DeleteMarker, 0, "delete markers must be empty")
|
require.Len(t, versions.DeleteMarker, 0, "delete markers must be empty")
|
||||||
require.Len(t, versions.Version, 0, "versions must be empty")
|
require.Len(t, versions.Version, 0, "versions must be empty")
|
||||||
|
|
||||||
require.False(t, existInMockedNeoFS(tc, bktInfo, objInfo), "object exists but shouldn't")
|
require.False(t, existInMockedFrostFS(tc, bktInfo, objInfo), "object exists but shouldn't")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveDeleteMarker(t *testing.T) {
|
func TestRemoveDeleteMarker(t *testing.T) {
|
||||||
|
@ -144,7 +144,7 @@ func TestRemoveDeleteMarker(t *testing.T) {
|
||||||
deleteObject(t, tc, bktName, objName, deleteMarkerVersion)
|
deleteObject(t, tc, bktName, objName, deleteMarkerVersion)
|
||||||
checkFound(t, tc, bktName, objName, emptyVersion)
|
checkFound(t, tc, bktName, objName, emptyVersion)
|
||||||
|
|
||||||
require.True(t, existInMockedNeoFS(tc, bktInfo, objInfo), "object doesn't exist but should")
|
require.True(t, existInMockedFrostFS(tc, bktInfo, objInfo), "object doesn't exist but should")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteObjectCombined(t *testing.T) {
|
func TestDeleteObjectCombined(t *testing.T) {
|
||||||
|
@ -161,7 +161,7 @@ func TestDeleteObjectCombined(t *testing.T) {
|
||||||
|
|
||||||
checkFound(t, tc, bktName, objName, objInfo.VersionID())
|
checkFound(t, tc, bktName, objName, objInfo.VersionID())
|
||||||
|
|
||||||
require.True(t, existInMockedNeoFS(tc, bktInfo, objInfo), "object doesn't exist but should")
|
require.True(t, existInMockedFrostFS(tc, bktInfo, objInfo), "object doesn't exist but should")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteObjectSuspended(t *testing.T) {
|
func TestDeleteObjectSuspended(t *testing.T) {
|
||||||
|
@ -181,7 +181,7 @@ func TestDeleteObjectSuspended(t *testing.T) {
|
||||||
deleteObject(t, tc, bktName, objName, emptyVersion)
|
deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||||
checkNotFound(t, tc, bktName, objName, objInfo.VersionID())
|
checkNotFound(t, tc, bktName, objName, objInfo.VersionID())
|
||||||
|
|
||||||
require.False(t, existInMockedNeoFS(tc, bktInfo, objInfo), "object exists but shouldn't")
|
require.False(t, existInMockedFrostFS(tc, bktInfo, objInfo), "object exists but shouldn't")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteMarkers(t *testing.T) {
|
func TestDeleteMarkers(t *testing.T) {
|
||||||
|
@ -200,7 +200,7 @@ func TestDeleteMarkers(t *testing.T) {
|
||||||
require.Len(t, versions.DeleteMarker, 3, "invalid delete markers length")
|
require.Len(t, versions.DeleteMarker, 3, "invalid delete markers length")
|
||||||
require.Len(t, versions.Version, 0, "versions must be empty")
|
require.Len(t, versions.Version, 0, "versions must be empty")
|
||||||
|
|
||||||
require.Len(t, listOIDsFromMockedNeoFS(t, tc, bktName), 0, "shouldn't be any object in neofs")
|
require.Len(t, listOIDsFromMockedFrostFS(t, tc, bktName), 0, "shouldn't be any object in frostfs")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteObjectFromListCache(t *testing.T) {
|
func TestDeleteObjectFromListCache(t *testing.T) {
|
||||||
|
@ -220,7 +220,7 @@ func TestDeleteObjectFromListCache(t *testing.T) {
|
||||||
versions = listObjectsV1(t, tc, bktName, "", "", "", -1)
|
versions = listObjectsV1(t, tc, bktName, "", "", "", -1)
|
||||||
require.Len(t, versions.Contents, 0)
|
require.Len(t, versions.Contents, 0)
|
||||||
|
|
||||||
require.False(t, existInMockedNeoFS(tc, bktInfo, objInfo))
|
require.False(t, existInMockedFrostFS(tc, bktInfo, objInfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteObjectCheckMarkerReturn(t *testing.T) {
|
func TestDeleteObjectCheckMarkerReturn(t *testing.T) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ type handlerContext struct {
|
||||||
owner user.ID
|
owner user.ID
|
||||||
t *testing.T
|
t *testing.T
|
||||||
h *handler
|
h *handler
|
||||||
tp *layer.TestNeoFS
|
tp *layer.TestFrostFS
|
||||||
context context.Context
|
context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func (hc *handlerContext) Handler() *handler {
|
||||||
return hc.h
|
return hc.h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *handlerContext) MockedPool() *layer.TestNeoFS {
|
func (hc *handlerContext) MockedPool() *layer.TestFrostFS {
|
||||||
return hc.tp
|
return hc.tp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ func prepareHandlerContext(t *testing.T) *handlerContext {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
l := zap.NewExample()
|
l := zap.NewExample()
|
||||||
tp := layer.NewTestNeoFS()
|
tp := layer.NewTestFrostFS()
|
||||||
|
|
||||||
testResolver := &resolver.Resolver{Name: "test_resolver"}
|
testResolver := &resolver.Resolver{Name: "test_resolver"}
|
||||||
testResolver.SetResolveFunc(func(_ context.Context, name string) (cid.ID, error) {
|
testResolver.SetResolveFunc(func(_ context.Context, name string) (cid.ID, error) {
|
||||||
|
@ -208,7 +208,7 @@ func parseTestResponse(t *testing.T, response *httptest.ResponseRecorder, body i
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func existInMockedNeoFS(tc *handlerContext, bktInfo *data.BucketInfo, objInfo *data.ObjectInfo) bool {
|
func existInMockedFrostFS(tc *handlerContext, bktInfo *data.BucketInfo, objInfo *data.ObjectInfo) bool {
|
||||||
p := &layer.GetObjectParams{
|
p := &layer.GetObjectParams{
|
||||||
BucketInfo: bktInfo,
|
BucketInfo: bktInfo,
|
||||||
ObjectInfo: objInfo,
|
ObjectInfo: objInfo,
|
||||||
|
@ -218,7 +218,7 @@ func existInMockedNeoFS(tc *handlerContext, bktInfo *data.BucketInfo, objInfo *d
|
||||||
return tc.Layer().GetObject(tc.Context(), p) == nil
|
return tc.Layer().GetObject(tc.Context(), p) == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func listOIDsFromMockedNeoFS(t *testing.T, tc *handlerContext, bktName string) []oid.ID {
|
func listOIDsFromMockedFrostFS(t *testing.T, tc *handlerContext, bktName string) []oid.ID {
|
||||||
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -313,7 +313,7 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCopiesNumberOrDefault(metadata map[string]string, defaultCopiesNumber uint32) (uint32, error) {
|
func getCopiesNumberOrDefault(metadata map[string]string, defaultCopiesNumber uint32) (uint32, error) {
|
||||||
copiesNumberStr, ok := metadata[layer.AttributeNeofsCopiesNumber]
|
copiesNumberStr, ok := metadata[layer.AttributeFrostfsCopiesNumber]
|
||||||
if !ok {
|
if !ok {
|
||||||
return defaultCopiesNumber, nil
|
return defaultCopiesNumber, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ func TestPutObjectOverrideCopiesNumber(t *testing.T) {
|
||||||
bktInfo := createTestBucket(tc, bktName)
|
bktInfo := createTestBucket(tc, bktName)
|
||||||
|
|
||||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
r.Header.Set(api.MetadataPrefix+strings.ToUpper(layer.AttributeNeofsCopiesNumber), "1")
|
r.Header.Set(api.MetadataPrefix+strings.ToUpper(layer.AttributeFrostfsCopiesNumber), "1")
|
||||||
tc.Handler().PutObjectHandler(w, r)
|
tc.Handler().PutObjectHandler(w, r)
|
||||||
|
|
||||||
p := &layer.HeadObjectParams{
|
p := &layer.HeadObjectParams{
|
||||||
|
@ -124,5 +124,5 @@ func TestPutObjectOverrideCopiesNumber(t *testing.T) {
|
||||||
|
|
||||||
objInfo, err := tc.Layer().GetObjectInfo(tc.Context(), p)
|
objInfo, err := tc.Layer().GetObjectInfo(tc.Context(), p)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "1", objInfo.Headers[layer.AttributeNeofsCopiesNumber])
|
require.Equal(t, "1", objInfo.Headers[layer.AttributeFrostfsCopiesNumber])
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,17 @@ package api
|
||||||
|
|
||||||
// Standard S3 HTTP request/response constants.
|
// Standard S3 HTTP request/response constants.
|
||||||
const (
|
const (
|
||||||
MetadataPrefix = "X-Amz-Meta-"
|
MetadataPrefix = "X-Amz-Meta-"
|
||||||
NeoFSSystemMetadataPrefix = "S3-"
|
FrostFSSystemMetadataPrefix = "S3-"
|
||||||
AmzMetadataDirective = "X-Amz-Metadata-Directive"
|
AmzMetadataDirective = "X-Amz-Metadata-Directive"
|
||||||
AmzTaggingDirective = "X-Amz-Tagging-Directive"
|
AmzTaggingDirective = "X-Amz-Tagging-Directive"
|
||||||
AmzVersionID = "X-Amz-Version-Id"
|
AmzVersionID = "X-Amz-Version-Id"
|
||||||
AmzTaggingCount = "X-Amz-Tagging-Count"
|
AmzTaggingCount = "X-Amz-Tagging-Count"
|
||||||
AmzTagging = "X-Amz-Tagging"
|
AmzTagging = "X-Amz-Tagging"
|
||||||
AmzDeleteMarker = "X-Amz-Delete-Marker"
|
AmzDeleteMarker = "X-Amz-Delete-Marker"
|
||||||
AmzCopySource = "X-Amz-Copy-Source"
|
AmzCopySource = "X-Amz-Copy-Source"
|
||||||
AmzCopySourceRange = "X-Amz-Copy-Source-Range"
|
AmzCopySourceRange = "X-Amz-Copy-Source-Range"
|
||||||
AmzDate = "X-Amz-Date"
|
AmzDate = "X-Amz-Date"
|
||||||
|
|
||||||
LastModified = "Last-Modified"
|
LastModified = "Last-Modified"
|
||||||
Date = "Date"
|
Date = "Date"
|
||||||
|
|
|
@ -41,14 +41,14 @@ func (n *layer) containerInfo(ctx context.Context, idCnr cid.ID) (*data.BucketIn
|
||||||
Name: idCnr.EncodeToString(),
|
Name: idCnr.EncodeToString(),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
res, err = n.neoFS.Container(ctx, idCnr)
|
res, err = n.frostFS.Container(ctx, idCnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("could not fetch container", zap.Error(err))
|
log.Error("could not fetch container", zap.Error(err))
|
||||||
|
|
||||||
if client.IsErrContainerNotFound(err) {
|
if client.IsErrContainerNotFound(err) {
|
||||||
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("get neofs container: %w", err)
|
return nil, fmt.Errorf("get frostfs container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cnr := *res
|
cnr := *res
|
||||||
|
@ -83,7 +83,7 @@ func (n *layer) containerList(ctx context.Context) ([]*data.BucketInfo, error) {
|
||||||
res []cid.ID
|
res []cid.ID
|
||||||
rid = api.GetRequestID(ctx)
|
rid = api.GetRequestID(ctx)
|
||||||
)
|
)
|
||||||
res, err = n.neoFS.UserContainers(ctx, own)
|
res, err = n.frostFS.UserContainers(ctx, own)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.log.Error("could not list user containers",
|
n.log.Error("could not list user containers",
|
||||||
zap.String("request_id", rid),
|
zap.String("request_id", rid),
|
||||||
|
@ -132,7 +132,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*da
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
idCnr, err := n.neoFS.CreateContainer(ctx, PrmContainerCreate{
|
idCnr, err := n.frostFS.CreateContainer(ctx, PrmContainerCreate{
|
||||||
Creator: bktInfo.Owner,
|
Creator: bktInfo.Owner,
|
||||||
Policy: p.Policy,
|
Policy: p.Policy,
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
|
@ -158,9 +158,9 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*da
|
||||||
func (n *layer) setContainerEACLTable(ctx context.Context, idCnr cid.ID, table *eacl.Table, sessionToken *session.Container) error {
|
func (n *layer) setContainerEACLTable(ctx context.Context, idCnr cid.ID, table *eacl.Table, sessionToken *session.Container) error {
|
||||||
table.SetCID(idCnr)
|
table.SetCID(idCnr)
|
||||||
|
|
||||||
return n.neoFS.SetContainerEACL(ctx, *table, sessionToken)
|
return n.frostFS.SetContainerEACL(ctx, *table, sessionToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *layer) GetContainerEACL(ctx context.Context, idCnr cid.ID) (*eacl.Table, error) {
|
func (n *layer) GetContainerEACL(ctx context.Context, idCnr cid.ID) (*eacl.Table, error) {
|
||||||
return n.neoFS.ContainerEACL(ctx, idCnr)
|
return n.frostFS.ContainerEACL(ctx, idCnr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,9 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrmContainerCreate groups parameters of NeoFS.CreateContainer operation.
|
// PrmContainerCreate groups parameters of FrostFS.CreateContainer operation.
|
||||||
type PrmContainerCreate struct {
|
type PrmContainerCreate struct {
|
||||||
// NeoFS identifier of the container creator.
|
// FrostFS identifier of the container creator.
|
||||||
Creator user.ID
|
Creator user.ID
|
||||||
|
|
||||||
// Container placement policy.
|
// Container placement policy.
|
||||||
|
@ -43,7 +43,7 @@ type PrmContainerCreate struct {
|
||||||
AdditionalAttributes [][2]string
|
AdditionalAttributes [][2]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrmAuth groups authentication parameters for the NeoFS operation.
|
// PrmAuth groups authentication parameters for the FrostFS operation.
|
||||||
type PrmAuth struct {
|
type PrmAuth struct {
|
||||||
// Bearer token to be used for the operation. Overlaps PrivateKey. Optional.
|
// Bearer token to be used for the operation. Overlaps PrivateKey. Optional.
|
||||||
BearerToken *bearer.Token
|
BearerToken *bearer.Token
|
||||||
|
@ -52,7 +52,7 @@ type PrmAuth struct {
|
||||||
PrivateKey *ecdsa.PrivateKey
|
PrivateKey *ecdsa.PrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrmObjectRead groups parameters of NeoFS.ReadObject operation.
|
// PrmObjectRead groups parameters of FrostFS.ReadObject operation.
|
||||||
type PrmObjectRead struct {
|
type PrmObjectRead struct {
|
||||||
// Authentication parameters.
|
// Authentication parameters.
|
||||||
PrmAuth
|
PrmAuth
|
||||||
|
@ -73,7 +73,7 @@ type PrmObjectRead struct {
|
||||||
PayloadRange [2]uint64
|
PayloadRange [2]uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectPart represents partially read NeoFS object.
|
// ObjectPart represents partially read FrostFS object.
|
||||||
type ObjectPart struct {
|
type ObjectPart struct {
|
||||||
// Object header with optional in-memory payload part.
|
// Object header with optional in-memory payload part.
|
||||||
Head *object.Object
|
Head *object.Object
|
||||||
|
@ -83,7 +83,7 @@ type ObjectPart struct {
|
||||||
Payload io.ReadCloser
|
Payload io.ReadCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrmObjectCreate groups parameters of NeoFS.CreateObject operation.
|
// PrmObjectCreate groups parameters of FrostFS.CreateObject operation.
|
||||||
type PrmObjectCreate struct {
|
type PrmObjectCreate struct {
|
||||||
// Authentication parameters.
|
// Authentication parameters.
|
||||||
PrmAuth
|
PrmAuth
|
||||||
|
@ -91,7 +91,7 @@ type PrmObjectCreate struct {
|
||||||
// Container to store the object.
|
// Container to store the object.
|
||||||
Container cid.ID
|
Container cid.ID
|
||||||
|
|
||||||
// NeoFS identifier of the object creator.
|
// FrostFS identifier of the object creator.
|
||||||
Creator user.ID
|
Creator user.ID
|
||||||
|
|
||||||
// Key-value object attributes.
|
// Key-value object attributes.
|
||||||
|
@ -116,7 +116,7 @@ type PrmObjectCreate struct {
|
||||||
CopiesNumber uint32
|
CopiesNumber uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrmObjectDelete groups parameters of NeoFS.DeleteObject operation.
|
// PrmObjectDelete groups parameters of FrostFS.DeleteObject operation.
|
||||||
type PrmObjectDelete struct {
|
type PrmObjectDelete struct {
|
||||||
// Authentication parameters.
|
// Authentication parameters.
|
||||||
PrmAuth
|
PrmAuth
|
||||||
|
@ -128,12 +128,12 @@ type PrmObjectDelete struct {
|
||||||
Object oid.ID
|
Object oid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrAccessDenied is returned from NeoFS in case of access violation.
|
// ErrAccessDenied is returned from FrostFS in case of access violation.
|
||||||
var ErrAccessDenied = errors.New("access denied")
|
var ErrAccessDenied = errors.New("access denied")
|
||||||
|
|
||||||
// NeoFS represents virtual connection to NeoFS network.
|
// FrostFS represents virtual connection to FrostFS network.
|
||||||
type NeoFS interface {
|
type FrostFS interface {
|
||||||
// CreateContainer creates and saves parameterized container in NeoFS.
|
// CreateContainer creates and saves parameterized container in FrostFS.
|
||||||
// It sets 'Timestamp' attribute to the current time.
|
// It sets 'Timestamp' attribute to the current time.
|
||||||
// It returns the ID of the saved container.
|
// It returns the ID of the saved container.
|
||||||
//
|
//
|
||||||
|
@ -143,7 +143,7 @@ type NeoFS interface {
|
||||||
// prevented the container from being created.
|
// prevented the container from being created.
|
||||||
CreateContainer(context.Context, PrmContainerCreate) (cid.ID, error)
|
CreateContainer(context.Context, PrmContainerCreate) (cid.ID, error)
|
||||||
|
|
||||||
// Container reads a container from NeoFS by ID.
|
// Container reads a container from FrostFS by ID.
|
||||||
//
|
//
|
||||||
// It returns exactly one non-nil value. It returns any error encountered which
|
// It returns exactly one non-nil value. It returns any error encountered which
|
||||||
// prevented the container from being read.
|
// prevented the container from being read.
|
||||||
|
@ -155,26 +155,26 @@ type NeoFS interface {
|
||||||
// prevented the containers from being listed.
|
// prevented the containers from being listed.
|
||||||
UserContainers(context.Context, user.ID) ([]cid.ID, error)
|
UserContainers(context.Context, user.ID) ([]cid.ID, error)
|
||||||
|
|
||||||
// SetContainerEACL saves the eACL table of the container in NeoFS. The
|
// SetContainerEACL saves the eACL table of the container in FrostFS. The
|
||||||
// extended ACL is modified within session if session token is not nil.
|
// extended ACL is modified within session if session token is not nil.
|
||||||
//
|
//
|
||||||
// It returns any error encountered which prevented the eACL from being saved.
|
// It returns any error encountered which prevented the eACL from being saved.
|
||||||
SetContainerEACL(context.Context, eacl.Table, *session.Container) error
|
SetContainerEACL(context.Context, eacl.Table, *session.Container) error
|
||||||
|
|
||||||
// ContainerEACL reads the container eACL from NeoFS by the container ID.
|
// ContainerEACL reads the container eACL from FrostFS by the container ID.
|
||||||
//
|
//
|
||||||
// It returns exactly one non-nil value. It returns any error encountered which
|
// It returns exactly one non-nil value. It returns any error encountered which
|
||||||
// prevented the eACL from being read.
|
// prevented the eACL from being read.
|
||||||
ContainerEACL(context.Context, cid.ID) (*eacl.Table, error)
|
ContainerEACL(context.Context, cid.ID) (*eacl.Table, error)
|
||||||
|
|
||||||
// DeleteContainer marks the container to be removed from NeoFS by ID.
|
// DeleteContainer marks the container to be removed from FrostFS by ID.
|
||||||
// Request is sent within session if the session token is specified.
|
// Request is sent within session if the session token is specified.
|
||||||
// Successful return does not guarantee actual removal.
|
// Successful return does not guarantee actual removal.
|
||||||
//
|
//
|
||||||
// It returns any error encountered which prevented the removal request from being sent.
|
// It returns any error encountered which prevented the removal request from being sent.
|
||||||
DeleteContainer(context.Context, cid.ID, *session.Container) error
|
DeleteContainer(context.Context, cid.ID, *session.Container) error
|
||||||
|
|
||||||
// ReadObject reads a part of the object from the NeoFS container by identifier.
|
// ReadObject reads a part of the object from the FrostFS container by identifier.
|
||||||
// Exact part is returned according to the parameters:
|
// Exact part is returned according to the parameters:
|
||||||
// * with header only: empty payload (both in-mem and reader parts are nil);
|
// * with header only: empty payload (both in-mem and reader parts are nil);
|
||||||
// * with payload only: header is nil (zero range means full payload);
|
// * with payload only: header is nil (zero range means full payload);
|
||||||
|
@ -190,7 +190,7 @@ type NeoFS interface {
|
||||||
// prevented the object header from being read.
|
// prevented the object header from being read.
|
||||||
ReadObject(context.Context, PrmObjectRead) (*ObjectPart, error)
|
ReadObject(context.Context, PrmObjectRead) (*ObjectPart, error)
|
||||||
|
|
||||||
// CreateObject creates and saves a parameterized object in the NeoFS container.
|
// CreateObject creates and saves a parameterized object in the FrostFS container.
|
||||||
// It sets 'Timestamp' attribute to the current time.
|
// It sets 'Timestamp' attribute to the current time.
|
||||||
// It returns the ID of the saved object.
|
// It returns the ID of the saved object.
|
||||||
//
|
//
|
||||||
|
@ -202,7 +202,7 @@ type NeoFS interface {
|
||||||
// prevented the container from being created.
|
// prevented the container from being created.
|
||||||
CreateObject(context.Context, PrmObjectCreate) (oid.ID, error)
|
CreateObject(context.Context, PrmObjectCreate) (oid.ID, error)
|
||||||
|
|
||||||
// DeleteObject marks the object to be removed from the NeoFS container by identifier.
|
// DeleteObject marks the object to be removed from the FrostFS container by identifier.
|
||||||
// Successful return does not guarantee actual removal.
|
// Successful return does not guarantee actual removal.
|
||||||
//
|
//
|
||||||
// It returns ErrAccessDenied on remove access violation.
|
// It returns ErrAccessDenied on remove access violation.
|
|
@ -45,7 +45,7 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
layer struct {
|
layer struct {
|
||||||
neoFS NeoFS
|
frostFS FrostFS
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
anonKey AnonymousKey
|
anonKey AnonymousKey
|
||||||
resolver BucketResolver
|
resolver BucketResolver
|
||||||
|
@ -250,12 +250,12 @@ const (
|
||||||
|
|
||||||
AESEncryptionAlgorithm = "AES256"
|
AESEncryptionAlgorithm = "AES256"
|
||||||
AESKeySize = 32
|
AESKeySize = 32
|
||||||
AttributeEncryptionAlgorithm = api.NeoFSSystemMetadataPrefix + "Algorithm"
|
AttributeEncryptionAlgorithm = api.FrostFSSystemMetadataPrefix + "Algorithm"
|
||||||
AttributeDecryptedSize = api.NeoFSSystemMetadataPrefix + "Decrypted-Size"
|
AttributeDecryptedSize = api.FrostFSSystemMetadataPrefix + "Decrypted-Size"
|
||||||
AttributeHMACSalt = api.NeoFSSystemMetadataPrefix + "HMAC-Salt"
|
AttributeHMACSalt = api.FrostFSSystemMetadataPrefix + "HMAC-Salt"
|
||||||
AttributeHMACKey = api.NeoFSSystemMetadataPrefix + "HMAC-Key"
|
AttributeHMACKey = api.FrostFSSystemMetadataPrefix + "HMAC-Key"
|
||||||
|
|
||||||
AttributeNeofsCopiesNumber = "neofs-copies-number" // such formate to match X-Amz-Meta-Neofs-Copies-Number header
|
AttributeFrostfsCopiesNumber = "frostfs-copies-number" // such format to match X-Amz-Meta-Frostfs-Copies-Number header
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *VersionedObject) String() string {
|
func (t *VersionedObject) String() string {
|
||||||
|
@ -268,9 +268,9 @@ func (f MsgHandlerFunc) HandleMessage(ctx context.Context, msg *nats.Msg) error
|
||||||
|
|
||||||
// NewLayer creates an instance of a layer. It checks credentials
|
// NewLayer creates an instance of a layer. It checks credentials
|
||||||
// and establishes gRPC connection with the node.
|
// and establishes gRPC connection with the node.
|
||||||
func NewLayer(log *zap.Logger, neoFS NeoFS, config *Config) Client {
|
func NewLayer(log *zap.Logger, frostFS FrostFS, config *Config) Client {
|
||||||
return &layer{
|
return &layer{
|
||||||
neoFS: neoFS,
|
frostFS: frostFS,
|
||||||
log: log,
|
log: log,
|
||||||
anonKey: config.AnonKey,
|
anonKey: config.AnonKey,
|
||||||
resolver: config.Resolver,
|
resolver: config.Resolver,
|
||||||
|
@ -377,7 +377,7 @@ func (n *layer) PutBucketACL(ctx context.Context, param *PutBucketACLParams) err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListBuckets returns all user containers. The name of the bucket is a container
|
// ListBuckets returns all user containers. The name of the bucket is a container
|
||||||
// id. Timestamp is omitted since it is not saved in neofs container.
|
// id. Timestamp is omitted since it is not saved in frostfs container.
|
||||||
func (n *layer) ListBuckets(ctx context.Context) ([]*data.BucketInfo, error) {
|
func (n *layer) ListBuckets(ctx context.Context) ([]*data.BucketInfo, error) {
|
||||||
return n.containerList(ctx)
|
return n.containerList(ctx)
|
||||||
}
|
}
|
||||||
|
@ -661,5 +661,5 @@ func (n *layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
n.cache.DeleteBucket(p.BktInfo.Name)
|
n.cache.DeleteBucket(p.BktInfo.Name)
|
||||||
return n.neoFS.DeleteContainer(ctx, p.BktInfo.CID, p.SessionToken)
|
return n.frostFS.DeleteContainer(ctx, p.BktInfo.CID, p.SessionToken)
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,7 +311,7 @@ func (n *layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.
|
||||||
return n.uploadPart(ctx, multipartInfo, params)
|
return n.uploadPart(ctx, multipartInfo, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
// implements io.Reader of payloads of the object list stored in the NeoFS network.
|
// implements io.Reader of payloads of the object list stored in the FrostFS network.
|
||||||
type multiObjectReader struct {
|
type multiObjectReader struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestNeoFS struct {
|
type TestFrostFS struct {
|
||||||
NeoFS
|
FrostFS
|
||||||
|
|
||||||
objects map[string]*object.Object
|
objects map[string]*object.Object
|
||||||
containers map[string]*container.Container
|
containers map[string]*container.Container
|
||||||
|
@ -33,19 +33,19 @@ type TestNeoFS struct {
|
||||||
currentEpoch uint64
|
currentEpoch uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestNeoFS() *TestNeoFS {
|
func NewTestFrostFS() *TestFrostFS {
|
||||||
return &TestNeoFS{
|
return &TestFrostFS{
|
||||||
objects: make(map[string]*object.Object),
|
objects: make(map[string]*object.Object),
|
||||||
containers: make(map[string]*container.Container),
|
containers: make(map[string]*container.Container),
|
||||||
eaclTables: make(map[string]*eacl.Table),
|
eaclTables: make(map[string]*eacl.Table),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) CurrentEpoch() uint64 {
|
func (t *TestFrostFS) CurrentEpoch() uint64 {
|
||||||
return t.currentEpoch
|
return t.currentEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) Objects() []*object.Object {
|
func (t *TestFrostFS) Objects() []*object.Object {
|
||||||
res := make([]*object.Object, 0, len(t.objects))
|
res := make([]*object.Object, 0, len(t.objects))
|
||||||
|
|
||||||
for _, obj := range t.objects {
|
for _, obj := range t.objects {
|
||||||
|
@ -55,11 +55,11 @@ func (t *TestNeoFS) Objects() []*object.Object {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) AddObject(key string, obj *object.Object) {
|
func (t *TestFrostFS) AddObject(key string, obj *object.Object) {
|
||||||
t.objects[key] = obj
|
t.objects[key] = obj
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) ContainerID(name string) (cid.ID, error) {
|
func (t *TestFrostFS) ContainerID(name string) (cid.ID, error) {
|
||||||
for id, cnr := range t.containers {
|
for id, cnr := range t.containers {
|
||||||
if container.Name(*cnr) == name {
|
if container.Name(*cnr) == name {
|
||||||
var cnrID cid.ID
|
var cnrID cid.ID
|
||||||
|
@ -69,7 +69,7 @@ func (t *TestNeoFS) ContainerID(name string) (cid.ID, error) {
|
||||||
return cid.ID{}, fmt.Errorf("not found")
|
return cid.ID{}, fmt.Errorf("not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) CreateContainer(_ context.Context, prm PrmContainerCreate) (cid.ID, error) {
|
func (t *TestFrostFS) CreateContainer(_ context.Context, prm PrmContainerCreate) (cid.ID, error) {
|
||||||
var cnr container.Container
|
var cnr container.Container
|
||||||
cnr.Init()
|
cnr.Init()
|
||||||
cnr.SetOwner(prm.Creator)
|
cnr.SetOwner(prm.Creator)
|
||||||
|
@ -106,13 +106,13 @@ func (t *TestNeoFS) CreateContainer(_ context.Context, prm PrmContainerCreate) (
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) DeleteContainer(_ context.Context, cnrID cid.ID, _ *session.Container) error {
|
func (t *TestFrostFS) DeleteContainer(_ context.Context, cnrID cid.ID, _ *session.Container) error {
|
||||||
delete(t.containers, cnrID.EncodeToString())
|
delete(t.containers, cnrID.EncodeToString())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) Container(_ context.Context, id cid.ID) (*container.Container, error) {
|
func (t *TestFrostFS) Container(_ context.Context, id cid.ID) (*container.Container, error) {
|
||||||
for k, v := range t.containers {
|
for k, v := range t.containers {
|
||||||
if k == id.EncodeToString() {
|
if k == id.EncodeToString() {
|
||||||
return v, nil
|
return v, nil
|
||||||
|
@ -122,7 +122,7 @@ func (t *TestNeoFS) Container(_ context.Context, id cid.ID) (*container.Containe
|
||||||
return nil, fmt.Errorf("container not found %s", id)
|
return nil, fmt.Errorf("container not found %s", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) UserContainers(_ context.Context, _ user.ID) ([]cid.ID, error) {
|
func (t *TestFrostFS) UserContainers(_ context.Context, _ user.ID) ([]cid.ID, error) {
|
||||||
var res []cid.ID
|
var res []cid.ID
|
||||||
for k := range t.containers {
|
for k := range t.containers {
|
||||||
var idCnr cid.ID
|
var idCnr cid.ID
|
||||||
|
@ -135,7 +135,7 @@ func (t *TestNeoFS) UserContainers(_ context.Context, _ user.ID) ([]cid.ID, erro
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) ReadObject(ctx context.Context, prm PrmObjectRead) (*ObjectPart, error) {
|
func (t *TestFrostFS) ReadObject(ctx context.Context, prm PrmObjectRead) (*ObjectPart, error) {
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
addr.SetContainer(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObject(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
@ -164,7 +164,7 @@ func (t *TestNeoFS) ReadObject(ctx context.Context, prm PrmObjectRead) (*ObjectP
|
||||||
return nil, fmt.Errorf("object not found %s", addr)
|
return nil, fmt.Errorf("object not found %s", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) CreateObject(ctx context.Context, prm PrmObjectCreate) (oid.ID, error) {
|
func (t *TestFrostFS) CreateObject(ctx context.Context, prm PrmObjectCreate) (oid.ID, error) {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
||||||
return oid.ID{}, err
|
return oid.ID{}, err
|
||||||
|
@ -223,7 +223,7 @@ func (t *TestNeoFS) CreateObject(ctx context.Context, prm PrmObjectCreate) (oid.
|
||||||
return objID, nil
|
return objID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) DeleteObject(ctx context.Context, prm PrmObjectDelete) error {
|
func (t *TestFrostFS) DeleteObject(ctx context.Context, prm PrmObjectDelete) error {
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
addr.SetContainer(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObject(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
@ -240,11 +240,11 @@ func (t *TestNeoFS) DeleteObject(ctx context.Context, prm PrmObjectDelete) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) TimeToEpoch(_ context.Context, now, futureTime time.Time) (uint64, uint64, error) {
|
func (t *TestFrostFS) TimeToEpoch(_ context.Context, now, futureTime time.Time) (uint64, uint64, error) {
|
||||||
return t.currentEpoch, t.currentEpoch + uint64(futureTime.Sub(now).Seconds()), nil
|
return t.currentEpoch, t.currentEpoch + uint64(futureTime.Sub(now).Seconds()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) AllObjects(cnrID cid.ID) []oid.ID {
|
func (t *TestFrostFS) AllObjects(cnrID cid.ID) []oid.ID {
|
||||||
result := make([]oid.ID, 0, len(t.objects))
|
result := make([]oid.ID, 0, len(t.objects))
|
||||||
|
|
||||||
for _, val := range t.objects {
|
for _, val := range t.objects {
|
||||||
|
@ -258,7 +258,7 @@ func (t *TestNeoFS) AllObjects(cnrID cid.ID) []oid.ID {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) SetContainerEACL(_ context.Context, table eacl.Table, _ *session.Container) error {
|
func (t *TestFrostFS) SetContainerEACL(_ context.Context, table eacl.Table, _ *session.Container) error {
|
||||||
cnrID, ok := table.CID()
|
cnrID, ok := table.CID()
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("invalid cid")
|
return errors.New("invalid cid")
|
||||||
|
@ -273,7 +273,7 @@ func (t *TestNeoFS) SetContainerEACL(_ context.Context, table eacl.Table, _ *ses
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) ContainerEACL(_ context.Context, cnrID cid.ID) (*eacl.Table, error) {
|
func (t *TestFrostFS) ContainerEACL(_ context.Context, cnrID cid.ID) (*eacl.Table, error) {
|
||||||
table, ok := t.eaclTables[cnrID.EncodeToString()]
|
table, ok := t.eaclTables[cnrID.EncodeToString()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("not found")
|
return nil, errors.New("not found")
|
||||||
|
|
|
@ -90,7 +90,7 @@ func (n *layer) objectHead(ctx context.Context, bktInfo *data.BucketInfo, idObj
|
||||||
|
|
||||||
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)
|
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)
|
||||||
|
|
||||||
res, err := n.neoFS.ReadObject(ctx, prm)
|
res, err := n.frostFS.ReadObject(ctx, prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ func (n *layer) objectHead(ctx context.Context, bktInfo *data.BucketInfo, idObj
|
||||||
return res.Head, nil
|
return res.Head, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// initializes payload reader of the NeoFS object.
|
// initializes payload reader of the FrostFS object.
|
||||||
// Zero range corresponds to full payload (panics if only offset is set).
|
// Zero range corresponds to full payload (panics if only offset is set).
|
||||||
func (n *layer) initObjectPayloadReader(ctx context.Context, p getParams) (io.Reader, error) {
|
func (n *layer) initObjectPayloadReader(ctx context.Context, p getParams) (io.Reader, error) {
|
||||||
prm := PrmObjectRead{
|
prm := PrmObjectRead{
|
||||||
|
@ -110,7 +110,7 @@ func (n *layer) initObjectPayloadReader(ctx context.Context, p getParams) (io.Re
|
||||||
|
|
||||||
n.prepareAuthParameters(ctx, &prm.PrmAuth, p.bktInfo.Owner)
|
n.prepareAuthParameters(ctx, &prm.PrmAuth, p.bktInfo.Owner)
|
||||||
|
|
||||||
res, err := n.neoFS.ReadObject(ctx, prm)
|
res, err := n.frostFS.ReadObject(ctx, prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ func (n *layer) objectGet(ctx context.Context, bktInfo *data.BucketInfo, objID o
|
||||||
|
|
||||||
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)
|
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)
|
||||||
|
|
||||||
res, err := n.neoFS.ReadObject(ctx, prm)
|
res, err := n.frostFS.ReadObject(ctx, prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ func ParseCompletedPartHeader(hdr string) (*Part, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutObject stores object into NeoFS, took payload from io.Reader.
|
// PutObject stores object into FrostFS, took payload from io.Reader.
|
||||||
func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ExtendedObjectInfo, error) {
|
func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ExtendedObjectInfo, error) {
|
||||||
owner := n.Owner(ctx)
|
owner := n.Owner(ctx)
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ func (n *layer) headVersion(ctx context.Context, bkt *data.BucketInfo, p *HeadOb
|
||||||
return extObjInfo, nil
|
return extObjInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectDelete puts tombstone object into neofs.
|
// objectDelete puts tombstone object into frostfs.
|
||||||
func (n *layer) objectDelete(ctx context.Context, bktInfo *data.BucketInfo, idObj oid.ID) error {
|
func (n *layer) objectDelete(ctx context.Context, bktInfo *data.BucketInfo, idObj oid.ID) error {
|
||||||
prm := PrmObjectDelete{
|
prm := PrmObjectDelete{
|
||||||
Container: bktInfo.CID,
|
Container: bktInfo.CID,
|
||||||
|
@ -394,10 +394,10 @@ func (n *layer) objectDelete(ctx context.Context, bktInfo *data.BucketInfo, idOb
|
||||||
|
|
||||||
n.cache.DeleteObject(newAddress(bktInfo.CID, idObj))
|
n.cache.DeleteObject(newAddress(bktInfo.CID, idObj))
|
||||||
|
|
||||||
return n.neoFS.DeleteObject(ctx, prm)
|
return n.frostFS.DeleteObject(ctx, prm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectPutAndHash prepare auth parameters and invoke neofs.CreateObject.
|
// objectPutAndHash prepare auth parameters and invoke frostfs.CreateObject.
|
||||||
// Returns object ID and payload sha256 hash.
|
// Returns object ID and payload sha256 hash.
|
||||||
func (n *layer) objectPutAndHash(ctx context.Context, prm PrmObjectCreate, bktInfo *data.BucketInfo) (oid.ID, []byte, error) {
|
func (n *layer) objectPutAndHash(ctx context.Context, prm PrmObjectCreate, bktInfo *data.BucketInfo) (oid.ID, []byte, error) {
|
||||||
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)
|
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)
|
||||||
|
@ -405,7 +405,7 @@ func (n *layer) objectPutAndHash(ctx context.Context, prm PrmObjectCreate, bktIn
|
||||||
prm.Payload = wrapReader(prm.Payload, 64*1024, func(buf []byte) {
|
prm.Payload = wrapReader(prm.Payload, 64*1024, func(buf []byte) {
|
||||||
hash.Write(buf)
|
hash.Write(buf)
|
||||||
})
|
})
|
||||||
id, err := n.neoFS.CreateObject(ctx, prm)
|
id, err := n.frostFS.CreateObject(ctx, prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oid.ID{}, nil, err
|
return oid.ID{}, nil, err
|
||||||
}
|
}
|
||||||
|
@ -577,10 +577,10 @@ func (n *layer) initWorkerPool(ctx context.Context, size int, p allObjectParams,
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
err = pool.Submit(func() {
|
err = pool.Submit(func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
oi := n.objectInfoFromObjectsCacheOrNeoFS(ctx, p.Bucket, node, p.Prefix, p.Delimiter)
|
oi := n.objectInfoFromObjectsCacheOrFrostFS(ctx, p.Bucket, node, p.Prefix, p.Delimiter)
|
||||||
if oi == nil {
|
if oi == nil {
|
||||||
// try to get object again
|
// try to get object again
|
||||||
if oi = n.objectInfoFromObjectsCacheOrNeoFS(ctx, p.Bucket, node, p.Prefix, p.Delimiter); oi == nil {
|
if oi = n.objectInfoFromObjectsCacheOrFrostFS(ctx, p.Bucket, node, p.Prefix, p.Delimiter); oi == nil {
|
||||||
// form object info with data that the tree node contains
|
// form object info with data that the tree node contains
|
||||||
oi = getPartialObjectInfo(p.Bucket, node)
|
oi = getPartialObjectInfo(p.Bucket, node)
|
||||||
}
|
}
|
||||||
|
@ -646,14 +646,14 @@ func (n *layer) getAllObjectsVersions(ctx context.Context, bkt *data.BucketInfo,
|
||||||
for _, nodeVersion := range nodeVersions {
|
for _, nodeVersion := range nodeVersions {
|
||||||
oi := &data.ObjectInfo{}
|
oi := &data.ObjectInfo{}
|
||||||
|
|
||||||
if nodeVersion.IsDeleteMarker() { // delete marker does not match any object in NeoFS
|
if nodeVersion.IsDeleteMarker() { // delete marker does not match any object in FrostFS
|
||||||
oi.ID = nodeVersion.OID
|
oi.ID = nodeVersion.OID
|
||||||
oi.Name = nodeVersion.FilePath
|
oi.Name = nodeVersion.FilePath
|
||||||
oi.Owner = nodeVersion.DeleteMarker.Owner
|
oi.Owner = nodeVersion.DeleteMarker.Owner
|
||||||
oi.Created = nodeVersion.DeleteMarker.Created
|
oi.Created = nodeVersion.DeleteMarker.Created
|
||||||
oi.IsDeleteMarker = true
|
oi.IsDeleteMarker = true
|
||||||
} else {
|
} else {
|
||||||
if oi = n.objectInfoFromObjectsCacheOrNeoFS(ctx, bkt, nodeVersion, prefix, delimiter); oi == nil {
|
if oi = n.objectInfoFromObjectsCacheOrFrostFS(ctx, bkt, nodeVersion, prefix, delimiter); oi == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -677,7 +677,7 @@ func (n *layer) getAllObjectsVersions(ctx context.Context, bkt *data.BucketInfo,
|
||||||
|
|
||||||
func IsSystemHeader(key string) bool {
|
func IsSystemHeader(key string) bool {
|
||||||
_, ok := api.SystemMetadata[key]
|
_, ok := api.SystemMetadata[key]
|
||||||
return ok || strings.HasPrefix(key, api.NeoFSSystemMetadataPrefix)
|
return ok || strings.HasPrefix(key, api.FrostFSSystemMetadataPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldSkip(node *data.NodeVersion, p allObjectParams, existed map[string]struct{}) bool {
|
func shouldSkip(node *data.NodeVersion, p allObjectParams, existed map[string]struct{}) bool {
|
||||||
|
@ -734,7 +734,7 @@ func triageExtendedObjects(allObjects []*data.ExtendedObjectInfo) (prefixes []st
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *layer) objectInfoFromObjectsCacheOrNeoFS(ctx context.Context, bktInfo *data.BucketInfo, node *data.NodeVersion, prefix, delimiter string) (oi *data.ObjectInfo) {
|
func (n *layer) objectInfoFromObjectsCacheOrFrostFS(ctx context.Context, bktInfo *data.BucketInfo, node *data.NodeVersion, prefix, delimiter string) (oi *data.ObjectInfo) {
|
||||||
if oiDir := tryDirectory(bktInfo, node, prefix, delimiter); oiDir != nil {
|
if oiDir := tryDirectory(bktInfo, node, prefix, delimiter); oiDir != nil {
|
||||||
return oiDir
|
return oiDir
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ func (n *layer) PutLockInfo(ctx context.Context, p *PutLockInfoParams) (err erro
|
||||||
// sometimes node version can be provided from executing context
|
// sometimes node version can be provided from executing context
|
||||||
// if not, then receive node version from tree service
|
// if not, then receive node version from tree service
|
||||||
if versionNode == nil {
|
if versionNode == nil {
|
||||||
versionNode, err = n.getNodeVersionFromCacheOrNeofs(ctx, p.ObjVersion)
|
versionNode, err = n.getNodeVersionFromCacheOrFrostfs(ctx, p.ObjVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ func (n *layer) PutLockInfo(ctx context.Context, p *PutLockInfoParams) (err erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *layer) getNodeVersionFromCacheOrNeofs(ctx context.Context, objVersion *ObjectVersion) (nodeVersion *data.NodeVersion, err error) {
|
func (n *layer) getNodeVersionFromCacheOrFrostfs(ctx context.Context, objVersion *ObjectVersion) (nodeVersion *data.NodeVersion, err error) {
|
||||||
// check cache if node version is stored inside extendedObjectVersion
|
// check cache if node version is stored inside extendedObjectVersion
|
||||||
nodeVersion = n.getNodeVersionFromCache(n.Owner(ctx), objVersion)
|
nodeVersion = n.getNodeVersionFromCache(n.Owner(ctx), objVersion)
|
||||||
if nodeVersion == nil {
|
if nodeVersion == nil {
|
||||||
|
@ -228,7 +228,7 @@ func (n *layer) attributesFromLock(ctx context.Context, lock *data.ObjectLock) (
|
||||||
)
|
)
|
||||||
|
|
||||||
if lock.Retention != nil {
|
if lock.Retention != nil {
|
||||||
if _, expEpoch, err = n.neoFS.TimeToEpoch(ctx, TimeNow(ctx), lock.Retention.Until); err != nil {
|
if _, expEpoch, err = n.frostFS.TimeToEpoch(ctx, TimeNow(ctx), lock.Retention.Until); err != nil {
|
||||||
return nil, fmt.Errorf("fetch time to epoch: %w", err)
|
return nil, fmt.Errorf("fetch time to epoch: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ func (n *layer) attributesFromLock(ctx context.Context, lock *data.ObjectLock) (
|
||||||
}
|
}
|
||||||
|
|
||||||
if lock.LegalHold != nil && lock.LegalHold.Enabled {
|
if lock.LegalHold != nil && lock.LegalHold.Enabled {
|
||||||
// todo: (@KirillovDenis) reconsider this when NeoFS will support Legal Hold https://github.com/nspcc-dev/neofs-contract/issues/247
|
// todo: (@KirillovDenis) reconsider this when FrostFS will support Legal Hold https://github.com/TrueCloudLab/frostfs-contract/issues/2
|
||||||
// Currently lock object must have an expiration epoch.
|
// Currently lock object must have an expiration epoch.
|
||||||
// Besides we need to override retention expiration epoch since legal hold cannot be deleted yet.
|
// Besides we need to override retention expiration epoch since legal hold cannot be deleted yet.
|
||||||
expEpoch = math.MaxUint64
|
expEpoch = math.MaxUint64
|
||||||
|
|
|
@ -38,7 +38,7 @@ func (n *layer) GetObjectTagging(ctx context.Context, p *GetObjectTaggingParams)
|
||||||
|
|
||||||
nodeVersion := p.NodeVersion
|
nodeVersion := p.NodeVersion
|
||||||
if nodeVersion == nil {
|
if nodeVersion == nil {
|
||||||
nodeVersion, err = n.getNodeVersionFromCacheOrNeofs(ctx, p.ObjectVersion)
|
nodeVersion, err = n.getNodeVersionFromCacheOrFrostfs(ctx, p.ObjectVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ func (n *layer) GetObjectTagging(ctx context.Context, p *GetObjectTaggingParams)
|
||||||
func (n *layer) PutObjectTagging(ctx context.Context, p *PutObjectTaggingParams) (nodeVersion *data.NodeVersion, err error) {
|
func (n *layer) PutObjectTagging(ctx context.Context, p *PutObjectTaggingParams) (nodeVersion *data.NodeVersion, err error) {
|
||||||
nodeVersion = p.NodeVersion
|
nodeVersion = p.NodeVersion
|
||||||
if nodeVersion == nil {
|
if nodeVersion == nil {
|
||||||
nodeVersion, err = n.getNodeVersionFromCacheOrNeofs(ctx, p.ObjectVersion)
|
nodeVersion, err = n.getNodeVersionFromCacheOrFrostfs(ctx, p.ObjectVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ type TreeService interface {
|
||||||
GetNotificationConfigurationNode(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error)
|
GetNotificationConfigurationNode(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error)
|
||||||
|
|
||||||
// PutNotificationConfigurationNode puts a node to a system tree
|
// PutNotificationConfigurationNode puts a node to a system tree
|
||||||
// and returns objectID of a previous notif config which must be deleted in NeoFS.
|
// and returns objectID of a previous notif config which must be deleted in FrostFS.
|
||||||
//
|
//
|
||||||
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
||||||
PutNotificationConfigurationNode(ctx context.Context, bktInfo *data.BucketInfo, objID oid.ID) (oid.ID, error)
|
PutNotificationConfigurationNode(ctx context.Context, bktInfo *data.BucketInfo, objID oid.ID) (oid.ID, error)
|
||||||
|
@ -34,12 +34,12 @@ type TreeService interface {
|
||||||
// If object id is not found returns ErrNodeNotFound error.
|
// If object id is not found returns ErrNodeNotFound error.
|
||||||
GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error)
|
GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error)
|
||||||
|
|
||||||
// PutBucketCORS puts a node to a system tree and returns objectID of a previous cors config which must be deleted in NeoFS.
|
// PutBucketCORS puts a node to a system tree and returns objectID of a previous cors config which must be deleted in FrostFS.
|
||||||
//
|
//
|
||||||
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
||||||
PutBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, objID oid.ID) (oid.ID, error)
|
PutBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, objID oid.ID) (oid.ID, error)
|
||||||
|
|
||||||
// DeleteBucketCORS removes a node from a system tree and returns objID which must be deleted in NeoFS.
|
// DeleteBucketCORS removes a node from a system tree and returns objID which must be deleted in FrostFS.
|
||||||
//
|
//
|
||||||
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
||||||
DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error)
|
DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.ID, error)
|
||||||
|
@ -69,7 +69,7 @@ type TreeService interface {
|
||||||
GetMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, objectName, uploadID string) (*data.MultipartInfo, error)
|
GetMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, objectName, uploadID string) (*data.MultipartInfo, error)
|
||||||
|
|
||||||
// AddPart puts a node to a system tree as a child of appropriate multipart upload
|
// AddPart puts a node to a system tree as a child of appropriate multipart upload
|
||||||
// and returns objectID of a previous part which must be deleted in NeoFS.
|
// and returns objectID of a previous part which must be deleted in FrostFS.
|
||||||
//
|
//
|
||||||
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
// If object id to remove is not found returns ErrNoNodeToRemove error.
|
||||||
AddPart(ctx context.Context, bktInfo *data.BucketInfo, multipartNodeID uint64, info *data.PartInfo) (oldObjIDToDelete oid.ID, err error)
|
AddPart(ctx context.Context, bktInfo *data.BucketInfo, multipartNodeID uint64, info *data.PartInfo) (oldObjIDToDelete oid.ID, err error)
|
||||||
|
|
|
@ -113,7 +113,7 @@ func (tc *testContext) checkListObjects(ids ...oid.ID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *testContext) getObjectByID(objID oid.ID) *object.Object {
|
func (tc *testContext) getObjectByID(objID oid.ID) *object.Object {
|
||||||
for _, obj := range tc.testNeoFS.Objects() {
|
for _, obj := range tc.testFrostFS.Objects() {
|
||||||
id, _ := obj.ID()
|
id, _ := obj.ID()
|
||||||
if id.Equals(objID) {
|
if id.Equals(objID) {
|
||||||
return obj
|
return obj
|
||||||
|
@ -123,12 +123,12 @@ func (tc *testContext) getObjectByID(objID oid.ID) *object.Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
type testContext struct {
|
type testContext struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
layer Client
|
layer Client
|
||||||
bktInfo *data.BucketInfo
|
bktInfo *data.BucketInfo
|
||||||
obj string
|
obj string
|
||||||
testNeoFS *TestNeoFS
|
testFrostFS *TestFrostFS
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
|
@ -146,7 +146,7 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
GateKey: key.PublicKey(),
|
GateKey: key.PublicKey(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
tp := NewTestNeoFS()
|
tp := NewTestFrostFS()
|
||||||
|
|
||||||
bktName := "testbucket1"
|
bktName := "testbucket1"
|
||||||
bktID, err := tp.CreateContainer(ctx, PrmContainerCreate{
|
bktID, err := tp.CreateContainer(ctx, PrmContainerCreate{
|
||||||
|
@ -176,9 +176,9 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
CID: bktID,
|
CID: bktID,
|
||||||
},
|
},
|
||||||
obj: "obj1",
|
obj: "obj1",
|
||||||
t: t,
|
t: t,
|
||||||
testNeoFS: tp,
|
testFrostFS: tp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,22 +55,22 @@ var (
|
||||||
httpStatsMetric = new(HTTPStats)
|
httpStatsMetric = new(HTTPStats)
|
||||||
httpRequestsDuration = prometheus.NewHistogramVec(
|
httpRequestsDuration = prometheus.NewHistogramVec(
|
||||||
prometheus.HistogramOpts{
|
prometheus.HistogramOpts{
|
||||||
Name: "neofs_s3_request_seconds",
|
Name: "frostfs_s3_request_seconds",
|
||||||
Help: "Time taken by requests served by current NeoFS S3 Gate instance",
|
Help: "Time taken by requests served by current FrostFS S3 Gate instance",
|
||||||
Buckets: []float64{.05, .1, .25, .5, 1, 2.5, 5, 10},
|
Buckets: []float64{.05, .1, .25, .5, 1, 2.5, 5, 10},
|
||||||
},
|
},
|
||||||
[]string{"api"},
|
[]string{"api"},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Collects HTTP metrics for NeoFS S3 Gate in Prometheus specific format
|
// Collects HTTP metrics for FrostFS S3 Gate in Prometheus specific format
|
||||||
// and sends to the given channel.
|
// and sends to the given channel.
|
||||||
func collectHTTPMetrics(ch chan<- prometheus.Metric) {
|
func collectHTTPMetrics(ch chan<- prometheus.Metric) {
|
||||||
for api, value := range httpStatsMetric.currentS3Requests.Load() {
|
for api, value := range httpStatsMetric.currentS3Requests.Load() {
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName("neofs_s3", "requests", "current"),
|
prometheus.BuildFQName("frostfs_s3", "requests", "current"),
|
||||||
"Total number of running s3 requests in current NeoFS S3 Gate instance",
|
"Total number of running s3 requests in current FrostFS S3 Gate instance",
|
||||||
[]string{"api"}, nil),
|
[]string{"api"}, nil),
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(value),
|
float64(value),
|
||||||
|
@ -81,8 +81,8 @@ func collectHTTPMetrics(ch chan<- prometheus.Metric) {
|
||||||
for api, value := range httpStatsMetric.totalS3Requests.Load() {
|
for api, value := range httpStatsMetric.totalS3Requests.Load() {
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName("neofs_s3", "requests", "total"),
|
prometheus.BuildFQName("frostfs_s3", "requests", "total"),
|
||||||
"Total number of s3 requests in current NeoFS S3 Gate instance",
|
"Total number of s3 requests in current FrostFS S3 Gate instance",
|
||||||
[]string{"api"}, nil),
|
[]string{"api"}, nil),
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(value),
|
float64(value),
|
||||||
|
@ -93,8 +93,8 @@ func collectHTTPMetrics(ch chan<- prometheus.Metric) {
|
||||||
for api, value := range httpStatsMetric.totalS3Errors.Load() {
|
for api, value := range httpStatsMetric.totalS3Errors.Load() {
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName("neofs_s3", "errors", "total"),
|
prometheus.BuildFQName("frostfs_s3", "errors", "total"),
|
||||||
"Total number of s3 errors in current NeoFS S3 Gate instance",
|
"Total number of s3 errors in current FrostFS S3 Gate instance",
|
||||||
[]string{"api"}, nil),
|
[]string{"api"}, nil),
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(value),
|
float64(value),
|
||||||
|
|
|
@ -12,9 +12,9 @@ type stats struct {
|
||||||
var (
|
var (
|
||||||
versionInfo = prometheus.NewGaugeVec(
|
versionInfo = prometheus.NewGaugeVec(
|
||||||
prometheus.GaugeOpts{
|
prometheus.GaugeOpts{
|
||||||
Namespace: "neofs_s3",
|
Namespace: "frostfs_s3",
|
||||||
Name: "version_info",
|
Name: "version_info",
|
||||||
Help: "Version of current NeoFS S3 Gate instance",
|
Help: "Version of current FrostFS S3 Gate instance",
|
||||||
},
|
},
|
||||||
[]string{
|
[]string{
|
||||||
// current version
|
// current version
|
||||||
|
@ -23,7 +23,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
statsMetrics = &stats{
|
statsMetrics = &stats{
|
||||||
desc: prometheus.NewDesc("neofs_s3_stats", "Statistics exposed by NeoFS S3 Gate instance", nil, nil),
|
desc: prometheus.NewDesc("frostfs_s3_stats", "Statistics exposed by FrostFS S3 Gate instance", nil, nil),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ func collectNetworkMetrics(ch chan<- prometheus.Metric) {
|
||||||
// Network Sent/Received Bytes (Outbound)
|
// Network Sent/Received Bytes (Outbound)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName("neofs_s3", "tx", "bytes_total"),
|
prometheus.BuildFQName("frostfs_s3", "tx", "bytes_total"),
|
||||||
"Total number of bytes sent by current NeoFS S3 Gate instance",
|
"Total number of bytes sent by current FrostFS S3 Gate instance",
|
||||||
nil, nil),
|
nil, nil),
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(httpStatsMetric.getInputBytes()),
|
float64(httpStatsMetric.getInputBytes()),
|
||||||
|
@ -46,8 +46,8 @@ func collectNetworkMetrics(ch chan<- prometheus.Metric) {
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName("neofs_s3", "rx", "bytes_total"),
|
prometheus.BuildFQName("frostfs_s3", "rx", "bytes_total"),
|
||||||
"Total number of bytes received by current NeoFS S3 Gate instance",
|
"Total number of bytes received by current FrostFS S3 Gate instance",
|
||||||
nil, nil),
|
nil, nil),
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(httpStatsMetric.getOutputBytes()),
|
float64(httpStatsMetric.getOutputBytes()),
|
||||||
|
|
|
@ -61,7 +61,7 @@ type (
|
||||||
|
|
||||||
EventRecord struct {
|
EventRecord struct {
|
||||||
EventVersion string `json:"eventVersion"`
|
EventVersion string `json:"eventVersion"`
|
||||||
EventSource string `json:"eventSource"` // neofs:s3
|
EventSource string `json:"eventSource"` // frostfs:s3
|
||||||
AWSRegion string `json:"awsRegion,omitempty"` // empty
|
AWSRegion string `json:"awsRegion,omitempty"` // empty
|
||||||
EventTime time.Time `json:"eventTime"`
|
EventTime time.Time `json:"eventTime"`
|
||||||
EventName string `json:"eventName"`
|
EventName string `json:"eventName"`
|
||||||
|
@ -199,7 +199,7 @@ func (c *Controller) SendNotifications(topics map[string]string, p *handler.Send
|
||||||
|
|
||||||
func (c *Controller) SendTestNotification(topic, bucketName, requestID, HostID string, now time.Time) error {
|
func (c *Controller) SendTestNotification(topic, bucketName, requestID, HostID string, now time.Time) error {
|
||||||
event := &TestEvent{
|
event := &TestEvent{
|
||||||
Service: "NeoFS S3",
|
Service: "FrostFS S3",
|
||||||
Event: "s3:TestEvent",
|
Event: "s3:TestEvent",
|
||||||
Time: now,
|
Time: now,
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
|
@ -220,7 +220,7 @@ func prepareEvent(p *handler.SendNotificationParams) *Event {
|
||||||
Records: []EventRecord{
|
Records: []EventRecord{
|
||||||
{
|
{
|
||||||
EventVersion: EventVersion21,
|
EventVersion: EventVersion21,
|
||||||
EventSource: "neofs:s3",
|
EventSource: "frostfs:s3",
|
||||||
AWSRegion: "",
|
AWSRegion: "",
|
||||||
EventTime: p.Time,
|
EventTime: p.Time,
|
||||||
EventName: p.Event,
|
EventName: p.Event,
|
||||||
|
|
|
@ -19,9 +19,9 @@ const (
|
||||||
// ErrNoResolvers returns when trying to resolve container without any resolver.
|
// ErrNoResolvers returns when trying to resolve container without any resolver.
|
||||||
var ErrNoResolvers = errors.New("no resolvers")
|
var ErrNoResolvers = errors.New("no resolvers")
|
||||||
|
|
||||||
// NeoFS represents virtual connection to the NeoFS network.
|
// FrostFS represents virtual connection to the FrostFS network.
|
||||||
type NeoFS interface {
|
type FrostFS interface {
|
||||||
// SystemDNS reads system DNS network parameters of the NeoFS.
|
// SystemDNS reads system DNS network parameters of the FrostFS.
|
||||||
//
|
//
|
||||||
// It returns exactly on non-zero value. It returns any error encountered
|
// It returns exactly on non-zero value. It returns any error encountered
|
||||||
// which prevented the parameter from being read.
|
// which prevented the parameter from being read.
|
||||||
|
@ -29,7 +29,7 @@ type NeoFS interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
NeoFS NeoFS
|
FrostFS FrostFS
|
||||||
RPCAddress string
|
RPCAddress string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ func (r *BucketResolver) equals(resolverNames []string) bool {
|
||||||
func newResolver(name string, cfg *Config) (*Resolver, error) {
|
func newResolver(name string, cfg *Config) (*Resolver, error) {
|
||||||
switch name {
|
switch name {
|
||||||
case DNSResolver:
|
case DNSResolver:
|
||||||
return NewDNSResolver(cfg.NeoFS)
|
return NewDNSResolver(cfg.FrostFS)
|
||||||
case NNSResolver:
|
case NNSResolver:
|
||||||
return NewNNSResolver(cfg.RPCAddress)
|
return NewNNSResolver(cfg.RPCAddress)
|
||||||
default:
|
default:
|
||||||
|
@ -142,17 +142,17 @@ func newResolver(name string, cfg *Config) (*Resolver, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDNSResolver(neoFS NeoFS) (*Resolver, error) {
|
func NewDNSResolver(frostFS FrostFS) (*Resolver, error) {
|
||||||
if neoFS == nil {
|
if frostFS == nil {
|
||||||
return nil, fmt.Errorf("pool must not be nil for DNS resolver")
|
return nil, fmt.Errorf("pool must not be nil for DNS resolver")
|
||||||
}
|
}
|
||||||
|
|
||||||
var dns ns.DNS
|
var dns ns.DNS
|
||||||
|
|
||||||
resolveFunc := func(ctx context.Context, name string) (cid.ID, error) {
|
resolveFunc := func(ctx context.Context, name string) (cid.ID, error) {
|
||||||
domain, err := neoFS.SystemDNS(ctx)
|
domain, err := frostFS.SystemDNS(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.ID{}, fmt.Errorf("read system DNS parameter of the NeoFS: %w", err)
|
return cid.ID{}, fmt.Errorf("read system DNS parameter of the FrostFS: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
domain = name + "." + domain
|
domain = name + "." + domain
|
||||||
|
|
|
@ -117,7 +117,7 @@ func WriteErrorResponse(w http.ResponseWriter, reqInfo *ReqInfo, err error) int
|
||||||
code = e.HTTPStatusCode
|
code = e.HTTPStatusCode
|
||||||
|
|
||||||
switch e.Code {
|
switch e.Code {
|
||||||
case "SlowDown", "XNeoFSServerNotInitialized", "XNeoFSReadQuorum", "XNeoFSWriteQuorum":
|
case "SlowDown", "XFrostFSServerNotInitialized", "XFrostFSReadQuorum", "XFrostFSWriteQuorum":
|
||||||
// Set retry-after header to indicate user-agents to retry request after 120secs.
|
// Set retry-after header to indicate user-agents to retry request after 120secs.
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
||||||
w.Header().Set(hdrRetryAfter, "120")
|
w.Header().Set(hdrRetryAfter, "120")
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/creds/tokens"
|
"github.com/TrueCloudLab/frostfs-s3-gw/creds/tokens"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
neofsecdsa "github.com/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
frostfsecdsa "github.com/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -29,7 +29,7 @@ import (
|
||||||
|
|
||||||
// PrmContainerCreate groups parameters of containers created by authmate.
|
// PrmContainerCreate groups parameters of containers created by authmate.
|
||||||
type PrmContainerCreate struct {
|
type PrmContainerCreate struct {
|
||||||
// NeoFS identifier of the container creator.
|
// FrostFS identifier of the container creator.
|
||||||
Owner user.ID
|
Owner user.ID
|
||||||
|
|
||||||
// Container placement policy.
|
// Container placement policy.
|
||||||
|
@ -39,26 +39,26 @@ type PrmContainerCreate struct {
|
||||||
FriendlyName string
|
FriendlyName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkState represents NeoFS network state which is needed for authmate processing.
|
// NetworkState represents FrostFS network state which is needed for authmate processing.
|
||||||
type NetworkState struct {
|
type NetworkState struct {
|
||||||
// Current NeoFS time.
|
// Current FrostFS time.
|
||||||
Epoch uint64
|
Epoch uint64
|
||||||
// Duration of the Morph chain block in ms.
|
// Duration of the Morph chain block in ms.
|
||||||
BlockDuration int64
|
BlockDuration int64
|
||||||
// Duration of the NeoFS epoch in Morph chain blocks.
|
// Duration of the FrostFS epoch in Morph chain blocks.
|
||||||
EpochDuration uint64
|
EpochDuration uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeoFS represents virtual connection to NeoFS network.
|
// FrostFS represents virtual connection to FrostFS network.
|
||||||
type NeoFS interface {
|
type FrostFS interface {
|
||||||
// NeoFS interface required by credential tool.
|
// FrostFS interface required by credential tool.
|
||||||
tokens.NeoFS
|
tokens.FrostFS
|
||||||
|
|
||||||
// ContainerExists checks container presence in NeoFS by identifier.
|
// ContainerExists checks container presence in FrostFS by identifier.
|
||||||
// Returns nil if container exists.
|
// Returns nil if container exists.
|
||||||
ContainerExists(context.Context, cid.ID) error
|
ContainerExists(context.Context, cid.ID) error
|
||||||
|
|
||||||
// CreateContainer creates and saves parameterized container in NeoFS.
|
// CreateContainer creates and saves parameterized container in FrostFS.
|
||||||
// It sets 'Timestamp' attribute to the current time.
|
// It sets 'Timestamp' attribute to the current time.
|
||||||
// It returns the ID of the saved container.
|
// It returns the ID of the saved container.
|
||||||
//
|
//
|
||||||
|
@ -78,25 +78,25 @@ type NeoFS interface {
|
||||||
TimeToEpoch(context.Context, time.Time) (uint64, uint64, error)
|
TimeToEpoch(context.Context, time.Time) (uint64, uint64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Agent contains client communicating with NeoFS and logger.
|
// Agent contains client communicating with FrostFS and logger.
|
||||||
type Agent struct {
|
type Agent struct {
|
||||||
neoFS NeoFS
|
frostFS FrostFS
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates an object of type Agent that consists of Client and logger.
|
// New creates an object of type Agent that consists of Client and logger.
|
||||||
func New(log *zap.Logger, neoFS NeoFS) *Agent {
|
func New(log *zap.Logger, frostFS FrostFS) *Agent {
|
||||||
return &Agent{log: log, neoFS: neoFS}
|
return &Agent{log: log, frostFS: frostFS}
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// ContainerPolicies contains mapping of aws LocationConstraint to neofs PlacementPolicy.
|
// ContainerPolicies contains mapping of aws LocationConstraint to frostfs PlacementPolicy.
|
||||||
ContainerPolicies map[string]string
|
ContainerPolicies map[string]string
|
||||||
|
|
||||||
// IssueSecretOptions contains options for passing to Agent.IssueSecret method.
|
// IssueSecretOptions contains options for passing to Agent.IssueSecret method.
|
||||||
IssueSecretOptions struct {
|
IssueSecretOptions struct {
|
||||||
Container ContainerOptions
|
Container ContainerOptions
|
||||||
NeoFSKey *keys.PrivateKey
|
FrostFSKey *keys.PrivateKey
|
||||||
GatesPublicKeys []*keys.PublicKey
|
GatesPublicKeys []*keys.PublicKey
|
||||||
EACLRules []byte
|
EACLRules []byte
|
||||||
SessionTokenRules []byte
|
SessionTokenRules []byte
|
||||||
|
@ -120,7 +120,7 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// lifetimeOptions holds NeoFS epochs, iat -- epoch which the token was issued at, exp -- epoch when the token expires.
|
// lifetimeOptions holds FrostFS epochs, iat -- epoch which the token was issued at, exp -- epoch when the token expires.
|
||||||
type lifetimeOptions struct {
|
type lifetimeOptions struct {
|
||||||
Iat uint64
|
Iat uint64
|
||||||
Exp uint64
|
Exp uint64
|
||||||
|
@ -143,7 +143,7 @@ type (
|
||||||
|
|
||||||
func (a *Agent) checkContainer(ctx context.Context, opts ContainerOptions, idOwner user.ID) (cid.ID, error) {
|
func (a *Agent) checkContainer(ctx context.Context, opts ContainerOptions, idOwner user.ID) (cid.ID, error) {
|
||||||
if !opts.ID.Equals(cid.ID{}) {
|
if !opts.ID.Equals(cid.ID{}) {
|
||||||
return opts.ID, a.neoFS.ContainerExists(ctx, opts.ID)
|
return opts.ID, a.frostFS.ContainerExists(ctx, opts.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
var prm PrmContainerCreate
|
var prm PrmContainerCreate
|
||||||
|
@ -156,9 +156,9 @@ func (a *Agent) checkContainer(ctx context.Context, opts ContainerOptions, idOwn
|
||||||
prm.Owner = idOwner
|
prm.Owner = idOwner
|
||||||
prm.FriendlyName = opts.FriendlyName
|
prm.FriendlyName = opts.FriendlyName
|
||||||
|
|
||||||
cnrID, err := a.neoFS.CreateContainer(ctx, prm)
|
cnrID, err := a.frostFS.CreateContainer(ctx, prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.ID{}, fmt.Errorf("create container in NeoFS: %w", err)
|
return cid.ID{}, fmt.Errorf("create container in FrostFS: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cnrID, nil
|
return cnrID, nil
|
||||||
|
@ -200,7 +200,7 @@ func preparePolicy(policy ContainerPolicies) ([]*accessbox.AccessBox_ContainerPo
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IssueSecret creates an auth token, puts it in the NeoFS network and writes to io.Writer a new secret access key.
|
// IssueSecret creates an auth token, puts it in the FrostFS network and writes to io.Writer a new secret access key.
|
||||||
func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecretOptions) error {
|
func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecretOptions) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
@ -213,7 +213,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
return fmt.Errorf("prepare policies: %w", err)
|
return fmt.Errorf("prepare policies: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lifetime.Iat, lifetime.Exp, err = a.neoFS.TimeToEpoch(ctx, time.Now().Add(options.Lifetime))
|
lifetime.Iat, lifetime.Exp, err = a.frostFS.TimeToEpoch(ctx, time.Now().Add(options.Lifetime))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fetch time to epoch: %w", err)
|
return fmt.Errorf("fetch time to epoch: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
box.ContainerPolicy = policies
|
box.ContainerPolicy = policies
|
||||||
|
|
||||||
var idOwner user.ID
|
var idOwner user.ID
|
||||||
user.IDFromKey(&idOwner, options.NeoFSKey.PrivateKey.PublicKey)
|
user.IDFromKey(&idOwner, options.FrostFSKey.PrivateKey.PublicKey)
|
||||||
|
|
||||||
a.log.Info("check container or create", zap.Stringer("cid", options.Container.ID),
|
a.log.Info("check container or create", zap.Stringer("cid", options.Container.ID),
|
||||||
zap.String("friendly_name", options.Container.FriendlyName),
|
zap.String("friendly_name", options.Container.FriendlyName),
|
||||||
|
@ -241,11 +241,11 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
return fmt.Errorf("check container: %w", err)
|
return fmt.Errorf("check container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.log.Info("store bearer token into NeoFS",
|
a.log.Info("store bearer token into FrostFS",
|
||||||
zap.Stringer("owner_tkn", idOwner))
|
zap.Stringer("owner_tkn", idOwner))
|
||||||
|
|
||||||
addr, err := tokens.
|
addr, err := tokens.
|
||||||
New(a.neoFS, secrets.EphemeralKey, cache.DefaultAccessBoxConfig(a.log)).
|
New(a.frostFS, secrets.EphemeralKey, cache.DefaultAccessBoxConfig(a.log)).
|
||||||
Put(ctx, id, idOwner, box, lifetime.Exp, options.GatesPublicKeys...)
|
Put(ctx, id, idOwner, box, lifetime.Exp, options.GatesPublicKeys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to put bearer token: %w", err)
|
return fmt.Errorf("failed to put bearer token: %w", err)
|
||||||
|
@ -260,7 +260,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
AccessKeyID: accessKeyID,
|
AccessKeyID: accessKeyID,
|
||||||
SecretAccessKey: secrets.AccessKey,
|
SecretAccessKey: secrets.AccessKey,
|
||||||
OwnerPrivateKey: hex.EncodeToString(secrets.EphemeralKey.Bytes()),
|
OwnerPrivateKey: hex.EncodeToString(secrets.EphemeralKey.Bytes()),
|
||||||
WalletPublicKey: hex.EncodeToString(options.NeoFSKey.PublicKey().Bytes()),
|
WalletPublicKey: hex.EncodeToString(options.FrostFSKey.PublicKey().Bytes()),
|
||||||
ContainerID: id.EncodeToString(),
|
ContainerID: id.EncodeToString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,10 +288,10 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObtainSecret receives an existing secret access key from NeoFS and
|
// ObtainSecret receives an existing secret access key from FrostFS and
|
||||||
// writes to io.Writer the secret access key.
|
// writes to io.Writer the secret access key.
|
||||||
func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error {
|
func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error {
|
||||||
bearerCreds := tokens.New(a.neoFS, options.GatePrivateKey, cache.DefaultAccessBoxConfig(a.log))
|
bearerCreds := tokens.New(a.frostFS, options.GatePrivateKey, cache.DefaultAccessBoxConfig(a.log))
|
||||||
|
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
if err := addr.DecodeString(options.SecretAddress); err != nil {
|
if err := addr.DecodeString(options.SecretAddress); err != nil {
|
||||||
|
@ -381,7 +381,7 @@ func buildSessionToken(key *keys.PrivateKey, lifetime lifetimeOptions, ctx sessi
|
||||||
tok.AppliedTo(ctx.containerID)
|
tok.AppliedTo(ctx.containerID)
|
||||||
|
|
||||||
tok.SetID(uuid.New())
|
tok.SetID(uuid.New())
|
||||||
tok.SetAuthKey((*neofsecdsa.PublicKey)(gateKey))
|
tok.SetAuthKey((*frostfsecdsa.PublicKey)(gateKey))
|
||||||
|
|
||||||
tok.SetIat(lifetime.Iat)
|
tok.SetIat(lifetime.Iat)
|
||||||
tok.SetNbf(lifetime.Iat)
|
tok.SetNbf(lifetime.Iat)
|
||||||
|
@ -413,7 +413,7 @@ func createTokens(options *IssueSecretOptions, lifetime lifetimeOptions) ([]*acc
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to build eacl table: %w", err)
|
return nil, fmt.Errorf("failed to build eacl table: %w", err)
|
||||||
}
|
}
|
||||||
bearerTokens, err := buildBearerTokens(options.NeoFSKey, table, lifetime, options.GatesPublicKeys)
|
bearerTokens, err := buildBearerTokens(options.FrostFSKey, table, lifetime, options.GatesPublicKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to build bearer tokens: %w", err)
|
return nil, fmt.Errorf("failed to build bearer tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,7 @@ func createTokens(options *IssueSecretOptions, lifetime lifetimeOptions) ([]*acc
|
||||||
return nil, fmt.Errorf("failed to build context for session token: %w", err)
|
return nil, fmt.Errorf("failed to build context for session token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionTokens, err := buildSessionTokens(options.NeoFSKey, lifetime, sessionRules, options.GatesPublicKeys)
|
sessionTokens, err := buildSessionTokens(options.FrostFSKey, lifetime, sessionRules, options.GatesPublicKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to biuild session token: %w", err)
|
return nil, fmt.Errorf("failed to biuild session token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/api"
|
"github.com/TrueCloudLab/frostfs-s3-gw/api"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/authmate"
|
"github.com/TrueCloudLab/frostfs-s3-gw/authmate"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/internal/neofs"
|
"github.com/TrueCloudLab/frostfs-s3-gw/internal/frostfs"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/internal/version"
|
"github.com/TrueCloudLab/frostfs-s3-gw/internal/version"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/internal/wallet"
|
"github.com/TrueCloudLab/frostfs-s3-gw/internal/wallet"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
@ -164,7 +164,7 @@ func appCommands() []*cli.Command {
|
||||||
func issueSecret() *cli.Command {
|
func issueSecret() *cli.Command {
|
||||||
return &cli.Command{
|
return &cli.Command{
|
||||||
Name: "issue-secret",
|
Name: "issue-secret",
|
||||||
Usage: "Issue a secret in NeoFS network",
|
Usage: "Issue a secret in FrostFS network",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "wallet",
|
Name: "wallet",
|
||||||
|
@ -183,7 +183,7 @@ func issueSecret() *cli.Command {
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "peer",
|
Name: "peer",
|
||||||
Value: "",
|
Value: "",
|
||||||
Usage: "address of a neofs peer to connect to",
|
Usage: "address of a frostfs peer to connect to",
|
||||||
Required: true,
|
Required: true,
|
||||||
Destination: &peerAddressFlag,
|
Destination: &peerAddressFlag,
|
||||||
},
|
},
|
||||||
|
@ -235,7 +235,7 @@ It will be ceil rounded to the nearest amount of epoch.`,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "container-policy",
|
Name: "container-policy",
|
||||||
Usage: "mapping AWS storage class to NeoFS storage policy as plain json string or path to json file",
|
Usage: "mapping AWS storage class to FrostFS storage policy as plain json string or path to json file",
|
||||||
Required: false,
|
Required: false,
|
||||||
Destination: &containerPolicies,
|
Destination: &containerPolicies,
|
||||||
},
|
},
|
||||||
|
@ -252,18 +252,18 @@ It will be ceil rounded to the nearest amount of epoch.`,
|
||||||
password := wallet.GetPassword(viper.GetViper(), envWalletPassphrase)
|
password := wallet.GetPassword(viper.GetViper(), envWalletPassphrase)
|
||||||
key, err := wallet.GetKeyFromPath(walletPathFlag, accountAddressFlag, password)
|
key, err := wallet.GetKeyFromPath(walletPathFlag, accountAddressFlag, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.Exit(fmt.Sprintf("failed to load neofs private key: %s", err), 1)
|
return cli.Exit(fmt.Sprintf("failed to load frostfs private key: %s", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
neoFS, err := createNeoFS(ctx, log, &key.PrivateKey, peerAddressFlag)
|
frostFS, err := createFrostFS(ctx, log, &key.PrivateKey, peerAddressFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.Exit(fmt.Sprintf("failed to create NeoFS component: %s", err), 2)
|
return cli.Exit(fmt.Sprintf("failed to create FrostFS component: %s", err), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
agent := authmate.New(log, neoFS)
|
agent := authmate.New(log, frostFS)
|
||||||
|
|
||||||
var containerID cid.ID
|
var containerID cid.ID
|
||||||
if len(containerIDFlag) > 0 {
|
if len(containerIDFlag) > 0 {
|
||||||
|
@ -306,7 +306,7 @@ It will be ceil rounded to the nearest amount of epoch.`,
|
||||||
FriendlyName: containerFriendlyName,
|
FriendlyName: containerFriendlyName,
|
||||||
PlacementPolicy: containerPlacementPolicy,
|
PlacementPolicy: containerPlacementPolicy,
|
||||||
},
|
},
|
||||||
NeoFSKey: key,
|
FrostFSKey: key,
|
||||||
GatesPublicKeys: gatesPublicKeys,
|
GatesPublicKeys: gatesPublicKeys,
|
||||||
EACLRules: bearerRules,
|
EACLRules: bearerRules,
|
||||||
SessionTokenRules: sessionRules,
|
SessionTokenRules: sessionRules,
|
||||||
|
@ -335,7 +335,7 @@ func generatePresignedURL() *cli.Command {
|
||||||
You provide profile to load using --profile flag or explicitly provide credentials and region using
|
You provide profile to load using --profile flag or explicitly provide credentials and region using
|
||||||
--aws-access-key-id, --aws-secret-access-key, --region.
|
--aws-access-key-id, --aws-secret-access-key, --region.
|
||||||
Note to override credentials you must provide both access key and secret key.`,
|
Note to override credentials you must provide both access key and secret key.`,
|
||||||
Usage: "generate-presigned-url --endpoint http://s3.neofs.devenv:8080 --bucket bucket-name --object object-name --method get --profile aws-profile",
|
Usage: "generate-presigned-url --endpoint http://s3.frostfs.devenv:8080 --bucket bucket-name --object object-name --method get --profile aws-profile",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "lifetime",
|
Name: "lifetime",
|
||||||
|
@ -499,7 +499,7 @@ func getSessionRules(r string) ([]byte, bool, error) {
|
||||||
func obtainSecret() *cli.Command {
|
func obtainSecret() *cli.Command {
|
||||||
command := &cli.Command{
|
command := &cli.Command{
|
||||||
Name: "obtain-secret",
|
Name: "obtain-secret",
|
||||||
Usage: "Obtain a secret from NeoFS network",
|
Usage: "Obtain a secret from FrostFS network",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "wallet",
|
Name: "wallet",
|
||||||
|
@ -518,7 +518,7 @@ func obtainSecret() *cli.Command {
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "peer",
|
Name: "peer",
|
||||||
Value: "",
|
Value: "",
|
||||||
Usage: "address of neofs peer to connect to",
|
Usage: "address of frostfs peer to connect to",
|
||||||
Required: true,
|
Required: true,
|
||||||
Destination: &peerAddressFlag,
|
Destination: &peerAddressFlag,
|
||||||
},
|
},
|
||||||
|
@ -549,18 +549,18 @@ func obtainSecret() *cli.Command {
|
||||||
password := wallet.GetPassword(viper.GetViper(), envWalletPassphrase)
|
password := wallet.GetPassword(viper.GetViper(), envWalletPassphrase)
|
||||||
key, err := wallet.GetKeyFromPath(walletPathFlag, accountAddressFlag, password)
|
key, err := wallet.GetKeyFromPath(walletPathFlag, accountAddressFlag, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.Exit(fmt.Sprintf("failed to load neofs private key: %s", err), 1)
|
return cli.Exit(fmt.Sprintf("failed to load frostfs private key: %s", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
neoFS, err := createNeoFS(ctx, log, &key.PrivateKey, peerAddressFlag)
|
frostFS, err := createFrostFS(ctx, log, &key.PrivateKey, peerAddressFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.Exit(fmt.Sprintf("failed to create NeoFS component: %s", err), 2)
|
return cli.Exit(fmt.Sprintf("failed to create FrostFS component: %s", err), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
agent := authmate.New(log, neoFS)
|
agent := authmate.New(log, frostFS)
|
||||||
|
|
||||||
var _ = agent
|
var _ = agent
|
||||||
|
|
||||||
|
@ -591,7 +591,7 @@ func obtainSecret() *cli.Command {
|
||||||
return command
|
return command
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNeoFS(ctx context.Context, log *zap.Logger, key *ecdsa.PrivateKey, peerAddress string) (authmate.NeoFS, error) {
|
func createFrostFS(ctx context.Context, log *zap.Logger, key *ecdsa.PrivateKey, peerAddress string) (authmate.FrostFS, error) {
|
||||||
log.Debug("prepare connection pool")
|
log.Debug("prepare connection pool")
|
||||||
|
|
||||||
var prm pool.InitParameters
|
var prm pool.InitParameters
|
||||||
|
@ -609,5 +609,5 @@ func createNeoFS(ctx context.Context, log *zap.Logger, key *ecdsa.PrivateKey, pe
|
||||||
return nil, fmt.Errorf("dial pool: %w", err)
|
return nil, fmt.Errorf("dial pool: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return neofs.NewAuthmateNeoFS(p), nil
|
return frostfs.NewAuthmateFrostFS(p), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/api/layer"
|
"github.com/TrueCloudLab/frostfs-s3-gw/api/layer"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/api/notifications"
|
"github.com/TrueCloudLab/frostfs-s3-gw/api/notifications"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/api/resolver"
|
"github.com/TrueCloudLab/frostfs-s3-gw/api/resolver"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/internal/neofs"
|
"github.com/TrueCloudLab/frostfs-s3-gw/internal/frostfs"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/internal/version"
|
"github.com/TrueCloudLab/frostfs-s3-gw/internal/version"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/internal/wallet"
|
"github.com/TrueCloudLab/frostfs-s3-gw/internal/wallet"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
|
@ -88,7 +88,7 @@ func newApp(ctx context.Context, log *Logger, v *viper.Viper) *App {
|
||||||
conns, key := getPool(ctx, log.logger, v)
|
conns, key := getPool(ctx, log.logger, v)
|
||||||
|
|
||||||
// prepare auth center
|
// prepare auth center
|
||||||
ctr := auth.New(neofs.NewAuthmateNeoFS(conns), key, v.GetStringSlice(cfgAllowedAccessKeyIDPrefixes), getAccessBoxCacheConfig(v, log.logger))
|
ctr := auth.New(frostfs.NewAuthmateFrostFS(conns), key, v.GetStringSlice(cfgAllowedAccessKeyIDPrefixes), getAccessBoxCacheConfig(v, log.logger))
|
||||||
|
|
||||||
app := &App{
|
app := &App{
|
||||||
ctr: ctr,
|
ctr: ctr,
|
||||||
|
@ -119,7 +119,7 @@ func (a *App) initLayer(ctx context.Context) {
|
||||||
a.initResolver()
|
a.initResolver()
|
||||||
|
|
||||||
treeServiceEndpoint := a.cfg.GetString(cfgTreeServiceEndpoint)
|
treeServiceEndpoint := a.cfg.GetString(cfgTreeServiceEndpoint)
|
||||||
treeService, err := neofs.NewTreeClient(ctx, treeServiceEndpoint, a.key)
|
treeService, err := frostfs.NewTreeClient(ctx, treeServiceEndpoint, a.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Fatal("failed to create tree service", zap.Error(err))
|
a.log.Fatal("failed to create tree service", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ func (a *App) initLayer(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare object layer
|
// prepare object layer
|
||||||
a.obj = layer.NewLayer(a.log, neofs.NewNeoFS(a.pool), layerCfg)
|
a.obj = layer.NewLayer(a.log, frostfs.NewFrostFS(a.pool), layerCfg)
|
||||||
|
|
||||||
if a.cfg.GetBool(cfgEnableNATS) {
|
if a.cfg.GetBool(cfgEnableNATS) {
|
||||||
nopts := getNotificationsOptions(a.cfg, a.log)
|
nopts := getNotificationsOptions(a.cfg, a.log)
|
||||||
|
@ -183,7 +183,7 @@ func (a *App) initAPI(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) initMetrics() {
|
func (a *App) initMetrics() {
|
||||||
gateMetricsProvider := newGateMetrics(neofs.NewPoolStatistic(a.pool))
|
gateMetricsProvider := newGateMetrics(frostfs.NewPoolStatistic(a.pool))
|
||||||
a.metrics = newAppMetrics(a.log, gateMetricsProvider, a.cfg.GetBool(cfgPrometheusEnabled))
|
a.metrics = newAppMetrics(a.log, gateMetricsProvider, a.cfg.GetBool(cfgPrometheusEnabled))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ func (a *App) initResolver() {
|
||||||
|
|
||||||
func (a *App) getResolverConfig() ([]string, *resolver.Config) {
|
func (a *App) getResolverConfig() ([]string, *resolver.Config) {
|
||||||
resolveCfg := &resolver.Config{
|
resolveCfg := &resolver.Config{
|
||||||
NeoFS: neofs.NewResolverNeoFS(a.pool),
|
FrostFS: frostfs.NewResolverFrostFS(a.pool),
|
||||||
RPCAddress: a.cfg.GetString(cfgRPCEndpoint),
|
RPCAddress: a.cfg.GetString(cfgRPCEndpoint),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,11 +234,11 @@ func getPool(ctx context.Context, logger *zap.Logger, cfg *viper.Viper) (*pool.P
|
||||||
password := wallet.GetPassword(cfg, cfgWalletPassphrase)
|
password := wallet.GetPassword(cfg, cfgWalletPassphrase)
|
||||||
key, err := wallet.GetKeyFromPath(cfg.GetString(cfgWalletPath), cfg.GetString(cfgWalletAddress), password)
|
key, err := wallet.GetKeyFromPath(cfg.GetString(cfgWalletPath), cfg.GetString(cfgWalletAddress), password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal("could not load NeoFS private key", zap.Error(err))
|
logger.Fatal("could not load FrostFS private key", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
prm.SetKey(&key.PrivateKey)
|
prm.SetKey(&key.PrivateKey)
|
||||||
logger.Info("using credentials", zap.String("NeoFS", hex.EncodeToString(key.PublicKey().Bytes())))
|
logger.Info("using credentials", zap.String("FrostFS", hex.EncodeToString(key.PublicKey().Bytes())))
|
||||||
|
|
||||||
for _, peer := range fetchPeers(logger, cfg) {
|
for _, peer := range fetchPeers(logger, cfg) {
|
||||||
prm.AddNode(peer)
|
prm.AddNode(peer)
|
||||||
|
@ -396,7 +396,7 @@ func remove(list []string, element string) []string {
|
||||||
// Wait waits for an application to finish.
|
// Wait waits for an application to finish.
|
||||||
//
|
//
|
||||||
// Pre-logs a message about the launch of the application mentioning its
|
// Pre-logs a message about the launch of the application mentioning its
|
||||||
// version (version.Version) and its name (neofs-s3-gw). At the end, it writes
|
// version (version.Version) and its name (frostfs-s3-gw). At the end, it writes
|
||||||
// about the stop to the log.
|
// about the stop to the log.
|
||||||
func (a *App) Wait() {
|
func (a *App) Wait() {
|
||||||
a.log.Info("application started",
|
a.log.Info("application started",
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
namespace = "neofs_s3_gw"
|
namespace = "frostfs_s3_gw"
|
||||||
stateSubsystem = "state"
|
stateSubsystem = "state"
|
||||||
poolSubsystem = "pool"
|
poolSubsystem = "pool"
|
||||||
|
|
||||||
|
|
|
@ -121,9 +121,9 @@ const ( // Settings.
|
||||||
|
|
||||||
cmdListenAddress = "listen_address"
|
cmdListenAddress = "listen_address"
|
||||||
|
|
||||||
// Configuration of parameters of requests to NeoFS.
|
// Configuration of parameters of requests to FrostFS.
|
||||||
// Number of the object copies to consider PUT to NeoFS successful.
|
// Number of the object copies to consider PUT to FrostFS successful.
|
||||||
cfgSetCopiesNumber = "neofs.set_copies_number"
|
cfgSetCopiesNumber = "frostfs.set_copies_number"
|
||||||
|
|
||||||
// List of allowed AccessKeyID prefixes.
|
// List of allowed AccessKeyID prefixes.
|
||||||
cfgAllowedAccessKeyIDPrefixes = "allowed_access_key_id_prefixes"
|
cfgAllowedAccessKeyIDPrefixes = "allowed_access_key_id_prefixes"
|
||||||
|
@ -217,7 +217,7 @@ func newSettings() *viper.Viper {
|
||||||
flags.String(cmdConfig, "", "config path")
|
flags.String(cmdConfig, "", "config path")
|
||||||
|
|
||||||
flags.Duration(cfgHealthcheckTimeout, defaultHealthcheckTimeout, "set timeout to check node health during rebalance")
|
flags.Duration(cfgHealthcheckTimeout, defaultHealthcheckTimeout, "set timeout to check node health during rebalance")
|
||||||
flags.Duration(cfgConnectTimeout, defaultConnectTimeout, "set timeout to connect to NeoFS nodes")
|
flags.Duration(cfgConnectTimeout, defaultConnectTimeout, "set timeout to connect to FrostFS nodes")
|
||||||
flags.Duration(cfgRebalanceInterval, defaultRebalanceInterval, "set rebalance interval")
|
flags.Duration(cfgRebalanceInterval, defaultRebalanceInterval, "set rebalance interval")
|
||||||
|
|
||||||
flags.Int(cfgMaxClientsCount, defaultMaxClientsCount, "set max-clients count")
|
flags.Int(cfgMaxClientsCount, defaultMaxClientsCount, "set max-clients count")
|
||||||
|
@ -227,7 +227,7 @@ func newSettings() *viper.Viper {
|
||||||
flags.String(cfgTLSCertFile, "", "TLS certificate file to use")
|
flags.String(cfgTLSCertFile, "", "TLS certificate file to use")
|
||||||
flags.String(cfgTLSKeyFile, "", "TLS key file to use")
|
flags.String(cfgTLSKeyFile, "", "TLS key file to use")
|
||||||
|
|
||||||
peers := flags.StringArrayP(cfgPeers, "p", nil, "set NeoFS nodes")
|
peers := flags.StringArrayP(cfgPeers, "p", nil, "set FrostFS nodes")
|
||||||
|
|
||||||
flags.StringP(cfgRPCEndpoint, "r", "", "set RPC endpoint")
|
flags.StringP(cfgRPCEndpoint, "r", "", "set RPC endpoint")
|
||||||
resolveMethods := flags.StringSlice(cfgResolveOrder, []string{resolver.DNSResolver}, "set bucket name resolve order")
|
resolveMethods := flags.StringSlice(cfgResolveOrder, []string{resolver.DNSResolver}, "set bucket name resolve order")
|
||||||
|
|
|
@ -7,19 +7,19 @@ S3_GW_WALLET_ADDRESS=NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP
|
||||||
S3_GW_WALLET_PASSPHRASE=s3
|
S3_GW_WALLET_PASSPHRASE=s3
|
||||||
|
|
||||||
# Nodes
|
# Nodes
|
||||||
# This configuration makes the gateway use the first node (grpc://s01.neofs.devenv:8080)
|
# This configuration makes the gateway use the first node (grpc://s01.frostfs.devenv:8080)
|
||||||
# while it's healthy. Otherwise, gateway uses the second node (grpc://s01.neofs.devenv:8080)
|
# while it's healthy. Otherwise, gateway uses the second node (grpc://s01.frostfs.devenv:8080)
|
||||||
# for 10% of requests and the third node (grpc://s03.neofs.devenv:8080) for 90% of requests.
|
# for 10% of requests and the third node (grpc://s03.frostfs.devenv:8080) for 90% of requests.
|
||||||
# Until nodes with the same priority level are healthy
|
# Until nodes with the same priority level are healthy
|
||||||
# nodes with other priority are not used.
|
# nodes with other priority are not used.
|
||||||
# The lower the value, the higher the priority.
|
# The lower the value, the higher the priority.
|
||||||
S3_GW_PEERS_0_ADDRESS=grpc://s01.neofs.devenv:8080
|
S3_GW_PEERS_0_ADDRESS=grpc://s01.frostfs.devenv:8080
|
||||||
S3_GW_PEERS_0_PRIORITY=1
|
S3_GW_PEERS_0_PRIORITY=1
|
||||||
S3_GW_PEERS_0_WEIGHT=1
|
S3_GW_PEERS_0_WEIGHT=1
|
||||||
S3_GW_PEERS_1_ADDRESS=grpc://s02.neofs.devenv:8080
|
S3_GW_PEERS_1_ADDRESS=grpc://s02.frostfs.devenv:8080
|
||||||
S3_GW_PEERS_1_PRIORITY=2
|
S3_GW_PEERS_1_PRIORITY=2
|
||||||
S3_GW_PEERS_1_WEIGHT=0.1
|
S3_GW_PEERS_1_WEIGHT=0.1
|
||||||
S3_GW_PEERS_2_ADDRESS=grpc://s03.neofs.devenv:8080
|
S3_GW_PEERS_2_ADDRESS=grpc://s03.frostfs.devenv:8080
|
||||||
S3_GW_PEERS_2_PRIORITY=2
|
S3_GW_PEERS_2_PRIORITY=2
|
||||||
S3_GW_PEERS_2_WEIGHT=0.9
|
S3_GW_PEERS_2_WEIGHT=0.9
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ S3_GW_SERVER_1_TLS_CERT_FILE=/path/to/tls/cert
|
||||||
S3_GW_SERVER_1_TLS_KEY_FILE=/path/to/tls/key
|
S3_GW_SERVER_1_TLS_KEY_FILE=/path/to/tls/key
|
||||||
|
|
||||||
# Domains to be able to use virtual-hosted-style access to bucket.
|
# Domains to be able to use virtual-hosted-style access to bucket.
|
||||||
S3_GW_LISTEN_DOMAINS=s3dev.neofs.devenv
|
S3_GW_LISTEN_DOMAINS=s3dev.frostfs.devenv
|
||||||
|
|
||||||
# Config file
|
# Config file
|
||||||
S3_GW_CONFIG=/path/to/config/yaml
|
S3_GW_CONFIG=/path/to/config/yaml
|
||||||
|
@ -43,10 +43,10 @@ S3_GW_CONFIG=/path/to/config/yaml
|
||||||
S3_GW_LOGGER_LEVEL=debug
|
S3_GW_LOGGER_LEVEL=debug
|
||||||
|
|
||||||
# Endpoint of the tree service. Must be provided. Can be one of the node address (from the `peers` section).
|
# Endpoint of the tree service. Must be provided. Can be one of the node address (from the `peers` section).
|
||||||
S3_GW_TREE_SERVICE=grpc://s01.neofs.devenv:8080
|
S3_GW_TREE_SERVICE=grpc://s01.frostfs.devenv:8080
|
||||||
|
|
||||||
# RPC endpoint and order of resolving of bucket names
|
# RPC endpoint and order of resolving of bucket names
|
||||||
S3_GW_RPC_ENDPOINT=http://morph-chain.neofs.devenv:30333/
|
S3_GW_RPC_ENDPOINT=http://morph-chain.frostfs.devenv:30333/
|
||||||
S3_GW_RESOLVE_ORDER="nns dns"
|
S3_GW_RESOLVE_ORDER="nns dns"
|
||||||
|
|
||||||
# Metrics
|
# Metrics
|
||||||
|
@ -97,14 +97,14 @@ S3_GW_CACHE_ACCESSCONTROL_SIZE=100000
|
||||||
|
|
||||||
# NATS
|
# NATS
|
||||||
S3_GW_NATS_ENABLED=true
|
S3_GW_NATS_ENABLED=true
|
||||||
S3_GW_NATS_ENDPOINT=nats://nats.neofs.devenv:4222
|
S3_GW_NATS_ENDPOINT=nats://nats.frostfs.devenv:4222
|
||||||
S3_GW_NATS_TIMEOUT=30s
|
S3_GW_NATS_TIMEOUT=30s
|
||||||
S3_GW_NATS_CERT_FILE=/path/to/cert
|
S3_GW_NATS_CERT_FILE=/path/to/cert
|
||||||
S3_GW_NATS_KEY_FILE=/path/to/key
|
S3_GW_NATS_KEY_FILE=/path/to/key
|
||||||
S3_GW_NATS_ROOT_CA=/path/to/ca
|
S3_GW_NATS_ROOT_CA=/path/to/ca
|
||||||
|
|
||||||
# Default policy of placing containers in NeoFS
|
# Default policy of placing containers in FrostFS
|
||||||
# If a user sends a request `CreateBucket` and doesn't define policy for placing of a container in NeoFS, the S3 Gateway
|
# If a user sends a request `CreateBucket` and doesn't define policy for placing of a container in FrostFS, the S3 Gateway
|
||||||
# will put the container with default policy. It can be specified via environment variable, e.g.:
|
# will put the container with default policy. It can be specified via environment variable, e.g.:
|
||||||
S3_GW_PLACEMENT_POLICY_DEFAULT_POLICY="REP 3"
|
S3_GW_PLACEMENT_POLICY_DEFAULT_POLICY="REP 3"
|
||||||
# Region to placement policy mapping json file.
|
# Region to placement policy mapping json file.
|
||||||
|
@ -115,10 +115,10 @@ S3_GW_PLACEMENT_POLICY_REGION_MAPPING=/path/to/container/policy.json
|
||||||
# value of Access-Control-Max-Age header if this value is not set in a rule. Has an int type.
|
# value of Access-Control-Max-Age header if this value is not set in a rule. Has an int type.
|
||||||
S3_GW_CORS_DEFAULT_MAX_AGE=600
|
S3_GW_CORS_DEFAULT_MAX_AGE=600
|
||||||
|
|
||||||
# Parameters of requests to NeoFS
|
# Parameters of requests to FrostFS
|
||||||
# Number of the object copies to consider PUT to NeoFS successful.
|
# Number of the object copies to consider PUT to FrostFS successful.
|
||||||
# If not set, default value 0 will be used -- it means that object will be processed according to the container's placement policy
|
# If not set, default value 0 will be used -- it means that object will be processed according to the container's placement policy
|
||||||
S3_GW_NEOFS_SET_COPIES_NUMBER=0
|
S3_GW_FROSTFS_SET_COPIES_NUMBER=0
|
||||||
|
|
||||||
# List of allowed AccessKeyID prefixes
|
# List of allowed AccessKeyID prefixes
|
||||||
# If not set, S3 GW will accept all AccessKeyIDs
|
# If not set, S3 GW will accept all AccessKeyIDs
|
||||||
|
|
|
@ -5,23 +5,23 @@ wallet:
|
||||||
address: NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP # Account address. If omitted default one will be used.
|
address: NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP # Account address. If omitted default one will be used.
|
||||||
|
|
||||||
# Nodes configuration
|
# Nodes configuration
|
||||||
# This configuration makes the gateway use the first node (grpc://s01.neofs.devenv:8080)
|
# This configuration makes the gateway use the first node (grpc://s01.frostfs.devenv:8080)
|
||||||
# while it's healthy. Otherwise, gateway uses the second node (grpc://s01.neofs.devenv:8080)
|
# while it's healthy. Otherwise, gateway uses the second node (grpc://s01.frostfs.devenv:8080)
|
||||||
# for 10% of requests and the third node (grpc://s03.neofs.devenv:8080) for 90% of requests.
|
# for 10% of requests and the third node (grpc://s03.frostfs.devenv:8080) for 90% of requests.
|
||||||
# Until nodes with the same priority level are healthy
|
# Until nodes with the same priority level are healthy
|
||||||
# nodes with other priority are not used.
|
# nodes with other priority are not used.
|
||||||
# The lower the value, the higher the priority.
|
# The lower the value, the higher the priority.
|
||||||
peers:
|
peers:
|
||||||
0:
|
0:
|
||||||
address: node1.neofs:8080
|
address: node1.frostfs:8080
|
||||||
priority: 1
|
priority: 1
|
||||||
weight: 1
|
weight: 1
|
||||||
1:
|
1:
|
||||||
address: node2.neofs:8080
|
address: node2.frostfs:8080
|
||||||
priority: 2
|
priority: 2
|
||||||
weight: 0.1
|
weight: 0.1
|
||||||
2:
|
2:
|
||||||
address: node3.neofs:8080
|
address: node3.frostfs:8080
|
||||||
priority: 2
|
priority: 2
|
||||||
weight: 0.9
|
weight: 0.9
|
||||||
|
|
||||||
|
@ -39,17 +39,17 @@ server:
|
||||||
|
|
||||||
# Domains to be able to use virtual-hosted-style access to bucket.
|
# Domains to be able to use virtual-hosted-style access to bucket.
|
||||||
listen_domains:
|
listen_domains:
|
||||||
- s3dev.neofs.devenv
|
- s3dev.frostfs.devenv
|
||||||
|
|
||||||
logger:
|
logger:
|
||||||
level: debug
|
level: debug
|
||||||
|
|
||||||
# Endpoint of the tree service. Must be provided. Can be one of the node address (from the `peers` section).
|
# Endpoint of the tree service. Must be provided. Can be one of the node address (from the `peers` section).
|
||||||
tree:
|
tree:
|
||||||
service: node1.neofs:8080
|
service: node1.frostfs:8080
|
||||||
|
|
||||||
# RPC endpoint and order of resolving of bucket names
|
# RPC endpoint and order of resolving of bucket names
|
||||||
rpc_endpoint: http://morph-chain.neofs.devenv:30333
|
rpc_endpoint: http://morph-chain.frostfs.devenv:30333
|
||||||
resolve_order:
|
resolve_order:
|
||||||
- nns
|
- nns
|
||||||
|
|
||||||
|
@ -118,10 +118,10 @@ nats:
|
||||||
key_file: /path/to/key
|
key_file: /path/to/key
|
||||||
root_ca: /path/to/ca
|
root_ca: /path/to/ca
|
||||||
|
|
||||||
# Parameters of NeoFS container placement policy
|
# Parameters of FrostFS container placement policy
|
||||||
placement_policy:
|
placement_policy:
|
||||||
# Default policy of placing containers in NeoFS
|
# Default policy of placing containers in FrostFS
|
||||||
# If a user sends a request `CreateBucket` and doesn't define policy for placing of a container in NeoFS, the S3 Gateway
|
# If a user sends a request `CreateBucket` and doesn't define policy for placing of a container in FrostFS, the S3 Gateway
|
||||||
# will put the container with default policy.
|
# will put the container with default policy.
|
||||||
default: REP 3
|
default: REP 3
|
||||||
# Region to placement policy mapping json file.
|
# Region to placement policy mapping json file.
|
||||||
|
@ -133,9 +133,9 @@ placement_policy:
|
||||||
cors:
|
cors:
|
||||||
default_max_age: 600
|
default_max_age: 600
|
||||||
|
|
||||||
# Parameters of requests to NeoFS
|
# Parameters of requests to FrostFS
|
||||||
neofs:
|
frostfs:
|
||||||
# Number of the object copies to consider PUT to NeoFS successful.
|
# Number of the object copies to consider PUT to FrostFS successful.
|
||||||
# `0` means that object will be processed according to the container's placement policy
|
# `0` means that object will be processed according to the container's placement policy
|
||||||
set_copies_number: 0
|
set_copies_number: 0
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
neofsecdsa "github.com/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
frostfsecdsa "github.com/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -89,7 +89,7 @@ func TestSessionTokenInAccessBox(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
tkn.SetID(uuid.New())
|
tkn.SetID(uuid.New())
|
||||||
tkn.SetAuthKey((*neofsecdsa.PublicKey)(sec.PublicKey()))
|
tkn.SetAuthKey((*frostfsecdsa.PublicKey)(sec.PublicKey()))
|
||||||
require.NoError(t, tkn.Sign(sec.PrivateKey))
|
require.NoError(t, tkn.Sign(sec.PrivateKey))
|
||||||
|
|
||||||
var newTkn bearer.Token
|
var newTkn bearer.Token
|
||||||
|
|
|
@ -23,41 +23,41 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
cred struct {
|
cred struct {
|
||||||
key *keys.PrivateKey
|
key *keys.PrivateKey
|
||||||
neoFS NeoFS
|
frostFS FrostFS
|
||||||
cache *cache.AccessBoxCache
|
cache *cache.AccessBoxCache
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrmObjectCreate groups parameters of objects created by credential tool.
|
// PrmObjectCreate groups parameters of objects created by credential tool.
|
||||||
type PrmObjectCreate struct {
|
type PrmObjectCreate struct {
|
||||||
// NeoFS identifier of the object creator.
|
// FrostFS identifier of the object creator.
|
||||||
Creator user.ID
|
Creator user.ID
|
||||||
|
|
||||||
// NeoFS container to store the object.
|
// FrostFS container to store the object.
|
||||||
Container cid.ID
|
Container cid.ID
|
||||||
|
|
||||||
// File path.
|
// File path.
|
||||||
Filepath string
|
Filepath string
|
||||||
|
|
||||||
// Last NeoFS epoch of the object lifetime.
|
// Last FrostFS epoch of the object lifetime.
|
||||||
ExpirationEpoch uint64
|
ExpirationEpoch uint64
|
||||||
|
|
||||||
// Object payload.
|
// Object payload.
|
||||||
Payload []byte
|
Payload []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeoFS represents virtual connection to NeoFS network.
|
// FrostFS represents virtual connection to FrostFS network.
|
||||||
type NeoFS interface {
|
type FrostFS interface {
|
||||||
// CreateObject creates and saves a parameterized object in the specified
|
// CreateObject creates and saves a parameterized object in the specified
|
||||||
// NeoFS container from a specific user. It sets 'Timestamp' attribute to the current time.
|
// FrostFS container from a specific user. It sets 'Timestamp' attribute to the current time.
|
||||||
// It returns the ID of the saved object.
|
// It returns the ID of the saved object.
|
||||||
//
|
//
|
||||||
// It returns exactly one non-nil value. It returns any error encountered which
|
// It returns exactly one non-nil value. It returns any error encountered which
|
||||||
// prevented the object from being created.
|
// prevented the object from being created.
|
||||||
CreateObject(context.Context, PrmObjectCreate) (oid.ID, error)
|
CreateObject(context.Context, PrmObjectCreate) (oid.ID, error)
|
||||||
|
|
||||||
// ReadObjectPayload reads payload of the object from NeoFS network by address
|
// ReadObjectPayload reads payload of the object from FrostFS network by address
|
||||||
// into memory.
|
// into memory.
|
||||||
//
|
//
|
||||||
// It returns exactly one non-nil value. It returns any error encountered which
|
// It returns exactly one non-nil value. It returns any error encountered which
|
||||||
|
@ -75,8 +75,8 @@ var (
|
||||||
var _ = New
|
var _ = New
|
||||||
|
|
||||||
// New creates a new Credentials instance using the given cli and key.
|
// New creates a new Credentials instance using the given cli and key.
|
||||||
func New(neoFS NeoFS, key *keys.PrivateKey, config *cache.Config) Credentials {
|
func New(frostFS FrostFS, key *keys.PrivateKey, config *cache.Config) Credentials {
|
||||||
return &cred{neoFS: neoFS, key: key, cache: cache.NewAccessBoxCache(config)}
|
return &cred{frostFS: frostFS, key: key, cache: cache.NewAccessBoxCache(config)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, error) {
|
func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, error) {
|
||||||
|
@ -103,7 +103,7 @@ func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, er
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.AccessBox, error) {
|
func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.AccessBox, error) {
|
||||||
data, err := c.neoFS.ReadObjectPayload(ctx, addr)
|
data, err := c.frostFS.ReadObjectPayload(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("read payload: %w", err)
|
return nil, fmt.Errorf("read payload: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ func (c *cred) Put(ctx context.Context, idCnr cid.ID, issuer user.ID, box *acces
|
||||||
return oid.Address{}, fmt.Errorf("marshall box: %w", err)
|
return oid.Address{}, fmt.Errorf("marshall box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
idObj, err := c.neoFS.CreateObject(ctx, PrmObjectCreate{
|
idObj, err := c.frostFS.CreateObject(ctx, PrmObjectCreate{
|
||||||
Creator: issuer,
|
Creator: issuer,
|
||||||
Container: idCnr,
|
Container: idCnr,
|
||||||
Filepath: strconv.FormatInt(time.Now().Unix(), 10) + "_access.box",
|
Filepath: strconv.FormatInt(time.Now().Unix(), 10) + "_access.box",
|
||||||
|
|
|
@ -165,7 +165,7 @@ There are some custom types used for brevity:
|
||||||
| `cors` | [CORS configuration](#cors-section) |
|
| `cors` | [CORS configuration](#cors-section) |
|
||||||
| `pprof` | [Pprof configuration](#pprof-section) |
|
| `pprof` | [Pprof configuration](#pprof-section) |
|
||||||
| `prometheus` | [Prometheus configuration](#prometheus-section) |
|
| `prometheus` | [Prometheus configuration](#prometheus-section) |
|
||||||
| `neofs` | [Parameters of requests to FrostFS](#neofs-section) |
|
| `frostfs` | [Parameters of requests to FrostFS](#frostfs-section) |
|
||||||
|
|
||||||
### General section
|
### General section
|
||||||
|
|
||||||
|
@ -447,10 +447,10 @@ prometheus:
|
||||||
| `enabled` | `bool` | yes | `false` | Flag to enable the service. |
|
| `enabled` | `bool` | yes | `false` | Flag to enable the service. |
|
||||||
| `address` | `string` | yes | `localhost:8086` | Address that service listener binds to. |
|
| `address` | `string` | yes | `localhost:8086` | Address that service listener binds to. |
|
||||||
|
|
||||||
# `neofs` section
|
# `frostfs` section
|
||||||
|
|
||||||
Contains parameters of requests to FrostFS.
|
Contains parameters of requests to FrostFS.
|
||||||
This value can be overridden with `X-Amz-Meta-Neofs-Copies-Number` header for `PutObject`, `CopyObject`, `CreateMultipartUpload`.
|
This value can be overridden with `X-Amz-Meta-Frostfs-Copies-Number` header for `PutObject`, `CopyObject`, `CreateMultipartUpload`.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
frostfs:
|
frostfs:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package neofs
|
package frostfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -26,10 +26,10 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NeoFS represents virtual connection to the NeoFS network.
|
// FrostFS represents virtual connection to the FrostFS network.
|
||||||
// It is used to provide an interface to dependent packages
|
// It is used to provide an interface to dependent packages
|
||||||
// which work with NeoFS.
|
// which work with FrostFS.
|
||||||
type NeoFS struct {
|
type FrostFS struct {
|
||||||
pool *pool.Pool
|
pool *pool.Pool
|
||||||
await pool.WaitParams
|
await pool.WaitParams
|
||||||
}
|
}
|
||||||
|
@ -39,20 +39,20 @@ const (
|
||||||
defaultPollTimeout = 120 * time.Second // same as default value from pool
|
defaultPollTimeout = 120 * time.Second // same as default value from pool
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewNeoFS creates new NeoFS using provided pool.Pool.
|
// NewFrostFS creates new FrostFS using provided pool.Pool.
|
||||||
func NewNeoFS(p *pool.Pool) *NeoFS {
|
func NewFrostFS(p *pool.Pool) *FrostFS {
|
||||||
var await pool.WaitParams
|
var await pool.WaitParams
|
||||||
await.SetPollInterval(defaultPollInterval)
|
await.SetPollInterval(defaultPollInterval)
|
||||||
await.SetTimeout(defaultPollTimeout)
|
await.SetTimeout(defaultPollTimeout)
|
||||||
|
|
||||||
return &NeoFS{
|
return &FrostFS{
|
||||||
pool: p,
|
pool: p,
|
||||||
await: await,
|
await: await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeToEpoch implements neofs.NeoFS interface method.
|
// TimeToEpoch implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) TimeToEpoch(ctx context.Context, now, futureTime time.Time) (uint64, uint64, error) {
|
func (x *FrostFS) TimeToEpoch(ctx context.Context, now, futureTime time.Time) (uint64, uint64, error) {
|
||||||
dur := futureTime.Sub(now)
|
dur := futureTime.Sub(now)
|
||||||
if dur < 0 {
|
if dur < 0 {
|
||||||
return 0, 0, fmt.Errorf("time '%s' must be in the future (after %s)",
|
return 0, 0, fmt.Errorf("time '%s' must be in the future (after %s)",
|
||||||
|
@ -87,8 +87,8 @@ func (x *NeoFS) TimeToEpoch(ctx context.Context, now, futureTime time.Time) (uin
|
||||||
return curr, epoch, nil
|
return curr, epoch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container implements neofs.NeoFS interface method.
|
// Container implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) Container(ctx context.Context, idCnr cid.ID) (*container.Container, error) {
|
func (x *FrostFS) Container(ctx context.Context, idCnr cid.ID) (*container.Container, error) {
|
||||||
var prm pool.PrmContainerGet
|
var prm pool.PrmContainerGet
|
||||||
prm.SetContainerID(idCnr)
|
prm.SetContainerID(idCnr)
|
||||||
|
|
||||||
|
@ -102,10 +102,10 @@ func (x *NeoFS) Container(ctx context.Context, idCnr cid.ID) (*container.Contain
|
||||||
|
|
||||||
var basicACLZero acl.Basic
|
var basicACLZero acl.Basic
|
||||||
|
|
||||||
// CreateContainer implements neofs.NeoFS interface method.
|
// CreateContainer implements frostfs.FrostFS interface method.
|
||||||
//
|
//
|
||||||
// If prm.BasicACL is zero, 'eacl-public-read-write' is used.
|
// If prm.BasicACL is zero, 'eacl-public-read-write' is used.
|
||||||
func (x *NeoFS) CreateContainer(ctx context.Context, prm layer.PrmContainerCreate) (cid.ID, error) {
|
func (x *FrostFS) CreateContainer(ctx context.Context, prm layer.PrmContainerCreate) (cid.ID, error) {
|
||||||
if prm.BasicACL == basicACLZero {
|
if prm.BasicACL == basicACLZero {
|
||||||
prm.BasicACL = acl.PublicRWExtended
|
prm.BasicACL = acl.PublicRWExtended
|
||||||
}
|
}
|
||||||
|
@ -156,8 +156,8 @@ func (x *NeoFS) CreateContainer(ctx context.Context, prm layer.PrmContainerCreat
|
||||||
return idCnr, nil
|
return idCnr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserContainers implements neofs.NeoFS interface method.
|
// UserContainers implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) UserContainers(ctx context.Context, id user.ID) ([]cid.ID, error) {
|
func (x *FrostFS) UserContainers(ctx context.Context, id user.ID) ([]cid.ID, error) {
|
||||||
var prm pool.PrmContainerList
|
var prm pool.PrmContainerList
|
||||||
prm.SetOwnerID(id)
|
prm.SetOwnerID(id)
|
||||||
|
|
||||||
|
@ -169,8 +169,8 @@ func (x *NeoFS) UserContainers(ctx context.Context, id user.ID) ([]cid.ID, error
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContainerEACL implements neofs.NeoFS interface method.
|
// SetContainerEACL implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) SetContainerEACL(ctx context.Context, table eacl.Table, sessionToken *session.Container) error {
|
func (x *FrostFS) SetContainerEACL(ctx context.Context, table eacl.Table, sessionToken *session.Container) error {
|
||||||
var prm pool.PrmContainerSetEACL
|
var prm pool.PrmContainerSetEACL
|
||||||
prm.SetTable(table)
|
prm.SetTable(table)
|
||||||
prm.SetWaitParams(x.await)
|
prm.SetWaitParams(x.await)
|
||||||
|
@ -187,8 +187,8 @@ func (x *NeoFS) SetContainerEACL(ctx context.Context, table eacl.Table, sessionT
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerEACL implements neofs.NeoFS interface method.
|
// ContainerEACL implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) ContainerEACL(ctx context.Context, id cid.ID) (*eacl.Table, error) {
|
func (x *FrostFS) ContainerEACL(ctx context.Context, id cid.ID) (*eacl.Table, error) {
|
||||||
var prm pool.PrmContainerEACL
|
var prm pool.PrmContainerEACL
|
||||||
prm.SetContainerID(id)
|
prm.SetContainerID(id)
|
||||||
|
|
||||||
|
@ -200,8 +200,8 @@ func (x *NeoFS) ContainerEACL(ctx context.Context, id cid.ID) (*eacl.Table, erro
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteContainer implements neofs.NeoFS interface method.
|
// DeleteContainer implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.Container) error {
|
func (x *FrostFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.Container) error {
|
||||||
var prm pool.PrmContainerDelete
|
var prm pool.PrmContainerDelete
|
||||||
prm.SetContainerID(id)
|
prm.SetContainerID(id)
|
||||||
prm.SetWaitParams(x.await)
|
prm.SetWaitParams(x.await)
|
||||||
|
@ -218,8 +218,8 @@ func (x *NeoFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.C
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateObject implements neofs.NeoFS interface method.
|
// CreateObject implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oid.ID, error) {
|
func (x *FrostFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oid.ID, error) {
|
||||||
attrNum := len(prm.Attributes) + 1 // + creation time
|
attrNum := len(prm.Attributes) + 1 // + creation time
|
||||||
|
|
||||||
if prm.Filepath != "" {
|
if prm.Filepath != "" {
|
||||||
|
@ -290,7 +290,7 @@ func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oi
|
||||||
}
|
}
|
||||||
|
|
||||||
// wraps io.ReadCloser and transforms Read errors related to access violation
|
// wraps io.ReadCloser and transforms Read errors related to access violation
|
||||||
// to neofs.ErrAccessDenied.
|
// to frostfs.ErrAccessDenied.
|
||||||
type payloadReader struct {
|
type payloadReader struct {
|
||||||
io.ReadCloser
|
io.ReadCloser
|
||||||
}
|
}
|
||||||
|
@ -306,8 +306,8 @@ func (x payloadReader) Read(p []byte) (int, error) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadObject implements neofs.NeoFS interface method.
|
// ReadObject implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) ReadObject(ctx context.Context, prm layer.PrmObjectRead) (*layer.ObjectPart, error) {
|
func (x *FrostFS) ReadObject(ctx context.Context, prm layer.PrmObjectRead) (*layer.ObjectPart, error) {
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
addr.SetContainer(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObject(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
@ -407,8 +407,8 @@ func (x *NeoFS) ReadObject(ctx context.Context, prm layer.PrmObjectRead) (*layer
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteObject implements neofs.NeoFS interface method.
|
// DeleteObject implements frostfs.FrostFS interface method.
|
||||||
func (x *NeoFS) DeleteObject(ctx context.Context, prm layer.PrmObjectDelete) error {
|
func (x *FrostFS) DeleteObject(ctx context.Context, prm layer.PrmObjectDelete) error {
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
addr.SetContainer(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObject(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
@ -451,19 +451,19 @@ func isErrAccessDenied(err error) (string, bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolverNeoFS represents virtual connection to the NeoFS network.
|
// ResolverFrostFS represents virtual connection to the FrostFS network.
|
||||||
// It implements resolver.NeoFS.
|
// It implements resolver.FrostFS.
|
||||||
type ResolverNeoFS struct {
|
type ResolverFrostFS struct {
|
||||||
pool *pool.Pool
|
pool *pool.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewResolverNeoFS creates new ResolverNeoFS using provided pool.Pool.
|
// NewResolverFrostFS creates new ResolverFrostFS using provided pool.Pool.
|
||||||
func NewResolverNeoFS(p *pool.Pool) *ResolverNeoFS {
|
func NewResolverFrostFS(p *pool.Pool) *ResolverFrostFS {
|
||||||
return &ResolverNeoFS{pool: p}
|
return &ResolverFrostFS{pool: p}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemDNS implements resolver.NeoFS interface method.
|
// SystemDNS implements resolver.FrostFS interface method.
|
||||||
func (x *ResolverNeoFS) SystemDNS(ctx context.Context) (string, error) {
|
func (x *ResolverFrostFS) SystemDNS(ctx context.Context) (string, error) {
|
||||||
networkInfo, err := x.pool.NetworkInfo(ctx)
|
networkInfo, err := x.pool.NetworkInfo(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("read network info via client: %w", err)
|
return "", fmt.Errorf("read network info via client: %w", err)
|
||||||
|
@ -477,19 +477,19 @@ func (x *ResolverNeoFS) SystemDNS(ctx context.Context) (string, error) {
|
||||||
return string(domain), nil
|
return string(domain), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthmateNeoFS is a mediator which implements authmate.NeoFS through pool.Pool.
|
// AuthmateFrostFS is a mediator which implements authmate.FrostFS through pool.Pool.
|
||||||
type AuthmateNeoFS struct {
|
type AuthmateFrostFS struct {
|
||||||
neoFS *NeoFS
|
frostFS *FrostFS
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAuthmateNeoFS creates new AuthmateNeoFS using provided pool.Pool.
|
// NewAuthmateFrostFS creates new AuthmateFrostFS using provided pool.Pool.
|
||||||
func NewAuthmateNeoFS(p *pool.Pool) *AuthmateNeoFS {
|
func NewAuthmateFrostFS(p *pool.Pool) *AuthmateFrostFS {
|
||||||
return &AuthmateNeoFS{neoFS: NewNeoFS(p)}
|
return &AuthmateFrostFS{frostFS: NewFrostFS(p)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerExists implements authmate.NeoFS interface method.
|
// ContainerExists implements authmate.FrostFS interface method.
|
||||||
func (x *AuthmateNeoFS) ContainerExists(ctx context.Context, idCnr cid.ID) error {
|
func (x *AuthmateFrostFS) ContainerExists(ctx context.Context, idCnr cid.ID) error {
|
||||||
_, err := x.neoFS.Container(ctx, idCnr)
|
_, err := x.frostFS.Container(ctx, idCnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("get container via connection pool: %w", err)
|
return fmt.Errorf("get container via connection pool: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -497,18 +497,18 @@ func (x *AuthmateNeoFS) ContainerExists(ctx context.Context, idCnr cid.ID) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeToEpoch implements authmate.NeoFS interface method.
|
// TimeToEpoch implements authmate.FrostFS interface method.
|
||||||
func (x *AuthmateNeoFS) TimeToEpoch(ctx context.Context, futureTime time.Time) (uint64, uint64, error) {
|
func (x *AuthmateFrostFS) TimeToEpoch(ctx context.Context, futureTime time.Time) (uint64, uint64, error) {
|
||||||
return x.neoFS.TimeToEpoch(ctx, time.Now(), futureTime)
|
return x.frostFS.TimeToEpoch(ctx, time.Now(), futureTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateContainer implements authmate.NeoFS interface method.
|
// CreateContainer implements authmate.FrostFS interface method.
|
||||||
func (x *AuthmateNeoFS) CreateContainer(ctx context.Context, prm authmate.PrmContainerCreate) (cid.ID, error) {
|
func (x *AuthmateFrostFS) CreateContainer(ctx context.Context, prm authmate.PrmContainerCreate) (cid.ID, error) {
|
||||||
basicACL := acl.Private
|
basicACL := acl.Private
|
||||||
// allow reading objects to OTHERS in order to provide read access to S3 gateways
|
// allow reading objects to OTHERS in order to provide read access to S3 gateways
|
||||||
basicACL.AllowOp(acl.OpObjectGet, acl.RoleOthers)
|
basicACL.AllowOp(acl.OpObjectGet, acl.RoleOthers)
|
||||||
|
|
||||||
return x.neoFS.CreateContainer(ctx, layer.PrmContainerCreate{
|
return x.frostFS.CreateContainer(ctx, layer.PrmContainerCreate{
|
||||||
Creator: prm.Owner,
|
Creator: prm.Owner,
|
||||||
Policy: prm.Policy,
|
Policy: prm.Policy,
|
||||||
Name: prm.FriendlyName,
|
Name: prm.FriendlyName,
|
||||||
|
@ -516,9 +516,9 @@ func (x *AuthmateNeoFS) CreateContainer(ctx context.Context, prm authmate.PrmCon
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadObjectPayload implements authmate.NeoFS interface method.
|
// ReadObjectPayload implements authmate.FrostFS interface method.
|
||||||
func (x *AuthmateNeoFS) ReadObjectPayload(ctx context.Context, addr oid.Address) ([]byte, error) {
|
func (x *AuthmateFrostFS) ReadObjectPayload(ctx context.Context, addr oid.Address) ([]byte, error) {
|
||||||
res, err := x.neoFS.ReadObject(ctx, layer.PrmObjectRead{
|
res, err := x.frostFS.ReadObject(ctx, layer.PrmObjectRead{
|
||||||
Container: addr.Container(),
|
Container: addr.Container(),
|
||||||
Object: addr.Object(),
|
Object: addr.Object(),
|
||||||
WithPayload: true,
|
WithPayload: true,
|
||||||
|
@ -532,9 +532,9 @@ func (x *AuthmateNeoFS) ReadObjectPayload(ctx context.Context, addr oid.Address)
|
||||||
return io.ReadAll(res.Payload)
|
return io.ReadAll(res.Payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateObject implements authmate.NeoFS interface method.
|
// CreateObject implements authmate.FrostFS interface method.
|
||||||
func (x *AuthmateNeoFS) CreateObject(ctx context.Context, prm tokens.PrmObjectCreate) (oid.ID, error) {
|
func (x *AuthmateFrostFS) CreateObject(ctx context.Context, prm tokens.PrmObjectCreate) (oid.ID, error) {
|
||||||
return x.neoFS.CreateObject(ctx, layer.PrmObjectCreate{
|
return x.frostFS.CreateObject(ctx, layer.PrmObjectCreate{
|
||||||
Creator: prm.Creator,
|
Creator: prm.Creator,
|
||||||
Container: prm.Container,
|
Container: prm.Container,
|
||||||
Filepath: prm.Filepath,
|
Filepath: prm.Filepath,
|
||||||
|
@ -544,7 +544,7 @@ func (x *AuthmateNeoFS) CreateObject(ctx context.Context, prm tokens.PrmObjectCr
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoolStatistic is a mediator which implements authmate.NeoFS through pool.Pool.
|
// PoolStatistic is a mediator which implements authmate.FrostFS through pool.Pool.
|
||||||
type PoolStatistic struct {
|
type PoolStatistic struct {
|
||||||
pool *pool.Pool
|
pool *pool.Pool
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package neofs
|
package frostfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package neofs
|
package frostfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/api/data"
|
"github.com/TrueCloudLab/frostfs-s3-gw/api/data"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/api/layer"
|
"github.com/TrueCloudLab/frostfs-s3-gw/api/layer"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
"github.com/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
||||||
"github.com/TrueCloudLab/frostfs-s3-gw/internal/neofs/services/tree"
|
"github.com/TrueCloudLab/frostfs-s3-gw/internal/frostfs/services/tree"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
|
@ -1,5 +1,5 @@
|
||||||
/*REMOVE THIS AFTER SIGNATURE WILL BE AVAILABLE IN TREE CLIENT FROM NEOFS NODE*/
|
/*REMOVE THIS AFTER SIGNATURE WILL BE AVAILABLE IN TREE CLIENT FROM FROSTFS NODE*/
|
||||||
package neofs
|
package frostfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
crypto "github.com/TrueCloudLab/frostfs-crypto"
|
crypto "github.com/TrueCloudLab/frostfs-crypto"
|
|
@ -1,4 +1,4 @@
|
||||||
package neofs
|
package frostfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
mkdir -p internal/neofs/services/tree 2>/dev/null
|
mkdir -p internal/frostfs/services/tree 2>/dev/null
|
||||||
|
|
||||||
REVISION="feaa9eace7098c343598bf08fb50746a1e8d2deb"
|
REVISION="feaa9eace7098c343598bf08fb50746a1e8d2deb"
|
||||||
|
|
||||||
|
@ -15,5 +15,5 @@ for file in $FILES; do
|
||||||
else
|
else
|
||||||
echo "sync '$file' in tree service"
|
echo "sync '$file' in tree service"
|
||||||
fi
|
fi
|
||||||
curl -s "https://raw.githubusercontent.com/TrueCloudLab/frostfs-node/${REVISION}/pkg/services/tree/${file}" -o "./internal/neofs/services/tree/${file}"
|
curl -s "https://raw.githubusercontent.com/TrueCloudLab/frostfs-node/${REVISION}/pkg/services/tree/${file}" -o "./internal/frostfs/services/tree/${file}"
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in a new issue