forked from TrueCloudLab/policy-engine
102 lines
2.6 KiB
Go
102 lines
2.6 KiB
Go
|
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
|
||
|
}
|