forked from TrueCloudLab/frostfs-s3-gw
[#260] Use namespace as domain when resolve bucket
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
a61ff3b8cb
commit
055cc6a22a
16 changed files with 159 additions and 46 deletions
|
@ -6,9 +6,11 @@ import (
|
|||
"fmt"
|
||||
"sync"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ns"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -16,6 +18,8 @@ const (
|
|||
DNSResolver = "dns"
|
||||
)
|
||||
|
||||
const nsDomain = ".ns"
|
||||
|
||||
// ErrNoResolvers returns when trying to resolve container without any resolver.
|
||||
var ErrNoResolvers = errors.New("no resolvers")
|
||||
|
||||
|
@ -28,14 +32,20 @@ type FrostFS interface {
|
|||
SystemDNS(context.Context) (string, error)
|
||||
}
|
||||
|
||||
type Settings interface {
|
||||
DefaultNamespaces() []string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
FrostFS FrostFS
|
||||
RPCAddress string
|
||||
Settings Settings
|
||||
}
|
||||
|
||||
type BucketResolver struct {
|
||||
rpcAddress string
|
||||
frostfs FrostFS
|
||||
settings Settings
|
||||
|
||||
mu sync.RWMutex
|
||||
resolvers []*Resolver
|
||||
|
@ -113,7 +123,13 @@ func (r *BucketResolver) UpdateResolvers(resolverNames []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
resolvers, err := createResolvers(resolverNames, &Config{FrostFS: r.frostfs, RPCAddress: r.rpcAddress})
|
||||
cfg := &Config{
|
||||
FrostFS: r.frostfs,
|
||||
RPCAddress: r.rpcAddress,
|
||||
Settings: r.settings,
|
||||
}
|
||||
|
||||
resolvers, err := createResolvers(resolverNames, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -139,25 +155,33 @@ func (r *BucketResolver) equals(resolverNames []string) bool {
|
|||
func newResolver(name string, cfg *Config) (*Resolver, error) {
|
||||
switch name {
|
||||
case DNSResolver:
|
||||
return NewDNSResolver(cfg.FrostFS)
|
||||
return NewDNSResolver(cfg.FrostFS, cfg.Settings)
|
||||
case NNSResolver:
|
||||
return NewNNSResolver(cfg.RPCAddress)
|
||||
return NewNNSResolver(cfg.RPCAddress, cfg.Settings)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown resolver: %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
func NewDNSResolver(frostFS FrostFS) (*Resolver, error) {
|
||||
func NewDNSResolver(frostFS FrostFS, settings Settings) (*Resolver, error) {
|
||||
if frostFS == nil {
|
||||
return nil, fmt.Errorf("pool must not be nil for DNS resolver")
|
||||
}
|
||||
if settings == nil {
|
||||
return nil, fmt.Errorf("resolver settings must not be nil for DNS resolver")
|
||||
}
|
||||
|
||||
var dns ns.DNS
|
||||
|
||||
resolveFunc := func(ctx context.Context, name string) (cid.ID, error) {
|
||||
domain, err := frostFS.SystemDNS(ctx)
|
||||
if err != nil {
|
||||
return cid.ID{}, fmt.Errorf("read system DNS parameter of the FrostFS: %w", err)
|
||||
var err error
|
||||
reqInfo := middleware.GetReqInfo(ctx)
|
||||
domain := reqInfo.Namespace + nsDomain
|
||||
if slices.Contains(settings.DefaultNamespaces(), domain) {
|
||||
domain, err = frostFS.SystemDNS(ctx)
|
||||
if err != nil {
|
||||
return cid.ID{}, fmt.Errorf("read system DNS parameter of the FrostFS: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
domain = name + "." + domain
|
||||
|
@ -174,10 +198,13 @@ func NewDNSResolver(frostFS FrostFS) (*Resolver, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func NewNNSResolver(address string) (*Resolver, error) {
|
||||
func NewNNSResolver(address string, settings Settings) (*Resolver, error) {
|
||||
if address == "" {
|
||||
return nil, fmt.Errorf("rpc address must not be empty for NNS resolver")
|
||||
}
|
||||
if settings == nil {
|
||||
return nil, fmt.Errorf("resolver settings must not be nil for NNS resolver")
|
||||
}
|
||||
|
||||
var nns ns.NNS
|
||||
|
||||
|
@ -185,10 +212,15 @@ func NewNNSResolver(address string) (*Resolver, error) {
|
|||
return nil, fmt.Errorf("dial %s: %w", address, err)
|
||||
}
|
||||
|
||||
resolveFunc := func(_ context.Context, name string) (cid.ID, error) {
|
||||
resolveFunc := func(ctx context.Context, name string) (cid.ID, error) {
|
||||
var d container.Domain
|
||||
d.SetName(name)
|
||||
|
||||
reqInfo := middleware.GetReqInfo(ctx)
|
||||
if !slices.Contains(settings.DefaultNamespaces(), reqInfo.Namespace) {
|
||||
d.SetZone(reqInfo.Namespace + nsDomain)
|
||||
}
|
||||
|
||||
cnrID, err := nns.ResolveContainerDomain(d)
|
||||
if err != nil {
|
||||
return cid.ID{}, fmt.Errorf("couldn't resolve container '%s': %w", name, err)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue