forked from TrueCloudLab/frostfs-s3-gw
34a221c5c9
Core changes: - `object.ID` moved to new package `oid`; - `object.Address` moved to new package `address`; - `pool.Object` interface changes. Additionally: - Set container owner in `Agent.IssueSecret`. - Remove no longer needed fields from `GetObjectParams` - `Length` and `Offset` are never assigned. These values are set in `Range` field. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
154 lines
3.5 KiB
Go
154 lines
3.5 KiB
Go
package resolver
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
|
neofsclient "github.com/nspcc-dev/neofs-sdk-go/client"
|
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
|
"github.com/nspcc-dev/neofs-sdk-go/pool"
|
|
"github.com/nspcc-dev/neofs-sdk-go/resolver"
|
|
)
|
|
|
|
const (
|
|
NNSResolver = "nns"
|
|
DNSResolver = "dns"
|
|
|
|
networkSystemDNSParam = "SystemDNS"
|
|
)
|
|
|
|
type Config struct {
|
|
Pool pool.Pool
|
|
RPC *client.Client
|
|
}
|
|
|
|
type BucketResolver struct {
|
|
Name string
|
|
resolve func(context.Context, string) (*cid.ID, error)
|
|
|
|
next *BucketResolver
|
|
}
|
|
|
|
func (r *BucketResolver) Resolve(ctx context.Context, name string) (*cid.ID, error) {
|
|
cnrID, err := r.resolve(ctx, name)
|
|
if err != nil {
|
|
if r.next != nil {
|
|
return r.next.Resolve(ctx, name)
|
|
}
|
|
return nil, err
|
|
}
|
|
return cnrID, err
|
|
}
|
|
|
|
func NewResolver(order []string, cfg *Config) (*BucketResolver, error) {
|
|
if len(order) == 0 {
|
|
return nil, fmt.Errorf("resolving order must not be empty")
|
|
}
|
|
|
|
bucketResolver, err := newResolver(order[len(order)-1], cfg, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for i := len(order) - 2; i >= 0; i-- {
|
|
resolverName := order[i]
|
|
next := bucketResolver
|
|
|
|
bucketResolver, err = newResolver(resolverName, cfg, next)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return bucketResolver, nil
|
|
}
|
|
|
|
func newResolver(name string, cfg *Config, next *BucketResolver) (*BucketResolver, error) {
|
|
switch name {
|
|
case DNSResolver:
|
|
return NewDNSResolver(cfg.Pool, next)
|
|
case NNSResolver:
|
|
return NewNNSResolver(cfg.RPC, next)
|
|
default:
|
|
return nil, fmt.Errorf("unknown resolver: %s", name)
|
|
}
|
|
}
|
|
|
|
func NewDNSResolver(p pool.Pool, next *BucketResolver) (*BucketResolver, error) {
|
|
if p == nil {
|
|
return nil, fmt.Errorf("pool must not be nil for DNS resolver")
|
|
}
|
|
|
|
resolveFunc := func(ctx context.Context, name string) (*cid.ID, error) {
|
|
conn, _, err := p.Connection()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
networkInfoRes, err := conn.NetworkInfo(ctx, neofsclient.PrmNetworkInfo{})
|
|
if err == nil {
|
|
err = apistatus.ErrFromStatus(networkInfoRes.Status())
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
networkInfo := networkInfoRes.Info()
|
|
|
|
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 == "" {
|
|
return nil, fmt.Errorf("couldn't resolve container '%s': not found", name)
|
|
}
|
|
|
|
domain = name + "." + domain
|
|
cnrID, err := resolver.ResolveContainerDomainName(domain)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("couldn't resolve container '%s' as '%s': %w", name, domain, err)
|
|
}
|
|
return cnrID, nil
|
|
}
|
|
|
|
return &BucketResolver{
|
|
Name: DNSResolver,
|
|
|
|
resolve: resolveFunc,
|
|
next: next,
|
|
}, nil
|
|
}
|
|
|
|
func NewNNSResolver(rpc *client.Client, next *BucketResolver) (*BucketResolver, error) {
|
|
if rpc == nil {
|
|
return nil, fmt.Errorf("rpc client must not be nil for NNS resolver")
|
|
}
|
|
|
|
nnsRPCResolver, err := resolver.NewNNSResolver(rpc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resolveFunc := func(_ context.Context, name string) (*cid.ID, error) {
|
|
cnrID, err := nnsRPCResolver.ResolveContainerName(name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("couldn't resolve container '%s': %w", name, err)
|
|
}
|
|
return cnrID, nil
|
|
}
|
|
|
|
return &BucketResolver{
|
|
Name: NNSResolver,
|
|
|
|
resolve: resolveFunc,
|
|
next: next,
|
|
}, nil
|
|
}
|