mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Added GetNames and GetKinds function (#11327)
* Added GetNames and GetKinds function Signed-off-by: utsab818 <utsabsapkota4231@gmail.com> * fix: updated func GetAutogenRuleNames Signed-off-by: utsab818 <utsabsapkota4231@gmail.com> * fix: exception controller Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix: autogen status Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: utsab818 <utsabsapkota4231@gmail.com> Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
6dc328fb0c
commit
c44b532d73
3 changed files with 316 additions and 1 deletions
pkg
|
@ -172,6 +172,109 @@ func GetControllers(meta *metav1.ObjectMeta, spec *kyvernov1.Spec) ([]string, []
|
|||
return requested.UnsortedList(), supported.UnsortedList(), activated
|
||||
}
|
||||
|
||||
// getAutogenRuleName generates an auto-gen rule name with the given prefix.
|
||||
func getAutogenRuleName(prefix string, name string) string {
|
||||
name = prefix + "-" + name
|
||||
if len(name) > 63 {
|
||||
name = name[:63]
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func isAutogenRuleName(name string) bool {
|
||||
return strings.HasPrefix(name, "autogen-")
|
||||
}
|
||||
|
||||
// GetAutogenRuleNames generates autogen rule names for pod controllers based on the provided policy
|
||||
func GetAutogenRuleNames(p kyvernov1.PolicyInterface) []string {
|
||||
spec := p.GetSpec()
|
||||
applyAutoGen, desiredControllers := CanAutoGen(spec)
|
||||
|
||||
// Handle the case where auto-generation is not applicable
|
||||
if !applyAutoGen {
|
||||
desiredControllers = sets.New("none")
|
||||
}
|
||||
|
||||
var actualControllers sets.Set[string]
|
||||
ann := p.GetAnnotations()
|
||||
actualControllersString, ok := ann[kyverno.AnnotationAutogenControllers]
|
||||
|
||||
// Determine actual controllers based on annotations
|
||||
if !ok || !applyAutoGen {
|
||||
actualControllers = desiredControllers
|
||||
} else {
|
||||
actualControllers = sets.New(strings.Split(actualControllersString, ",")...)
|
||||
}
|
||||
|
||||
// Determine the kind of controllers we are working with
|
||||
kind := strings.Join(actualControllers.UnsortedList(), ",")
|
||||
if kind == "none" {
|
||||
// If kind is "none", return the original rule names
|
||||
var ruleNames []string
|
||||
for _, rule := range spec.Rules {
|
||||
if !isAutogenRuleName(rule.Name) {
|
||||
ruleNames = append(ruleNames, rule.Name)
|
||||
}
|
||||
}
|
||||
return ruleNames
|
||||
}
|
||||
|
||||
// Prepare a slice for the autogenerated rule names
|
||||
var out []string
|
||||
|
||||
// Iterate over the existing rules to construct the rule names
|
||||
for _, rule := range spec.Rules {
|
||||
// Only consider non-autogenerated rules for original names
|
||||
if !isAutogenRuleName(rule.Name) {
|
||||
out = append(out, rule.Name) // Add the original rule name
|
||||
|
||||
if actualControllers.HasAny("DaemonSet", "Deployment", "Job", "StatefulSet", "ReplicaSet", "ReplicationController") {
|
||||
if genName := getAutogenRuleName("autogen", rule.Name); genName != "" {
|
||||
out = append(out, genName)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate autogen rule names based on actual controllers
|
||||
if actualControllers.Has("CronJob") {
|
||||
if genName := getAutogenRuleName("autogen-cronjob", rule.Name); genName != "" {
|
||||
out = append(out, genName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// GetRelevantKinds extracts the resource kinds from the match.resources field of the rules.
|
||||
func GetAutogenKinds(p kyvernov1.PolicyInterface) []string {
|
||||
spec := p.GetSpec()
|
||||
applyAutoGen, desiredControllers := CanAutoGen(spec)
|
||||
if !applyAutoGen {
|
||||
desiredControllers = sets.New("none")
|
||||
}
|
||||
var actualControllers sets.Set[string]
|
||||
ann := p.GetAnnotations()
|
||||
actualControllersString, ok := ann[kyverno.AnnotationAutogenControllers]
|
||||
if !ok || !applyAutoGen {
|
||||
actualControllers = desiredControllers
|
||||
} else {
|
||||
if !applyAutoGen {
|
||||
actualControllers = desiredControllers
|
||||
} else {
|
||||
actualControllers = sets.New(strings.Split(actualControllersString, ",")...)
|
||||
}
|
||||
}
|
||||
list := actualControllers.UnsortedList()
|
||||
var out []string
|
||||
for _, item := range list {
|
||||
if item != "none" {
|
||||
out = append(out, item)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// ExtractPodSpec extracts the PodSpec from an unstructured resource if the controller supports autogen.
|
||||
func (a *ImplAutogenV2) ExtractPodSpec(resource unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
kind := resource.GetKind()
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/kyverno/kyverno/api/kyverno"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
|
||||
"gotest.tools/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -408,3 +409,212 @@ func TestExtractPodSpec(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GetAutogenRuleNames(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
policy string
|
||||
expectedRules []string
|
||||
}{
|
||||
{
|
||||
name: "rule-with-match-name",
|
||||
policy: `
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: check-image
|
||||
spec:
|
||||
background: false
|
||||
webhookTimeoutSeconds: 30
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: check-image
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
verifyImages:
|
||||
- imageReferences:
|
||||
- "*"
|
||||
attestors:
|
||||
- count: 1
|
||||
entries:
|
||||
- keyless:
|
||||
roots: |-
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDjTCCAnWgAwIBAgIQb8yUrbw3aYZAubIjOJkFBjANBgkqhkiG9w0BAQsFADBZ
|
||||
MRMwEQYKCZImiZPyLGQBGRYDY29tMRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVt
|
||||
bzEmMCQGA1UEAxMddmVuYWZpZGVtby1FQzJBTUFaLVFOSVI4OUktQ0EwHhcNMjAx
|
||||
MjE0MjEzNzAzWhcNMjUxMjE0MjE0NzAzWjBZMRMwEQYKCZImiZPyLGQBGRYDY29t
|
||||
MRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVtbzEmMCQGA1UEAxMddmVuYWZpZGVt
|
||||
by1FQzJBTUFaLVFOSVI4OUktQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQC5CTVQczGnh77yNxq+BGh5ff0qNcRTkFll+y8lJbMPHevebF7JLWBQTGS7
|
||||
9aHIqUQLjy9sPOkdMrDh/vOZNVhVrHon9uwepF81dUMJ9lMbfQSI/tytp78f0z6b
|
||||
DVRHYZr/taYSkqNPT2FuHOijc7Y+oB3Q1DzPSoBc3a6I5DM6ET6O2GZWo3mqpImG
|
||||
J8+dNllYgjVKEuxuPqQjT7VD4fB2GqJbwwL0E8bSyfsgMV9Y+qHdznkm8v+TbYoc
|
||||
9uS83f1fjjp98D7VtWpSC4O/27JWgEED/BB58sOipUQHiECr6dD5VWGJ9fnVOV2i
|
||||
vHqj9cKS6BGMkAh99ss0Bu/3DEBxAgMBAAGjUTBPMAsGA1UdDwQEAwIBhjAPBgNV
|
||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTuZecNgrj3Gdv9XpekFZuIkYtu9jAQBgkr
|
||||
BgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQsFAAOCAQEADPNrGypaKliXJ+H7gt6b
|
||||
NJSBdWB9EV63CdvxjLOuqvp3IUu8KIV2mMsulEjxjAb5kya0SURJVFvr9rrLVxvR
|
||||
e6B2SJUGUKJkX1Cq4nIthwGfJTEnypYhqMKkfUYjqfszU+1CerRD2ZTJHeKZsc7M
|
||||
GdxLXeocztZ220idf6uDYeNLnGLBfkodEgFV0RmrlnHQYQdRqj3hjClLAkNqKVrz
|
||||
rxNyyQvgaswK+4kHAPQhv+ipx4Q0eeROpp3prJ+dD0hhk8niQSKWQWZHyElhzIKv
|
||||
FlDw3fzPhtberBblY4Y9u525ev999SogMBTXoSkfajRR2ol10xUxY60kVbqoEUln
|
||||
kA==
|
||||
-----END CERTIFICATE-----`,
|
||||
expectedRules: []string{"check-image", "autogen-check-image", "autogen-cronjob-check-image"},
|
||||
},
|
||||
{
|
||||
name: "rule-with-match-name",
|
||||
policy: `
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: check-image
|
||||
annotations:
|
||||
pod-policies.kyverno.io/autogen-controllers: Deployment,Job,StatefulSet
|
||||
spec:
|
||||
background: false
|
||||
webhookTimeoutSeconds: 30
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: check-image
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
verifyImages:
|
||||
- imageReferences:
|
||||
- "*"
|
||||
attestors:
|
||||
- count: 1
|
||||
entries:
|
||||
- keyless:
|
||||
roots: |-
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDjTCCAnWgAwIBAgIQb8yUrbw3aYZAubIjOJkFBjANBgkqhkiG9w0BAQsFADBZ
|
||||
MRMwEQYKCZImiZPyLGQBGRYDY29tMRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVt
|
||||
bzEmMCQGA1UEAxMddmVuYWZpZGVtby1FQzJBTUFaLVFOSVI4OUktQ0EwHhcNMjAx
|
||||
MjE0MjEzNzAzWhcNMjUxMjE0MjE0NzAzWjBZMRMwEQYKCZImiZPyLGQBGRYDY29t
|
||||
MRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVtbzEmMCQGA1UEAxMddmVuYWZpZGVt
|
||||
by1FQzJBTUFaLVFOSVI4OUktQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQC5CTVQczGnh77yNxq+BGh5ff0qNcRTkFll+y8lJbMPHevebF7JLWBQTGS7
|
||||
9aHIqUQLjy9sPOkdMrDh/vOZNVhVrHon9uwepF81dUMJ9lMbfQSI/tytp78f0z6b
|
||||
DVRHYZr/taYSkqNPT2FuHOijc7Y+oB3Q1DzPSoBc3a6I5DM6ET6O2GZWo3mqpImG
|
||||
J8+dNllYgjVKEuxuPqQjT7VD4fB2GqJbwwL0E8bSyfsgMV9Y+qHdznkm8v+TbYoc
|
||||
9uS83f1fjjp98D7VtWpSC4O/27JWgEED/BB58sOipUQHiECr6dD5VWGJ9fnVOV2i
|
||||
vHqj9cKS6BGMkAh99ss0Bu/3DEBxAgMBAAGjUTBPMAsGA1UdDwQEAwIBhjAPBgNV
|
||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTuZecNgrj3Gdv9XpekFZuIkYtu9jAQBgkr
|
||||
BgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQsFAAOCAQEADPNrGypaKliXJ+H7gt6b
|
||||
NJSBdWB9EV63CdvxjLOuqvp3IUu8KIV2mMsulEjxjAb5kya0SURJVFvr9rrLVxvR
|
||||
e6B2SJUGUKJkX1Cq4nIthwGfJTEnypYhqMKkfUYjqfszU+1CerRD2ZTJHeKZsc7M
|
||||
GdxLXeocztZ220idf6uDYeNLnGLBfkodEgFV0RmrlnHQYQdRqj3hjClLAkNqKVrz
|
||||
rxNyyQvgaswK+4kHAPQhv+ipx4Q0eeROpp3prJ+dD0hhk8niQSKWQWZHyElhzIKv
|
||||
FlDw3fzPhtberBblY4Y9u525ev999SogMBTXoSkfajRR2ol10xUxY60kVbqoEUln
|
||||
kA==
|
||||
-----END CERTIFICATE-----`,
|
||||
expectedRules: []string{"check-image", "autogen-check-image"},
|
||||
},
|
||||
{
|
||||
name: "rule-with-match-name",
|
||||
policy: `
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: check-image
|
||||
annotations:
|
||||
pod-policies.kyverno.io/autogen-controllers: Deployment,CronJob,Job
|
||||
spec:
|
||||
background: false
|
||||
webhookTimeoutSeconds: 30
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: check-image
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
verifyImages:
|
||||
- imageReferences:
|
||||
- "*"
|
||||
attestors:
|
||||
- count: 1
|
||||
entries:
|
||||
- keyless:
|
||||
roots: |-
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDjTCCAnWgAwIBAgIQb8yUrbw3aYZAubIjOJkFBjANBgkqhkiG9w0BAQsFADBZ
|
||||
MRMwEQYKCZImiZPyLGQBGRYDY29tMRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVt
|
||||
bzEmMCQGA1UEAxMddmVuYWZpZGVtby1FQzJBTUFaLVFOSVI4OUktQ0EwHhcNMjAx
|
||||
MjE0MjEzNzAzWhcNMjUxMjE0MjE0NzAzWjBZMRMwEQYKCZImiZPyLGQBGRYDY29t
|
||||
MRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVtbzEmMCQGA1UEAxMddmVuYWZpZGVt
|
||||
by1FQzJBTUFaLVFOSVI4OUktQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQC5CTVQczGnh77yNxq+BGh5ff0qNcRTkFll+y8lJbMPHevebF7JLWBQTGS7
|
||||
9aHIqUQLjy9sPOkdMrDh/vOZNVhVrHon9uwepF81dUMJ9lMbfQSI/tytp78f0z6b
|
||||
DVRHYZr/taYSkqNPT2FuHOijc7Y+oB3Q1DzPSoBc3a6I5DM6ET6O2GZWo3mqpImG
|
||||
J8+dNllYgjVKEuxuPqQjT7VD4fB2GqJbwwL0E8bSyfsgMV9Y+qHdznkm8v+TbYoc
|
||||
9uS83f1fjjp98D7VtWpSC4O/27JWgEED/BB58sOipUQHiECr6dD5VWGJ9fnVOV2i
|
||||
vHqj9cKS6BGMkAh99ss0Bu/3DEBxAgMBAAGjUTBPMAsGA1UdDwQEAwIBhjAPBgNV
|
||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTuZecNgrj3Gdv9XpekFZuIkYtu9jAQBgkr
|
||||
BgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQsFAAOCAQEADPNrGypaKliXJ+H7gt6b
|
||||
NJSBdWB9EV63CdvxjLOuqvp3IUu8KIV2mMsulEjxjAb5kya0SURJVFvr9rrLVxvR
|
||||
e6B2SJUGUKJkX1Cq4nIthwGfJTEnypYhqMKkfUYjqfszU+1CerRD2ZTJHeKZsc7M
|
||||
GdxLXeocztZ220idf6uDYeNLnGLBfkodEgFV0RmrlnHQYQdRqj3hjClLAkNqKVrz
|
||||
rxNyyQvgaswK+4kHAPQhv+ipx4Q0eeROpp3prJ+dD0hhk8niQSKWQWZHyElhzIKv
|
||||
FlDw3fzPhtberBblY4Y9u525ev999SogMBTXoSkfajRR2ol10xUxY60kVbqoEUln
|
||||
kA==
|
||||
-----END CERTIFICATE-----`,
|
||||
expectedRules: []string{"check-image", "autogen-check-image", "autogen-cronjob-check-image"},
|
||||
},
|
||||
{
|
||||
name: "rule-with-match-name",
|
||||
policy: `
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: disallow-latest-tag
|
||||
annotations:
|
||||
pod-policies.kyverno.io/autogen-controllers: Deployment,CronJob
|
||||
spec:
|
||||
rules:
|
||||
- match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
name: require-image-tag
|
||||
validate:
|
||||
failureAction: Audit
|
||||
message: An image tag is required.
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- image: '*:*'
|
||||
- match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
name: validate-image-tag
|
||||
validate:
|
||||
failureAction: Audit
|
||||
message: Using a mutable image tag e.g. 'latest' is not allowed.
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- image: '!*:latest' `,
|
||||
expectedRules: []string{"require-image-tag", "autogen-require-image-tag", "autogen-cronjob-require-image-tag", "validate-image-tag", "autogen-validate-image-tag", "autogen-cronjob-validate-image-tag"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
policies, _, _, err := yamlutils.GetPolicy([]byte(test.policy))
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 1, len(policies))
|
||||
rules := GetAutogenRuleNames(policies[0])
|
||||
assert.DeepEqual(t, test.expectedRules, rules)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1"
|
||||
"github.com/kyverno/kyverno/ext/wildcard"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
autogenv2 "github.com/kyverno/kyverno/pkg/autogenv2"
|
||||
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
|
||||
kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
|
||||
kyvernov2alpha1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v2alpha1"
|
||||
|
@ -1128,7 +1129,8 @@ func (gvs GroupVersionResourceScope) String() string {
|
|||
// mergeWebhook merges the matching kinds of the policy to webhook.rule
|
||||
func (c *controller) mergeWebhook(dst *webhook, policy kyvernov1.PolicyInterface, updateValidate bool) {
|
||||
var matchedGVK []string
|
||||
for _, rule := range autogen.ComputeRules(policy, "") {
|
||||
matchedGVK = append(matchedGVK, autogenv2.GetAutogenKinds(policy)...)
|
||||
for _, rule := range policy.GetSpec().Rules {
|
||||
// matching kinds in generate policies need to be added to both webhook
|
||||
if rule.HasGenerate() {
|
||||
matchedGVK = append(matchedGVK, rule.MatchResources.GetKinds()...)
|
||||
|
|
Loading…
Add table
Reference in a new issue