package engine import ( "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource" ) type defaultChainRouter struct { morph MorphRuleChainStorage local LocalOverrideStorage } func NewDefaultChainRouter(morph MorphRuleChainStorage) ChainRouter { return &defaultChainRouter{ morph: morph, } } func NewDefaultChainRouterWithLocalOverrides(morph MorphRuleChainStorage, local LocalOverrideStorage) ChainRouter { return &defaultChainRouter{ morph: morph, local: local, } } func (dr *defaultChainRouter) IsAllowed(name chain.Name, namespace string, r resource.Request) (status chain.Status, ruleFound bool, err error) { status, ruleFound, err = dr.checkLocal(name, namespace, r) if err != nil { return chain.NoRuleFound, false, err } else if ruleFound { return } status, ruleFound, err = dr.checkMorph(name, namespace, r) return } func (dr *defaultChainRouter) checkLocal(name chain.Name, namespace string, r resource.Request) (status chain.Status, ruleFound bool, err error) { if dr.local == nil { return } status, ruleFound, err = dr.matchLocalOverrides(name, ContainerTarget(r.Resource().Name()), r) if err != nil { return chain.NoRuleFound, false, err } else if ruleFound { return } status, ruleFound, err = dr.matchLocalOverrides(name, NamespaceTarget(namespace), r) return } func (dr *defaultChainRouter) checkMorph(name chain.Name, namespace string, r resource.Request) (status chain.Status, ruleFound bool, err error) { var namespaceRuleFound bool status, namespaceRuleFound, err = dr.matchMorphRuleChains(name, NamespaceTarget(namespace), r) if err != nil { return } else if namespaceRuleFound && status != chain.Allow { ruleFound = true return } var cnrRuleFound bool status, cnrRuleFound, err = dr.matchMorphRuleChains(name, ContainerTarget(r.Resource().Name()), r) if err != nil { return } else if cnrRuleFound && status != chain.Allow { ruleFound = true return } status = chain.NoRuleFound if ruleFound = namespaceRuleFound || cnrRuleFound; ruleFound { status = chain.Allow } return } func (dr *defaultChainRouter) matchLocalOverrides(name chain.Name, target Target, r resource.Request) (status chain.Status, ruleFound bool, err error) { localOverrides, err := dr.local.ListOverrides(name, target) if err != nil { return } for _, c := range localOverrides { if status, ruleFound = c.Match(r); ruleFound && status != chain.Allow { return } } return } func (dr *defaultChainRouter) matchMorphRuleChains(name chain.Name, target Target, r resource.Request) (status chain.Status, ruleFound bool, err error) { namespaceChains, err := dr.morph.ListMorphRuleChains(name, target) if err != nil { return } for _, c := range namespaceChains { if status, ruleFound = c.Match(r); ruleFound { return } } return }