1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-13 19:28:55 +00:00

Matched list to configure the matched resources (#1844)

* Fix Dev setup

* initial commit

* add testcases for matchlist

* fix e2e issue

* fix comment

* fix issue

* fix lock issue

* revert changes

* fix cache issue

* Fix cache test

* fix policy object

* fix comments

* fix public methos issue

Co-authored-by: vyankatesh <vyankatesh@neualto.com>
This commit is contained in:
Vyankatesh Kudtarkar 2021-05-07 00:32:06 +05:30 committed by GitHub
parent c0be318788
commit 299547f376
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 284 additions and 222 deletions

View file

@ -57,7 +57,7 @@ func ConvertPolicyToClusterPolicy(nsPolicies *kyverno.Policy) *kyverno.ClusterPo
return &cpol
}
func parseNamespacedPolicy(key string) (string, string, bool) {
func ParseNamespacedPolicy(key string) (string, string, bool) {
namespace := ""
index := strings.Index(key, "/")
if index != -1 {

View file

@ -474,7 +474,7 @@ func (pc *PolicyController) syncPolicy(key string) error {
}
func (pc *PolicyController) getPolicy(key string) (policy *kyverno.ClusterPolicy, err error) {
namespace, key, isNamespacedPolicy := parseNamespacedPolicy(key)
namespace, key, isNamespacedPolicy := ParseNamespacedPolicy(key)
if !isNamespacedPolicy {
return pc.pLister.Get(key)
}

View file

@ -5,18 +5,18 @@ import (
"github.com/go-logr/logr"
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
kyvernolister "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
policy2 "github.com/kyverno/kyverno/pkg/policy"
)
type pMap struct {
sync.RWMutex
// dataMap field stores ClusterPolicies
dataMap map[PolicyType][]*kyverno.ClusterPolicy
// nsDataMap field stores Namespaced Policies for each namespaces.
// The Policy is converted internally to ClusterPolicy and stored as a ClusterPolicy
// Since both the policy use same type (i.e. Policy), Both policies can be differentiated based on
// "Kind" or "namespace". When the Policy is converted it will retain the value of kind as "Policy".
// Cluster policy will be having namespace as Blank (""), but Policy will always be having namespace field and "default" value by default
nsDataMap map[string]map[PolicyType][]*kyverno.ClusterPolicy
// kindDataMap field stores names of ClusterPolicies and Namespaced Policies.
// Since both the policy name use same type (i.e. string), Both policies can be differentiated based on
// "namespace". namespace policy get stored with policy namespace with policy name"
// kindDataMap {"kind": {{"policytype" : {"policyName","nsname/policyName}}},"kind2": {{"policytype" : {"nsname/policyName" }}}}
kindDataMap map[string]map[PolicyType][]string
// nameCacheMap stores the names of all existing policies in dataMap
// Policy names are stored as <namespace>/<name>
@ -27,17 +27,24 @@ type pMap struct {
type policyCache struct {
pMap
logr.Logger
// list/get cluster policy resource
pLister kyvernolister.ClusterPolicyLister
// npLister can list/get namespace policy from the shared informer's store
npLister kyvernolister.PolicyLister
}
// Interface ...
// Interface get method use for to get policy names and mostly use to test cache testcases
type Interface interface {
Add(policy *kyverno.ClusterPolicy)
Remove(policy *kyverno.ClusterPolicy)
Get(pkey PolicyType, nspace *string) []*kyverno.ClusterPolicy
GetPolicyObject(pkey PolicyType, kind *string, nspace *string) []*kyverno.ClusterPolicy
get(pkey PolicyType, kind *string, nspace *string) []string
}
// newPolicyCache ...
func newPolicyCache(log logr.Logger) Interface {
func newPolicyCache(log logr.Logger, pLister kyvernolister.ClusterPolicyLister, npLister kyvernolister.PolicyLister) Interface {
namesCache := map[PolicyType]map[string]bool{
Mutate: make(map[string]bool),
ValidateEnforce: make(map[string]bool),
@ -47,24 +54,27 @@ func newPolicyCache(log logr.Logger) Interface {
return &policyCache{
pMap{
dataMap: make(map[PolicyType][]*kyverno.ClusterPolicy),
nsDataMap: make(map[string]map[PolicyType][]*kyverno.ClusterPolicy),
nameCacheMap: namesCache,
kindDataMap: make(map[string]map[PolicyType][]string),
},
log,
pLister,
npLister,
}
}
// Add a policy to cache
func (pc *policyCache) Add(policy *kyverno.ClusterPolicy) {
pc.pMap.add(policy)
pc.Logger.V(4).Info("policy is added to cache", "name", policy.GetName())
}
// Get the list of matched policies
func (pc *policyCache) Get(pkey PolicyType, nspace *string) []*kyverno.ClusterPolicy {
return pc.pMap.get(pkey, nspace)
func (pc *policyCache) get(pkey PolicyType, kind, nspace *string) []string {
return pc.pMap.get(pkey, kind, nspace)
}
func (pc *policyCache) GetPolicyObject(pkey PolicyType, kind, nspace *string) []*kyverno.ClusterPolicy {
return pc.getPolicyObject(pkey, kind, nspace)
}
// Remove a policy from cache
@ -84,136 +94,121 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
generateMap := m.nameCacheMap[Generate]
var pName = policy.GetName()
pSpace := policy.GetNamespace()
isNamespacedPolicy := false
if pSpace != "" {
pName = pSpace + "/" + pName
isNamespacedPolicy = true
// Initialize Namespace Cache Map
_, ok := m.nsDataMap[policy.GetNamespace()]
if !ok {
m.nsDataMap[policy.GetNamespace()] = make(map[PolicyType][]*kyverno.ClusterPolicy)
}
}
for _, rule := range policy.Spec.Rules {
if rule.HasMutate() {
if !mutateMap[pName] {
mutateMap[pName] = true
if isNamespacedPolicy {
mutatePolicy := m.nsDataMap[policy.GetNamespace()][Mutate]
m.nsDataMap[policy.GetNamespace()][Mutate] = append(mutatePolicy, policy)
for _, kind := range rule.MatchResources.Kinds {
_, ok := m.kindDataMap[kind]
if !ok {
m.kindDataMap[kind] = make(map[PolicyType][]string)
}
if rule.HasMutate() {
if !mutateMap[kind+"/"+pName] {
mutateMap[kind+"/"+pName] = true
mutatePolicy := m.kindDataMap[kind][Mutate]
m.kindDataMap[kind][Mutate] = append(mutatePolicy, pName)
}
continue
}
if rule.HasValidate() {
if enforcePolicy {
if !validateEnforceMap[kind+"/"+pName] {
validateEnforceMap[kind+"/"+pName] = true
validatePolicy := m.kindDataMap[kind][ValidateEnforce]
m.kindDataMap[kind][ValidateEnforce] = append(validatePolicy, pName)
}
continue
}
mutatePolicy := m.dataMap[Mutate]
m.dataMap[Mutate] = append(mutatePolicy, policy)
}
continue
}
if rule.HasValidate() {
if enforcePolicy {
if !validateEnforceMap[pName] {
validateEnforceMap[pName] = true
if isNamespacedPolicy {
validatePolicy := m.nsDataMap[policy.GetNamespace()][ValidateEnforce]
m.nsDataMap[policy.GetNamespace()][ValidateEnforce] = append(validatePolicy, policy)
continue
}
validatePolicy := m.dataMap[ValidateEnforce]
m.dataMap[ValidateEnforce] = append(validatePolicy, policy)
// ValidateAudit
if !validateAuditMap[kind+"/"+pName] {
validateAuditMap[kind+"/"+pName] = true
validatePolicy := m.kindDataMap[kind][ValidateAudit]
m.kindDataMap[kind][ValidateAudit] = append(validatePolicy, pName)
}
continue
}
// ValidateAudit
if !validateAuditMap[pName] {
validateAuditMap[pName] = true
if isNamespacedPolicy {
validatePolicy := m.nsDataMap[policy.GetNamespace()][ValidateAudit]
m.nsDataMap[policy.GetNamespace()][ValidateAudit] = append(validatePolicy, policy)
continue
if rule.HasGenerate() {
if !generateMap[kind+"/"+pName] {
generateMap[kind+"/"+pName] = true
generatePolicy := m.kindDataMap[kind][Generate]
m.kindDataMap[kind][Generate] = append(generatePolicy, pName)
}
validatePolicy := m.dataMap[ValidateAudit]
m.dataMap[ValidateAudit] = append(validatePolicy, policy)
continue
}
continue
}
if rule.HasGenerate() {
if !generateMap[pName] {
generateMap[pName] = true
if isNamespacedPolicy {
generatePolicy := m.nsDataMap[policy.GetNamespace()][Generate]
m.nsDataMap[policy.GetNamespace()][Generate] = append(generatePolicy, policy)
continue
}
generatePolicy := m.dataMap[Generate]
m.dataMap[Generate] = append(generatePolicy, policy)
}
continue
}
}
m.nameCacheMap[Mutate] = mutateMap
m.nameCacheMap[ValidateEnforce] = validateEnforceMap
m.nameCacheMap[ValidateAudit] = validateAuditMap
m.nameCacheMap[Generate] = generateMap
}
func (m *pMap) get(key PolicyType, nspace *string) []*kyverno.ClusterPolicy {
m.RLock()
defer m.RUnlock()
if nspace == nil || *nspace == "" {
return m.dataMap[key]
func (pc *pMap) get(key PolicyType, kind, namespace *string) (names []string) {
pc.RLock()
defer pc.RUnlock()
for _, policyName := range pc.kindDataMap[*kind][key] {
ns, key, isNamespacedPolicy := policy2.ParseNamespacedPolicy(policyName)
if !isNamespacedPolicy {
names = append(names, key)
} else {
if ns == *namespace {
names = append(names, policyName)
}
}
}
return m.nsDataMap[*nspace][key]
return names
}
func (m *pMap) remove(policy *kyverno.ClusterPolicy) {
m.Lock()
defer m.Unlock()
var pName = policy.GetName()
pSpace := policy.GetNamespace()
isNamespacedPolicy := false
if pSpace != "" {
pName = pSpace + "/" + pName
isNamespacedPolicy = true
}
if !isNamespacedPolicy {
dataMap := m.dataMap
for k, policies := range dataMap {
var newPolicies []*kyverno.ClusterPolicy
for _, p := range policies {
if p.GetName() == pName {
continue
}
newPolicies = append(newPolicies, p)
}
m.dataMap[k] = newPolicies
}
} else {
dataMap := m.nsDataMap[pSpace]
for k, policies := range dataMap {
var newPolicies []*kyverno.ClusterPolicy
for _, p := range policies {
if (p.GetNamespace() + "/" + p.GetName()) == pName {
continue
}
newPolicies = append(newPolicies, p)
}
m.nsDataMap[pSpace][k] = newPolicies
}
}
for _, nameCache := range m.nameCacheMap {
if _, ok := nameCache[pName]; ok {
delete(nameCache, pName)
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
dataMap := m.kindDataMap[kind]
for policyType, policies := range dataMap {
var newPolicies []string
for _, p := range policies {
if p == pName {
continue
}
newPolicies = append(newPolicies, p)
}
m.kindDataMap[kind][policyType] = newPolicies
}
for _, nameCache := range m.nameCacheMap {
if ok := nameCache[kind+"/"+pName]; ok {
delete(nameCache, kind+"/"+pName)
}
}
}
}
}
func (m *policyCache) getPolicyObject(key PolicyType, kind *string, nspace *string) (policyObject []*kyverno.ClusterPolicy) {
policyNames := m.pMap.get(key, kind, nspace)
for _, policyName := range policyNames {
var policy *kyverno.ClusterPolicy
ns, key, isNamespacedPolicy := policy2.ParseNamespacedPolicy(policyName)
if !isNamespacedPolicy {
policy, _ = m.pLister.Get(key)
} else {
if ns == *nspace {
nspolicy, _ := m.npLister.Policies(ns).Get(key)
policy = policy2.ConvertPolicyToClusterPolicy(nspolicy)
}
}
policyObject = append(policyObject, policy)
}
return policyObject
}

View file

@ -2,101 +2,151 @@ package policycache
import (
"encoding/json"
"fmt"
"testing"
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
lv1 "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
"gotest.tools/assert"
"k8s.io/apimachinery/pkg/labels"
"sigs.k8s.io/controller-runtime/pkg/log"
)
type dummyLister struct {
}
func (dl dummyLister) List(selector labels.Selector) (ret []*kyverno.ClusterPolicy, err error) {
return nil, fmt.Errorf("not implemented")
}
func (dl dummyLister) Get(name string) (*kyverno.ClusterPolicy, error) {
return nil, fmt.Errorf("not implemented")
}
func (dl dummyLister) ListResources(selector labels.Selector) (ret []*kyverno.ClusterPolicy, err error) {
return nil, fmt.Errorf("not implemented")
}
// type dymmyNsNamespace struct {}
type dummyNsLister struct {
}
func (dl dummyNsLister) Policies(name string) lv1.PolicyNamespaceLister {
return dummyNsLister{}
}
func (dl dummyNsLister) List(selector labels.Selector) (ret []*kyverno.Policy, err error) {
return nil, fmt.Errorf("not implemented")
}
func (dl dummyNsLister) Get(name string) (*kyverno.Policy, error) {
return nil, fmt.Errorf("not implemented")
}
func Test_All(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newPolicy(t)
// add
//add
pCache.Add(policy)
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
// get
if len(pCache.Get(Mutate, nil)) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, nil)))
}
// get
mutate := pCache.get(Mutate, &kind, nil)
if len(mutate) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(mutate))
}
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
}
if len(pCache.Get(Generate, nil)) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, nil)))
validateEnforce := pCache.get(ValidateEnforce, &kind, nil)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate policy, found %v", len(validateEnforce))
}
generate := pCache.get(Generate, &kind, nil)
if len(generate) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(generate))
}
}
}
// remove
pCache.Remove(policy)
assert.Assert(t, len(pCache.Get(ValidateEnforce, nil)) == 0)
kind := "pod"
validateEnforce := pCache.get(ValidateEnforce, &kind, nil)
assert.Assert(t, len(validateEnforce) == 0)
}
func Test_Add_Duplicate_Policy(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newPolicy(t)
pCache.Add(policy)
pCache.Add(policy)
pCache.Add(policy)
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
if len(pCache.Get(Mutate, nil)) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, nil)))
}
mutate := pCache.get(Mutate, &kind, nil)
if len(mutate) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(mutate))
}
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
}
if len(pCache.Get(Generate, nil)) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, nil)))
validateEnforce := pCache.get(ValidateEnforce, &kind, nil)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate policy, found %v", len(validateEnforce))
}
generate := pCache.get(Generate, &kind, nil)
if len(generate) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(generate))
}
}
}
}
func Test_Add_Validate_Audit(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newPolicy(t)
pCache.Add(policy)
pCache.Add(policy)
policy.Spec.ValidationFailureAction = "audit"
pCache.Add(policy)
pCache.Add(policy)
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
}
validateEnforce := pCache.get(ValidateEnforce, &kind, nil)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(validateEnforce))
}
if len(pCache.Get(ValidateAudit, nil)) != 1 {
t.Errorf("expected 1 validate audit policy, found %v", len(pCache.Get(ValidateAudit, nil)))
validateAudit := pCache.get(ValidateAudit, &kind, nil)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate policy, found %v", len(validateAudit))
}
}
}
}
func Test_Add_Remove(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newPolicy(t)
kind := "Pod"
pCache.Add(policy)
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
validateEnforce := pCache.get(ValidateEnforce, &kind, nil)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(validateEnforce))
}
pCache.Remove(policy)
if len(pCache.Get(ValidateEnforce, nil)) != 0 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
}
pCache.Add(policy)
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
deletedValidateEnforce := pCache.get(ValidateEnforce, &kind, nil)
if len(deletedValidateEnforce) != 0 {
t.Errorf("expected 0 validate enforce policy, found %v", len(deletedValidateEnforce))
}
}
func Test_Remove_From_Empty_Cache(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, nil, nil)
policy := newPolicy(t)
pCache.Remove(policy)
@ -115,19 +165,20 @@ func newPolicy(t *testing.T) *kyverno.ClusterPolicy {
"match": {
"resources": {
"kinds": [
"Pod"
"Pod",
"Namespace"
]
}
},
"validate": {
"deny": {
"conditions": {
"all": [
{
"key": "a",
"operator": "Equals",
"value": "a"
}
"all": [
{
"key": "a",
"operator": "Equals",
"value": "a"
}
]
}
}
@ -159,7 +210,8 @@ func newPolicy(t *testing.T) *kyverno.ClusterPolicy {
"match": {
"resources": {
"kinds": [
"Pod"
"Pod",
"Namespace"
]
}
},
@ -178,7 +230,8 @@ func newPolicy(t *testing.T) *kyverno.ClusterPolicy {
"match": {
"resources": {
"kinds": [
"Namespace"
"Namespace",
"Pod"
]
}
},
@ -285,7 +338,7 @@ func newNsPolicy(t *testing.T) *kyverno.ClusterPolicy {
"match": {
"resources": {
"kinds": [
"Namespace"
"Pod"
]
}
},
@ -316,89 +369,103 @@ func newNsPolicy(t *testing.T) *kyverno.ClusterPolicy {
}
func Test_Ns_All(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newNsPolicy(t)
// add
//add
pCache.Add(policy)
nspace := policy.GetNamespace()
// get
if len(pCache.Get(Mutate, &nspace)) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, &nspace)))
}
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
}
// get
mutate := pCache.get(Mutate, &kind, &nspace)
if len(mutate) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(mutate))
}
if len(pCache.Get(Generate, &nspace)) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, &nspace)))
validateEnforce := pCache.get(ValidateEnforce, &kind, &nspace)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate policy, found %v", len(validateEnforce))
}
generate := pCache.get(Generate, &kind, &nspace)
if len(generate) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(generate))
}
}
}
// remove
pCache.Remove(policy)
assert.Assert(t, len(pCache.Get(ValidateEnforce, &nspace)) == 0)
kind := "pod"
validateEnforce := pCache.get(ValidateEnforce, &kind, &nspace)
assert.Assert(t, len(validateEnforce) == 0)
}
func Test_Ns_Add_Duplicate_Policy(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newNsPolicy(t)
pCache.Add(policy)
pCache.Add(policy)
pCache.Add(policy)
nspace := policy.GetNamespace()
if len(pCache.Get(Mutate, &nspace)) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, &nspace)))
}
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
}
mutate := pCache.get(Mutate, &kind, &nspace)
if len(mutate) != 1 {
t.Errorf("expected 1 mutate policy, found %v", len(mutate))
}
if len(pCache.Get(Generate, &nspace)) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, &nspace)))
validateEnforce := pCache.get(ValidateEnforce, &kind, &nspace)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate policy, found %v", len(validateEnforce))
}
generate := pCache.get(Generate, &kind, &nspace)
if len(generate) != 1 {
t.Errorf("expected 1 generate policy, found %v", len(generate))
}
}
}
}
func Test_Ns_Add_Validate_Audit(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newNsPolicy(t)
pCache.Add(policy)
pCache.Add(policy)
nspace := policy.GetNamespace()
pCache.Add(policy)
pCache.Add(policy)
policy.Spec.ValidationFailureAction = "audit"
pCache.Add(policy)
pCache.Add(policy)
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
}
validateEnforce := pCache.get(ValidateEnforce, &kind, &nspace)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate policy, found %v", len(validateEnforce))
}
if len(pCache.Get(ValidateAudit, &nspace)) != 1 {
t.Errorf("expected 1 validate audit policy, found %v", len(pCache.Get(ValidateAudit, &nspace)))
validateAudit := pCache.get(ValidateAudit, &kind, &nspace)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate policy, found %v", len(validateAudit))
}
}
}
}
func Test_Ns_Add_Remove(t *testing.T) {
pCache := newPolicyCache(log.Log)
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
policy := newNsPolicy(t)
pCache.Add(policy)
nspace := policy.GetNamespace()
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
kind := "Pod"
pCache.Add(policy)
validateEnforce := pCache.get(ValidateEnforce, &kind, &nspace)
if len(validateEnforce) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(validateEnforce))
}
pCache.Remove(policy)
if len(pCache.Get(ValidateEnforce, &nspace)) != 0 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
}
pCache.Add(policy)
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
deletedValidateEnforce := pCache.get(ValidateEnforce, &kind, &nspace)
if len(deletedValidateEnforce) != 0 {
t.Errorf("expected 0 validate enforce policy, found %v", len(deletedValidateEnforce))
}
}

