mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-13 19:28:55 +00:00
fix: polex matching code (#9955)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
7bf4033c6e
commit
c241cfce44
8 changed files with 365 additions and 31 deletions
|
@ -144,6 +144,7 @@ func main() {
|
|||
// informer factories
|
||||
kyvernoInformer := kyvernoinformer.NewSharedInformerFactory(setup.KyvernoClient, resyncPeriod)
|
||||
var wg sync.WaitGroup
|
||||
polexCache, polexController := internal.NewExceptionSelector(setup.Logger, kyvernoInformer)
|
||||
eventGenerator := event.NewEventGenerator(
|
||||
setup.EventsClient,
|
||||
logging.WithName("EventGenerator"),
|
||||
|
@ -187,6 +188,7 @@ func main() {
|
|||
setup.KyvernoClient,
|
||||
setup.RegistrySecretLister,
|
||||
apicall.NewAPICallConfiguration(maxAPICallResponseLength),
|
||||
polexCache,
|
||||
gcstore,
|
||||
)
|
||||
// start informers and wait for cache sync
|
||||
|
@ -247,6 +249,9 @@ func main() {
|
|||
// start non leader controllers
|
||||
eventController.Run(signalCtx, setup.Logger, &wg)
|
||||
gceController.Run(signalCtx, setup.Logger, &wg)
|
||||
if polexController != nil {
|
||||
polexController.Run(signalCtx, setup.Logger, &wg)
|
||||
}
|
||||
// start leader election
|
||||
le.Run(signalCtx)
|
||||
// wait for everything to shut down and exit
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
exceptioncontroller "github.com/kyverno/kyverno/pkg/controllers/exceptions"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
"github.com/kyverno/kyverno/pkg/engine/adapters"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
|
@ -18,7 +19,6 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
|
||||
"github.com/kyverno/kyverno/pkg/engine/factories"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/exceptions"
|
||||
"github.com/kyverno/kyverno/pkg/imageverifycache"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
@ -38,10 +38,10 @@ func NewEngine(
|
|||
kyvernoClient versioned.Interface,
|
||||
secretLister corev1listers.SecretNamespaceLister,
|
||||
apiCallConfig apicall.APICallConfiguration,
|
||||
exceptionsSelector engineapi.PolicyExceptionSelector,
|
||||
gctxStore loaders.Store,
|
||||
) engineapi.Engine {
|
||||
configMapResolver := NewConfigMapResolver(ctx, logger, kubeClient, 15*time.Minute)
|
||||
exceptionsSelector := NewExceptionSelector(ctx, logger, kyvernoClient, 15*time.Minute)
|
||||
logger = logger.WithName("engine")
|
||||
logger.Info("setup engine...")
|
||||
return engine.NewEngine(
|
||||
|
@ -57,29 +57,26 @@ func NewEngine(
|
|||
}
|
||||
|
||||
func NewExceptionSelector(
|
||||
ctx context.Context,
|
||||
logger logr.Logger,
|
||||
kyvernoClient versioned.Interface,
|
||||
resyncPeriod time.Duration,
|
||||
) engineapi.PolicyExceptionSelector {
|
||||
kyvernoInformer kyvernoinformer.SharedInformerFactory,
|
||||
) (engineapi.PolicyExceptionSelector, Controller) {
|
||||
logger = logger.WithName("exception-selector").WithValues("enablePolicyException", enablePolicyException, "exceptionNamespace", exceptionNamespace)
|
||||
logger.Info("setup exception selector...")
|
||||
var exceptionsLister engineapi.PolicyExceptionSelector
|
||||
if enablePolicyException {
|
||||
factory := kyvernoinformer.NewSharedInformerFactory(kyvernoClient, resyncPeriod)
|
||||
var lister exceptions.Lister
|
||||
if exceptionNamespace != "" {
|
||||
lister = factory.Kyverno().V2beta1().PolicyExceptions().Lister().PolicyExceptions(exceptionNamespace)
|
||||
} else {
|
||||
lister = factory.Kyverno().V2beta1().PolicyExceptions().Lister()
|
||||
}
|
||||
// start informers and wait for cache sync
|
||||
if !StartInformersAndWaitForCacheSync(ctx, logger, factory) {
|
||||
checkError(logger, errors.New("failed to wait for cache sync"), "failed to wait for cache sync")
|
||||
}
|
||||
exceptionsLister = exceptions.New(lister)
|
||||
if !enablePolicyException {
|
||||
return nil, nil
|
||||
}
|
||||
return exceptionsLister
|
||||
polexCache := exceptioncontroller.NewController(
|
||||
kyvernoInformer.Kyverno().V1().ClusterPolicies(),
|
||||
kyvernoInformer.Kyverno().V1().Policies(),
|
||||
kyvernoInformer.Kyverno().V2beta1().PolicyExceptions(),
|
||||
exceptionNamespace,
|
||||
)
|
||||
polexController := NewController(
|
||||
exceptioncontroller.ControllerName,
|
||||
polexCache,
|
||||
exceptioncontroller.Workers,
|
||||
)
|
||||
return polexCache, polexController
|
||||
}
|
||||
|
||||
func NewConfigMapResolver(
|
||||
|
|
|
@ -370,6 +370,7 @@ func main() {
|
|||
),
|
||||
globalcontextcontroller.Workers,
|
||||
)
|
||||
polexCache, polexController := internal.NewExceptionSelector(setup.Logger, kyvernoInformer)
|
||||
eventController := internal.NewController(
|
||||
event.ControllerName,
|
||||
eventGenerator,
|
||||
|
@ -415,6 +416,7 @@ func main() {
|
|||
setup.KyvernoClient,
|
||||
setup.RegistrySecretLister,
|
||||
apicall.NewAPICallConfiguration(maxAPICallResponseLength),
|
||||
polexCache,
|
||||
gcstore,
|
||||
)
|
||||
// create non leader controllers
|
||||
|
@ -577,6 +579,9 @@ func main() {
|
|||
// start non leader controllers
|
||||
eventController.Run(signalCtx, setup.Logger, &wg)
|
||||
gceController.Run(signalCtx, setup.Logger, &wg)
|
||||
if polexController != nil {
|
||||
polexController.Run(signalCtx, setup.Logger, &wg)
|
||||
}
|
||||
for _, controller := range nonLeaderControllers {
|
||||
controller.Run(signalCtx, setup.Logger.WithName("controllers"), &wg)
|
||||
}
|
||||
|
|
|
@ -262,6 +262,7 @@ func main() {
|
|||
// informer factories
|
||||
kyvernoInformer := kyvernoinformer.NewSharedInformerFactory(setup.KyvernoClient, resyncPeriod)
|
||||
var wg sync.WaitGroup
|
||||
polexCache, polexController := internal.NewExceptionSelector(setup.Logger, kyvernoInformer)
|
||||
eventGenerator := event.NewEventGenerator(
|
||||
setup.EventsClient,
|
||||
logging.WithName("EventGenerator"),
|
||||
|
@ -300,6 +301,7 @@ func main() {
|
|||
setup.KyvernoClient,
|
||||
setup.RegistrySecretLister,
|
||||
apicall.NewAPICallConfiguration(maxAPICallResponseLength),
|
||||
polexCache,
|
||||
gcstore,
|
||||
)
|
||||
// start informers and wait for cache sync
|
||||
|
@ -376,6 +378,9 @@ func main() {
|
|||
// start non leader controllers
|
||||
eventController.Run(ctx, setup.Logger, &wg)
|
||||
gceController.Run(ctx, setup.Logger, &wg)
|
||||
if polexController != nil {
|
||||
polexController.Run(ctx, setup.Logger, &wg)
|
||||
}
|
||||
// start leader election
|
||||
le.Run(ctx)
|
||||
// wait for everything to shut down and exit
|
||||
|
|
188
pkg/controllers/exceptions/controller.go
Normal file
188
pkg/controllers/exceptions/controller.go
Normal file
|
@ -0,0 +1,188 @@
|
|||
package exceptions
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
|
||||
kyvernov2beta1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v2beta1"
|
||||
kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
|
||||
kyvernov2beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2beta1"
|
||||
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
type ruleIndex = map[string][]*kyvernov2beta1.PolicyException
|
||||
|
||||
type policyIndex = map[string]ruleIndex
|
||||
|
||||
type controller struct {
|
||||
// listers
|
||||
cpolLister kyvernov1listers.ClusterPolicyLister
|
||||
polLister kyvernov1listers.PolicyLister
|
||||
polexLister kyvernov2beta1listers.PolicyExceptionLister
|
||||
|
||||
// queue
|
||||
queue workqueue.RateLimitingInterface
|
||||
|
||||
// state
|
||||
lock sync.RWMutex
|
||||
index policyIndex
|
||||
namespace string
|
||||
}
|
||||
|
||||
const (
|
||||
maxRetries = 10
|
||||
Workers = 3
|
||||
ControllerName = "exceptions-controller"
|
||||
)
|
||||
|
||||
func NewController(
|
||||
cpolInformer kyvernov1informers.ClusterPolicyInformer,
|
||||
polInformer kyvernov1informers.PolicyInformer,
|
||||
polexInformer kyvernov2beta1informers.PolicyExceptionInformer,
|
||||
namespace string,
|
||||
) *controller {
|
||||
queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName)
|
||||
if _, _, err := controllerutils.AddDefaultEventHandlers(logger, cpolInformer.Informer(), queue); err != nil {
|
||||
logger.Error(err, "failed to register event handlers")
|
||||
}
|
||||
if _, _, err := controllerutils.AddDefaultEventHandlers(logger, polInformer.Informer(), queue); err != nil {
|
||||
logger.Error(err, "failed to register event handlers")
|
||||
}
|
||||
c := &controller{
|
||||
cpolLister: cpolInformer.Lister(),
|
||||
polLister: polInformer.Lister(),
|
||||
polexLister: polexInformer.Lister(),
|
||||
queue: queue,
|
||||
index: policyIndex{},
|
||||
namespace: namespace,
|
||||
}
|
||||
if _, err := controllerutils.AddEventHandlersT(polexInformer.Informer(), c.addPolex, c.updatePolex, c.deletePolex); err != nil {
|
||||
logger.Error(err, "failed to register event handlers")
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *controller) Run(ctx context.Context, workers int) {
|
||||
controllerutils.Run(ctx, logger.V(3), ControllerName, time.Second, c.queue, workers, maxRetries, c.reconcile)
|
||||
}
|
||||
|
||||
func (c *controller) Find(policyName string, ruleName string) ([]*kyvernov2beta1.PolicyException, error) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.index[policyName][ruleName], nil
|
||||
}
|
||||
|
||||
func (c *controller) addPolex(polex *kyvernov2beta1.PolicyException) {
|
||||
names := sets.New[string]()
|
||||
for _, ex := range polex.Spec.Exceptions {
|
||||
names.Insert(ex.PolicyName)
|
||||
}
|
||||
for name := range names {
|
||||
c.queue.Add(name)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) updatePolex(old *kyvernov2beta1.PolicyException, new *kyvernov2beta1.PolicyException) {
|
||||
names := sets.New[string]()
|
||||
for _, ex := range old.Spec.Exceptions {
|
||||
names.Insert(ex.PolicyName)
|
||||
}
|
||||
for _, ex := range new.Spec.Exceptions {
|
||||
names.Insert(ex.PolicyName)
|
||||
}
|
||||
for name := range names {
|
||||
c.queue.Add(name)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) deletePolex(polex *kyvernov2beta1.PolicyException) {
|
||||
names := sets.New[string]()
|
||||
for _, ex := range polex.Spec.Exceptions {
|
||||
names.Insert(ex.PolicyName)
|
||||
}
|
||||
for name := range names {
|
||||
c.queue.Add(name)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) getPolicy(namespace, name string) (kyvernov1.PolicyInterface, error) {
|
||||
if namespace == "" {
|
||||
cpolicy, err := c.cpolLister.Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cpolicy, nil
|
||||
} else {
|
||||
policy, err := c.polLister.Policies(namespace).Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return policy, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) listExceptions() ([]*kyvernov2beta1.PolicyException, error) {
|
||||
if c.namespace == "" {
|
||||
return c.polexLister.List(labels.Everything())
|
||||
}
|
||||
return c.polexLister.PolicyExceptions(c.namespace).List(labels.Everything())
|
||||
}
|
||||
|
||||
func (c *controller) buildRuleIndex(key string, policy kyvernov1.PolicyInterface) (ruleIndex, error) {
|
||||
polexList, err := c.listExceptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slices.SortFunc(polexList, func(a, b *kyvernov2beta1.PolicyException) int {
|
||||
if cmp := cmp.Compare(a.Namespace, b.Namespace); cmp != 0 {
|
||||
return cmp
|
||||
}
|
||||
if cmp := cmp.Compare(a.Name, b.Name); cmp != 0 {
|
||||
return cmp
|
||||
}
|
||||
return 0
|
||||
})
|
||||
index := ruleIndex{}
|
||||
for _, rule := range autogen.ComputeRules(policy) {
|
||||
for _, polex := range polexList {
|
||||
if polex.Contains(key, rule.Name) {
|
||||
index[rule.Name] = append(index[rule.Name], polex)
|
||||
}
|
||||
}
|
||||
}
|
||||
return index, nil
|
||||
}
|
||||
|
||||
func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, namespace, name string) error {
|
||||
policy, err := c.getPolicy(namespace, name)
|
||||
if err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
logger.Error(err, "unable to get the policy from policy informer")
|
||||
return err
|
||||
}
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
delete(c.index, key)
|
||||
return nil
|
||||
}
|
||||
ruleIndex, err := c.buildRuleIndex(key, policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
c.index[key] = ruleIndex
|
||||
return nil
|
||||
}
|
5
pkg/controllers/exceptions/log.go
Normal file
5
pkg/controllers/exceptions/log.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package exceptions
|
||||
|
||||
import "github.com/kyverno/kyverno/pkg/logging"
|
||||
|
||||
var logger = logging.WithName(ControllerName)
|
|
@ -2,26 +2,27 @@ package utils
|
|||
|
||||
import (
|
||||
"github.com/go-logr/logr"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/utils/conditions"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
matched "github.com/kyverno/kyverno/pkg/utils/match"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// MatchesException takes a list of exceptions and checks if there is an exception applies to the incoming resource.
|
||||
// It returns the matched policy exception.
|
||||
func MatchesException(
|
||||
polexs []*kyvernov2beta1.PolicyException,
|
||||
policyContext engineapi.PolicyContext,
|
||||
logger logr.Logger,
|
||||
) *kyvernov2beta1.PolicyException {
|
||||
func MatchesException(polexs []*kyvernov2beta1.PolicyException, policyContext engineapi.PolicyContext, logger logr.Logger) *kyvernov2beta1.PolicyException {
|
||||
gvk, subresource := policyContext.ResourceKind()
|
||||
resource := policyContext.NewResource()
|
||||
if resource.Object == nil {
|
||||
resource = policyContext.OldResource()
|
||||
}
|
||||
for _, polex := range polexs {
|
||||
err := matched.CheckMatchesResources(
|
||||
match := checkMatchesResources(
|
||||
resource,
|
||||
polex.Spec.Match,
|
||||
policyContext.NamespaceLabels(),
|
||||
|
@ -29,8 +30,7 @@ func MatchesException(
|
|||
gvk,
|
||||
subresource,
|
||||
)
|
||||
// if there's no error it means a match
|
||||
if err == nil {
|
||||
if match {
|
||||
if polex.Spec.Conditions != nil {
|
||||
passed, err := conditions.CheckAnyAllConditions(logger, policyContext.JSONContext(), *polex.Spec.Conditions)
|
||||
if err != nil {
|
||||
|
@ -45,3 +45,132 @@ func MatchesException(
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMatchesResources(
|
||||
resource unstructured.Unstructured,
|
||||
statement kyvernov2beta1.MatchResources,
|
||||
namespaceLabels map[string]string,
|
||||
admissionInfo kyvernov1beta1.RequestInfo,
|
||||
gvk schema.GroupVersionKind,
|
||||
subresource string,
|
||||
) bool {
|
||||
if len(statement.Any) > 0 {
|
||||
for _, rmr := range statement.Any {
|
||||
if checkResourceFilter(rmr, resource, namespaceLabels, admissionInfo, gvk, subresource) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
} else if len(statement.All) > 0 {
|
||||
for _, rmr := range statement.All {
|
||||
if !checkResourceFilter(rmr, resource, namespaceLabels, admissionInfo, gvk, subresource) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkResourceFilter(
|
||||
statement kyvernov1.ResourceFilter,
|
||||
resource unstructured.Unstructured,
|
||||
namespaceLabels map[string]string,
|
||||
admissionInfo kyvernov1beta1.RequestInfo,
|
||||
gvk schema.GroupVersionKind,
|
||||
subresource string,
|
||||
) bool {
|
||||
if statement.IsEmpty() {
|
||||
return false
|
||||
}
|
||||
return checkResourceDescription(statement.ResourceDescription, resource, namespaceLabels, gvk, subresource) &&
|
||||
checkUserInfo(statement.UserInfo, admissionInfo)
|
||||
}
|
||||
|
||||
func checkResourceDescription(
|
||||
conditionBlock kyvernov1.ResourceDescription,
|
||||
resource unstructured.Unstructured,
|
||||
namespaceLabels map[string]string,
|
||||
gvk schema.GroupVersionKind,
|
||||
subresource string,
|
||||
) bool {
|
||||
if len(conditionBlock.Kinds) > 0 {
|
||||
// Matching on ephemeralcontainers even when they are not explicitly specified is only applicable to policies.
|
||||
if !matched.CheckKind(conditionBlock.Kinds, gvk, subresource, false) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if conditionBlock.Name != "" || len(conditionBlock.Names) > 0 {
|
||||
resourceName := resource.GetName()
|
||||
if resourceName == "" {
|
||||
resourceName = resource.GetGenerateName()
|
||||
}
|
||||
if conditionBlock.Name != "" {
|
||||
if !matched.CheckName(conditionBlock.Name, resourceName) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(conditionBlock.Names) > 0 {
|
||||
noneMatch := true
|
||||
for i := range conditionBlock.Names {
|
||||
if matched.CheckName(conditionBlock.Names[i], resourceName) {
|
||||
noneMatch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if noneMatch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(conditionBlock.Namespaces) > 0 {
|
||||
if !matched.CheckNameSpace(conditionBlock.Namespaces, resource) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(conditionBlock.Annotations) > 0 {
|
||||
if !matched.CheckAnnotations(conditionBlock.Annotations, resource.GetAnnotations()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if conditionBlock.Selector != nil {
|
||||
hasPassed, err := matched.CheckSelector(conditionBlock.Selector, resource.GetLabels())
|
||||
if err != nil {
|
||||
return false
|
||||
} else {
|
||||
if !hasPassed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if conditionBlock.NamespaceSelector != nil && resource.GetKind() != "Namespace" && resource.GetKind() != "" {
|
||||
hasPassed, err := matched.CheckSelector(conditionBlock.NamespaceSelector, namespaceLabels)
|
||||
if err != nil {
|
||||
return false
|
||||
} else {
|
||||
if !hasPassed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func checkUserInfo(userInfo kyvernov1.UserInfo, admissionInfo kyvernov1beta1.RequestInfo) bool {
|
||||
if len(userInfo.Roles) > 0 {
|
||||
if !datautils.SliceContains(userInfo.Roles, admissionInfo.Roles...) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(userInfo.ClusterRoles) > 0 {
|
||||
if !datautils.SliceContains(userInfo.ClusterRoles, admissionInfo.ClusterRoles...) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(userInfo.Subjects) > 0 {
|
||||
if !matched.CheckSubjects(userInfo.Subjects, admissionInfo.AdmissionUserInfo) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ func checkResourceDescription(
|
|||
}
|
||||
}
|
||||
if len(conditionBlock.Namespaces) > 0 {
|
||||
if !checkNameSpace(conditionBlock.Namespaces, resource) {
|
||||
if !CheckNameSpace(conditionBlock.Namespaces, resource) {
|
||||
errs = append(errs, fmt.Errorf("namespace does not match"))
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func checkResourceDescription(
|
|||
return errs
|
||||
}
|
||||
|
||||
func checkNameSpace(namespaces []string, resource unstructured.Unstructured) bool {
|
||||
func CheckNameSpace(namespaces []string, resource unstructured.Unstructured) bool {
|
||||
resourceNameSpace := resource.GetNamespace()
|
||||
if resource.GetKind() == "Namespace" {
|
||||
resourceNameSpace = resource.GetName()
|
||||
|
|
Loading…
Add table
Reference in a new issue