mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
feat: fix variables used in tests (#8438)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
2b583b1a86
commit
382754c055
18 changed files with 267 additions and 177 deletions
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/fix"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/userinfo"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/values"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
@ -142,6 +143,53 @@ func (o options) execute(out io.Writer, dirs ...string) error {
|
|||
fmt.Fprintln(out, " OK")
|
||||
}
|
||||
}
|
||||
if testCase.Test.Variables != "" {
|
||||
fmt.Fprintf(out, " Processing values file (%s)...\n", testCase.Test.Variables)
|
||||
path := filepath.Join(testCase.Dir(), testCase.Test.Variables)
|
||||
values, err := values.Load(nil, path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(out, " ERROR: failed to load values: %s\n", err)
|
||||
continue
|
||||
}
|
||||
fixed, messages, err := fix.FixValues(*values)
|
||||
for _, warning := range messages {
|
||||
fmt.Fprintln(out, " WARNING:", warning)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintln(out, " ERROR:", err)
|
||||
continue
|
||||
}
|
||||
needsSave := !reflect.DeepEqual(values, &fixed)
|
||||
if o.save && (o.force || needsSave) {
|
||||
fmt.Fprintf(out, " Saving values file (%s)...\n", path)
|
||||
untyped, err := kubeutils.ObjToUnstructured(fixed)
|
||||
if err != nil {
|
||||
fmt.Fprintf(out, " ERROR: converting to unstructured: %s\n", err)
|
||||
continue
|
||||
}
|
||||
unstructured.RemoveNestedField(untyped.UnstructuredContent(), "metadata", "creationTimestamp")
|
||||
unstructured.RemoveNestedField(untyped.UnstructuredContent(), "metadata", "generation")
|
||||
unstructured.RemoveNestedField(untyped.UnstructuredContent(), "metadata", "uid")
|
||||
if item, _, _ := unstructured.NestedMap(untyped.UnstructuredContent(), "metadata"); len(item) == 0 {
|
||||
unstructured.RemoveNestedField(untyped.UnstructuredContent(), "metadata")
|
||||
}
|
||||
jsonBytes, err := untyped.MarshalJSON()
|
||||
if err != nil {
|
||||
fmt.Fprintf(out, " ERROR: converting to json: %s\n", err)
|
||||
continue
|
||||
}
|
||||
yamlBytes, err := yaml.JSONToYAML(jsonBytes)
|
||||
if err != nil {
|
||||
fmt.Fprintf(out, " ERROR: converting to yaml: %s\n", err)
|
||||
continue
|
||||
}
|
||||
if err := os.WriteFile(path, yamlBytes, os.ModePerm); err != nil {
|
||||
fmt.Fprintf(out, " ERROR: saving values file (%s): %s\n", path, err)
|
||||
continue
|
||||
}
|
||||
fmt.Fprintln(out, " OK")
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
}
|
||||
fmt.Fprintln(out, "Done.")
|
||||
|
|
18
cmd/cli/kubectl-kyverno/fix/values.go
Normal file
18
cmd/cli/kubectl-kyverno/fix/values.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package fix
|
||||
|
||||
import (
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/apis/v1alpha1"
|
||||
)
|
||||
|
||||
func FixValues(values v1alpha1.Values) (v1alpha1.Values, []string, error) {
|
||||
var messages []string
|
||||
if values.APIVersion == "" {
|
||||
messages = append(messages, "api version is not set, setting `cli.kyverno.io/v1alpha1`")
|
||||
values.APIVersion = "cli.kyverno.io/v1alpha1"
|
||||
}
|
||||
if values.Kind == "" {
|
||||
messages = append(messages, "kind is not set, setting `Values`")
|
||||
values.Kind = "Values"
|
||||
}
|
||||
return values, messages, nil
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: foreach-json-patch
|
||||
rules:
|
||||
- name: add-security-context
|
||||
- name: mutate-images
|
||||
resources:
|
||||
- name: nginx
|
||||
values:
|
||||
request.operation: CREATE
|
||||
- name: myapp
|
||||
values:
|
||||
request.operation: CREATE
|
||||
request.operation: CREATE
|
||||
rules:
|
||||
- name: add-security-context
|
||||
- name: mutate-images
|
||||
|
|
|
@ -21,4 +21,3 @@ values:
|
|||
- name: nginx-demo
|
||||
values:
|
||||
request.operation: CREATE
|
||||
variables: variables.yaml
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
namespaceSelector:
|
||||
- name: test1
|
||||
labels:
|
||||
foo.com/managed-state: managed
|
||||
- labels:
|
||||
foo.com/managed-state: managed
|
||||
name: test1
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: test-policy
|
||||
rules:
|
||||
- name: test-rule
|
||||
values:
|
||||
excludedPolicies: []
|
||||
- name: test-policy
|
||||
rules:
|
||||
- name: test-rule
|
||||
values:
|
||||
excludedPolicies: []
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: block-images
|
||||
rules:
|
||||
- name: block-images
|
||||
foreachValues:
|
||||
imageData: ["foo", "foo1"]
|
||||
- foreachValues:
|
||||
imageData:
|
||||
- foo
|
||||
- foo1
|
||||
name: block-images
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: deny-modify-platform-label
|
||||
resources:
|
||||
- name: my-role-with-platform
|
||||
values:
|
||||
request.object.metadata.annotations."hpedevops.net/platform": 'true'
|
||||
- name: deny-modify-platform-label
|
||||
resources:
|
||||
- name: my-role-with-platform-false
|
||||
values:
|
||||
request.object.metadata.annotations."hpedevops.net/platform": 'false'
|
||||
- name: deny-modify-platform-label
|
||||
resources:
|
||||
- name: my-role-with-platform
|
||||
values:
|
||||
request.object.metadata.annotations."hpedevops.net/platform": "true"
|
||||
- name: deny-modify-platform-label
|
||||
resources:
|
||||
- name: my-role-with-platform-false
|
||||
values:
|
||||
request.object.metadata.annotations."hpedevops.net/platform": "false"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: deny-modify-platform-label
|
||||
resources:
|
||||
- name: my-role-with-platform
|
||||
values:
|
||||
request.object.metadata.annotations."hpedevops.net/platform": 'true'
|
||||
- name: deny-modify-platform-label
|
||||
resources:
|
||||
- name: my-role-with-platform
|
||||
values:
|
||||
request.object.metadata.annotations."hpedevops.net/platform": "true"
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# This file sets the values that will be null unless otherwise set explicitly.
|
||||
# We are effectively mocking these values because there is no real API call.
|
||||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: deny-modify-platform-label
|
||||
rules:
|
||||
- name: deny-modify-platform-role
|
||||
values:
|
||||
request:
|
||||
operation: "UPDATE"
|
||||
userInfo:
|
||||
groups:
|
||||
- "system:masters"
|
||||
- name: deny-modify-platform-label
|
||||
rules:
|
||||
- name: deny-modify-platform-role
|
||||
values:
|
||||
request:
|
||||
operation: UPDATE
|
||||
userInfo:
|
||||
groups:
|
||||
- system:masters
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: limit-configmap-for-sa
|
||||
resources:
|
||||
- name: any-configmap-name-good
|
||||
values:
|
||||
request.operation: UPDATE
|
||||
- name: any-configmap-name-bad
|
||||
values:
|
||||
request.operation: UPDATE
|
||||
- name: limit-configmap-for-sa
|
||||
resources:
|
||||
- name: any-configmap-name-good
|
||||
values:
|
||||
request.operation: UPDATE
|
||||
- name: any-configmap-name-bad
|
||||
values:
|
||||
request.operation: UPDATE
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: exclude-namespaces-example
|
||||
rules:
|
||||
- name: exclude-namespaces-dynamically
|
||||
resources:
|
||||
- name: bad-pod01
|
||||
values:
|
||||
namespacefilters.data.exclude: "[\"default\", \"test\"]"
|
||||
request.namespace: default
|
||||
- name: bad-pod02
|
||||
- name: exclude-namespaces-example
|
||||
resources:
|
||||
- name: bad-pod01
|
||||
values:
|
||||
namespacefilters.data.exclude: '["default", "test"]'
|
||||
request.namespace: default
|
||||
- name: bad-pod02
|
||||
rules:
|
||||
- name: exclude-namespaces-dynamically
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: disallow-naked-pods
|
||||
resources:
|
||||
- name: blank-skip
|
||||
# It doesn't satifies the precondition. Therefore can not proceed
|
||||
# further for validation.
|
||||
values:
|
||||
ignorepolicy: "ignore"
|
||||
- name: blank-fail
|
||||
# It satisfies the precondition. Therefore can proceed
|
||||
# further for validation against policy.
|
||||
values:
|
||||
ignorepolicy: "allowit"
|
||||
|
||||
- name: disallow-naked-pods
|
||||
resources:
|
||||
- name: blank-skip
|
||||
values:
|
||||
ignorepolicy: ignore
|
||||
- name: blank-fail
|
||||
values:
|
||||
ignorepolicy: allowit
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: unique-ingress-host
|
||||
rules:
|
||||
- name: check-single-host
|
||||
values:
|
||||
hosts: "[\"www.github.com\", \"www.kyverno.com\", \"www.nirmata.com\"]"
|
||||
resources:
|
||||
- name: ingress-kyverno-host
|
||||
values:
|
||||
request.operation: CREATE
|
||||
- name: ingress-foo-host
|
||||
values:
|
||||
request.operation: CREATE
|
||||
request.operation: CREATE
|
||||
rules:
|
||||
- name: check-single-host
|
||||
values:
|
||||
hosts: '["www.github.com", "www.kyverno.com", "www.nirmata.com"]'
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
subresources:
|
||||
- subresource:
|
||||
name: "deployments/scale"
|
||||
kind: "Scale"
|
||||
group: "autoscaling"
|
||||
version: "v1"
|
||||
parentResource:
|
||||
name: "deployments"
|
||||
kind: "Deployment"
|
||||
group: "apps"
|
||||
version: "v1"
|
||||
- parentResource:
|
||||
group: apps
|
||||
kind: Deployment
|
||||
name: deployments
|
||||
namespaced: false
|
||||
singularName: ""
|
||||
verbs: null
|
||||
version: v1
|
||||
subresource:
|
||||
group: autoscaling
|
||||
kind: Scale
|
||||
name: deployments/scale
|
||||
namespaced: false
|
||||
singularName: ""
|
||||
verbs: null
|
||||
version: v1
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: restrict-pod-counts
|
||||
rules:
|
||||
- name: restrict-pod-count
|
||||
values:
|
||||
podcounts: "40"
|
||||
resources:
|
||||
# operation is provided by user
|
||||
- name: myapp-pod
|
||||
values:
|
||||
request.operation: CREATE
|
||||
# operation is not provided by user
|
||||
- name: test-require-image-tag-pass
|
||||
values:
|
||||
# operation is empty
|
||||
- name: test-require-image-tag-fail
|
||||
values:
|
||||
request.operation: ""
|
||||
# No operation provided
|
||||
- name: test-validate-image-tag-ignore
|
||||
- name: test-validate-image-tag-fail
|
||||
- name: test-validate-image-tag-pass
|
||||
rules:
|
||||
- name: restrict-pod-count
|
||||
values:
|
||||
podcounts: "40"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
policies:
|
||||
- name: deny-something
|
||||
rules:
|
||||
- name: deny-everything
|
||||
values:
|
||||
varA.data.ValueOfB: "something"
|
||||
# request.namespace: kyverno
|
||||
- name: deny-something
|
||||
rules:
|
||||
- name: deny-everything
|
||||
values:
|
||||
varA.data.ValueOfB: something
|
||||
|
|
|
@ -1,77 +1,79 @@
|
|||
policies:
|
||||
- name: cm-multiple-example
|
||||
rules:
|
||||
- name: example-configmap-lookup
|
||||
values:
|
||||
dictionary.data.env: ''
|
||||
anotherdictionary.data.env: test
|
||||
- name: cm-variable-example
|
||||
rules:
|
||||
- name: example-configmap-lookup
|
||||
values:
|
||||
dictionary:
|
||||
data:
|
||||
env: test
|
||||
resources:
|
||||
- name: test-env-test
|
||||
values:
|
||||
request.object.metadata.name: test-env-test
|
||||
- name: test-env-dev
|
||||
values:
|
||||
request.object.metadata.name: test-env-dev
|
||||
- name: cm-array-example
|
||||
rules:
|
||||
- name: validate-role-annotation
|
||||
values:
|
||||
roles-dictionary.data.allowed-roles: '["app","test"]'
|
||||
resources:
|
||||
- name: test-web
|
||||
values:
|
||||
request.object.metadata.annotations.role: web
|
||||
- name: test-app
|
||||
values:
|
||||
request.object.metadata.annotations.role: app
|
||||
- name: cm-blk-scalar-example
|
||||
rules:
|
||||
- name: validate-blk-role-annotation
|
||||
values:
|
||||
roles-dictionary.data.allowed-roles: '["app", "test"]'
|
||||
resources:
|
||||
- name: test-blk-web
|
||||
values:
|
||||
request.object.metadata.annotations.role: web
|
||||
- name: test-blk-app
|
||||
values:
|
||||
request.object.metadata.annotations.role: app
|
||||
- name: cm-globalval-example
|
||||
resources:
|
||||
- name: test-global-prod
|
||||
values:
|
||||
request.mode: prod
|
||||
- name: images
|
||||
rules:
|
||||
- name: only-allow-trusted-images
|
||||
values:
|
||||
request.operation: CREATE
|
||||
resources:
|
||||
- name: test-pod-with-non-root-user-image
|
||||
values:
|
||||
imageData.registry: "index.docker.io"
|
||||
imageData.configData.config.User: "nginx"
|
||||
element.name: "nginx"
|
||||
- name: test-pod-with-trusted-registry
|
||||
values:
|
||||
element.name: "kyverno"
|
||||
imageData.registry: "ghcr.io"
|
||||
imageData.configData.config.User: ""
|
||||
- name: test-pod-with-non-trusted-registry
|
||||
values:
|
||||
element:
|
||||
name: "not-kyverno"
|
||||
imageData:
|
||||
registry: "gcr.io"
|
||||
configData:
|
||||
config:
|
||||
User: ""
|
||||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
globalValues:
|
||||
request.mode: dev
|
||||
kind: Values
|
||||
policies:
|
||||
- name: cm-multiple-example
|
||||
rules:
|
||||
- name: example-configmap-lookup
|
||||
values:
|
||||
anotherdictionary.data.env: test
|
||||
dictionary.data.env: ""
|
||||
- name: cm-variable-example
|
||||
resources:
|
||||
- name: test-env-test
|
||||
values:
|
||||
request.object.metadata.name: test-env-test
|
||||
- name: test-env-dev
|
||||
values:
|
||||
request.object.metadata.name: test-env-dev
|
||||
rules:
|
||||
- name: example-configmap-lookup
|
||||
values:
|
||||
dictionary:
|
||||
data:
|
||||
env: test
|
||||
- name: cm-array-example
|
||||
resources:
|
||||
- name: test-web
|
||||
values:
|
||||
request.object.metadata.annotations.role: web
|
||||
- name: test-app
|
||||
values:
|
||||
request.object.metadata.annotations.role: app
|
||||
rules:
|
||||
- name: validate-role-annotation
|
||||
values:
|
||||
roles-dictionary.data.allowed-roles: '["app","test"]'
|
||||
- name: cm-blk-scalar-example
|
||||
resources:
|
||||
- name: test-blk-web
|
||||
values:
|
||||
request.object.metadata.annotations.role: web
|
||||
- name: test-blk-app
|
||||
values:
|
||||
request.object.metadata.annotations.role: app
|
||||
rules:
|
||||
- name: validate-blk-role-annotation
|
||||
values:
|
||||
roles-dictionary.data.allowed-roles: '["app", "test"]'
|
||||
- name: cm-globalval-example
|
||||
resources:
|
||||
- name: test-global-prod
|
||||
values:
|
||||
request.mode: prod
|
||||
- name: images
|
||||
resources:
|
||||
- name: test-pod-with-non-root-user-image
|
||||
values:
|
||||
element.name: nginx
|
||||
imageData.configData.config.User: nginx
|
||||
imageData.registry: index.docker.io
|
||||
- name: test-pod-with-trusted-registry
|
||||
values:
|
||||
element.name: kyverno
|
||||
imageData.configData.config.User: ""
|
||||
imageData.registry: ghcr.io
|
||||
- name: test-pod-with-non-trusted-registry
|
||||
values:
|
||||
element:
|
||||
name: not-kyverno
|
||||
imageData:
|
||||
configData:
|
||||
config:
|
||||
User: ""
|
||||
registry: gcr.io
|
||||
rules:
|
||||
- name: only-allow-trusted-images
|
||||
values:
|
||||
request.operation: CREATE
|
||||
|
|
Loading…
Reference in a new issue