1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 02:18:15 +00:00

fix: match wildcard names for generateExisting policies (#10945)

* fix: match wildcard names for generateExisting policies

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

* fix chainsaw test

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

* chore: add unit tests

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

---------

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
Mariam Fahmy 2024-08-29 16:09:30 +03:00 committed by GitHub
parent 2cd462570a
commit e00596a551
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 199 additions and 3 deletions

View file

@ -2,16 +2,28 @@ package policy
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/ext/wildcard"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func resourceMatches(match kyvernov1.ResourceDescription, res unstructured.Unstructured, isNamespacedPolicy bool) bool {
if match.Name != "" && res.GetName() != match.Name {
if match.Name != "" && !wildcard.Match(match.Name, res.GetName()) {
return false
}
if len(match.Names) > 0 && !contains(match.Names, res.GetName()) {
return false
if len(match.Names) > 0 {
isMatch := false
for _, name := range match.Names {
if wildcard.Match(name, res.GetName()) {
isMatch = true
break
}
}
if !isMatch {
return false
}
}
if !isNamespacedPolicy && len(match.Namespaces) > 0 && !contains(match.Namespaces, res.GetNamespace()) {
return false
}

View file

@ -51,6 +51,78 @@ func Test_resourceMatches(t *testing.T) {
isNamespacedPolicy: false,
want: false,
},
{
name: "Matching resource with a wildcard name",
match: kyverno.ResourceDescription{
Kinds: []string{"Pod"},
Name: "my-*",
},
res: unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Pod",
"metadata": map[string]interface{}{
"name": "my-pod",
},
},
},
isNamespacedPolicy: false,
want: true,
},
{
name: "Non-matching resource with a wildcard name",
match: kyverno.ResourceDescription{
Kinds: []string{"Pod"},
Name: "my-*",
},
res: unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Pod",
"metadata": map[string]interface{}{
"name": "test-pod",
},
},
},
isNamespacedPolicy: false,
want: false,
},
{
name: "Matching resource with multiple wildcard names",
match: kyverno.ResourceDescription{
Kinds: []string{"Pod"},
Names: []string{"my-*", "test-pod"},
},
res: unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Pod",
"metadata": map[string]interface{}{
"name": "my-pod",
},
},
},
isNamespacedPolicy: false,
want: true,
},
{
name: "Non-matching resource with multiple wildcard names",
match: kyverno.ResourceDescription{
Kinds: []string{"Pod"},
Names: []string{"my-*", "test-pod"},
},
res: unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Pod",
"metadata": map[string]interface{}{
"name": "pod",
},
},
},
isNamespacedPolicy: false,
want: false,
},
{
name: "Matching resource based on its namespace",
match: kyverno.ResourceDescription{

View file

@ -0,0 +1,16 @@
## Description
This test makes sure that a generate existing policy that matches wildcard names in the `match` block works as expected. The policy should only generate resources for the existing resources that match the wildcard name.
## Expected Behavior
1. Create two Namespaces: `tst-home-dev` and `tst-mobile-dev`.
2. Create a policy that generates a ServiceAccount for all existing namespaces whose name matches the wildcard `tst-*`.
3. Two ServiceAccounts are generated in `tst-home-dev` and `tst-mobile-dev`.
## Reference Issue(s)
#10886

View file

@ -0,0 +1,27 @@
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
creationTimestamp: null
name: existing-with-wildcard-name-matching
spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: existing-resources.yaml
- name: step-02
try:
- apply:
file: policy.yaml
- assert:
file: policy-ready.yaml
- name: step-03
try:
- sleep:
duration: 3s
- name: step-04
try:
- assert:
file: generated-resources.yaml

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Namespace
metadata:
name: tst-home-dev
---
apiVersion: v1
kind: Namespace
metadata:
name: tst-mobile-dev

View file

@ -0,0 +1,11 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: home
namespace: tst-home-dev
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: mobile
namespace: tst-mobile-dev

View file

@ -0,0 +1,19 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:serviceaccount
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- serviceaccounts
verbs:
- get
- watch
- list
- delete
- create

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: create-default-serviceaccount
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,21 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: create-default-serviceaccount
spec:
rules:
- name: default-service-account
match:
any:
- resources:
kinds:
- Namespace
names:
- "tst-*"
generate:
generateExisting: true
synchronize: false
apiVersion: v1
kind: ServiceAccount
namespace: "{{request.object.metadata.name}}"
name: "{{to_lower(request.object.metadata.name | to_string(@) | split(@, '-') | [1])}}"