[#219] Add container name resolving

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2021-11-22 12:16:05 +03:00 committed by Alex Vanin
parent 1254f5dac0
commit befe084900
6 changed files with 89 additions and 38 deletions

View file

@ -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)

View file

@ -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
@ -218,8 +225,9 @@ 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 { if err != nil {
list, err := n.containerList(ctx) n.log.Debug("bucket not found", zap.Error(err))
if err != nil {
return nil, 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 {

View file

@ -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)

View file

@ -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{
Key: randomKey, layerCfg := &layer.Config{
Caches: getCacheOptions(v, l),
AnonKey: layer.AnonymousKey{
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
View file

@ -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
View file

@ -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=