View file

@ -28,7 +28,7 @@ func NewPolicyCacheController(
log logr.Logger) *Controller {
pc := Controller{
Cache: newPolicyCache(log),
Cache: newPolicyCache(log, pInformer.Lister(), nspInformer.Lister()),
log: log,
}

View file

@ -308,11 +308,11 @@ func (ws *WebhookServer) ResourceMutation(request *v1beta1.AdmissionRequest) *v1
}
logger.V(6).Info("received an admission request in mutating webhook")
mutatePolicies := ws.pCache.Get(policycache.Mutate, nil)
generatePolicies := ws.pCache.Get(policycache.Generate, nil)
mutatePolicies := ws.pCache.GetPolicyObject(policycache.Mutate, &request.Kind.Kind, nil)
generatePolicies := ws.pCache.GetPolicyObject(policycache.Generate, &request.Kind.Kind, nil)
// Get namespace policies from the cache for the requested resource namespace
nsMutatePolicies := ws.pCache.Get(policycache.Mutate, &request.Namespace)
nsMutatePolicies := ws.pCache.GetPolicyObject(policycache.Mutate, &request.Kind.Kind, &request.Namespace)
mutatePolicies = append(mutatePolicies, nsMutatePolicies...)
// convert RAW to unstructured
@ -395,9 +395,9 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
logger.V(6).Info("received an admission request in validating webhook")
policies := ws.pCache.Get(policycache.ValidateEnforce, nil)
policies := ws.pCache.GetPolicyObject(policycache.ValidateEnforce, &request.Kind.Kind, nil)
// Get namespace policies from the cache for the requested resource namespace
nsPolicies := ws.pCache.Get(policycache.ValidateEnforce, &request.Namespace)
nsPolicies := ws.pCache.GetPolicyObject(policycache.ValidateEnforce, &request.Kind.Kind, &request.Namespace)
policies = append(policies, nsPolicies...)
if len(policies) == 0 {
// push admission request to audit handler, this won't block the admission request

View file

@ -149,9 +149,9 @@ func (h *auditHandler) process(request *v1beta1.AdmissionRequest) error {
var err error
logger := h.log.WithName("process")
policies := h.pCache.Get(policycache.ValidateAudit, nil)
policies := h.pCache.GetPolicyObject(policycache.ValidateAudit, &request.Kind.Kind, nil)
// Get namespace policies from the cache for the requested resource namespace
nsPolicies := h.pCache.Get(policycache.ValidateAudit, &request.Namespace)
nsPolicies := h.pCache.GetPolicyObject(policycache.ValidateAudit, &request.Kind.Kind, &request.Namespace)
policies = append(policies, nsPolicies...)
// getRoleRef only if policy has roles/clusterroles defined
if containRBACInfo(policies) {