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) { if dr.local != nil { var localRuleFound bool status, localRuleFound, err = dr.checkLocalOverrides(name, r) if err != nil { return chain.NoRuleFound, false, err } else if localRuleFound { ruleFound = true return } } var namespaceRuleFound bool status, namespaceRuleFound, err = dr.checkNamespaceChains(name, namespace, r) if err != nil { return } else if namespaceRuleFound && status != chain.Allow { ruleFound = true return } var cnrRuleFound bool status, cnrRuleFound, err = dr.checkContainerChains(name, 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) checkLocalOverrides(name chain.Name, r resource.Request) (status chain.Status, ruleFound bool, err error) { localOverrides, err := dr.local.ListOverrides(name, r.Resource().Name()) if err != nil { return } for _, c := range localOverrides { if status, ruleFound = c.Match(r); ruleFound && status != chain.Allow { return } } return } func (dr *defaultChainRouter) checkNamespaceChains(name chain.Name, namespace string, r resource.Request) (status chain.Status, ruleFound bool, err error) { namespaceChains, err := dr.morph.ListMorphRuleChains(name, NamespaceTarget(namespace)) if err != nil { return } for _, c := range namespaceChains { if status, ruleFound = c.Match(r); ruleFound { return } } return } func (dr *defaultChainRouter) checkContainerChains(name chain.Name, container string, r resource.Request) (status chain.Status, ruleFound bool, err error) { containerChains, err := dr.morph.ListMorphRuleChains(name, ContainerTarget(container)) if err != nil { return } for _, c := range containerChains { if status, ruleFound = c.Match(r); ruleFound { return } } return }