forked from TrueCloudLab/frostfs-s3-gw
[#287] Support proxy for frostfsid and policy contracts
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
3b6d2bc522
commit
899213b3f3
7 changed files with 71 additions and 8 deletions
|
@ -21,6 +21,7 @@ This document outlines major changes between releases.
|
||||||
- Add `namespace` label to billing metrics (#271)
|
- Add `namespace` label to billing metrics (#271)
|
||||||
- Support policy-engine (#257)
|
- Support policy-engine (#257)
|
||||||
- Support `policy` contract (#259)
|
- Support `policy` contract (#259)
|
||||||
|
- Support `proxy` contract (#287)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Generalise config param `use_default_xmlns_for_complete_multipart` to `use_default_xmlns` so that use default xmlns for all requests (#221)
|
- Generalise config param `use_default_xmlns_for_complete_multipart` to `use_default_xmlns` so that use default xmlns for all requests (#221)
|
||||||
|
|
|
@ -438,9 +438,10 @@ func (a *App) initMetrics() {
|
||||||
func (a *App) initFrostfsID(ctx context.Context) {
|
func (a *App) initFrostfsID(ctx context.Context) {
|
||||||
var err error
|
var err error
|
||||||
a.frostfsid, err = frostfsid.New(ctx, frostfsid.Config{
|
a.frostfsid, err = frostfsid.New(ctx, frostfsid.Config{
|
||||||
RPCAddress: a.cfg.GetString(cfgRPCEndpoint),
|
RPCAddress: a.cfg.GetString(cfgRPCEndpoint),
|
||||||
Contract: a.cfg.GetString(cfgFrostfsIDContract),
|
Contract: a.cfg.GetString(cfgFrostfsIDContract),
|
||||||
Key: a.key,
|
ProxyContract: a.cfg.GetString(cfgProxyContract),
|
||||||
|
Key: a.key,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Fatal(logs.InitFrostfsIDContractFailed, zap.Error(err))
|
a.log.Fatal(logs.InitFrostfsIDContractFailed, zap.Error(err))
|
||||||
|
@ -455,9 +456,10 @@ func (a *App) initPolicyStorage(ctx context.Context) {
|
||||||
|
|
||||||
if a.cfg.GetBool(cfgPolicyEnabled) {
|
if a.cfg.GetBool(cfgPolicyEnabled) {
|
||||||
policyContract, err = contract.New(ctx, contract.Config{
|
policyContract, err = contract.New(ctx, contract.Config{
|
||||||
RPCAddress: a.cfg.GetString(cfgRPCEndpoint),
|
RPCAddress: a.cfg.GetString(cfgRPCEndpoint),
|
||||||
Contract: a.cfg.GetString(cfgPolicyContract),
|
Contract: a.cfg.GetString(cfgPolicyContract),
|
||||||
Key: a.key,
|
ProxyContract: a.cfg.GetString(cfgProxyContract),
|
||||||
|
Key: a.key,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Fatal(logs.InitPolicyContractFailed, zap.Error(err))
|
a.log.Fatal(logs.InitPolicyContractFailed, zap.Error(err))
|
||||||
|
|
|
@ -213,6 +213,9 @@ const ( // Settings.
|
||||||
cfgPolicyEnabled = "policy.enabled"
|
cfgPolicyEnabled = "policy.enabled"
|
||||||
cfgPolicyContract = "policy.contract"
|
cfgPolicyContract = "policy.contract"
|
||||||
|
|
||||||
|
// Proxy.
|
||||||
|
cfgProxyContract = "proxy.contract"
|
||||||
|
|
||||||
// envPrefix is an environment variables prefix used for configuration.
|
// envPrefix is an environment variables prefix used for configuration.
|
||||||
envPrefix = "S3_GW"
|
envPrefix = "S3_GW"
|
||||||
)
|
)
|
||||||
|
@ -702,6 +705,9 @@ func newSettings() *viper.Viper {
|
||||||
v.SetDefault(cfgPolicyContract, "policy.frostfs")
|
v.SetDefault(cfgPolicyContract, "policy.frostfs")
|
||||||
v.SetDefault(cfgPolicyEnabled, true)
|
v.SetDefault(cfgPolicyEnabled, true)
|
||||||
|
|
||||||
|
// proxy
|
||||||
|
v.SetDefault(cfgProxyContract, "proxy.frostfs")
|
||||||
|
|
||||||
// resolve
|
// resolve
|
||||||
v.SetDefault(cfgResolveNamespaceHeader, defaultNamespaceHeader)
|
v.SetDefault(cfgResolveNamespaceHeader, defaultNamespaceHeader)
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,10 @@ S3_GW_POLICY_ENABLED=true
|
||||||
# Policy contract hash (LE) or name in NNS.
|
# Policy contract hash (LE) or name in NNS.
|
||||||
S3_GW_POLICY_CONTRACT=policy.frostfs
|
S3_GW_POLICY_CONTRACT=policy.frostfs
|
||||||
|
|
||||||
|
# Proxy contract configuration. To enable this functionality the `rpc_endpoint` param must be also set.
|
||||||
|
# Proxy contract hash (LE) or name in NNS.
|
||||||
|
S3_GW_PROXY_CONTRACT=proxy.frostfs
|
||||||
|
|
||||||
# Namespaces configuration
|
# Namespaces configuration
|
||||||
S3_GW_NAMESPACES_CONFIG=namespaces.json
|
S3_GW_NAMESPACES_CONFIG=namespaces.json
|
||||||
|
|
||||||
|
|
|
@ -241,5 +241,10 @@ policy:
|
||||||
# Policy contract hash (LE) or name in NNS.
|
# Policy contract hash (LE) or name in NNS.
|
||||||
contract: policy.frostfs
|
contract: policy.frostfs
|
||||||
|
|
||||||
|
# Proxy contract configuration. To enable this functionality the `rpc_endpoint` param must be also set.
|
||||||
|
proxy:
|
||||||
|
# Proxy contract hash (LE) or name in NNS.
|
||||||
|
contract: proxy.frostfs
|
||||||
|
|
||||||
namespaces:
|
namespaces:
|
||||||
config: namespaces.json
|
config: namespaces.json
|
||||||
|
|
|
@ -191,6 +191,7 @@ There are some custom types used for brevity:
|
||||||
| `web` | [Web server configuration](#web-section) |
|
| `web` | [Web server configuration](#web-section) |
|
||||||
| `frostfsid` | [FrostfsID configuration](#frostfsid-section) |
|
| `frostfsid` | [FrostfsID configuration](#frostfsid-section) |
|
||||||
| `policy` | [Policy contract configuration](#policy-section) |
|
| `policy` | [Policy contract configuration](#policy-section) |
|
||||||
|
| `proxy` | [Proxy contract configuration](#proxy-section) |
|
||||||
| `namespaces` | [Namespaces configuration](#namespaces-section) |
|
| `namespaces` | [Namespaces configuration](#namespaces-section) |
|
||||||
|
|
||||||
### General section
|
### General section
|
||||||
|
@ -662,6 +663,19 @@ policy:
|
||||||
| `enabled` | `bool` | no | true | Enables using policies from Policy contract to check permissions. |
|
| `enabled` | `bool` | no | true | Enables using policies from Policy contract to check permissions. |
|
||||||
| `contract` | `string` | no | policy.frostfs | Policy contract hash (LE) or name in NNS. |
|
| `contract` | `string` | no | policy.frostfs | Policy contract hash (LE) or name in NNS. |
|
||||||
|
|
||||||
|
# `proxy` section
|
||||||
|
|
||||||
|
Proxy contract configuration. To enable this functionality the `rpc_endpoint` param must be also set.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
proxy:
|
||||||
|
contract: proxy.frostfs
|
||||||
|
```
|
||||||
|
|
||||||
|
| Parameter | Type | SIGHUP reload | Default value | Description |
|
||||||
|
|------------|----------|---------------|-----------------|------------------------------------------|
|
||||||
|
| `contract` | `string` | no | `proxy.frostfs` | Proxy contract hash (LE) or name in NNS. |
|
||||||
|
|
||||||
# `namespaces` section
|
# `namespaces` section
|
||||||
|
|
||||||
Namespaces configuration.
|
Namespaces configuration.
|
||||||
|
|
|
@ -9,9 +9,11 @@ import (
|
||||||
policyclient "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/policy"
|
policyclient "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/policy"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy"
|
||||||
frostfsutil "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/util"
|
frostfsutil "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"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"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
)
|
)
|
||||||
|
@ -28,6 +30,9 @@ type Config struct {
|
||||||
// Contract is hash of contract or its name in NNS.
|
// Contract is hash of contract or its name in NNS.
|
||||||
Contract string
|
Contract string
|
||||||
|
|
||||||
|
// ProxyContract is hash of proxy contract or its name in NNS to interact with policy.
|
||||||
|
ProxyContract string
|
||||||
|
|
||||||
// Key is used to interact with policy contract.
|
// Key is used to interact with policy contract.
|
||||||
// If this is nil than random key will be generated.
|
// If this is nil than random key will be generated.
|
||||||
Key *keys.PrivateKey
|
Key *keys.PrivateKey
|
||||||
|
@ -54,8 +59,12 @@ func New(ctx context.Context, cfg Config) (*Client, error) {
|
||||||
return nil, fmt.Errorf("create policy rpc client: %w", err)
|
return nil, fmt.Errorf("create policy rpc client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
acc := wallet.NewAccountFromPrivateKey(key)
|
proxyContractHash, err := frostfsutil.ResolveContractHash(cfg.ProxyContract, cfg.RPCAddress)
|
||||||
act, err := actor.NewSimple(rpcCli, acc)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("resolve frostfs contract hash: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
act, err := actor.New(rpcCli, getSigners(key, proxyContractHash, contractHash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create new actor: %w", err)
|
return nil, fmt.Errorf("create new actor: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -66,6 +75,28 @@ func New(ctx context.Context, cfg Config) (*Client, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSigners(key *keys.PrivateKey, proxyHash, contractHash util.Uint160) []actor.SignerAccount {
|
||||||
|
acc := wallet.NewAccountFromPrivateKey(key)
|
||||||
|
|
||||||
|
return []actor.SignerAccount{
|
||||||
|
{
|
||||||
|
Signer: transaction.Signer{
|
||||||
|
Account: proxyHash,
|
||||||
|
Scopes: transaction.CustomContracts,
|
||||||
|
AllowedContracts: []util.Uint160{contractHash},
|
||||||
|
},
|
||||||
|
Account: notary.FakeContractAccount(proxyHash),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Signer: transaction.Signer{
|
||||||
|
Account: acc.Contract.ScriptHash(),
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
},
|
||||||
|
Account: acc,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) AddChain(kind policycontract.Kind, entity string, name []byte, chain []byte) (util.Uint256, uint32, error) {
|
func (c *Client) AddChain(kind policycontract.Kind, entity string, name []byte, chain []byte) (util.Uint256, uint32, error) {
|
||||||
return c.policyContract.AddChain(big.NewInt(int64(kind)), entity, name, chain)
|
return c.policyContract.AddChain(big.NewInt(int64(kind)), entity, name, chain)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue