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

CLI fix for foreach policies (#2997)

* CLI fix for foreach policies

* add test-case for foreach container and initcontainer

* fix comments

Co-authored-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
Vyankatesh Kudtarkar 2022-01-19 05:08:49 +05:30 committed by GitHub
parent 1580837526
commit e22e9499b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 153 additions and 6 deletions

View file

@ -770,3 +770,142 @@ func Test_foreach_element_mutation(t *testing.T) {
assert.Equal(t, securityContext["privileged"], false)
}
}
func Test_Container_InitContainer_foreach(t *testing.T) {
policyRaw := []byte(`{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "prepend-registry",
"annotations": {
"pod-policies.kyverno.io/autogen-controllers": "none"
}
},
"spec": {
"background": false,
"rules": [
{
"name": "prepend-registry-containers",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"mutate": {
"foreach": [
{
"list": "request.object.spec.containers",
"patchStrategicMerge": {
"spec": {
"containers": [
{
"name": "{{ element.name }}",
"image": "registry.io/{{ images.containers.\"{{element.name}}\".path}}:{{images.containers.\"{{element.name}}\".tag}}"
}
]
}
}
},
{
"list": "request.object.spec.initContainers",
"patchStrategicMerge": {
"spec": {
"initContainers": [
{
"name": "{{ element.name }}",
"image": "registry.io/{{ images.initContainers.\"{{element.name}}\".name}}:{{images.initContainers.\"{{element.name}}\".tag}}"
}
]
}
}
}
]
}
}
]
}
}`)
resourceRaw := []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "mypod"
},
"spec": {
"automountServiceAccountToken": false,
"initContainers": [
{
"name": "alpine",
"image": "alpine:latest"
},
{
"name": "busybox",
"image": "busybox:1.28"
}
],
"containers": [
{
"name": "nginx",
"image": "nginx:1.2.3"
},
{
"name": "redis",
"image": "redis:latest"
}
]
}
}`)
var policy kyverno.ClusterPolicy
err := json.Unmarshal(policyRaw, &policy)
assert.NilError(t, err)
resource, err := utils.ConvertToUnstructured(resourceRaw)
assert.NilError(t, err)
ctx := context.NewContext()
err = ctx.AddResourceAsObject(resource.Object)
assert.NilError(t, err)
policyContext := &PolicyContext{
Policy: policy,
JSONContext: ctx,
NewResource: *resource,
}
err = ctx.AddImageInfo(resource)
assert.NilError(t, err)
err = context.MutateResourceWithImageInfo(resourceRaw, ctx)
assert.NilError(t, err)
er := Mutate(policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
assert.NilError(t, err)
for _, c := range containers {
ctnr := c.(map[string]interface{})
switch ctnr["name"] {
case "alpine":
assert.Equal(t, ctnr["image"], "registry.io/alpine:latest")
case "busybox":
assert.Equal(t, ctnr["image"], "registry.io/busybox:1.28")
}
}
initContainers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "initContainers")
assert.NilError(t, err)
for _, c := range initContainers {
ctnr := c.(map[string]interface{})
switch ctnr["name"] {
case "nginx":
assert.Equal(t, ctnr["image"], "registry.io/nginx:1.2.3")
case "redis":
assert.Equal(t, ctnr["image"], "registry.io/redis:latest")
}
}
}

View file

@ -25,12 +25,12 @@ import (
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
ut "github.com/kyverno/kyverno/pkg/engine/utils"
sanitizederror "github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
"github.com/kyverno/kyverno/pkg/kyverno/store"
"github.com/kyverno/kyverno/pkg/policymutation"
"github.com/kyverno/kyverno/pkg/policyreport"
"github.com/kyverno/kyverno/pkg/utils"
ut "github.com/kyverno/kyverno/pkg/utils"
yamlv2 "gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/util/yaml"
@ -489,16 +489,21 @@ func ApplyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst
resPath := fmt.Sprintf("%s/%s/%s", resource.GetNamespace(), resource.GetKind(), resource.GetName())
log.Log.V(3).Info("applying policy on resource", "policy", policy.Name, "resource", resPath)
ctx := context.NewContext()
resourceRaw, err := resource.MarshalJSON()
if err != nil {
log.Log.Error(err, "failed to marshal resource")
}
updated_resource, err := ut.ConvertToUnstructured(resourceRaw)
if err != nil {
log.Log.Error(err, "unable to convert raw resource to unstructured")
}
ctx := context.NewContext()
if operationIsDelete {
err = ctx.AddResourceInOldObject(resourceRaw)
} else {
err = ctx.AddResource(resourceRaw)
err = ctx.AddResourceAsObject(updated_resource.Object)
}
if err != nil {
@ -519,7 +524,10 @@ func ApplyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst
}
}
mutateResponse := engine.Mutate(&engine.PolicyContext{Policy: *policy, NewResource: *resource, JSONContext: ctx, NamespaceLabels: namespaceLabels})
if err := context.MutateResourceWithImageInfo(resourceRaw, ctx); err != nil {
log.Log.Error(err, "failed to add image variables to context")
}
mutateResponse := engine.Mutate(&engine.PolicyContext{Policy: *policy, NewResource: *updated_resource, JSONContext: ctx, NamespaceLabels: namespaceLabels})
if mutateResponse != nil {
engineResponses = append(engineResponses, mutateResponse)
}
@ -636,7 +644,7 @@ func GetPoliciesFromPaths(fs billy.Filesystem, dirPath []string, isGit bool, pol
fmt.Printf("failed to convert to JSON: %v", err)
continue
}
policiesFromFile, errFromFile := ut.GetPolicy(policyBytes)
policiesFromFile, errFromFile := utils.GetPolicy(policyBytes)
if errFromFile != nil {
err := fmt.Errorf("failed to process : %v", errFromFile.Error())
errors = append(errors, err)
@ -653,7 +661,7 @@ func GetPoliciesFromPaths(fs billy.Filesystem, dirPath []string, isGit bool, pol
policyStr = policyStr + scanner.Text() + "\n"
}
yamlBytes := []byte(policyStr)
policies, err = ut.GetPolicy(yamlBytes)
policies, err = utils.GetPolicy(yamlBytes)
if err != nil {
return nil, sanitizederror.NewWithError("failed to extract the resources", err)
}