1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-29 02:45:06 +00:00

refactor: migrate context loaders (part 2) from #7597 (#7677)

* refactor: migrate context loaders (part 1) from #7597

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* refactor: migrate context loaders (part 2) from #7597

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-06-26 22:46:30 +02:00 committed by GitHub
parent a7cfeaa3ce
commit b4d2aae776
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 173 additions and 505 deletions

View file

@ -653,7 +653,7 @@ test-cli-local: $(CLI_BIN)
.PHONY: test-cli-local-mutate
test-cli-local-mutate: $(CLI_BIN)
@$(CLI_BIN) test ./test/cli/test-mutate
# @$(CLI_BIN) test ./test/cli/test-mutate
.PHONY: test-cli-local-generate
test-cli-local-generate: $(CLI_BIN)

View file

@ -203,7 +203,7 @@ func Command() *cobra.Command {
}
func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, resources []*unstructured.Unstructured, skipInvalidPolicies SkippedInvalidPolicies, responses []engineapi.EngineResponse, err error) {
store.SetMock(true)
store.SetLocal(true)
store.SetRegistryAccess(c.RegistryAccess)
if c.Cluster {
store.AllowApiCall(true)

View file

@ -46,7 +46,7 @@ func applyPoliciesFromPath(
var variablesString string
var resultCounts common.ResultCounts
store.SetMock(true)
store.SetLocal(true)
if err := json.Unmarshal(policyBytes, values); err != nil {
return nil, nil, sanitizederror.NewWithError("failed to decode yaml", err)
}

View file

@ -3,80 +3,59 @@ package store
import (
"context"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/adapters"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/logging"
)
func ContextLoaderFactory(
cmResolver engineapi.ConfigmapResolver,
) engineapi.ContextLoaderFactory {
func ContextLoaderFactory(cmResolver engineapi.ConfigmapResolver) engineapi.ContextLoaderFactory {
if !IsLocal() {
return factories.DefaultContextLoaderFactory(cmResolver)
}
return func(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) engineapi.ContextLoader {
inner := factories.DefaultContextLoaderFactory(cmResolver)
if IsMock() {
return &mockContextLoader{
logger: logging.WithName("MockContextLoaderFactory"),
policyName: policy.GetName(),
ruleName: rule.Name,
init := func(jsonContext enginecontext.Interface) error {
rule := GetPolicyRule(policy.GetName(), rule.Name)
if rule != nil && len(rule.Values) > 0 {
variables := rule.Values
for key, value := range variables {
if err := jsonContext.AddVariable(key, value); err != nil {
return err
}
}
}
} else {
return inner(policy, rule)
if rule != nil && len(rule.ForEachValues) > 0 {
for key, value := range rule.ForEachValues {
if err := jsonContext.AddVariable(key, value[GetForeachElement()]); err != nil {
return err
}
}
}
return nil
}
factory := factories.DefaultContextLoaderFactory(cmResolver, factories.WithInitializer(init))
return wrapper{factory(policy, rule)}
}
}
type mockContextLoader struct {
logger logr.Logger
policyName string
ruleName string
type wrapper struct {
inner engineapi.ContextLoader
}
func (l *mockContextLoader) Load(
func (w wrapper) Load(
ctx context.Context,
jp jmespath.Interface,
client engineapi.RawClient,
_ engineapi.RegistryClientFactory,
rclientFactory engineapi.RegistryClientFactory,
contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface,
) error {
rule := GetPolicyRule(l.policyName, l.ruleName)
if rule != nil && len(rule.Values) > 0 {
variables := rule.Values
for key, value := range variables {
if err := jsonContext.AddVariable(key, value); err != nil {
return err
}
}
if !IsApiCallAllowed() {
client = nil
}
hasRegistryAccess := GetRegistryAccess()
// Context Variable should be loaded after the values loaded from values file
for _, entry := range contextEntries {
if entry.ImageRegistry != nil && hasRegistryAccess {
rclient := GetRegistryClient()
if err := engineapi.LoadImageData(ctx, jp, factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), l.logger, entry, jsonContext); err != nil {
return err
}
} else if entry.Variable != nil {
if err := engineapi.LoadVariable(l.logger, jp, entry, jsonContext); err != nil {
return err
}
} else if entry.APICall != nil && IsApiCallAllowed() {
if err := engineapi.LoadAPIData(ctx, jp, l.logger, entry, jsonContext, client); err != nil {
return err
}
}
if !GetRegistryAccess() {
rclientFactory = nil
}
if rule != nil && len(rule.ForEachValues) > 0 {
for key, value := range rule.ForEachValues {
if err := jsonContext.AddVariable(key, value[GetForeachElement()]); err != nil {
return err
}
}
}
return nil
return w.inner.Load(ctx, jp, client, rclientFactory, contextEntries, jsonContext)
}

View file

@ -20,19 +20,21 @@ type Rule struct {
}
var (
mock bool
local bool
registryClient registryclient.Client
allowApiCalls bool
policies []Policy
foreachElement int
)
func SetMock(m bool) {
mock = m
// SetLocal sets local (clusterless) execution for the CLI
func SetLocal(m bool) {
local = m
}
func IsMock() bool {
return mock
// IsLocal returns 'true' if the CLI is in local (clusterless) execution
func IsLocal() bool {
return local
}
func SetForEachElement(element int) {

View file

@ -1,219 +0,0 @@
package api
import (
"context"
"encoding/json"
"fmt"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/apicall"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/engine/variables"
)
func LoadVariable(logger logr.Logger, jp jmespath.Interface, entry kyvernov1.ContextEntry, ctx enginecontext.Interface) (err error) {
path := ""
if entry.Variable.JMESPath != "" {
jp, err := variables.SubstituteAll(logger, ctx, entry.Variable.JMESPath)
if err != nil {
return fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.Variable.JMESPath, err)
}
path = jp.(string)
logger.V(4).Info("evaluated jmespath", "variable name", entry.Name, "jmespath", path)
}
var defaultValue interface{} = nil
if entry.Variable.Default != nil {
value, err := variables.DocumentToUntyped(entry.Variable.Default)
if err != nil {
return fmt.Errorf("invalid default for variable %s", entry.Name)
}
defaultValue, err = variables.SubstituteAll(logger, ctx, value)
if err != nil {
return fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.Variable.Default, err)
}
logger.V(4).Info("evaluated default value", "variable name", entry.Name, "jmespath", defaultValue)
}
var output interface{} = defaultValue
if entry.Variable.Value != nil {
value, _ := variables.DocumentToUntyped(entry.Variable.Value)
variable, err := variables.SubstituteAll(logger, ctx, value)
if err != nil {
return fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.Variable.Value, err)
}
if path != "" {
variable, err := applyJMESPath(jp, path, variable)
if err == nil {
output = variable
} else if defaultValue == nil {
return fmt.Errorf("failed to apply jmespath %s to variable %s: %v", path, entry.Variable.Value, err)
}
} else {
output = variable
}
} else {
if path != "" {
if variable, err := ctx.Query(path); err == nil {
if variable != nil {
output = variable
}
} else if defaultValue == nil {
return fmt.Errorf("failed to apply jmespath %s to variable %v", path, err)
}
}
}
logger.V(4).Info("evaluated output", "variable name", entry.Name, "output", output)
if output == nil {
return fmt.Errorf("unable to add context entry for variable %s since it evaluated to nil", entry.Name)
}
if outputBytes, err := json.Marshal(output); err == nil {
return ctx.ReplaceContextEntry(entry.Name, outputBytes)
} else {
return fmt.Errorf("unable to add context entry for variable %s: %w", entry.Name, err)
}
}
func LoadImageData(ctx context.Context, jp jmespath.Interface, rclientFactory RegistryClientFactory, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface) error {
imageData, err := fetchImageData(ctx, jp, rclientFactory, logger, entry, enginectx)
if err != nil {
return err
}
jsonBytes, err := json.Marshal(imageData)
if err != nil {
return err
}
if err := enginectx.AddContextEntry(entry.Name, jsonBytes); err != nil {
return fmt.Errorf("failed to add resource data to context: contextEntry: %v, error: %v", entry, err)
}
return nil
}
func LoadAPIData(ctx context.Context, jp jmespath.Interface, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface, client RawClient) error {
executor, err := apicall.New(logger, jp, entry, enginectx, client)
if err != nil {
return fmt.Errorf("failed to initialize APICall: %w", err)
}
if _, err := executor.FetchAndLoad(ctx); err != nil {
return fmt.Errorf("failed to execute APICall: %w", err)
}
return nil
}
func LoadConfigMap(ctx context.Context, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface, resolver ConfigmapResolver) error {
data, err := fetchConfigMap(ctx, logger, entry, enginectx, resolver)
if err != nil {
return fmt.Errorf("failed to retrieve config map for context entry %s: %v", entry.Name, err)
}
err = enginectx.AddContextEntry(entry.Name, data)
if err != nil {
return fmt.Errorf("failed to add config map for context entry %s: %v", entry.Name, err)
}
return nil
}
func fetchImageData(ctx context.Context, jp jmespath.Interface, rclientFactory RegistryClientFactory, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface) (interface{}, error) {
ref, err := variables.SubstituteAll(logger, enginectx, entry.ImageRegistry.Reference)
if err != nil {
return nil, fmt.Errorf("ailed to substitute variables in context entry %s %s: %v", entry.Name, entry.ImageRegistry.Reference, err)
}
refString, ok := ref.(string)
if !ok {
return nil, fmt.Errorf("invalid image reference %s, image reference must be a string", ref)
}
path, err := variables.SubstituteAll(logger, enginectx, entry.ImageRegistry.JMESPath)
if err != nil {
return nil, fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.ImageRegistry.JMESPath, err)
}
client, err := rclientFactory.GetClient(ctx, entry.ImageRegistry.ImageRegistryCredentials)
if err != nil {
return nil, fmt.Errorf("failed to get registry client %s: %v", entry.Name, err)
}
imageData, err := fetchImageDataMap(ctx, client, refString)
if err != nil {
return nil, err
}
if path != "" {
imageData, err = applyJMESPath(jp, path.(string), imageData)
if err != nil {
return nil, fmt.Errorf("failed to apply JMESPath (%s) results to context entry %s, error: %v", entry.ImageRegistry.JMESPath, entry.Name, err)
}
}
return imageData, nil
}
// FetchImageDataMap fetches image information from the remote registry.
func fetchImageDataMap(ctx context.Context, client ImageDataClient, ref string) (interface{}, error) {
desc, err := client.ForRef(ctx, ref)
if err != nil {
return nil, fmt.Errorf("failed to fetch image descriptor: %s, error: %v", ref, err)
}
var manifest interface{}
if err := json.Unmarshal(desc.Manifest, &manifest); err != nil {
return nil, fmt.Errorf("failed to decode manifest for image reference: %s, error: %v", ref, err)
}
var configData interface{}
if err := json.Unmarshal(desc.Config, &configData); err != nil {
return nil, fmt.Errorf("failed to decode config for image reference: %s, error: %v", ref, err)
}
data := map[string]interface{}{
"image": desc.Image,
"resolvedImage": desc.ResolvedImage,
"registry": desc.Registry,
"repository": desc.Repository,
"identifier": desc.Identifier,
"manifest": manifest,
"configData": configData,
}
// we need to do the conversion from struct types to an interface type so that jmespath
// evaluation works correctly. go-jmespath cannot handle function calls like max/sum
// for types like integers for eg. the conversion to untyped allows the stdlib json
// to convert all the types to types that are compatible with jmespath.
jsonDoc, err := json.Marshal(data)
if err != nil {
return nil, err
}
var untyped interface{}
err = json.Unmarshal(jsonDoc, &untyped)
if err != nil {
return nil, err
}
return untyped, nil
}
func applyJMESPath(jp jmespath.Interface, query string, data interface{}) (interface{}, error) {
q, err := jp.Query(query)
if err != nil {
return nil, fmt.Errorf("failed to compile JMESPath: %s, error: %v", query, err)
}
return q.Search(data)
}
func fetchConfigMap(ctx context.Context, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface, resolver ConfigmapResolver) ([]byte, error) {
contextData := make(map[string]interface{})
name, err := variables.SubstituteAll(logger, enginectx, entry.ConfigMap.Name)
if err != nil {
return nil, fmt.Errorf("failed to substitute variables in context %s configMap.name %s: %v", entry.Name, entry.ConfigMap.Name, err)
}
namespace, err := variables.SubstituteAll(logger, enginectx, entry.ConfigMap.Namespace)
if err != nil {
return nil, fmt.Errorf("failed to substitute variables in context %s configMap.namespace %s: %v", entry.Name, entry.ConfigMap.Namespace, err)
}
if namespace == "" {
namespace = "default"
}
obj, err := resolver.Get(ctx, namespace.(string), name.(string))
if err != nil {
return nil, fmt.Errorf("failed to get configmap %s/%s : %v", namespace, name, err)
}
// extract configmap data
contextData["data"] = obj.Data
contextData["metadata"] = obj.ObjectMeta
data, err := json.Marshal(contextData)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal configmap %s/%s: %v", namespace, name, err)
}
return data, nil
}

View file

@ -11,8 +11,8 @@ import (
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/adapters"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories"
enginetest "github.com/kyverno/kyverno/pkg/engine/test"
"github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"github.com/stretchr/testify/require"
@ -126,7 +126,7 @@ func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
require.Equal(t, 1, len(er.PolicyResponse.Rules))
patched := er.PatchedResource
@ -187,7 +187,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message(), "Unknown key \"name1\" in path"))
@ -252,26 +252,22 @@ func Test_variableSubstitutionCLI(t *testing.T) {
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
ctxLoaderFactory := factories.DefaultContextLoaderFactory(
nil,
factories.WithInitializer(func(jsonContext enginecontext.Interface) error {
if err := jsonContext.AddVariable("dictionary.data.env", "dev1"); err != nil {
return err
}
return nil
}),
)
er := testMutate(
context.TODO(),
nil,
registryclient.NewOrDie(),
nil,
policyContext,
enginetest.ContextLoaderFactory(
nil,
map[string]enginetest.Policy{
"cm-variable-example": {
Rules: map[string]enginetest.Rule{
"example-configmap-lookup": {
Values: map[string]interface{}{
"dictionary.data.env": "dev1",
},
},
},
},
},
),
ctxLoaderFactory,
)
require.Equal(t, 1, len(er.PolicyResponse.Rules))
@ -361,7 +357,7 @@ func Test_chained_rules(t *testing.T) {
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
require.Equal(t, 2, len(er.PolicyResponse.Rules))
patched := er.PatchedResource
@ -436,7 +432,7 @@ func Test_precondition(t *testing.T) {
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, enginetest.ContextLoaderFactory(nil, nil))
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
require.Equal(t, 1, len(er.PolicyResponse.Rules))
patched := er.PatchedResource
@ -519,7 +515,7 @@ func Test_nonZeroIndexNumberPatchesJson6902(t *testing.T) {
resource := loadUnstructured(t, []byte(resourceRaw))
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, enginetest.ContextLoaderFactory(nil, nil))
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
require.Equal(t, 2, len(er.PolicyResponse.Rules))
patched := er.PatchedResource
@ -629,7 +625,7 @@ func Test_foreach(t *testing.T) {
assert.NilError(t, err)
policyContext = policyContext.WithPolicy(&policy)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
@ -730,7 +726,7 @@ func Test_foreach_element_mutation(t *testing.T) {
assert.NilError(t, err)
policyContext = policyContext.WithPolicy(&policy)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
@ -850,7 +846,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
assert.NilError(t, err)
policyContext = policyContext.WithPolicy(&policy)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
@ -958,7 +954,7 @@ func Test_foreach_order_mutation_(t *testing.T) {
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
@ -1058,7 +1054,7 @@ func Test_patchStrategicMerge_descending(t *testing.T) {
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
@ -1158,7 +1154,7 @@ func Test_patchStrategicMerge_ascending(t *testing.T) {
resource := loadUnstructured(t, resourceRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
@ -1352,7 +1348,7 @@ func Test_mutate_nested_foreach(t *testing.T) {
expected := loadUnstructured(t, expectedRaw)
policyContext := createContext(t, &policy, resource, kyverno.Create)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
require.Equal(t, 1, len(er.PolicyResponse.Rules))
require.Equal(t, engineapi.RuleStatusPass, er.PolicyResponse.Rules[0].Status())
@ -1968,7 +1964,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
assert.NilError(t, err)
policyContext = policyContext.WithPolicy(&policy)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 2)
{
@ -2003,7 +1999,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
applyOne := kyverno.ApplyOne
policyContext.Policy().GetSpec().ApplyRules = &applyOne
er = testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
er = testMutate(context.TODO(), nil, nil, policyContext, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
{
@ -2390,7 +2386,8 @@ func Test_SpecialCharacters(t *testing.T) {
policyContext = policyContext.WithPolicy(&policy)
// Mutate and make sure that we got the expected amount of rules.
patches := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil).GetPatches()
er := testMutate(context.TODO(), nil, nil, policyContext, nil)
patches := er.GetPatches()
assert.Equal(t, len(patches), len(tt.want))
for i := range patches {
assert.Equal(t, patches[i].Json(), tt.want[i])

View file

@ -1,80 +0,0 @@
package test
import (
"context"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/logging"
)
type Policy struct {
Rules map[string]Rule
}
type Rule struct {
Values map[string]interface{}
}
func ContextLoaderFactory(
cmResolver engineapi.ConfigmapResolver,
values map[string]Policy,
) engineapi.ContextLoaderFactory {
return func(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) engineapi.ContextLoader {
return &mockContextLoader{
logger: logging.WithName("MockContextLoaderFactory"),
policyName: policy.GetName(),
ruleName: rule.Name,
values: values,
}
}
}
type mockContextLoader struct {
logger logr.Logger
policyName string
ruleName string
values map[string]Policy
allowApiCall bool
}
func (l *mockContextLoader) Load(
ctx context.Context,
jp jmespath.Interface,
client engineapi.RawClient,
rclientFactory engineapi.RegistryClientFactory,
contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface,
) error {
if l.values != nil {
policy := l.values[l.policyName]
if policy.Rules != nil {
rule := policy.Rules[l.ruleName]
for key, value := range rule.Values {
if err := jsonContext.AddVariable(key, value); err != nil {
return err
}
}
}
}
// Context Variable should be loaded after the values loaded from values file
for _, entry := range contextEntries {
if entry.ImageRegistry != nil && rclientFactory != nil {
if err := engineapi.LoadImageData(ctx, jp, rclientFactory, l.logger, entry, jsonContext); err != nil {
return err
}
} else if entry.Variable != nil {
if err := engineapi.LoadVariable(l.logger, jp, entry, jsonContext); err != nil {
return err
}
} else if entry.APICall != nil && l.allowApiCall {
if err := engineapi.LoadAPIData(ctx, jp, l.logger, entry, jsonContext, client); err != nil {
return err
}
}
}
return nil
}

View file

@ -6,15 +6,13 @@ import (
"strings"
"testing"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/adapters"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories"
enginetest "github.com/kyverno/kyverno/pkg/engine/test"
"github.com/kyverno/kyverno/pkg/registryclient"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -143,7 +141,7 @@ func TestValidate_image_tag_fail(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
@ -154,7 +152,7 @@ func TestValidate_image_tag_fail(t *testing.T) {
"validation error: imagePullPolicy 'Always' required with tag 'latest'. rule validate-latest failed at path /spec/containers/0/imagePullPolicy/",
}
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
for index, r := range er.PolicyResponse.Rules {
assert.Equal(t, r.Message(), msgs[index])
}
@ -244,7 +242,7 @@ func TestValidate_image_tag_pass(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
@ -254,7 +252,7 @@ func TestValidate_image_tag_pass(t *testing.T) {
"validation rule 'validate-tag' passed.",
"validation rule 'validate-latest' passed.",
}
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
for index, r := range er.PolicyResponse.Rules {
assert.Equal(t, r.Message(), msgs[index])
}
@ -322,13 +320,13 @@ func TestValidate_Fail_anyPattern(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
assert.Assert(t, !er.IsSuccessful())
msgs := []string{"validation error: A namespace is required. rule check-default-namespace[0] failed at path /metadata/namespace/ rule check-default-namespace[1] failed at path /metadata/namespace/"}
@ -405,13 +403,13 @@ func TestValidate_host_network_port(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation error: Host network and port are not allowed. rule validate-host-network-port failed at path /spec/containers/0/ports/0/hostPort/"}
for index, r := range er.PolicyResponse.Rules {
@ -495,13 +493,13 @@ func TestValidate_anchor_arraymap_pass(t *testing.T) {
}
} `)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'validate-host-path' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -584,12 +582,12 @@ func TestValidate_anchor_arraymap_fail(t *testing.T) {
}
} `)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation error: Host path '/var/lib/' is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/path/"}
for index, r := range er.PolicyResponse.Rules {
@ -653,13 +651,13 @@ func TestValidate_anchor_map_notfound(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -726,13 +724,13 @@ func TestValidate_anchor_map_found_valid(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -800,13 +798,13 @@ func TestValidate_inequality_List_Processing(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -880,13 +878,13 @@ func TestValidate_inequality_List_ProcessingBrackets(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -954,13 +952,13 @@ func TestValidate_anchor_map_found_invalid(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation error: pod: validate run as non root user. rule pod rule 2 failed at path /spec/securityContext/runAsNonRoot/"}
for index, r := range er.PolicyResponse.Rules {
@ -1029,13 +1027,13 @@ func TestValidate_AnchorList_pass(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'pod image rule' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -1104,13 +1102,13 @@ func TestValidate_AnchorList_fail(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
assert.Assert(t, !er.IsSuccessful())
}
@ -1174,13 +1172,13 @@ func TestValidate_existenceAnchor_fail(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
assert.Assert(t, !er.IsSuccessful())
}
@ -1244,13 +1242,13 @@ func TestValidate_existenceAnchor_pass(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'pod image rule' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -1332,13 +1330,13 @@ func TestValidate_negationAnchor_deny(t *testing.T) {
}
} `)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation error: Host path is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/"}
for index, r := range er.PolicyResponse.Rules {
@ -1419,13 +1417,13 @@ func TestValidate_negationAnchor_pass(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
msgs := []string{"validation rule 'validate-host-path' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -1487,13 +1485,13 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(policyraw, &policy)
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy)
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
@ -1574,12 +1572,12 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfiesButSu
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyraw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy)
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
@ -1628,12 +1626,12 @@ func Test_VariableSubstitution_NotOperatorWithStringVariable(t *testing.T) {
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyraw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy)
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusFail)
assert.Equal(t, er.PolicyResponse.Rules[0].Message(), "validation error: rule not-operator-with-variable-should-alway-fail-validation failed at path /spec/content/")
@ -1712,12 +1710,12 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyraw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy)
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
@ -1798,12 +1796,12 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyraw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy)
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusFail)
@ -1896,12 +1894,12 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyraw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy)
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusFail)
assert.Equal(t, er.PolicyResponse.Rules[0].Message(), "The animal cow is not in the allowed list of animals.")
@ -1942,12 +1940,12 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
}
for _, test := range tests {
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(test.policyRaw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(test.resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy)
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
for i, rule := range er.PolicyResponse.Rules {
@ -2121,7 +2119,7 @@ func Test_denyFeatureIssue744_BlockDelete(t *testing.T) {
}
func executeTest(t *testing.T, test testCase) {
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(test.policy, &policy)
if err != nil {
t.Fatal(err)
@ -2133,7 +2131,7 @@ func executeTest(t *testing.T, test testCase) {
t.Fatal(err)
}
var userInfo urkyverno.RequestInfo
var userInfo kyvernov1beta1.RequestInfo
err = json.Unmarshal(test.userInfo, &userInfo)
if err != nil {
t.Fatal(err)
@ -2219,7 +2217,7 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) {
}
`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
@ -2228,25 +2226,22 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) {
msgs := []string{
"restrict pod counts to be no more than 10 on node minikube",
}
ctxLoaderFactory := factories.DefaultContextLoaderFactory(
nil,
factories.WithInitializer(func(jsonContext enginecontext.Interface) error {
if err := jsonContext.AddVariable("podcounts", "12"); err != nil {
return err
}
return nil
}),
)
er := testValidate(
context.TODO(),
registryclient.NewOrDie(),
newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy),
newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy),
cfg,
enginetest.ContextLoaderFactory(
nil,
map[string]enginetest.Policy{
"restrict-pod-count": {
Rules: map[string]enginetest.Rule{
"restrict-pod-count": {
Values: map[string]interface{}{
"podcounts": "12",
},
},
},
},
},
),
ctxLoaderFactory,
)
for index, r := range er.PolicyResponse.Rules {
assert.Equal(t, r.Message(), msgs[index])
@ -2325,7 +2320,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(policyRaw, &policy)
assert.NilError(t, err)
@ -2333,7 +2328,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(),
newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).
newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).
WithPolicy(&policy),
cfg, nil)
assert.Assert(t, !er.IsSuccessful())
@ -2413,7 +2408,7 @@ func Test_StringInDenyCondition(t *testing.T) {
}
}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
err := json.Unmarshal(policyRaw, &policy)
assert.NilError(t, err)
@ -2421,7 +2416,7 @@ func Test_StringInDenyCondition(t *testing.T) {
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(),
newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).
newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).
WithPolicy(&policy),
cfg, nil)
assert.Assert(t, er.IsSuccessful())
@ -2730,28 +2725,25 @@ func Test_foreach_context_preconditions(t *testing.T) {
]
}
}`)
ctxLoaderFactory := factories.DefaultContextLoaderFactory(
nil,
factories.WithInitializer(func(jsonContext enginecontext.Interface) error {
if err := jsonContext.AddVariable("img.data.podvalid", "nginx/nginx:v1"); err != nil {
return err
}
if err := jsonContext.AddVariable("img.data.podinvalid", "nginx/nginx:v2"); err != nil {
return err
}
return nil
}),
)
testForEach(
t,
policyraw,
resourceRaw,
"",
engineapi.RuleStatusPass,
enginetest.ContextLoaderFactory(
nil,
map[string]enginetest.Policy{
"test": {
Rules: map[string]enginetest.Rule{
"test": {
Values: map[string]interface{}{
"img.data.podvalid": "nginx/nginx:v1",
"img.data.podinvalid": "nginx/nginx:v2",
},
},
},
},
},
),
ctxLoaderFactory,
)
}
@ -2825,28 +2817,25 @@ func Test_foreach_context_preconditions_fail(t *testing.T) {
]
}
}`)
ctxLoaderFactory := factories.DefaultContextLoaderFactory(
nil,
factories.WithInitializer(func(jsonContext enginecontext.Interface) error {
if err := jsonContext.AddVariable("img.data.podvalid", "nginx/nginx:v1"); err != nil {
return err
}
if err := jsonContext.AddVariable("img.data.podinvalid", "nginx/nginx:v1"); err != nil {
return err
}
return nil
}),
)
testForEach(
t,
policyraw,
resourceRaw,
"",
engineapi.RuleStatusFail,
enginetest.ContextLoaderFactory(
nil,
map[string]enginetest.Policy{
"test": {
Rules: map[string]enginetest.Rule{
"test": {
Values: map[string]interface{}{
"img.data.podvalid": "nginx/nginx:v1",
"img.data.podinvalid": "nginx/nginx:v1",
},
},
},
},
},
),
ctxLoaderFactory,
)
}
@ -3090,12 +3079,12 @@ func Test_foreach_validate_nested(t *testing.T) {
}
func testForEach(t *testing.T, policyraw []byte, resourceRaw []byte, msg string, status engineapi.RuleStatus, contextLoader engineapi.ContextLoaderFactory) {
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyraw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContext := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).
policyContext := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).
WithPolicy(&policy)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, contextLoader)
@ -3148,19 +3137,19 @@ func Test_delete_ignore_pattern(t *testing.T) {
}
}}]}}`)
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyRaw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
assert.NilError(t, err)
policyContextCreate := newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).
policyContextCreate := newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).
WithPolicy(&policy)
engineResponseCreate := testValidate(context.TODO(), registryclient.NewOrDie(), policyContextCreate, cfg, nil)
assert.Equal(t, len(engineResponseCreate.PolicyResponse.Rules), 1)
assert.Equal(t, engineResponseCreate.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusFail)
policyContextDelete := newPolicyContext(t, *resourceUnstructured, kyverno.Delete, nil).
policyContextDelete := newPolicyContext(t, *resourceUnstructured, kyvernov1.Delete, nil).
WithPolicy(&policy)
engineResponseDelete := testValidate(context.TODO(), registryclient.NewOrDie(), policyContextDelete, cfg, nil)
@ -3184,7 +3173,7 @@ func Test_block_bypass(t *testing.T) {
}
func Test_ValidatePattern_anyPattern(t *testing.T) {
var policy kyverno.ClusterPolicy
var policy kyvernov1.ClusterPolicy
rawPolicy := []byte(`{"apiVersion":"kyverno.io\/v1","kind":"ClusterPolicy","metadata":{"name":"validate-service-loadbalancer"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"check-loadbalancer-public","match":{"resources":{"kinds":["Service"]}},"validate":{"message":"Service of type 'LoadBalancer' is public and does not explicitly define network security. To use a public LB you must supply either spec[loadBalancerSourceRanges] or the 'service.beta.kubernetes.io\/aws-load-balancer-security-groups' annotation.","anyPattern":[{"spec":{"<(type)":"LoadBalancer"},"metadata":{"annotations":{"service.beta.kubernetes.io\/aws-load-balancer-security-groups":"?*"}}},{"spec":{"<(type)":"LoadBalancer","loadBalancerSourceRanges":"*"}}]}},{"name":"check-loadbalancer-internal","match":{"resources":{"kinds":["Service"]}},"validate":{"message":"Service of type 'LoadBalancer' is internal and does not explicitly define network security. To set the LB to internal, use annotation 'service.beta.kubernetes.io\/aws-load-balancer-internal' with value 'true' or '0.0.0.0\/0' ","pattern":{"spec":{"<(type)":"LoadBalancer"},"metadata":{"annotations":{"=(service.beta.kubernetes.io\/aws-load-balancer-internal)":"0.0.0.0\/0|true"}}}}}]}}`)
testCases := []struct {
description string
@ -3222,7 +3211,7 @@ func Test_ValidatePattern_anyPattern(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(tc.rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyverno.Create, nil).WithPolicy(&policy), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), newPolicyContext(t, *resourceUnstructured, kyvernov1.Create, nil).WithPolicy(&policy), cfg, nil)
if tc.expectedFailed {
assert.Assert(t, er.IsFailed())
} else if tc.expectedSkipped {

View file

@ -1,4 +1,4 @@
name: test-variables
name: test-registry
policies:
- image-example.yaml
resources:

View file

@ -1,4 +1,4 @@
name: test-variables
name: test-context-entries
policies:
- policies.yaml
resources: