2023-12-08 07:44:13 +00:00
|
|
|
package policy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
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"
|
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MorphRuleChainStorage struct {
|
|
|
|
contract Contract
|
|
|
|
cache *cache.MorphPolicyCache
|
|
|
|
log *zap.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
type MorphRuleChainStorageConfig struct {
|
|
|
|
Contract Contract
|
|
|
|
Cache *cache.MorphPolicyCache
|
|
|
|
Log *zap.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ engine.MorphRuleChainStorage = (*MorphRuleChainStorage)(nil)
|
|
|
|
_ handler.MorphRuleChainStorage = (*MorphRuleChainStorage)(nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewMorphRuleChainStorage(config *MorphRuleChainStorageConfig) *MorphRuleChainStorage {
|
|
|
|
return &MorphRuleChainStorage{
|
|
|
|
contract: config.Contract,
|
|
|
|
cache: config.Cache,
|
|
|
|
log: config.Log,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *MorphRuleChainStorage) AddChain(target engine.Target, policyChain *chain.Chain) error {
|
|
|
|
return c.contract.Wait(c.AddMorphRuleChain(chain.S3, target, policyChain))
|
|
|
|
}
|
|
|
|
|
|
|
|
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) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) {
|
|
|
|
key := cache.MorphPolicyCacheKey{Target: target, Name: name}
|
|
|
|
list := c.cache.Get(key)
|
|
|
|
if list != nil {
|
|
|
|
return list, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
listChains, err := c.contract.ListChains(getKind(target), target.Name, []byte(name))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
list = make([]*chain.Chain, len(listChains))
|
|
|
|
for i, listChain := range listChains {
|
|
|
|
var item chain.Chain
|
2024-02-07 09:23:15 +00:00
|
|
|
if err = item.DecodeBytes(listChain); err != nil {
|
2023-12-08 07:44:13 +00:00
|
|
|
return nil, fmt.Errorf("unmarshal chain: %w", err)
|
|
|
|
}
|
|
|
|
list[i] = &item
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = c.cache.Put(key, list); err != nil {
|
|
|
|
c.log.Warn(logs.CouldntCacheListPolicyChains)
|
|
|
|
}
|
|
|
|
|
|
|
|
return list, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getKind(target engine.Target) policycontract.Kind {
|
|
|
|
var kind policycontract.Kind = policycontract.Container
|
|
|
|
if target.Type != engine.Container {
|
|
|
|
kind = policycontract.Namespace
|
|
|
|
}
|
|
|
|
|
|
|
|
return kind
|
|
|
|
}
|
|
|
|
func getName(name chain.Name, chainID chain.ID) []byte {
|
|
|
|
return append([]byte(name), []byte(chainID)...)
|
|
|
|
}
|