mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
feat: add namespace support in CLI values (#11958)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
83289c7a00
commit
a30fc14d4d
9 changed files with 306 additions and 21 deletions
|
@ -1,5 +1,9 @@
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
// ValuesSpec declares values to be loaded by the Kyverno CLI
|
// ValuesSpec declares values to be loaded by the Kyverno CLI
|
||||||
type ValuesSpec struct {
|
type ValuesSpec struct {
|
||||||
// GlobalValues are the global values
|
// GlobalValues are the global values
|
||||||
|
@ -14,6 +18,9 @@ type ValuesSpec struct {
|
||||||
// NamespaceSelectors are the namespace labels
|
// NamespaceSelectors are the namespace labels
|
||||||
NamespaceSelectors []NamespaceSelector `json:"namespaceSelector,omitempty"`
|
NamespaceSelectors []NamespaceSelector `json:"namespaceSelector,omitempty"`
|
||||||
|
|
||||||
|
// Namespaces are the namespaces
|
||||||
|
Namespaces []corev1.Namespace `json:"namespaces,omitempty"`
|
||||||
|
|
||||||
// Subresources are the subresource/parent resource mappings
|
// Subresources are the subresource/parent resource mappings
|
||||||
Subresources []Subresource `json:"subresources,omitempty"`
|
Subresources []Subresource `json:"subresources,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import (
|
||||||
policyvalidation "github.com/kyverno/kyverno/pkg/validation/policy"
|
policyvalidation "github.com/kyverno/kyverno/pkg/validation/policy"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
@ -261,7 +262,7 @@ func (c *ApplyCommandConfig) applyCommandHelper(out io.Writer) (*processor.Resul
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skippedInvalidPolicies, responses1, err
|
return rc, resources1, skippedInvalidPolicies, responses1, err
|
||||||
}
|
}
|
||||||
responses3, err := c.applyValidatingPolicies(vps, resources1, variables.NamespaceSelectors(), rc, dClient)
|
responses3, err := c.applyValidatingPolicies(vps, resources1, variables.Namespace, rc, dClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skippedInvalidPolicies, responses1, err
|
return rc, resources1, skippedInvalidPolicies, responses1, err
|
||||||
}
|
}
|
||||||
|
@ -315,7 +316,7 @@ func (c *ApplyCommandConfig) applyValidatingAdmissionPolicies(
|
||||||
func (c *ApplyCommandConfig) applyValidatingPolicies(
|
func (c *ApplyCommandConfig) applyValidatingPolicies(
|
||||||
vps []kyvernov2alpha1.ValidatingPolicy,
|
vps []kyvernov2alpha1.ValidatingPolicy,
|
||||||
resources []*unstructured.Unstructured,
|
resources []*unstructured.Unstructured,
|
||||||
namespaceSelectorMap map[string]map[string]string,
|
namespaceProvider func(string) *corev1.Namespace,
|
||||||
_ *processor.ResultCounts,
|
_ *processor.ResultCounts,
|
||||||
_ dclient.Interface,
|
_ dclient.Interface,
|
||||||
) ([]engineapi.EngineResponse, error) {
|
) ([]engineapi.EngineResponse, error) {
|
||||||
|
@ -325,12 +326,11 @@ func (c *ApplyCommandConfig) applyValidatingPolicies(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
eng := engine.NewEngine(provider)
|
eng := engine.NewEngine(provider, namespaceProvider)
|
||||||
responses := make([]engineapi.EngineResponse, 0)
|
responses := make([]engineapi.EngineResponse, 0)
|
||||||
for _, resource := range resources {
|
for _, resource := range resources {
|
||||||
request := engine.EngineRequest{
|
request := engine.EngineRequest{
|
||||||
Resource: resource,
|
Resource: resource,
|
||||||
NamespaceLabels: namespaceSelectorMap,
|
|
||||||
}
|
}
|
||||||
response, err := eng.Handle(ctx, request)
|
response, err := eng.Handle(ctx, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -58,6 +58,97 @@ spec:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
|
namespaces:
|
||||||
|
description: Namespaces are the namespaces
|
||||||
|
items:
|
||||||
|
description: |-
|
||||||
|
Namespace provides a scope for Names.
|
||||||
|
Use of multiple namespaces is optional.
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: |-
|
||||||
|
APIVersion defines the versioned schema of this representation of an object.
|
||||||
|
Servers should convert recognized schemas to the latest internal value, and
|
||||||
|
may reject unrecognized values.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: |-
|
||||||
|
Kind is a string value representing the REST resource this object represents.
|
||||||
|
Servers may infer this from the endpoint the client submits requests to.
|
||||||
|
Cannot be updated.
|
||||||
|
In CamelCase.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
description: |-
|
||||||
|
Standard object's metadata.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: |-
|
||||||
|
Spec defines the behavior of the Namespace.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||||
|
properties:
|
||||||
|
finalizers:
|
||||||
|
description: |-
|
||||||
|
Finalizers is an opaque list of values that must be empty to permanently remove object from storage.
|
||||||
|
More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
|
||||||
|
items:
|
||||||
|
description: FinalizerName is the name identifying a finalizer
|
||||||
|
during namespace lifecycle.
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: |-
|
||||||
|
Status describes the current status of a Namespace.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: Represents the latest available observations of
|
||||||
|
a namespace's current state.
|
||||||
|
items:
|
||||||
|
description: NamespaceCondition contains details about state
|
||||||
|
of namespace.
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: Last time the condition transitioned from
|
||||||
|
one status to another.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: Human-readable message indicating details
|
||||||
|
about last transition.
|
||||||
|
type: string
|
||||||
|
reason:
|
||||||
|
description: Unique, one-word, CamelCase reason for the
|
||||||
|
condition's last transition.
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: Status of the condition, one of True, False,
|
||||||
|
Unknown.
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
description: Type of namespace controller condition.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
phase:
|
||||||
|
description: |-
|
||||||
|
Phase is the current lifecycle phase of the namespace.
|
||||||
|
More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
policies:
|
policies:
|
||||||
description: Policies are the policy values
|
description: Policies are the policy values
|
||||||
items:
|
items:
|
||||||
|
|
|
@ -58,6 +58,97 @@ spec:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
|
namespaces:
|
||||||
|
description: Namespaces are the namespaces
|
||||||
|
items:
|
||||||
|
description: |-
|
||||||
|
Namespace provides a scope for Names.
|
||||||
|
Use of multiple namespaces is optional.
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: |-
|
||||||
|
APIVersion defines the versioned schema of this representation of an object.
|
||||||
|
Servers should convert recognized schemas to the latest internal value, and
|
||||||
|
may reject unrecognized values.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: |-
|
||||||
|
Kind is a string value representing the REST resource this object represents.
|
||||||
|
Servers may infer this from the endpoint the client submits requests to.
|
||||||
|
Cannot be updated.
|
||||||
|
In CamelCase.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
description: |-
|
||||||
|
Standard object's metadata.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: |-
|
||||||
|
Spec defines the behavior of the Namespace.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||||
|
properties:
|
||||||
|
finalizers:
|
||||||
|
description: |-
|
||||||
|
Finalizers is an opaque list of values that must be empty to permanently remove object from storage.
|
||||||
|
More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
|
||||||
|
items:
|
||||||
|
description: FinalizerName is the name identifying a finalizer
|
||||||
|
during namespace lifecycle.
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: |-
|
||||||
|
Status describes the current status of a Namespace.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: Represents the latest available observations of
|
||||||
|
a namespace's current state.
|
||||||
|
items:
|
||||||
|
description: NamespaceCondition contains details about state
|
||||||
|
of namespace.
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: Last time the condition transitioned from
|
||||||
|
one status to another.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: Human-readable message indicating details
|
||||||
|
about last transition.
|
||||||
|
type: string
|
||||||
|
reason:
|
||||||
|
description: Unique, one-word, CamelCase reason for the
|
||||||
|
condition's last transition.
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: Status of the condition, one of True, False,
|
||||||
|
Unknown.
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
description: Type of namespace controller condition.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
phase:
|
||||||
|
description: |-
|
||||||
|
Phase is the current lifecycle phase of the namespace.
|
||||||
|
More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
policies:
|
policies:
|
||||||
description: Policies are the policy values
|
description: Policies are the policy values
|
||||||
items:
|
items:
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
|
|
||||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/apis/v1alpha1"
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/apis/v1alpha1"
|
||||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/store"
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/store"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,10 +30,12 @@ func (v Variables) NamespaceSelectors() map[string]Labels {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
out := map[string]Labels{}
|
out := map[string]Labels{}
|
||||||
if v.values.NamespaceSelectors != nil {
|
|
||||||
for _, n := range v.values.NamespaceSelectors {
|
for _, n := range v.values.NamespaceSelectors {
|
||||||
out[n.Name] = n.Labels
|
out[n.Name] = n.Labels
|
||||||
}
|
}
|
||||||
|
// Give precedence to namespaces
|
||||||
|
for _, n := range v.values.Namespaces {
|
||||||
|
out[n.Name] = n.Labels
|
||||||
}
|
}
|
||||||
if len(out) == 0 {
|
if len(out) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -39,6 +43,33 @@ func (v Variables) NamespaceSelectors() map[string]Labels {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Variables) Namespace(name string) *corev1.Namespace {
|
||||||
|
if v.values == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Give precedence to namespaces
|
||||||
|
for _, n := range v.values.Namespaces {
|
||||||
|
if n.Name == name {
|
||||||
|
return &n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, n := range v.values.NamespaceSelectors {
|
||||||
|
if n.Name == name {
|
||||||
|
return &corev1.Namespace{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: corev1.SchemeGroupVersion.String(),
|
||||||
|
Kind: "Namespace",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Labels: n.Labels,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (v Variables) ComputeVariables(s *store.Store, policy, resource, kind string, kindMap sets.Set[string], variables ...string) (map[string]interface{}, error) {
|
func (v Variables) ComputeVariables(s *store.Store, policy, resource, kind string, kindMap sets.Set[string], variables ...string) (map[string]interface{}, error) {
|
||||||
resourceValues := map[string]interface{}{}
|
resourceValues := map[string]interface{}{}
|
||||||
// first apply global values
|
// first apply global values
|
||||||
|
|
|
@ -1046,6 +1046,19 @@ map[string]interface{}
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
<code>namespaces</code><br/>
|
||||||
|
<em>
|
||||||
|
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#namespace-v1-core">
|
||||||
|
[]Kubernetes core/v1.Namespace
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Namespaces are the namespaces</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
<code>subresources</code><br/>
|
<code>subresources</code><br/>
|
||||||
<em>
|
<em>
|
||||||
<a href="#cli.kyverno.io/v1alpha1.Subresource">
|
<a href="#cli.kyverno.io/v1alpha1.Subresource">
|
||||||
|
|
|
@ -2080,6 +2080,35 @@ This is DEPRECATED, Use <code>patchedResources</code> instead.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><code>namespaces</code>
|
||||||
|
|
||||||
|
<span style="color:blue;"> *</span>
|
||||||
|
|
||||||
|
</br>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<span style="font-family: monospace">[]core/v1.Namespace</span>
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Namespaces are the namespaces</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>subresources</code>
|
<td><code>subresources</code>
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,15 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/cel/policy"
|
"github.com/kyverno/kyverno/pkg/cel/policy"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
||||||
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||||
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EngineRequest struct {
|
type EngineRequest struct {
|
||||||
Resource *unstructured.Unstructured
|
Resource *unstructured.Unstructured
|
||||||
NamespaceLabels map[string]map[string]string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EngineResponse struct {
|
type EngineResponse struct {
|
||||||
|
@ -86,12 +87,16 @@ type Engine interface {
|
||||||
Handle(context.Context, EngineRequest, ...policy.CompiledPolicy) (EngineResponse, error)
|
Handle(context.Context, EngineRequest, ...policy.CompiledPolicy) (EngineResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NamespaceResolver = func(string) *corev1.Namespace
|
||||||
|
|
||||||
type engine struct {
|
type engine struct {
|
||||||
|
nsResolver NamespaceResolver
|
||||||
provider Provider
|
provider Provider
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEngine(provider Provider) *engine {
|
func NewEngine(provider Provider, nsResolver NamespaceResolver) *engine {
|
||||||
return &engine{
|
return &engine{
|
||||||
|
nsResolver: nsResolver,
|
||||||
provider: provider,
|
provider: provider,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,15 +109,27 @@ func (e *engine) Handle(ctx context.Context, request EngineRequest) (EngineRespo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
// resolve namespace
|
||||||
|
var namespace *unstructured.Unstructured
|
||||||
|
if ns := request.Resource.GetNamespace(); ns != "" {
|
||||||
|
coreNs := e.nsResolver(ns)
|
||||||
|
if coreNs != nil {
|
||||||
|
ns, err := kubeutils.ObjToUnstructured(coreNs)
|
||||||
|
if err != nil {
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
namespace = ns
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, policy := range policies {
|
for _, policy := range policies {
|
||||||
response.Policies = append(response.Policies, e.handlePolicy(ctx, policy, request))
|
response.Policies = append(response.Policies, e.handlePolicy(ctx, policy, request.Resource, namespace))
|
||||||
}
|
}
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) handlePolicy(ctx context.Context, policy policy.CompiledPolicy, request EngineRequest) PolicyResponse {
|
func (e *engine) handlePolicy(ctx context.Context, policy policy.CompiledPolicy, resource *unstructured.Unstructured, namespace *unstructured.Unstructured) PolicyResponse {
|
||||||
var rules []engineapi.RuleResponse
|
var rules []engineapi.RuleResponse
|
||||||
ok, err := policy.Evaluate(ctx, request.Resource, request.NamespaceLabels)
|
ok, err := policy.Evaluate(ctx, resource, namespace)
|
||||||
// TODO: evaluation should be per rule
|
// TODO: evaluation should be per rule
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rules = handlers.WithResponses(engineapi.RuleError("todo", engineapi.Validation, "failed to load context", err, nil))
|
rules = handlers.WithResponses(engineapi.RuleError("todo", engineapi.Validation, "failed to load context", err, nil))
|
||||||
|
|
|
@ -24,11 +24,16 @@ type CompiledPolicy struct {
|
||||||
func (p *CompiledPolicy) Evaluate(
|
func (p *CompiledPolicy) Evaluate(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
resource *unstructured.Unstructured,
|
resource *unstructured.Unstructured,
|
||||||
namespaceLabels map[string]map[string]string,
|
namespace *unstructured.Unstructured,
|
||||||
) (bool, error) {
|
) (bool, error) {
|
||||||
|
var nsData map[string]any
|
||||||
|
if namespace != nil {
|
||||||
|
nsData = namespace.UnstructuredContent()
|
||||||
|
}
|
||||||
matchConditions := func() (bool, error) {
|
matchConditions := func() (bool, error) {
|
||||||
var errs []error
|
var errs []error
|
||||||
data := map[string]any{
|
data := map[string]any{
|
||||||
|
NamespaceObjectKey: nsData,
|
||||||
ObjectKey: resource.UnstructuredContent(),
|
ObjectKey: resource.UnstructuredContent(),
|
||||||
}
|
}
|
||||||
for _, matchCondition := range p.matchConditions {
|
for _, matchCondition := range p.matchConditions {
|
||||||
|
@ -63,6 +68,7 @@ func (p *CompiledPolicy) Evaluate(
|
||||||
variables := func() map[string]any {
|
variables := func() map[string]any {
|
||||||
vars := lazy.NewMapValue(VariablesType)
|
vars := lazy.NewMapValue(VariablesType)
|
||||||
data := map[string]any{
|
data := map[string]any{
|
||||||
|
NamespaceObjectKey: nsData,
|
||||||
ObjectKey: resource.UnstructuredContent(),
|
ObjectKey: resource.UnstructuredContent(),
|
||||||
VariablesKey: vars,
|
VariablesKey: vars,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue