mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 02:18:15 +00:00
test(globalcontext): add e2e tests (#9661)
* fix(globalcontext): validation Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> * fix(globalcontext): use existence instead of ready for now Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> * chore(globalcontext): improve not ready error message Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> * fix(globalcontext): allow any APICall Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> * fix(globalcontext): prevent double marshal Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> * test(globalcontext): add e2e tests Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> * chore(globalcontext): move vaildation to OpenAPI V3 Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> --------- Signed-off-by: Khaled Emara <khaled.emara@nirmata.com> Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
parent
ace5b59003
commit
1eda4789d1
40 changed files with 590 additions and 14 deletions
|
@ -97,6 +97,7 @@ type ContextEntry struct {
|
|||
Variable *Variable `json:"variable,omitempty" yaml:"variable,omitempty"`
|
||||
|
||||
// GlobalContextEntryReference is a reference to a cached global context entry.
|
||||
// +kubebuilder:validation:Required
|
||||
GlobalReference *GlobalContextEntryReference `json:"globalReference,omitempty" yaml:"globalReference,omitempty"`
|
||||
}
|
||||
|
||||
|
|
|
@ -142,9 +142,6 @@ type ExternalAPICall struct {
|
|||
|
||||
// Validate implements programmatic validation
|
||||
func (e *ExternalAPICall) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if e.Service.URL == "" {
|
||||
errs = append(errs, field.Required(path.Child("url"), "An External API Call entry requires a url"))
|
||||
}
|
||||
if e.RefreshInterval.Duration == 0*time.Second {
|
||||
errs = append(errs, field.Required(path.Child("refreshIntervalSeconds"), "A Resource entry requires a refresh interval greater than 0 seconds"))
|
||||
}
|
||||
|
|
|
@ -426,7 +426,7 @@ func (c *controller) reconcileMutatingWebhookConfiguration(ctx context.Context,
|
|||
func (c *controller) isGlobalContextEntryReady(name string, gctxentries []*kyvernov2alpha1.GlobalContextEntry) bool {
|
||||
for _, gctxentry := range gctxentries {
|
||||
if gctxentry.Name == name {
|
||||
return gctxentry.Status.Ready
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
@ -466,7 +466,7 @@ func (c *controller) updatePolicyStatuses(ctx context.Context) error {
|
|||
for _, ctxEntry := range rule.Context {
|
||||
if ctxEntry.GlobalReference != nil {
|
||||
if !c.isGlobalContextEntryReady(ctxEntry.GlobalReference.Name, gctxentries) {
|
||||
ready, message = false, "Not ready yet"
|
||||
ready, message = false, "global context entry not ready"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,9 +100,14 @@ func (g *gctxLoader) loadGctxData() ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var jsonData []byte
|
||||
if _, ok := data.([]byte); ok {
|
||||
jsonData = data.([]byte)
|
||||
} else {
|
||||
jsonData, err = json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
g.logger.V(6).Info("fetched json data", "name", g.entry.Name, "jsondata", jsonData)
|
||||
|
||||
|
|
|
@ -70,6 +70,5 @@ func (e *entry) setData(data any) {
|
|||
}
|
||||
|
||||
func doCall(ctx context.Context, caller apicall.Caller, call kyvernov1.APICall) (any, error) {
|
||||
// TODO: unmarshall json ?
|
||||
return caller.Execute(ctx, &call)
|
||||
}
|
||||
|
|
|
@ -680,7 +680,7 @@ func getAllowedVariables(background bool, target bool) *regexp.Regexp {
|
|||
|
||||
func addContextVariables(entries []kyvernov1.ContextEntry, ctx *enginecontext.MockContext) {
|
||||
for _, contextEntry := range entries {
|
||||
if contextEntry.APICall != nil || contextEntry.ImageRegistry != nil || contextEntry.Variable != nil {
|
||||
if contextEntry.APICall != nil || contextEntry.GlobalReference != nil || contextEntry.ImageRegistry != nil || contextEntry.Variable != nil {
|
||||
ctx.AddVariable(contextEntry.Name + "*")
|
||||
}
|
||||
|
||||
|
@ -1197,13 +1197,15 @@ func validateRuleContext(rule kyvernov1.Rule) error {
|
|||
}
|
||||
|
||||
var err error
|
||||
if entry.ConfigMap != nil && entry.APICall == nil && entry.ImageRegistry == nil && entry.Variable == nil {
|
||||
if entry.ConfigMap != nil && entry.APICall == nil && entry.GlobalReference == nil && entry.ImageRegistry == nil && entry.Variable == nil {
|
||||
err = validateConfigMap(entry)
|
||||
} else if entry.ConfigMap == nil && entry.APICall != nil && entry.ImageRegistry == nil && entry.Variable == nil {
|
||||
} else if entry.ConfigMap == nil && entry.APICall != nil && entry.GlobalReference == nil && entry.ImageRegistry == nil && entry.Variable == nil {
|
||||
err = validateAPICall(entry)
|
||||
} else if entry.ConfigMap == nil && entry.APICall == nil && entry.ImageRegistry != nil && entry.Variable == nil {
|
||||
} else if entry.ConfigMap == nil && entry.APICall == nil && entry.GlobalReference != nil && entry.ImageRegistry == nil && entry.Variable == nil {
|
||||
err = validateGlobalReference(entry)
|
||||
} else if entry.ConfigMap == nil && entry.APICall == nil && entry.GlobalReference == nil && entry.ImageRegistry != nil && entry.Variable == nil {
|
||||
err = validateImageRegistry(entry)
|
||||
} else if entry.ConfigMap == nil && entry.APICall == nil && entry.ImageRegistry == nil && entry.Variable != nil {
|
||||
} else if entry.ConfigMap == nil && entry.APICall == nil && entry.GlobalReference == nil && entry.ImageRegistry == nil && entry.Variable != nil {
|
||||
err = validateVariable(entry)
|
||||
} else {
|
||||
return fmt.Errorf("exactly one of configMap or apiCall or imageRegistry or variable is required for context entries")
|
||||
|
@ -1311,6 +1313,26 @@ func validateAPICall(entry kyvernov1.ContextEntry) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateGlobalReference(entry kyvernov1.ContextEntry) error {
|
||||
if entry.GlobalReference == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If JMESPath contains variables, the validation will fail because it's not
|
||||
// possible to infer which value will be inserted by the variable
|
||||
// Skip validation if a variable is detected
|
||||
|
||||
jmesPath := variables.ReplaceAllVars(entry.GlobalReference.JMESPath, func(s string) string { return "kyvernojmespathvariable" })
|
||||
|
||||
if !strings.Contains(jmesPath, "kyvernojmespathvariable") && entry.GlobalReference.JMESPath != "" {
|
||||
if _, err := jmespath.NewParser().Parse(entry.GlobalReference.JMESPath); err != nil {
|
||||
return fmt.Errorf("failed to parse JMESPath %s: %v", entry.GlobalReference.JMESPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateImageRegistry(entry kyvernov1.ContextEntry) error {
|
||||
if entry.ImageRegistry.Reference == "" {
|
||||
return fmt.Errorf("a ref is required for imageRegistry context entry")
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test verifies that Global Context Entries are evaluated correctly.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
`new-deployment` should be created.
|
||||
|
||||
## Reference Issues
|
||||
|
||||
|
23
test/conformance/chainsaw/globalcontext/apicall-correct/chainsaw-test.yaml
Executable file
23
test/conformance/chainsaw/globalcontext/apicall-correct/chainsaw-test.yaml
Executable file
|
@ -0,0 +1,23 @@
|
|||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: resource-correct
|
||||
spec:
|
||||
steps:
|
||||
- name: scenario
|
||||
try:
|
||||
- apply:
|
||||
file: namespace.yaml
|
||||
- apply:
|
||||
file: main-deployment.yaml
|
||||
- apply:
|
||||
file: gctxentry.yaml
|
||||
- apply:
|
||||
file: clusterpolicy.yaml
|
||||
- apply:
|
||||
file: new-deployment.yaml
|
||||
- assert:
|
||||
file: clusterpolicy-succeeded.yaml
|
||||
- assert:
|
||||
file: new-deployment-exists.yaml
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
33
test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy.yaml
Executable file
33
test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy.yaml
Executable file
|
@ -0,0 +1,33 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: main-deployment-exists
|
||||
context:
|
||||
- name: deploymentCount
|
||||
globalReference:
|
||||
name: deployments
|
||||
jmesPath: "items | length(@)"
|
||||
match:
|
||||
all:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
preconditions:
|
||||
all:
|
||||
- key: '{{ request.operation }}'
|
||||
operator: AnyIn
|
||||
value:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
validate:
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ deploymentCount }}"
|
||||
operator: Equal
|
||||
value: 0
|
8
test/conformance/chainsaw/globalcontext/apicall-correct/gctxentry.yaml
Executable file
8
test/conformance/chainsaw/globalcontext/apicall-correct/gctxentry.yaml
Executable file
|
@ -0,0 +1,8 @@
|
|||
apiVersion: kyverno.io/v2alpha1
|
||||
kind: GlobalContextEntry
|
||||
metadata:
|
||||
name: deployments
|
||||
spec:
|
||||
apiCall:
|
||||
urlPath: "/apis/apps/v1/namespaces/test-globalcontext/deployments"
|
||||
refreshInterval: 10s
|
22
test/conformance/chainsaw/globalcontext/apicall-correct/main-deployment.yaml
Executable file
22
test/conformance/chainsaw/globalcontext/apicall-correct/main-deployment.yaml
Executable file
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: main-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: main-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
4
test/conformance/chainsaw/globalcontext/apicall-correct/namespace.yaml
Executable file
4
test/conformance/chainsaw/globalcontext/apicall-correct/namespace.yaml
Executable file
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: test-globalcontext
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: new-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: new-deployment
|
22
test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment.yaml
Executable file
22
test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment.yaml
Executable file
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: new-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: new-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test verifies that policies are not ready if referenced Global Context Entries don't exist.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
`new-deployment` should not be created because the policy is not ready.
|
||||
|
||||
## Reference Issues
|
||||
|
||||
|
26
test/conformance/chainsaw/globalcontext/apicall-not-exist/chainsaw-test.yaml
Executable file
26
test/conformance/chainsaw/globalcontext/apicall-not-exist/chainsaw-test.yaml
Executable file
|
@ -0,0 +1,26 @@
|
|||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: resource-not-exist
|
||||
spec:
|
||||
steps:
|
||||
- name: setup
|
||||
try:
|
||||
- apply:
|
||||
file: namespace.yaml
|
||||
- apply:
|
||||
file: main-deployment.yaml
|
||||
- apply:
|
||||
file: gctxentry.yaml
|
||||
- apply:
|
||||
file: clusterpolicy.yaml
|
||||
- assert:
|
||||
file: clusterpolicy-failed.yaml
|
||||
- name: negative
|
||||
try:
|
||||
- apply:
|
||||
expect:
|
||||
- check:
|
||||
($error != null): true
|
||||
file: new-deployment.yaml
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
status:
|
||||
conditions:
|
||||
- reason: Failed
|
||||
status: "False"
|
||||
type: Ready
|
33
test/conformance/chainsaw/globalcontext/apicall-not-exist/clusterpolicy.yaml
Executable file
33
test/conformance/chainsaw/globalcontext/apicall-not-exist/clusterpolicy.yaml
Executable file
|
@ -0,0 +1,33 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: main-deployment-exists
|
||||
context:
|
||||
- name: deploymentCount
|
||||
globalReference:
|
||||
name: non-existent-reference
|
||||
jmesPath: "items | length(@)"
|
||||
match:
|
||||
all:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
preconditions:
|
||||
all:
|
||||
- key: '{{ request.operation }}'
|
||||
operator: AnyIn
|
||||
value:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
validate:
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ deploymentCount }}"
|
||||
operator: Equal
|
||||
value: 0
|
8
test/conformance/chainsaw/globalcontext/apicall-not-exist/gctxentry.yaml
Executable file
8
test/conformance/chainsaw/globalcontext/apicall-not-exist/gctxentry.yaml
Executable file
|
@ -0,0 +1,8 @@
|
|||
apiVersion: kyverno.io/v2alpha1
|
||||
kind: GlobalContextEntry
|
||||
metadata:
|
||||
name: deployments
|
||||
spec:
|
||||
apiCall:
|
||||
urlPath: "/apis/apps/v1/namespaces/test-globalcontext/deployments"
|
||||
refreshInterval: 10s
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: main-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: main-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
4
test/conformance/chainsaw/globalcontext/apicall-not-exist/namespace.yaml
Executable file
4
test/conformance/chainsaw/globalcontext/apicall-not-exist/namespace.yaml
Executable file
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: test-globalcontext
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: new-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: new-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test verifies that Global Context Entries are evaluated correctly.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
`new-deployment` should be created.
|
||||
|
||||
## Reference Issues
|
||||
|
||||
|
23
test/conformance/chainsaw/globalcontext/resource-correct/chainsaw-test.yaml
Executable file
23
test/conformance/chainsaw/globalcontext/resource-correct/chainsaw-test.yaml
Executable file
|
@ -0,0 +1,23 @@
|
|||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: resource-correct
|
||||
spec:
|
||||
steps:
|
||||
- name: scenario
|
||||
try:
|
||||
- apply:
|
||||
file: namespace.yaml
|
||||
- apply:
|
||||
file: main-deployment.yaml
|
||||
- apply:
|
||||
file: gctxentry.yaml
|
||||
- apply:
|
||||
file: clusterpolicy.yaml
|
||||
- apply:
|
||||
file: new-deployment.yaml
|
||||
- assert:
|
||||
file: clusterpolicy-succeeded.yaml
|
||||
- assert:
|
||||
file: new-deployment-exists.yaml
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
33
test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy.yaml
Executable file
33
test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy.yaml
Executable file
|
@ -0,0 +1,33 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: main-deployment-exists
|
||||
context:
|
||||
- name: deploymentCount
|
||||
globalReference:
|
||||
name: deployments
|
||||
jmesPath: "length(@)"
|
||||
match:
|
||||
all:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
preconditions:
|
||||
all:
|
||||
- key: '{{ request.operation }}'
|
||||
operator: AnyIn
|
||||
value:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
validate:
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ deploymentCount }}"
|
||||
operator: Equal
|
||||
value: 0
|
10
test/conformance/chainsaw/globalcontext/resource-correct/gctxentry.yaml
Executable file
10
test/conformance/chainsaw/globalcontext/resource-correct/gctxentry.yaml
Executable file
|
@ -0,0 +1,10 @@
|
|||
apiVersion: kyverno.io/v2alpha1
|
||||
kind: GlobalContextEntry
|
||||
metadata:
|
||||
name: deployments
|
||||
spec:
|
||||
kubernetesResource:
|
||||
group: apps
|
||||
version: v1
|
||||
resource: deployments
|
||||
namespace: test-globalcontext
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: main-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: main-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
4
test/conformance/chainsaw/globalcontext/resource-correct/namespace.yaml
Executable file
4
test/conformance/chainsaw/globalcontext/resource-correct/namespace.yaml
Executable file
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: test-globalcontext
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: new-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: new-deployment
|
22
test/conformance/chainsaw/globalcontext/resource-correct/new-deployment.yaml
Executable file
22
test/conformance/chainsaw/globalcontext/resource-correct/new-deployment.yaml
Executable file
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: new-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: new-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test verifies that policies are not ready if referenced Global Context Entries don't exist.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
`new-deployment` should not be created because the policy is not ready.
|
||||
|
||||
## Reference Issues
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: resource-not-exist
|
||||
spec:
|
||||
steps:
|
||||
- name: setup
|
||||
try:
|
||||
- apply:
|
||||
file: namespace.yaml
|
||||
- apply:
|
||||
file: main-deployment.yaml
|
||||
- apply:
|
||||
file: gctxentry.yaml
|
||||
- apply:
|
||||
file: clusterpolicy.yaml
|
||||
- assert:
|
||||
file: clusterpolicy-failed.yaml
|
||||
- name: negative
|
||||
try:
|
||||
- apply:
|
||||
expect:
|
||||
- check:
|
||||
($error != null): true
|
||||
file: new-deployment.yaml
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
status:
|
||||
conditions:
|
||||
- reason: Failed
|
||||
status: "False"
|
||||
type: Ready
|
|
@ -0,0 +1,33 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: namespace-has-coordinator
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: main-deployment-exists
|
||||
context:
|
||||
- name: deploymentCount
|
||||
globalReference:
|
||||
name: non-existent-reference
|
||||
jmesPath: "length(@)"
|
||||
match:
|
||||
all:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
preconditions:
|
||||
all:
|
||||
- key: '{{ request.operation }}'
|
||||
operator: AnyIn
|
||||
value:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
validate:
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ deploymentCount }}"
|
||||
operator: Equal
|
||||
value: 0
|
10
test/conformance/chainsaw/globalcontext/resource-not-exist/gctxentry.yaml
Executable file
10
test/conformance/chainsaw/globalcontext/resource-not-exist/gctxentry.yaml
Executable file
|
@ -0,0 +1,10 @@
|
|||
apiVersion: kyverno.io/v2alpha1
|
||||
kind: GlobalContextEntry
|
||||
metadata:
|
||||
name: deployments
|
||||
spec:
|
||||
kubernetesResource:
|
||||
group: apps
|
||||
version: v1
|
||||
resource: deployments
|
||||
namespace: test-globalcontext
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: main-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: main-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: main-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: test-globalcontext
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: new-deployment
|
||||
namespace: test-globalcontext
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: new-deployment
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: new-deployment
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
Loading…
Add table
Reference in a new issue