forked from TrueCloudLab/frostfs-s3-gw
[#455] Use contract to get containers
Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
This commit is contained in:
parent
949fc0b484
commit
2ad2531d3a
16 changed files with 193 additions and 47 deletions
|
@ -256,6 +256,7 @@ func prepareHandlerContextBase(config *handlerConfig, log *zap.Logger) (*handler
|
|||
GateOwner: owner,
|
||||
GateKey: key,
|
||||
WorkerPool: pool,
|
||||
CnrContract: tp,
|
||||
}
|
||||
|
||||
if !config.withoutCORS {
|
||||
|
|
|
@ -7,14 +7,15 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
containerContract "git.frostfs.info/TrueCloudLab/frostfs-contract/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
|
||||
apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -23,23 +24,23 @@ const (
|
|||
AttributeLockEnabled = "LockEnabled"
|
||||
)
|
||||
|
||||
func (n *Layer) containerInfo(ctx context.Context, prm frostfs.PrmContainer) (*data.BucketInfo, error) {
|
||||
func (n *Layer) containerInfo(ctx context.Context, cnrID cid.ID) (*data.BucketInfo, error) {
|
||||
var (
|
||||
err error
|
||||
res *container.Container
|
||||
log = n.reqLogger(ctx).With(zap.Stringer("cid", prm.ContainerID))
|
||||
log = n.reqLogger(ctx).With(zap.Stringer("cid", cnrID))
|
||||
|
||||
info = &data.BucketInfo{
|
||||
CID: prm.ContainerID,
|
||||
Name: prm.ContainerID.EncodeToString(),
|
||||
CID: cnrID,
|
||||
Name: cnrID.EncodeToString(),
|
||||
}
|
||||
|
||||
reqInfo = middleware.GetReqInfo(ctx)
|
||||
)
|
||||
|
||||
res, err = n.frostFS.Container(ctx, prm)
|
||||
res, err = n.cnrContract.GetContainerByID(cnrID)
|
||||
if err != nil {
|
||||
if client.IsErrContainerNotFound(err) {
|
||||
if strings.Contains(err.Error(), containerContract.NotFoundError) {
|
||||
return nil, fmt.Errorf("%w: %s", apierr.GetAPIError(apierr.ErrNoSuchBucket), err.Error())
|
||||
}
|
||||
return nil, fmt.Errorf("get frostfs container: %w", err)
|
||||
|
@ -71,7 +72,7 @@ func (n *Layer) containerInfo(ctx context.Context, prm frostfs.PrmContainer) (*d
|
|||
|
||||
zone := n.features.FormContainerZone(reqInfo.Namespace)
|
||||
if zone != info.Zone {
|
||||
return nil, fmt.Errorf("ns '%s' and zone '%s' are mismatched for container '%s'", zone, info.Zone, prm.ContainerID)
|
||||
return nil, fmt.Errorf("ns '%s' and zone '%s' are mismatched for container '%s'", zone, info.Zone, cnrID)
|
||||
}
|
||||
|
||||
n.cache.PutBucket(info)
|
||||
|
@ -95,11 +96,7 @@ func (n *Layer) containerList(ctx context.Context, listParams ListBucketsParams)
|
|||
|
||||
list := make([]*data.BucketInfo, 0, len(res))
|
||||
for i := range res {
|
||||
getPrm := frostfs.PrmContainer{
|
||||
ContainerID: res[i],
|
||||
SessionToken: stoken,
|
||||
}
|
||||
info, err := n.containerInfo(ctx, getPrm)
|
||||
info, err := n.containerInfo(ctx, res[i])
|
||||
if err != nil {
|
||||
n.reqLogger(ctx).Error(logs.CouldNotFetchContainerInfo, zap.Error(err), logs.TagField(logs.TagExternalStorage))
|
||||
continue
|
||||
|
|
|
@ -361,3 +361,8 @@ type FrostFS interface {
|
|||
// NetmapSnapshot returns information about FrostFS network map.
|
||||
NetmapSnapshot(context.Context) (netmap.NetMap, error)
|
||||
}
|
||||
|
||||
type ContainerContract interface {
|
||||
// GetContainerByID reads a container from contract by ID.
|
||||
GetContainerByID(cid.ID) (*container.Container, error)
|
||||
}
|
||||
|
|
|
@ -621,6 +621,16 @@ func (t *TestFrostFS) AddContainerPolicyChain(_ context.Context, prm frostfs.Prm
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *TestFrostFS) GetContainerByID(cid cid.ID) (*container.Container, error) {
|
||||
for k, v := range t.containers {
|
||||
if k == cid.EncodeToString() {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("container does not exist %s", cid)
|
||||
}
|
||||
|
||||
func (t *TestFrostFS) checkAccess(cnrID cid.ID, owner user.ID) bool {
|
||||
cnr, ok := t.containers[cnrID.EncodeToString()]
|
||||
if !ok {
|
||||
|
|
|
@ -67,6 +67,7 @@ type (
|
|||
lifecycleCnrInfo *data.BucketInfo
|
||||
workerPool *ants.Pool
|
||||
removalChan chan removalParams
|
||||
cnrContract frostfs.ContainerContract
|
||||
}
|
||||
|
||||
removalParams struct {
|
||||
|
@ -89,6 +90,7 @@ type (
|
|||
CORSCnrInfo *data.BucketInfo
|
||||
LifecycleCnrInfo *data.BucketInfo
|
||||
WorkerPool *ants.Pool
|
||||
CnrContract frostfs.ContainerContract
|
||||
}
|
||||
|
||||
// AnonymousKey contains data for anonymous requests.
|
||||
|
@ -284,6 +286,7 @@ func NewLayer(ctx context.Context, log *zap.Logger, frostFS frostfs.FrostFS, con
|
|||
workerPool: config.WorkerPool,
|
||||
// TODO: consider closing channel
|
||||
removalChan: make(chan removalParams, config.Features.RemoveOnReplaceQueue()),
|
||||
cnrContract: config.CnrContract,
|
||||
}
|
||||
|
||||
go layer.removalRoutine(ctx)
|
||||
|
@ -379,12 +382,7 @@ func (n *Layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInf
|
|||
return nil, err
|
||||
}
|
||||
|
||||
prm := frostfs.PrmContainer{
|
||||
ContainerID: containerID,
|
||||
SessionToken: n.SessionTokenForRead(ctx),
|
||||
}
|
||||
|
||||
return n.containerInfo(ctx, prm)
|
||||
return n.containerInfo(ctx, containerID)
|
||||
}
|
||||
|
||||
// ResolveCID returns container id by name.
|
||||
|
|
|
@ -176,6 +176,7 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
|||
TreeService: NewTreeService(),
|
||||
Features: &FeatureSettingsMock{},
|
||||
GateOwner: owner,
|
||||
CnrContract: tp,
|
||||
}
|
||||
|
||||
return &testContext{
|
||||
|
@ -237,6 +238,7 @@ func prepareCORSContext(t *testing.T, cachesConfig ...*CachesConfig) *testContex
|
|||
CORSCnrInfo: corsCnrInfo,
|
||||
LifecycleCnrInfo: lifecycleCnrInfo,
|
||||
GateKey: key,
|
||||
CnrContract: tp,
|
||||
}
|
||||
|
||||
return &testContext{
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/wallet"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
|
@ -112,6 +113,11 @@ func parseKeys() (userKey *keys.PrivateKey, contractKey *keys.PrivateKey, err er
|
|||
func initFrostFSIDContract(ctx context.Context, log *zap.Logger, key *keys.PrivateKey) (*ffsidContract.FrostFSID, error) {
|
||||
log.Debug(logs.PrepareFrostfsIDClient)
|
||||
|
||||
rpcCli, err := rpcclient.New(ctx, viper.GetString(rpcEndpointFlag), rpcclient.Options{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create rpc client: %w", err)
|
||||
}
|
||||
|
||||
cfg := ffsidContract.Config{
|
||||
RPCAddress: viper.GetString(rpcEndpointFlag),
|
||||
Contract: viper.GetString(frostfsIDContractFlag),
|
||||
|
@ -121,9 +127,10 @@ func initFrostFSIDContract(ctx context.Context, log *zap.Logger, key *keys.Priva
|
|||
IgnoreAlreadyExistsError: false,
|
||||
VerifyExecResults: true,
|
||||
},
|
||||
RPCClient: rpcCli,
|
||||
}
|
||||
|
||||
cli, err := ffsidContract.New(ctx, cfg)
|
||||
cli, err := ffsidContract.New(cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create frostfsid client: %w", err)
|
||||
}
|
||||
|
@ -160,14 +167,20 @@ func registerPublicKey(log *zap.Logger, cli *ffsidContract.FrostFSID, key *keys.
|
|||
func initPolicyContract(ctx context.Context, log *zap.Logger, key *keys.PrivateKey) (*policyContact.Client, error) {
|
||||
log.Debug(logs.PreparePolicyClient)
|
||||
|
||||
rpcCli, err := rpcclient.New(ctx, viper.GetString(rpcEndpointFlag), rpcclient.Options{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create rpc client: %w", err)
|
||||
}
|
||||
|
||||
cfg := policyContact.Config{
|
||||
RPCAddress: viper.GetString(rpcEndpointFlag),
|
||||
Contract: viper.GetString(policyContractFlag),
|
||||
ProxyContract: viper.GetString(proxyContractFlag),
|
||||
Key: key,
|
||||
RPCClient: rpcCli,
|
||||
}
|
||||
|
||||
cli, err := policyContact.New(ctx, cfg)
|
||||
cli, err := policyContact.New(cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create policy client: %w", err)
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/resolver"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs"
|
||||
containerClient "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/frostfsid"
|
||||
ffidcontract "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/frostfsid/contract"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy"
|
||||
|
@ -51,6 +52,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
|
@ -249,14 +251,23 @@ func (a *App) init(ctx context.Context) {
|
|||
a.initResolver()
|
||||
a.initAuthCenter(ctx)
|
||||
a.setRuntimeParameters()
|
||||
a.initFrostfsID(ctx)
|
||||
a.initPolicyStorage(ctx)
|
||||
a.initAPI(ctx)
|
||||
rpcCli := a.initRPCClient(ctx)
|
||||
a.initFrostfsID(rpcCli)
|
||||
a.initPolicyStorage(rpcCli)
|
||||
a.initAPI(ctx, rpcCli)
|
||||
a.initMetrics()
|
||||
a.initServers(ctx)
|
||||
a.initTracing(ctx)
|
||||
}
|
||||
|
||||
func (a *App) initRPCClient(ctx context.Context) *rpcclient.Client {
|
||||
rpcCli, err := rpcclient.New(ctx, a.config().GetString(cfgRPCEndpoint), rpcclient.Options{})
|
||||
if err != nil {
|
||||
a.log.Fatal(logs.InitRPCClientFailed, zap.Error(err), logs.TagField(logs.TagApp))
|
||||
}
|
||||
return rpcCli
|
||||
}
|
||||
|
||||
func (a *App) initAuthCenter(ctx context.Context) {
|
||||
if a.config().IsSet(cfgContainersAccessBox) {
|
||||
cnrID, err := a.resolveContainerID(ctx, cfgContainersAccessBox)
|
||||
|
@ -276,7 +287,7 @@ func (a *App) initAuthCenter(ctx context.Context) {
|
|||
a.ctr = auth.New(tokens.New(cfg), a.config().GetStringSlice(cfgAllowedAccessKeyIDPrefixes), a.settings)
|
||||
}
|
||||
|
||||
func (a *App) initLayer(ctx context.Context) {
|
||||
func (a *App) initLayer(ctx context.Context, rpcCli *rpcclient.Client) {
|
||||
// prepare random key for anonymous requests
|
||||
randomKey, err := keys.NewPrivateKey()
|
||||
if err != nil {
|
||||
|
@ -299,6 +310,16 @@ func (a *App) initLayer(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
cnrClient, err := containerClient.New(containerClient.Config{
|
||||
RPCAddress: a.config().GetString(cfgRPCEndpoint),
|
||||
Contract: a.config().GetString(cfgContractsContainerName),
|
||||
Key: a.key,
|
||||
RPCClient: rpcCli,
|
||||
})
|
||||
if err != nil {
|
||||
a.log.Fatal(logs.InitContainerContractFailed, zap.Error(err), logs.TagField(logs.TagApp))
|
||||
}
|
||||
|
||||
layerCfg := &layer.Config{
|
||||
Cache: a.cache,
|
||||
AnonKey: layer.AnonymousKey{
|
||||
|
@ -312,6 +333,7 @@ func (a *App) initLayer(ctx context.Context) {
|
|||
CORSCnrInfo: corsCnrInfo,
|
||||
LifecycleCnrInfo: lifecycleCnrInfo,
|
||||
WorkerPool: a.initWorkerPool(),
|
||||
CnrContract: cnrClient,
|
||||
}
|
||||
|
||||
// prepare object layer
|
||||
|
@ -694,8 +716,8 @@ func (s *appSettings) LifecycleCopiesNumbers() []uint32 {
|
|||
return s.lifecycleCopiesNumbers
|
||||
}
|
||||
|
||||
func (a *App) initAPI(ctx context.Context) {
|
||||
a.initLayer(ctx)
|
||||
func (a *App) initAPI(ctx context.Context, rpcCli *rpcclient.Client) {
|
||||
a.initLayer(ctx, rpcCli)
|
||||
a.initHandler()
|
||||
}
|
||||
|
||||
|
@ -712,8 +734,8 @@ func (a *App) initMetrics() {
|
|||
a.loggerSettings.setMetrics(a.metrics)
|
||||
}
|
||||
|
||||
func (a *App) initFrostfsID(ctx context.Context) {
|
||||
cli, err := ffidcontract.New(ctx, ffidcontract.Config{
|
||||
func (a *App) initFrostfsID(rpcCli *rpcclient.Client) {
|
||||
cli, err := ffidcontract.New(ffidcontract.Config{
|
||||
RPCAddress: a.config().GetString(cfgRPCEndpoint),
|
||||
Contract: a.config().GetString(cfgFrostfsIDContract),
|
||||
ProxyContract: a.config().GetString(cfgProxyContract),
|
||||
|
@ -722,6 +744,7 @@ func (a *App) initFrostfsID(ctx context.Context) {
|
|||
IgnoreAlreadyExistsError: false,
|
||||
VerifyExecResults: true,
|
||||
},
|
||||
RPCClient: rpcCli,
|
||||
})
|
||||
if err != nil {
|
||||
a.log.Fatal(logs.InitFrostfsIDFailed, zap.Error(err), logs.TagField(logs.TagApp))
|
||||
|
@ -737,8 +760,8 @@ func (a *App) initFrostfsID(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *App) initPolicyStorage(ctx context.Context) {
|
||||
policyContract, err := contract.New(ctx, contract.Config{
|
||||
func (a *App) initPolicyStorage(rpcCli *rpcclient.Client) {
|
||||
policyContract, err := contract.New(contract.Config{
|
||||
RPCAddress: a.config().GetString(cfgRPCEndpoint),
|
||||
Contract: a.config().GetString(cfgPolicyContract),
|
||||
ProxyContract: a.config().GetString(cfgProxyContract),
|
||||
|
@ -747,6 +770,7 @@ func (a *App) initPolicyStorage(ctx context.Context) {
|
|||
IgnoreAlreadyExistsError: false,
|
||||
VerifyExecResults: true,
|
||||
},
|
||||
RPCClient: rpcCli,
|
||||
})
|
||||
if err != nil {
|
||||
a.log.Fatal(logs.InitPolicyContractFailed, zap.Error(err), logs.TagField(logs.TagApp))
|
||||
|
|
|
@ -306,6 +306,9 @@ const (
|
|||
// Encryption.
|
||||
cfgEncryptionTLSTerminationHeader = "encryption.tls_termination_header"
|
||||
|
||||
// Contracts.
|
||||
cfgContractsContainerName = "contracts.container.name"
|
||||
|
||||
// envPrefix is an environment variables prefix used for configuration.
|
||||
envPrefix = "S3_GW"
|
||||
)
|
||||
|
@ -1190,6 +1193,9 @@ func setDefaults(v *viper.Viper, flags *pflag.FlagSet) {
|
|||
// proxy
|
||||
v.SetDefault(cfgProxyContract, "proxy.frostfs")
|
||||
|
||||
// contracts
|
||||
v.SetDefault(cfgContractsContainerName, "container.frostfs")
|
||||
|
||||
// resolve
|
||||
v.SetDefault(cfgResolveNamespaceHeader, defaultNamespaceHeader)
|
||||
|
||||
|
|
|
@ -307,3 +307,6 @@ S3_GW_MULTINET_SUBNETS_1_SOURCE_IPS=1.2.3.4 1.2.3.5
|
|||
|
||||
# Header for determining the termination of TLS.
|
||||
S3_GW_ENCRYPTION_TLS_TERMINATION_TLS_HEADER=X-Frostfs-TLS-Termination
|
||||
|
||||
# Container contract hash (LE) or name in NNS.
|
||||
S3_GW_CONTRACTS_CONTAINER_NAME=container.frostfs
|
||||
|
|
|
@ -362,3 +362,8 @@ multinet:
|
|||
|
||||
encryption:
|
||||
tls_termination_header: X-Frostfs-TLS-Termination
|
||||
|
||||
contracts:
|
||||
container:
|
||||
# Container contract hash (LE) or name in NNS.
|
||||
name: container.frostfs
|
||||
|
|
|
@ -202,6 +202,7 @@ There are some custom types used for brevity:
|
|||
| `vhs` | [VHS configuration](#vhs-section) |
|
||||
| `multinet` | [Multinet configuration](#multinet-section) |
|
||||
| `encryption` | [Encryption configuration](#encryption-section) |
|
||||
| `contracts` | [Contracts configuration](#contracts-section) |
|
||||
|
||||
### General section
|
||||
|
||||
|
@ -971,3 +972,16 @@ encryption:
|
|||
| Parameter | Type | SIGHUP reload | Default value | Description |
|
||||
|--------------------------|----------|---------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `tls_termination_header` | `string` | yes | | The header for determining whether TLS needs to be checked. If the system requests come through a proxy server and TLS can terminate at the proxy level, you should use this header to disable TLS verification at server-side encryption. If the header is not specified or an empty string is set as the value, TLS will always be checked. |
|
||||
|
||||
# `contracts` section
|
||||
|
||||
```yaml
|
||||
contracts:
|
||||
container:
|
||||
name: container.frostfs
|
||||
```
|
||||
|
||||
| Parameter | Type | SIGHUP reload | Default value | Description |
|
||||
|------------------|----------|---------------|---------------------|----------------------------------------------|
|
||||
| `container.name` | `string` | no | `container.frostfs` | Container contract hash (LE) or name in NNS. |
|
||||
|
||||
|
|
72
internal/frostfs/container/client.go
Normal file
72
internal/frostfs/container/client.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
containerContract "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/container"
|
||||
frostfsutil "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/util"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
contract *containerContract.Contract
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
RPCAddress string
|
||||
Contract string
|
||||
Key *keys.PrivateKey
|
||||
RPCClient *rpcclient.Client
|
||||
}
|
||||
|
||||
func New(cfg Config) (*Client, error) {
|
||||
contractHash, err := frostfsutil.ResolveContractHash(cfg.Contract, cfg.RPCAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve frostfs contract hash: %w", err)
|
||||
}
|
||||
|
||||
key := cfg.Key
|
||||
if key == nil {
|
||||
if key, err = keys.NewPrivateKey(); err != nil {
|
||||
return nil, fmt.Errorf("generate anon private key for container contract: %w", err)
|
||||
}
|
||||
}
|
||||
acc := wallet.NewAccountFromPrivateKey(key)
|
||||
|
||||
act, err := actor.NewSimple(cfg.RPCClient, acc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create new actor: %w", err)
|
||||
}
|
||||
|
||||
return &Client{
|
||||
contract: containerContract.New(act, contractHash),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) GetContainerByID(cnrID cid.ID) (*container.Container, error) {
|
||||
items, err := c.contract.Get(cnrID[:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get container by cid: %w", err)
|
||||
}
|
||||
|
||||
if len(items) != 4 {
|
||||
return nil, fmt.Errorf("unexpected container stack item count: %d", len(items))
|
||||
}
|
||||
|
||||
cnrBytes, err := items[0].TryBytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get byte array of container: %w", err)
|
||||
}
|
||||
|
||||
var cnr container.Container
|
||||
if err = cnr.Unmarshal(cnrBytes); err != nil {
|
||||
return nil, fmt.Errorf("can't unmarshal container: %w", err)
|
||||
}
|
||||
|
||||
return &cnr, nil
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package contract
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/commonclient"
|
||||
|
@ -34,10 +33,13 @@ type Config struct {
|
|||
// Waiter contains options for awaiting blockchain transactions
|
||||
// submitted via the contract client.
|
||||
Waiter commonclient.WaiterOptions
|
||||
|
||||
// RPCClient is a client to neo rpc.
|
||||
RPCClient *rpcclient.Client
|
||||
}
|
||||
|
||||
// New creates new FrostfsID contract wrapper that implements auth.FrostFSID interface.
|
||||
func New(ctx context.Context, cfg Config) (*FrostFSID, error) {
|
||||
func New(cfg Config) (*FrostFSID, error) {
|
||||
contractHash, err := frostfsutil.ResolveContractHash(cfg.Contract, cfg.RPCAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve frostfs contract hash: %w", err)
|
||||
|
@ -50,11 +52,6 @@ func New(ctx context.Context, cfg Config) (*FrostFSID, error) {
|
|||
}
|
||||
}
|
||||
|
||||
rpcCli, err := rpcclient.New(ctx, cfg.RPCAddress, rpcclient.Options{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("init rpc client: %w", err)
|
||||
}
|
||||
|
||||
var opt client.Options
|
||||
opt.ProxyContract, err = frostfsutil.ResolveContractHash(cfg.ProxyContract, cfg.RPCAddress)
|
||||
if err != nil {
|
||||
|
@ -62,7 +59,7 @@ func New(ctx context.Context, cfg Config) (*FrostFSID, error) {
|
|||
}
|
||||
opt.Waiter = cfg.Waiter
|
||||
|
||||
cli, err := client.New(rpcCli, wallet.NewAccountFromPrivateKey(key), contractHash, opt)
|
||||
cli, err := client.New(cfg.RPCClient, wallet.NewAccountFromPrivateKey(key), contractHash, opt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("init frostfsid client: %w", err)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package contract
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
@ -45,6 +44,9 @@ type Config struct {
|
|||
// Waiter contains options for awaiting blockchain transactions
|
||||
// submitted via the contract client.
|
||||
Waiter commonclient.WaiterOptions
|
||||
|
||||
// RPCClient is a client to neo rpc.
|
||||
RPCClient *rpcclient.Client
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -55,7 +57,7 @@ const (
|
|||
var _ policy.Contract = (*Client)(nil)
|
||||
|
||||
// New creates new Policy contract wrapper.
|
||||
func New(ctx context.Context, cfg Config) (*Client, error) {
|
||||
func New(cfg Config) (*Client, error) {
|
||||
contractHash, err := frostfsutil.ResolveContractHash(cfg.Contract, cfg.RPCAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve frostfs contract hash: %w", err)
|
||||
|
@ -68,17 +70,12 @@ func New(ctx context.Context, cfg Config) (*Client, error) {
|
|||
}
|
||||
}
|
||||
|
||||
rpcCli, err := rpcclient.New(ctx, cfg.RPCAddress, rpcclient.Options{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create policy rpc client: %w", err)
|
||||
}
|
||||
|
||||
proxyContractHash, err := frostfsutil.ResolveContractHash(cfg.ProxyContract, cfg.RPCAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve frostfs contract hash: %w", err)
|
||||
}
|
||||
|
||||
act, err := actor.New(rpcCli, getSigners(key, proxyContractHash, contractHash))
|
||||
act, err := actor.New(cfg.RPCClient, getSigners(key, proxyContractHash, contractHash))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create new actor: %w", err)
|
||||
}
|
||||
|
|
|
@ -94,6 +94,8 @@ const (
|
|||
WarnDuplicateNamespaceVHS = "duplicate namespace with enabled VHS, config value skipped"
|
||||
WarnValueVHSEnabledFlagWrongType = "the value of the VHS enable flag for the namespace is of the wrong type, config value skipped"
|
||||
WarnDomainContainsInvalidPlaceholder = "the domain contains an invalid placeholder, domain skipped"
|
||||
InitContainerContractFailed = "init container contract failed"
|
||||
InitRPCClientFailed = "init rpc client failed"
|
||||
)
|
||||
|
||||
// Datapath.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue