1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-20 23:02:36 +00:00
kyverno/pkg/policystore/policystore.go

169 lines
4.3 KiB
Go
Raw Normal View History

2019-08-13 13:15:32 -07:00
package policystore
import (
"sync"
2020-03-17 11:05:20 -07:00
"github.com/go-logr/logr"
2019-11-13 13:41:08 -08:00
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
2019-11-15 15:59:37 -08:00
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1"
2019-11-13 13:41:08 -08:00
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
2020-03-17 11:05:20 -07:00
"k8s.io/apimachinery/pkg/labels"
2019-11-15 15:59:37 -08:00
"k8s.io/client-go/tools/cache"
2019-08-13 13:15:32 -07:00
)
2019-11-12 14:41:29 -08:00
type policyMap map[string]interface{}
type namespaceMap map[string]policyMap
type kindMap map[string]namespaceMap
2019-11-11 11:10:25 -08:00
//PolicyStore Store the meta-data information to faster lookup policies
type PolicyStore struct {
2019-11-15 15:59:37 -08:00
data map[string]namespaceMap
mu sync.RWMutex
// list/get cluster policy
2019-11-12 14:41:29 -08:00
pLister kyvernolister.ClusterPolicyLister
2019-11-15 15:59:37 -08:00
// returns true if the cluster policy store has been synced at least once
pSynched cache.InformerSynced
2020-03-17 11:05:20 -07:00
log logr.Logger
2019-08-13 13:15:32 -07:00
}
2019-11-12 14:41:29 -08:00
//UpdateInterface provides api to update policies
type UpdateInterface interface {
2019-11-11 11:10:25 -08:00
// Register a new policy
Register(policy kyverno.ClusterPolicy)
// Remove policy information
UnRegister(policy kyverno.ClusterPolicy) error
2019-11-12 14:41:29 -08:00
}
//LookupInterface provides api to lookup policies
type LookupInterface interface {
2020-02-05 16:29:37 +05:30
ListAll() ([]kyverno.ClusterPolicy, error)
2019-11-11 11:10:25 -08:00
}
// NewPolicyStore returns a new policy store
2020-03-17 11:05:20 -07:00
func NewPolicyStore(pInformer kyvernoinformer.ClusterPolicyInformer,
log logr.Logger) *PolicyStore {
2019-11-11 11:10:25 -08:00
ps := PolicyStore{
2019-11-15 15:59:37 -08:00
data: make(kindMap),
pLister: pInformer.Lister(),
pSynched: pInformer.Informer().HasSynced,
2020-03-17 11:05:20 -07:00
log: log,
2019-08-13 13:15:32 -07:00
}
2019-11-11 11:10:25 -08:00
return &ps
}
2019-08-13 13:15:32 -07:00
2019-11-15 15:59:37 -08:00
//Run checks syncing
func (ps *PolicyStore) Run(stopCh <-chan struct{}) {
2020-03-17 11:05:20 -07:00
logger := ps.log
2019-11-15 15:59:37 -08:00
if !cache.WaitForCacheSync(stopCh, ps.pSynched) {
2020-03-17 11:05:20 -07:00
logger.Info("failed to sync informer cache")
2019-11-15 15:59:37 -08:00
}
}
2019-11-11 11:10:25 -08:00
//Register a new policy
func (ps *PolicyStore) Register(policy kyverno.ClusterPolicy) {
2020-03-17 11:05:20 -07:00
logger := ps.log
logger.V(4).Info("adding policy", "name", policy.Name)
2019-11-11 11:10:25 -08:00
ps.mu.Lock()
defer ps.mu.Unlock()
var pmap policyMap
// add an entry for each rule in policy
for _, rule := range policy.Spec.Rules {
// rule.MatchResources.Kinds - List - mandatory - atleast on entry
for _, kind := range rule.MatchResources.Kinds {
2019-11-12 14:41:29 -08:00
kindMap := ps.addKind(kind)
2019-11-11 11:10:25 -08:00
// namespaces
if len(rule.MatchResources.Namespaces) == 0 {
// all namespaces - *
pmap = addNamespace(kindMap, "*")
} else {
for _, ns := range rule.MatchResources.Namespaces {
pmap = addNamespace(kindMap, ns)
}
}
// add policy to the pmap
2019-11-12 14:41:29 -08:00
addPolicyElement(pmap, policy.Name)
}
}
}
2020-02-05 16:29:37 +05:30
func (ps *PolicyStore) ListAll() ([]kyverno.ClusterPolicy, error) {
policyPointers, err := ps.pLister.List(labels.NewSelector())
if err != nil {
return nil, err
}
var policies = make([]kyverno.ClusterPolicy, 0, len(policyPointers))
for _, policy := range policyPointers {
policies = append(policies, *policy)
}
return policies, nil
}
2020-02-22 19:05:54 +05:30
func (ps *PolicyStore) Get(policyName string) (*kyverno.ClusterPolicy, error) {
return ps.pLister.Get(policyName)
}
2019-11-11 11:10:25 -08:00
//UnRegister Remove policy information
func (ps *PolicyStore) UnRegister(policy kyverno.ClusterPolicy) error {
ps.mu.Lock()
defer ps.mu.Unlock()
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
// get kind Map
2019-11-12 14:41:29 -08:00
kindMap := ps.getKind(kind)
2019-11-11 11:10:25 -08:00
if kindMap == nil {
// kind does not exist
return nil
}
if len(rule.MatchResources.Namespaces) == 0 {
namespace := "*"
pmap := getNamespace(kindMap, namespace)
// remove element
2019-11-12 14:41:29 -08:00
delete(pmap, policy.Name)
2019-11-11 11:10:25 -08:00
} else {
for _, ns := range rule.MatchResources.Namespaces {
pmap := getNamespace(kindMap, ns)
// remove element
2019-11-12 14:41:29 -08:00
delete(pmap, policy.Name)
2019-11-11 11:10:25 -08:00
}
}
2019-08-13 13:15:32 -07:00
}
2019-11-11 11:10:25 -08:00
}
return nil
}
2019-08-13 13:15:32 -07:00
2019-11-12 14:41:29 -08:00
func (ps *PolicyStore) addKind(kind string) namespaceMap {
val, ok := ps.data[kind]
2019-11-11 11:10:25 -08:00
if ok {
return val
}
2019-11-12 14:41:29 -08:00
ps.data[kind] = make(namespaceMap)
return ps.data[kind]
2019-08-13 13:15:32 -07:00
}
2019-11-12 14:41:29 -08:00
func (ps *PolicyStore) getKind(kind string) namespaceMap {
return ps.data[kind]
2019-11-11 11:10:25 -08:00
}
func addNamespace(kindMap map[string]policyMap, namespace string) policyMap {
val, ok := kindMap[namespace]
if ok {
return val
}
kindMap[namespace] = make(policyMap)
return kindMap[namespace]
}
func getNamespace(kindMap map[string]policyMap, namespace string) policyMap {
return kindMap[namespace]
}
2019-11-12 14:41:29 -08:00
func addPolicyElement(pmap policyMap, name string) {
2019-11-11 11:10:25 -08:00
var emptyInterface interface{}
2019-11-12 14:41:29 -08:00
if _, ok := pmap[name]; !ok {
pmap[name] = emptyInterface
2019-08-13 13:15:32 -07:00
}
}