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:
parent
1580837526
commit
e22e9499b6
2 changed files with 153 additions and 6 deletions
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue