1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 07:26:55 +00:00

Autogenv2 rule evaluation logic (#11434)

* Autogenv2 rule evaluation logic

Signed-off-by: utsab818 <utsabsapkota4231@gmail.com>

* Fixed lint error

Signed-off-by: utsab818 <utsabsapkota4231@gmail.com>

* resolve: comments

Signed-off-by: utsab818 <utsabsapkota4231@gmail.com>

* Updated resource reference in extractPodSpec

Signed-off-by: utsab818 <utsabsapkota4231@gmail.com>

---------

Signed-off-by: utsab818 <utsabsapkota4231@gmail.com>
This commit is contained in:
Utsab Sapkota 2024-11-05 14:59:24 +05:45 committed by GitHub
parent b31175cb03
commit 982b3fdcdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 23 deletions

View file

@ -23,19 +23,6 @@ var (
podControllersKindsSet = PodControllers.Union(sets.New("Pod")) podControllersKindsSet = PodControllers.Union(sets.New("Pod"))
) )
// AutogenV2 defines the interface for the new autogeneration strategy.
type AutogenV2 interface {
ExtractPodSpec(resource unstructured.Unstructured) (*unstructured.Unstructured, error)
}
// ImplAutogenV2 is the implementation of the AutogenV2 interface.
type ImplAutogenV2 struct{}
// NewAutogenV2 creates a new instance of AutogenV2.
func NewAutogenV2() AutogenV2 {
return &ImplAutogenV2{}
}
func splitKinds(controllers, separator string) []string { func splitKinds(controllers, separator string) []string {
kinds := strings.Split(controllers, separator) kinds := strings.Split(controllers, separator)
sort.Strings(kinds) sort.Strings(kinds)
@ -89,41 +76,41 @@ func CanAutoGen(spec *kyvernov1.Spec) (applyAutoGen bool, controllers sets.Set[s
match := rule.MatchResources match := rule.MatchResources
if !checkAutogenSupport(&needed, match.ResourceDescription) { if !checkAutogenSupport(&needed, match.ResourceDescription) {
debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name) debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
return false, sets.New[string]() return false, sets.New("none")
} }
for _, value := range match.Any { for _, value := range match.Any {
if !checkAutogenSupport(&needed, value.ResourceDescription) { if !checkAutogenSupport(&needed, value.ResourceDescription) {
debug.Info("skip generating rule on pod controllers: Name / Selector in match any block is not applicable.", "rule", rule.Name) debug.Info("skip generating rule on pod controllers: Name / Selector in match any block is not applicable.", "rule", rule.Name)
return false, sets.New[string]() return false, sets.New("none")
} }
} }
for _, value := range match.All { for _, value := range match.All {
if !checkAutogenSupport(&needed, value.ResourceDescription) { if !checkAutogenSupport(&needed, value.ResourceDescription) {
debug.Info("skip generating rule on pod controllers: Name / Selector in match all block is not applicable.", "rule", rule.Name) debug.Info("skip generating rule on pod controllers: Name / Selector in match all block is not applicable.", "rule", rule.Name)
return false, sets.New[string]() return false, sets.New("none")
} }
} }
if exclude := rule.ExcludeResources; exclude != nil { if exclude := rule.ExcludeResources; exclude != nil {
if !checkAutogenSupport(&needed, exclude.ResourceDescription) { if !checkAutogenSupport(&needed, exclude.ResourceDescription) {
debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name) debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
return false, sets.New[string]() return false, sets.New("none")
} }
for _, value := range exclude.Any { for _, value := range exclude.Any {
if !checkAutogenSupport(&needed, value.ResourceDescription) { if !checkAutogenSupport(&needed, value.ResourceDescription) {
debug.Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not applicable.", "rule", rule.Name) debug.Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not applicable.", "rule", rule.Name)
return false, sets.New[string]() return false, sets.New("none")
} }
} }
for _, value := range exclude.All { for _, value := range exclude.All {
if !checkAutogenSupport(&needed, value.ResourceDescription) { if !checkAutogenSupport(&needed, value.ResourceDescription) {
debug.Info("skip generating rule on pod controllers: Name / Selector in exclud all block is not applicable.", "rule", rule.Name) debug.Info("skip generating rule on pod controllers: Name / Selector in exclud all block is not applicable.", "rule", rule.Name)
return false, sets.New[string]() return false, sets.New("none")
} }
} }
} }
} }
if !needed { if !needed {
return false, sets.New[string]() return false, sets.New("none")
} }
return true, PodControllers return true, PodControllers
} }
@ -276,7 +263,10 @@ func GetAutogenKinds(p kyvernov1.PolicyInterface) []string {
} }
// ExtractPodSpec extracts the PodSpec from an unstructured resource if the controller supports autogen. // ExtractPodSpec extracts the PodSpec from an unstructured resource if the controller supports autogen.
func (a *ImplAutogenV2) ExtractPodSpec(resource unstructured.Unstructured) (*unstructured.Unstructured, error) { func extractPodSpec(resource *unstructured.Unstructured) (*unstructured.Unstructured, error) {
if resource == nil {
return nil, fmt.Errorf("resource is nil")
}
kind := resource.GetKind() kind := resource.GetKind()
var podSpec map[string]interface{} var podSpec map[string]interface{}
var found bool var found bool
@ -301,3 +291,30 @@ func (a *ImplAutogenV2) ExtractPodSpec(resource unstructured.Unstructured) (*uns
return &unstructured.Unstructured{Object: podSpec}, nil return &unstructured.Unstructured{Object: podSpec}, nil
} }
type ExtractPodFunc func(resource *unstructured.Unstructured) (*unstructured.Unstructured, error)
func getPodExtractor() ExtractPodFunc {
return func(resource *unstructured.Unstructured) (*unstructured.Unstructured, error) {
return extractPodSpec(resource)
}
}
func ComputeRules(p kyvernov1.PolicyInterface, kind string) ([]kyvernov1.Rule, ExtractPodFunc) {
spec := p.GetSpec()
applyAutoGen, desiredControllers := CanAutoGen(spec)
ann := p.GetAnnotations()
actualControllersString, ok := ann[kyverno.AnnotationAutogenControllers]
if ok && applyAutoGen {
desiredControllers = sets.New(strings.Split(actualControllersString, ",")...)
}
if desiredControllers.Has("none") || kind == "none" {
return spec.Rules, nil
}
if kind != "" {
if !desiredControllers.Has(kind) {
return spec.Rules, nil
}
}
return spec.Rules, getPodExtractor()
}

View file

@ -386,11 +386,10 @@ func TestExtractPodSpec(t *testing.T) {
}, },
} }
autogen := NewAutogenV2()
for _, test := range testCases { for _, test := range testCases {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
// Call the function under test // Call the function under test
podSpec, err := autogen.ExtractPodSpec(test.resource) podSpec, err := extractPodSpec(&test.resource)
// Check for errors // Check for errors
if test.expectError { if test.expectError {