policy-engine/pkg/engine/chain_router.go

102 lines
2.6 KiB
Go
Raw Normal View History

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
}