forked from TrueCloudLab/frostfs-s3-gw
[#219] Add container name resolving
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
1254f5dac0
commit
befe084900
6 changed files with 89 additions and 38 deletions
|
@ -26,6 +26,8 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const nnsNameAttr = "__NEOFS__NAME"
|
||||||
|
|
||||||
func (n *layer) containerInfo(ctx context.Context, cid *cid.ID) (*data.BucketInfo, error) {
|
func (n *layer) containerInfo(ctx context.Context, cid *cid.ID) (*data.BucketInfo, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
@ -126,6 +128,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*ci
|
||||||
container.WithPolicy(p.Policy),
|
container.WithPolicy(p.Policy),
|
||||||
container.WithCustomBasicACL(p.ACL),
|
container.WithCustomBasicACL(p.ACL),
|
||||||
container.WithAttribute(container.AttributeName, p.Name),
|
container.WithAttribute(container.AttributeName, p.Name),
|
||||||
|
container.WithAttribute(nnsNameAttr, p.Name),
|
||||||
container.WithAttribute(container.AttributeTimestamp, strconv.FormatInt(bktInfo.Created.Unix(), 10)))
|
container.WithAttribute(container.AttributeTimestamp, strconv.FormatInt(bktInfo.Created.Unix(), 10)))
|
||||||
|
|
||||||
cnr.SetSessionToken(p.SessionToken)
|
cnr.SetSessionToken(p.SessionToken)
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/pool"
|
"github.com/nspcc-dev/neofs-sdk-go/pool"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/resolver"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -40,6 +41,12 @@ type (
|
||||||
systemCache *cache.SystemCache
|
systemCache *cache.SystemCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Config struct {
|
||||||
|
ChainAddress string
|
||||||
|
Caches *CachesConfig
|
||||||
|
AnonKey AnonymousKey
|
||||||
|
}
|
||||||
|
|
||||||
// AnonymousKey contains data for anonymous requests.
|
// AnonymousKey contains data for anonymous requests.
|
||||||
AnonymousKey struct {
|
AnonymousKey struct {
|
||||||
Key *keys.PrivateKey
|
Key *keys.PrivateKey
|
||||||
|
@ -220,6 +227,7 @@ type (
|
||||||
const (
|
const (
|
||||||
tagPrefix = "S3-Tag-"
|
tagPrefix = "S3-Tag-"
|
||||||
tagEmptyMark = "\\"
|
tagEmptyMark = "\\"
|
||||||
|
networkSystemDNSParam = "SystemDNS"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *VersionedObject) String() string {
|
func (t *VersionedObject) String() string {
|
||||||
|
@ -239,16 +247,16 @@ func DefaultCachesConfigs() *CachesConfig {
|
||||||
|
|
||||||
// NewLayer creates instance of layer. It checks credentials
|
// NewLayer creates instance of layer. It checks credentials
|
||||||
// and establishes gRPC connection with node.
|
// and establishes gRPC connection with node.
|
||||||
func NewLayer(log *zap.Logger, conns pool.Pool, config *CachesConfig, anonKey AnonymousKey) Client {
|
func NewLayer(log *zap.Logger, conns pool.Pool, config *Config) Client {
|
||||||
return &layer{
|
return &layer{
|
||||||
pool: conns,
|
pool: conns,
|
||||||
log: log,
|
log: log,
|
||||||
anonKey: anonKey,
|
anonKey: config.AnonKey,
|
||||||
listsCache: cache.NewObjectsListCache(config.ObjectsList),
|
listsCache: cache.NewObjectsListCache(config.Caches.ObjectsList),
|
||||||
objCache: cache.New(config.Objects),
|
objCache: cache.New(config.Caches.Objects),
|
||||||
namesCache: cache.NewObjectsNameCache(config.Names),
|
namesCache: cache.NewObjectsNameCache(config.Caches.Names),
|
||||||
bucketCache: cache.NewBucketCache(config.Buckets),
|
bucketCache: cache.NewBucketCache(config.Caches.Buckets),
|
||||||
systemCache: cache.NewSystemCache(config.System),
|
systemCache: cache.NewSystemCache(config.Caches.System),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,18 +309,9 @@ func (n *layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInf
|
||||||
return bktInfo, nil
|
return bktInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
containerID := new(cid.ID)
|
containerID, err := n.ResolveBucket(ctx, name)
|
||||||
if err := containerID.Parse(name); err != nil {
|
|
||||||
list, err := n.containerList(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
n.log.Debug("bucket not found", zap.Error(err))
|
||||||
}
|
|
||||||
for _, bkt := range list {
|
|
||||||
if bkt.Name == name {
|
|
||||||
return bkt, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,6 +635,45 @@ func (n *layer) CreateBucket(ctx context.Context, p *CreateBucketParams) (*cid.I
|
||||||
return nil, errors.GetAPIError(errors.ErrBucketAlreadyExists)
|
return nil, errors.GetAPIError(errors.ErrBucketAlreadyExists)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *layer) ResolveBucket(ctx context.Context, name string) (*cid.ID, error) {
|
||||||
|
cnrID := cid.New()
|
||||||
|
if err := cnrID.Parse(name); err != nil {
|
||||||
|
conn, _, err := n.pool.Connection()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
networkInfo, err := conn.NetworkInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var domain string
|
||||||
|
networkInfo.NetworkConfig().IterateParameters(func(parameter *netmap.NetworkParameter) bool {
|
||||||
|
if string(parameter.Key()) == networkSystemDNSParam {
|
||||||
|
domain = string(parameter.Value())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
if domain != "" {
|
||||||
|
domain = name + "." + domain
|
||||||
|
if cnrID, err = resolver.ResolveContainerDomainName(domain); err == nil {
|
||||||
|
return cnrID, nil
|
||||||
|
}
|
||||||
|
n.log.Debug("trying fallback to direct nns since couldn't resolve system dns record",
|
||||||
|
zap.String("domain", domain), zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo add fallback to use nns contract directly
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("couldn't resolve container name '%s': not found", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnrID, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (n *layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
|
func (n *layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error {
|
||||||
bucketInfo, err := n.GetBucketInfo(ctx, p.Name)
|
bucketInfo, err := n.GetBucketInfo(ctx, p.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -214,7 +214,7 @@ func (t *testPool) WaitForContainerPresence(ctx context.Context, id *cid.ID, par
|
||||||
|
|
||||||
func (tc *testContext) putObject(content []byte) *data.ObjectInfo {
|
func (tc *testContext) putObject(content []byte) *data.ObjectInfo {
|
||||||
objInfo, err := tc.layer.PutObject(tc.ctx, &PutObjectParams{
|
objInfo, err := tc.layer.PutObject(tc.ctx, &PutObjectParams{
|
||||||
Bucket: tc.bkt,
|
Bucket: tc.bktID.String(),
|
||||||
Object: tc.obj,
|
Object: tc.obj,
|
||||||
Size: int64(len(content)),
|
Size: int64(len(content)),
|
||||||
Reader: bytes.NewReader(content),
|
Reader: bytes.NewReader(content),
|
||||||
|
@ -348,9 +348,14 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
config = cachesConfig[0]
|
config = cachesConfig[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layerCfg := &Config{
|
||||||
|
Caches: config,
|
||||||
|
AnonKey: AnonymousKey{Key: key},
|
||||||
|
}
|
||||||
|
|
||||||
return &testContext{
|
return &testContext{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
layer: NewLayer(l, tp, config, AnonymousKey{Key: key}),
|
layer: NewLayer(l, tp, layerCfg),
|
||||||
bkt: bktName,
|
bkt: bktName,
|
||||||
bktID: bktID,
|
bktID: bktID,
|
||||||
obj: "obj1",
|
obj: "obj1",
|
||||||
|
@ -362,7 +367,7 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
func TestSimpleVersioning(t *testing.T) {
|
func TestSimpleVersioning(t *testing.T) {
|
||||||
tc := prepareContext(t)
|
tc := prepareContext(t)
|
||||||
_, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
_, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
||||||
Bucket: tc.bkt,
|
Bucket: tc.bktID.String(),
|
||||||
Settings: &BucketSettings{VersioningEnabled: true},
|
Settings: &BucketSettings{VersioningEnabled: true},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -403,7 +408,7 @@ func TestSimpleNoVersioning(t *testing.T) {
|
||||||
func TestVersioningDeleteObject(t *testing.T) {
|
func TestVersioningDeleteObject(t *testing.T) {
|
||||||
tc := prepareContext(t)
|
tc := prepareContext(t)
|
||||||
_, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
_, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
||||||
Bucket: tc.bkt,
|
Bucket: tc.bktID.String(),
|
||||||
Settings: &BucketSettings{VersioningEnabled: true},
|
Settings: &BucketSettings{VersioningEnabled: true},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -420,7 +425,7 @@ func TestVersioningDeleteObject(t *testing.T) {
|
||||||
func TestVersioningDeleteSpecificObjectVersion(t *testing.T) {
|
func TestVersioningDeleteSpecificObjectVersion(t *testing.T) {
|
||||||
tc := prepareContext(t)
|
tc := prepareContext(t)
|
||||||
_, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
_, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
||||||
Bucket: tc.bkt,
|
Bucket: tc.bktID.String(),
|
||||||
Settings: &BucketSettings{VersioningEnabled: true},
|
Settings: &BucketSettings{VersioningEnabled: true},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -751,7 +756,7 @@ func TestSystemObjectsVersioning(t *testing.T) {
|
||||||
|
|
||||||
tc := prepareContext(t, cacheConfig)
|
tc := prepareContext(t, cacheConfig)
|
||||||
objInfo, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
objInfo, err := tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
||||||
Bucket: tc.bkt,
|
Bucket: tc.bktID.String(),
|
||||||
Settings: &BucketSettings{VersioningEnabled: false},
|
Settings: &BucketSettings{VersioningEnabled: false},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -760,7 +765,7 @@ func TestSystemObjectsVersioning(t *testing.T) {
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
|
|
||||||
_, err = tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
_, err = tc.layer.PutBucketVersioning(tc.ctx, &PutVersioningParams{
|
||||||
Bucket: tc.bkt,
|
Bucket: tc.bktID.String(),
|
||||||
Settings: &BucketSettings{VersioningEnabled: true},
|
Settings: &BucketSettings{VersioningEnabled: true},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -783,10 +788,10 @@ func TestDeleteSystemObjectsVersioning(t *testing.T) {
|
||||||
"tag1": "val1",
|
"tag1": "val1",
|
||||||
}
|
}
|
||||||
|
|
||||||
err := tc.layer.PutBucketTagging(tc.ctx, tc.bkt, tagSet)
|
err := tc.layer.PutBucketTagging(tc.ctx, tc.bktID.String(), tagSet)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bkt))
|
objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bktID.String()))
|
||||||
|
|
||||||
tagSet["tag2"] = "val2"
|
tagSet["tag2"] = "val2"
|
||||||
err = tc.layer.PutBucketTagging(tc.ctx, tc.bkt, tagSet)
|
err = tc.layer.PutBucketTagging(tc.ctx, tc.bkt, tagSet)
|
||||||
|
|
|
@ -117,14 +117,16 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatal("couldn't generate random key", zap.Error(err))
|
l.Fatal("couldn't generate random key", zap.Error(err))
|
||||||
}
|
}
|
||||||
anonKey := layer.AnonymousKey{
|
|
||||||
|
layerCfg := &layer.Config{
|
||||||
|
Caches: getCacheOptions(v, l),
|
||||||
|
AnonKey: layer.AnonymousKey{
|
||||||
Key: randomKey,
|
Key: randomKey,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheCfg := getCacheOptions(v, l)
|
|
||||||
|
|
||||||
// prepare object layer
|
// prepare object layer
|
||||||
obj = layer.NewLayer(l, conns, cacheCfg, anonKey)
|
obj = layer.NewLayer(l, conns, layerCfg)
|
||||||
|
|
||||||
// prepare auth center
|
// prepare auth center
|
||||||
ctr = auth.New(conns, key, getAccessBoxCacheConfig(v, l))
|
ctr = auth.New(conns, key, getAccessBoxCacheConfig(v, l))
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -10,7 +10,7 @@ require (
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/nspcc-dev/neo-go v0.97.3
|
github.com/nspcc-dev/neo-go v0.97.3
|
||||||
github.com/nspcc-dev/neofs-api-go v1.30.0
|
github.com/nspcc-dev/neofs-api-go v1.30.0
|
||||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211115110427-df6a622c20e8
|
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211122074021-02f328a03cfb
|
||||||
github.com/prometheus/client_golang v1.11.0
|
github.com/prometheus/client_golang v1.11.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.7.1
|
github.com/spf13/viper v1.7.1
|
||||||
|
|
7
go.sum
7
go.sum
|
@ -23,6 +23,7 @@ github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t
|
||||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
|
github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
|
||||||
|
github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig=
|
||||||
github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A=
|
github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A=
|
||||||
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
|
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
|
||||||
github.com/abiosoft/ishell/v2 v2.0.2/go.mod h1:E4oTCXfo6QjoCart0QYa5m9w4S+deXs/P/9jA77A9Bs=
|
github.com/abiosoft/ishell/v2 v2.0.2/go.mod h1:E4oTCXfo6QjoCart0QYa5m9w4S+deXs/P/9jA77A9Bs=
|
||||||
|
@ -195,6 +196,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
@ -314,8 +316,8 @@ github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9K
|
||||||
github.com/nspcc-dev/neofs-crypto v0.2.3/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
github.com/nspcc-dev/neofs-crypto v0.2.3/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
|
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
||||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211115110427-df6a622c20e8 h1:nhJSZwE2qbrCrVq4TsHlqYlwXePpqD7BsoEsu4TY5vs=
|
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211122074021-02f328a03cfb h1:OBdHw4soQoO7B+61+UQXZLnLspTB4iRV7cVMSpKO5nU=
|
||||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211115110427-df6a622c20e8/go.mod h1:kISVlyRa5l6UIDFigT2AZSW7yUK0QOEmd5mw9WPeYVI=
|
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211122074021-02f328a03cfb/go.mod h1:kISVlyRa5l6UIDFigT2AZSW7yUK0QOEmd5mw9WPeYVI=
|
||||||
github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||||
|
@ -433,6 +435,7 @@ github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
||||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
|
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtbp7r/7QSyGz8mKUbYJBg2+6Cd7OjM8o/GNOcVo=
|
||||||
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c=
|
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
|
Loading…
Reference in a new issue