forked from TrueCloudLab/frostfs-s3-gw
[#306] Reduce number of policy contract invocations
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
499a202d28
commit
c452d58ce2
11 changed files with 235 additions and 159 deletions
|
@ -27,7 +27,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
engineiam "git.frostfs.info/TrueCloudLab/policy-engine/iam"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -439,13 +438,9 @@ func (h *handler) putBucketACLAPEHandler(w http.ResponseWriter, r *http.Request,
|
|||
}
|
||||
|
||||
chainRules := bucketCannedACLToAPERules(cannedACL, reqInfo, key, bktInfo.CID)
|
||||
|
||||
target := engine.NamespaceTarget(reqInfo.Namespace)
|
||||
for _, chainPolicy := range chainRules {
|
||||
if err = h.ape.AddChain(target, chainPolicy); err != nil {
|
||||
h.logAndSendError(w, "failed to add morph rule chain", reqInfo, err, zap.String("chain_id", string(chainPolicy.ID)))
|
||||
return
|
||||
}
|
||||
if err = h.ape.SaveACLChains(reqInfo.Namespace, chainRules); err != nil {
|
||||
h.logAndSendError(w, "failed to add morph rule chains", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
settings.CannedACL = cannedACL
|
||||
|
@ -654,7 +649,7 @@ func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
jsonPolicy, err := h.ape.GetPolicy(reqInfo.Namespace, bktInfo.CID)
|
||||
jsonPolicy, err := h.ape.GetBucketPolicy(reqInfo.Namespace, bktInfo.CID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucketPolicy), err.Error())
|
||||
|
@ -680,14 +675,7 @@ func (h *handler) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Reque
|
|||
return
|
||||
}
|
||||
|
||||
target := engine.NamespaceTarget(reqInfo.Namespace)
|
||||
chainID := getBucketChainID(bktInfo)
|
||||
if err = h.ape.RemoveChain(target, chainID); err != nil {
|
||||
h.logAndSendError(w, "failed to remove morph rule chain", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = h.ape.DeletePolicy(reqInfo.Namespace, bktInfo.CID); err != nil {
|
||||
if err = h.ape.DeleteBucketPolicy(reqInfo.Namespace, bktInfo.CID, getBucketChainID(bktInfo)); err != nil {
|
||||
h.logAndSendError(w, "failed to delete policy from storage", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
@ -743,14 +731,8 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
}
|
||||
|
||||
target := engine.NamespaceTarget(reqInfo.Namespace)
|
||||
if err = h.ape.AddChain(target, s3Chain); err != nil {
|
||||
h.logAndSendError(w, "failed to add morph rule chain", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = h.ape.PutPolicy(reqInfo.Namespace, bktInfo.CID, jsonPolicy); err != nil {
|
||||
h.logAndSendError(w, "failed to save policy to storage", reqInfo, err)
|
||||
if err = h.ape.PutBucketPolicy(reqInfo.Namespace, bktInfo.CID, jsonPolicy, s3Chain); err != nil {
|
||||
h.logAndSendError(w, "failed to update policy in contract", reqInfo, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1325,7 +1325,7 @@ func TestPutBucketAPE(t *testing.T) {
|
|||
_, err := hc.tp.ContainerEACL(hc.Context(), info.BktInfo.CID)
|
||||
require.ErrorContains(t, err, "not found")
|
||||
|
||||
chains, err := hc.h.ape.ListChains(engine.NamespaceTarget(""))
|
||||
chains, err := hc.h.ape.(*apeMock).ListChains(engine.NamespaceTarget(""))
|
||||
require.NoError(t, err)
|
||||
require.Len(t, chains, 2)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -55,23 +54,10 @@ type (
|
|||
|
||||
// APE is Access Policy Engine that needs to save policy and acl info to different places.
|
||||
APE interface {
|
||||
MorphRuleChainStorage
|
||||
PolicyStorage
|
||||
}
|
||||
|
||||
// MorphRuleChainStorage is a similar to engine.MorphRuleChainStorage
|
||||
// but doesn't know anything about tx.
|
||||
MorphRuleChainStorage interface {
|
||||
AddChain(target engine.Target, c *chain.Chain) error
|
||||
RemoveChain(target engine.Target, chainID chain.ID) error
|
||||
ListChains(target engine.Target) ([]*chain.Chain, error)
|
||||
}
|
||||
|
||||
// PolicyStorage is interface to save intact initial user provided policy.
|
||||
PolicyStorage interface {
|
||||
PutPolicy(namespace string, cnrID cid.ID, policy []byte) error
|
||||
GetPolicy(namespace string, cnrID cid.ID) ([]byte, error)
|
||||
DeletePolicy(namespace string, cnrID cid.ID) error
|
||||
PutBucketPolicy(ns string, cnrID cid.ID, policy []byte, s3Chain *chain.Chain) error
|
||||
DeleteBucketPolicy(ns string, cnrID cid.ID, chainID chain.ID) error
|
||||
GetBucketPolicy(ns string, cnrID cid.ID) ([]byte, error)
|
||||
SaveACLChains(ns string, chains []*chain.Chain) error
|
||||
}
|
||||
|
||||
frostfsIDDisabled struct{}
|
||||
|
|
|
@ -251,8 +251,27 @@ func (a *apeMock) PutPolicy(namespace string, cnrID cid.ID, policy []byte) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (a *apeMock) GetPolicy(namespace string, cnrID cid.ID) ([]byte, error) {
|
||||
policy, ok := a.policyMap[namespace+cnrID.EncodeToString()]
|
||||
func (a *apeMock) DeletePolicy(namespace string, cnrID cid.ID) error {
|
||||
delete(a.policyMap, namespace+cnrID.EncodeToString())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *apeMock) PutBucketPolicy(ns string, cnrID cid.ID, policy []byte, s3Chain *chain.Chain) error {
|
||||
if err := a.PutPolicy(ns, cnrID, policy); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.AddChain(engine.NamespaceTarget(ns), s3Chain)
|
||||
}
|
||||
|
||||
func (a *apeMock) DeleteBucketPolicy(ns string, cnrID cid.ID, chainID chain.ID) error {
|
||||
if err := a.DeletePolicy(ns, cnrID); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.RemoveChain(engine.NamespaceTarget(ns), chainID)
|
||||
}
|
||||
|
||||
func (a *apeMock) GetBucketPolicy(ns string, cnrID cid.ID) ([]byte, error) {
|
||||
policy, ok := a.policyMap[ns+cnrID.EncodeToString()]
|
||||
if !ok {
|
||||
return nil, errors.New("not found")
|
||||
}
|
||||
|
@ -260,8 +279,13 @@ func (a *apeMock) GetPolicy(namespace string, cnrID cid.ID) ([]byte, error) {
|
|||
return policy, nil
|
||||
}
|
||||
|
||||
func (a *apeMock) DeletePolicy(namespace string, cnrID cid.ID) error {
|
||||
delete(a.policyMap, namespace+cnrID.EncodeToString())
|
||||
func (a *apeMock) SaveACLChains(ns string, chains []*chain.Chain) error {
|
||||
for i := range chains {
|
||||
if err := a.AddChain(engine.NamespaceTarget(ns), chains[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/schema/s3"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -822,14 +821,10 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
h.reqLogger(ctx).Info(logs.BucketIsCreated, zap.Stringer("container_id", bktInfo.CID))
|
||||
|
||||
chainRules := bucketCannedACLToAPERules(cannedACL, reqInfo, key, bktInfo.CID)
|
||||
|
||||
target := engine.NamespaceTarget(reqInfo.Namespace)
|
||||
for _, chainPolicy := range chainRules {
|
||||
if err = h.ape.AddChain(target, chainPolicy); err != nil {
|
||||
h.logAndSendError(w, "failed to add morph rule chain", reqInfo, err, zap.String("chain_id", string(chainPolicy.ID)))
|
||||
return
|
||||
}
|
||||
chains := bucketCannedACLToAPERules(cannedACL, reqInfo, key, bktInfo.CID)
|
||||
if err = h.ape.SaveACLChains(reqInfo.Namespace, chains); err != nil {
|
||||
h.logAndSendError(w, "failed to add morph rule chain", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
sp := &layer.PutSettingsParams{
|
||||
|
|
|
@ -2,9 +2,11 @@ package contract
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/commonclient"
|
||||
policycontract "git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
||||
policyclient "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/policy"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy"
|
||||
|
@ -21,6 +23,7 @@ import (
|
|||
type Client struct {
|
||||
actor *actor.Actor
|
||||
policyContract *policyclient.Contract
|
||||
contractHash util.Uint160
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
|
@ -72,6 +75,7 @@ func New(ctx context.Context, cfg Config) (*Client, error) {
|
|||
return &Client{
|
||||
actor: act,
|
||||
policyContract: policyclient.New(act, contractHash),
|
||||
contractHash: contractHash,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -130,3 +134,87 @@ func (c *Client) Wait(tx util.Uint256, vub uint32, err error) error {
|
|||
_, err = c.actor.Wait(tx, vub, err)
|
||||
return err
|
||||
}
|
||||
|
||||
type multiTX struct {
|
||||
contractHash util.Uint160
|
||||
txs []*commonclient.Transaction
|
||||
err error
|
||||
}
|
||||
|
||||
func (m *multiTX) AddChain(entity policycontract.Kind, entityName string, name []byte, chain []byte) {
|
||||
m.wrapCall("addChain", []any{big.NewInt(int64(entity)), entityName, name, chain})
|
||||
}
|
||||
|
||||
func (m *multiTX) RemoveChain(entity policycontract.Kind, entityName string, name []byte) {
|
||||
m.wrapCall("removeChain", []any{big.NewInt(int64(entity)), entityName, name})
|
||||
}
|
||||
|
||||
func (m *multiTX) Scripts() ([][]byte, error) {
|
||||
if m.err != nil {
|
||||
return nil, m.err
|
||||
}
|
||||
|
||||
if len(m.txs) == 0 {
|
||||
return nil, errors.New("tx isn't initialized")
|
||||
}
|
||||
|
||||
res := make([][]byte, 0, len(m.txs))
|
||||
for _, tx := range m.txs {
|
||||
script, err := tx.Bytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, script)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (m *multiTX) wrapCall(method string, args []any) {
|
||||
if m.err != nil {
|
||||
return
|
||||
}
|
||||
if len(m.txs) == 0 {
|
||||
m.err = errors.New("multi tx isn't initialized")
|
||||
return
|
||||
}
|
||||
|
||||
err := m.txs[len(m.txs)-1].WrapCall(method, args)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
if !errors.Is(commonclient.ErrTransactionTooLarge, err) {
|
||||
m.err = err
|
||||
return
|
||||
}
|
||||
|
||||
tx := commonclient.NewTransaction(m.contractHash)
|
||||
m.err = tx.WrapCall(method, args)
|
||||
if m.err == nil {
|
||||
m.txs = append(m.txs, tx)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) StartTx() policy.MultiTransaction {
|
||||
return &multiTX{
|
||||
txs: []*commonclient.Transaction{commonclient.NewTransaction(c.contractHash)},
|
||||
contractHash: c.contractHash,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) SendTx(mtx policy.MultiTransaction) error {
|
||||
var err error
|
||||
|
||||
scripts, err := mtx.Scripts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range scripts {
|
||||
if _, err = c.actor.Wait(c.actor.SendRun(scripts[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -83,6 +83,17 @@ func (c *InMemoryContract) Wait(_ util.Uint256, _ uint32, err error) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (c *InMemoryContract) StartTx() policy.MultiTransaction {
|
||||
return &inMemoryTx{operations: make([]func(*InMemoryContract), 0)}
|
||||
}
|
||||
|
||||
func (c *InMemoryContract) SendTx(tx policy.MultiTransaction) error {
|
||||
for _, operation := range tx.(*inMemoryTx).operations {
|
||||
operation(c)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *InMemoryContract) getMap(kind policycontract.Kind) *syncedMap {
|
||||
switch kind {
|
||||
case policycontract.IAM:
|
||||
|
@ -95,3 +106,23 @@ func (c *InMemoryContract) getMap(kind policycontract.Kind) *syncedMap {
|
|||
return &syncedMap{data: map[string][]byte{}}
|
||||
}
|
||||
}
|
||||
|
||||
type inMemoryTx struct {
|
||||
operations []func(contract *InMemoryContract)
|
||||
}
|
||||
|
||||
func (t *inMemoryTx) AddChain(kind policycontract.Kind, entity string, name []byte, chain []byte) {
|
||||
t.operations = append(t.operations, func(c *InMemoryContract) {
|
||||
_, _, _ = c.AddChain(kind, entity, name, chain)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *inMemoryTx) RemoveChain(kind policycontract.Kind, entity string, name []byte) {
|
||||
t.operations = append(t.operations, func(c *InMemoryContract) {
|
||||
_, _, _ = c.RemoveChain(kind, entity, name)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *inMemoryTx) Scripts() ([][]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
package policy
|
||||
|
||||
import (
|
||||
policycontract "git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/handler"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type MorphPolicyStorage struct {
|
||||
contract Contract
|
||||
}
|
||||
|
||||
type MorphPolicyStorageConfig struct {
|
||||
Contract Contract
|
||||
Log *zap.Logger
|
||||
}
|
||||
|
||||
var _ handler.PolicyStorage = (*MorphPolicyStorage)(nil)
|
||||
|
||||
const policyStoragePrefix = 'b'
|
||||
|
||||
func NewMorphPolicyStorage(config *MorphPolicyStorageConfig) *MorphPolicyStorage {
|
||||
return &MorphPolicyStorage{
|
||||
contract: config.Contract,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *MorphPolicyStorage) PutPolicy(namespace string, cnrID cid.ID, policy []byte) error {
|
||||
name := getPolicyStorageName(cnrID)
|
||||
return c.contract.Wait(c.contract.AddChain(policycontract.IAM, namespace, name, policy))
|
||||
}
|
||||
|
||||
func (c *MorphPolicyStorage) GetPolicy(namespace string, cnrID cid.ID) ([]byte, error) {
|
||||
name := getPolicyStorageName(cnrID)
|
||||
return c.contract.GetChain(policycontract.IAM, namespace, name)
|
||||
}
|
||||
|
||||
func (c *MorphPolicyStorage) DeletePolicy(namespace string, cnrID cid.ID) error {
|
||||
name := getPolicyStorageName(cnrID)
|
||||
return c.contract.Wait(c.contract.RemoveChain(policycontract.IAM, namespace, name))
|
||||
}
|
||||
|
||||
func getPolicyStorageName(cnrID cid.ID) []byte {
|
||||
return append([]byte{policyStoragePrefix}, cnrID[:]...)
|
||||
}
|
|
@ -5,8 +5,8 @@ import (
|
|||
|
||||
policycontract "git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/handler"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -25,10 +25,9 @@ type MorphRuleChainStorageConfig struct {
|
|||
Log *zap.Logger
|
||||
}
|
||||
|
||||
var (
|
||||
_ engine.MorphRuleChainStorage = (*MorphRuleChainStorage)(nil)
|
||||
_ handler.MorphRuleChainStorage = (*MorphRuleChainStorage)(nil)
|
||||
)
|
||||
var _ engine.MorphRuleChainStorage = (*MorphRuleChainStorage)(nil)
|
||||
|
||||
const bucketPolicyPrefix = 'b'
|
||||
|
||||
func NewMorphRuleChainStorage(config *MorphRuleChainStorageConfig) *MorphRuleChainStorage {
|
||||
return &MorphRuleChainStorage{
|
||||
|
@ -38,26 +37,12 @@ func NewMorphRuleChainStorage(config *MorphRuleChainStorageConfig) *MorphRuleCha
|
|||
}
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) AddChain(target engine.Target, policyChain *chain.Chain) error {
|
||||
return c.contract.Wait(c.AddMorphRuleChain(chain.S3, target, policyChain))
|
||||
func (c *MorphRuleChainStorage) AddMorphRuleChain(chain.Name, engine.Target, *chain.Chain) (util.Uint256, uint32, error) {
|
||||
panic("should never be called")
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) RemoveChain(target engine.Target, chainID chain.ID) error {
|
||||
return c.contract.Wait(c.RemoveMorphRuleChain(chain.S3, target, chainID))
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) ListChains(target engine.Target) ([]*chain.Chain, error) {
|
||||
return c.ListMorphRuleChains(chain.S3, target)
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) AddMorphRuleChain(name chain.Name, target engine.Target, policyChain *chain.Chain) (util.Uint256, uint32, error) {
|
||||
c.cache.Delete(cache.MorphPolicyCacheKey{Target: target, Name: name})
|
||||
return c.contract.AddChain(getKind(target), target.Name, getName(name, policyChain.ID), policyChain.Bytes())
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) RemoveMorphRuleChain(name chain.Name, target engine.Target, chainID chain.ID) (util.Uint256, uint32, error) {
|
||||
c.cache.Delete(cache.MorphPolicyCacheKey{Target: target, Name: name})
|
||||
return c.contract.RemoveChain(getKind(target), target.Name, getName(name, chainID))
|
||||
func (c *MorphRuleChainStorage) RemoveMorphRuleChain(chain.Name, engine.Target, chain.ID) (util.Uint256, uint32, error) {
|
||||
panic("should never be called")
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) {
|
||||
|
@ -88,6 +73,42 @@ func (c *MorphRuleChainStorage) ListMorphRuleChains(name chain.Name, target engi
|
|||
return list, nil
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) PutBucketPolicy(ns string, cnrID cid.ID, policy []byte, s3Chain *chain.Chain) error {
|
||||
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.NamespaceTarget(ns), Name: chain.S3})
|
||||
|
||||
tx := c.contract.StartTx()
|
||||
tx.AddChain(policycontract.Namespace, ns, s3Chain.ID, s3Chain.Bytes())
|
||||
tx.AddChain(policycontract.IAM, ns, getBucketPolicyName(cnrID), policy)
|
||||
|
||||
return c.contract.SendTx(tx)
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) DeleteBucketPolicy(ns string, cnrID cid.ID, chainID chain.ID) error {
|
||||
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.NamespaceTarget(ns), Name: chain.S3})
|
||||
|
||||
tx := c.contract.StartTx()
|
||||
tx.RemoveChain(policycontract.Namespace, ns, chainID)
|
||||
tx.RemoveChain(policycontract.IAM, ns, getBucketPolicyName(cnrID))
|
||||
|
||||
return c.contract.SendTx(tx)
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) GetBucketPolicy(ns string, cnrID cid.ID) ([]byte, error) {
|
||||
return c.contract.GetChain(policycontract.IAM, ns, getBucketPolicyName(cnrID))
|
||||
}
|
||||
|
||||
func (c *MorphRuleChainStorage) SaveACLChains(ns string, chains []*chain.Chain) error {
|
||||
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.NamespaceTarget(ns), Name: chain.S3})
|
||||
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.NamespaceTarget(ns), Name: chain.Ingress})
|
||||
|
||||
tx := c.contract.StartTx()
|
||||
for i := range chains {
|
||||
tx.AddChain(policycontract.Namespace, ns, chains[i].ID, chains[i].Bytes())
|
||||
}
|
||||
|
||||
return c.contract.SendTx(tx)
|
||||
}
|
||||
|
||||
func getKind(target engine.Target) policycontract.Kind {
|
||||
var kind policycontract.Kind = policycontract.Container
|
||||
if target.Type != engine.Container {
|
||||
|
@ -96,6 +117,7 @@ func getKind(target engine.Target) policycontract.Kind {
|
|||
|
||||
return kind
|
||||
}
|
||||
func getName(name chain.Name, chainID chain.ID) []byte {
|
||||
return append([]byte(name), []byte(chainID)...)
|
||||
|
||||
func getBucketPolicyName(cnrID cid.ID) []byte {
|
||||
return append([]byte{bucketPolicyPrefix}, cnrID[:]...)
|
||||
}
|
||||
|
|
|
@ -9,18 +9,15 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine/inmemory"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Storage struct {
|
||||
router engine.ChainRouter
|
||||
|
||||
morph handler.MorphRuleChainStorage
|
||||
morph *MorphRuleChainStorage
|
||||
|
||||
local engine.LocalOverrideStorage
|
||||
|
||||
policy handler.PolicyStorage
|
||||
}
|
||||
|
||||
type StorageConfig struct {
|
||||
|
@ -29,18 +26,23 @@ type StorageConfig struct {
|
|||
Log *zap.Logger
|
||||
}
|
||||
|
||||
type MultiTransaction interface {
|
||||
AddChain(entity policycontract.Kind, entityName string, name []byte, chain []byte)
|
||||
RemoveChain(entity policycontract.Kind, entityName string, name []byte)
|
||||
Scripts() ([][]byte, error)
|
||||
}
|
||||
|
||||
type Contract interface {
|
||||
AddChain(kind policycontract.Kind, entity string, name []byte, chain []byte) (util.Uint256, uint32, error)
|
||||
GetChain(kind policycontract.Kind, entity string, name []byte) ([]byte, error)
|
||||
RemoveChain(kind policycontract.Kind, entity string, name []byte) (util.Uint256, uint32, error)
|
||||
ListChains(kind policycontract.Kind, entity string, name []byte) ([][]byte, error)
|
||||
Wait(tx util.Uint256, vub uint32, err error) error
|
||||
GetChain(entity policycontract.Kind, entityName string, name []byte) ([]byte, error)
|
||||
ListChains(entity policycontract.Kind, entityName string, prefix []byte) ([][]byte, error)
|
||||
|
||||
StartTx() MultiTransaction
|
||||
SendTx(transaction MultiTransaction) error
|
||||
}
|
||||
|
||||
var _ handler.APE = (*Storage)(nil)
|
||||
|
||||
func NewStorage(cfg StorageConfig) *Storage {
|
||||
// todo use thread safe inmemory https://git.frostfs.info/TrueCloudLab/policy-engine/issues/35
|
||||
local := inmemory.NewInmemoryLocalStorage()
|
||||
|
||||
morph := NewMorphRuleChainStorage(&MorphRuleChainStorageConfig{
|
||||
|
@ -49,16 +51,10 @@ func NewStorage(cfg StorageConfig) *Storage {
|
|||
Log: cfg.Log,
|
||||
})
|
||||
|
||||
policyStorage := NewMorphPolicyStorage(&MorphPolicyStorageConfig{
|
||||
Contract: cfg.Contract,
|
||||
Log: cfg.Log,
|
||||
})
|
||||
|
||||
return &Storage{
|
||||
router: engine.NewDefaultChainRouterWithLocalOverrides(morph, local),
|
||||
morph: morph,
|
||||
local: local,
|
||||
policy: policyStorage,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,26 +66,23 @@ func (s *Storage) LocalStorage() engine.LocalOverrideStorage {
|
|||
return s.local
|
||||
}
|
||||
|
||||
func (s *Storage) AddChain(target engine.Target, policyChain *chain.Chain) error {
|
||||
return s.morph.AddChain(target, policyChain)
|
||||
func (s *Storage) PutBucketPolicy(ns string, cnrID cid.ID, policy []byte, s3Chain *chain.Chain) error {
|
||||
return s.morph.PutBucketPolicy(ns, cnrID, policy, s3Chain)
|
||||
}
|
||||
|
||||
func (s *Storage) RemoveChain(target engine.Target, chainID chain.ID) error {
|
||||
return s.morph.RemoveChain(target, chainID)
|
||||
func (s *Storage) DeleteBucketPolicy(ns string, cnrID cid.ID, chainID chain.ID) error {
|
||||
return s.morph.DeleteBucketPolicy(ns, cnrID, chainID)
|
||||
}
|
||||
|
||||
func (s *Storage) ListChains(target engine.Target) ([]*chain.Chain, error) {
|
||||
return s.morph.ListChains(target)
|
||||
func (s *Storage) GetBucketPolicy(ns string, cnrID cid.ID) ([]byte, error) {
|
||||
return s.morph.GetBucketPolicy(ns, cnrID)
|
||||
}
|
||||
|
||||
func (s *Storage) PutPolicy(namespace string, cnrID cid.ID, policy []byte) error {
|
||||
return s.policy.PutPolicy(namespace, cnrID, policy)
|
||||
func (s *Storage) SaveACLChains(ns string, chains []*chain.Chain) error {
|
||||
return s.morph.SaveACLChains(ns, chains)
|
||||
}
|
||||
|
||||
func (s *Storage) GetPolicy(namespace string, cnrID cid.ID) ([]byte, error) {
|
||||
return s.policy.GetPolicy(namespace, cnrID)
|
||||
}
|
||||
|
||||
func (s *Storage) DeletePolicy(namespace string, cnrID cid.ID) error {
|
||||
return s.policy.DeletePolicy(namespace, cnrID)
|
||||
}
|
||||
//
|
||||
//func (s *Storage) ListChains(target engine.Target) ([]*chain.Chain, error) {
|
||||
// return s.morph.ListMorphRuleChains(target)
|
||||
//}
|
||||
|
|
|
@ -145,4 +145,5 @@ const (
|
|||
CouldNotCloseRequestBody = "could not close request body"
|
||||
BucketOwnerKeyIsMissing = "bucket owner key is missing"
|
||||
SettingsNodeInvalidOwnerKey = "settings node: invalid owner key"
|
||||
FailedToSendTransaction = "failed to send transaction"
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue