1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-29 02:45:06 +00:00

feat(autogen): use static bytes instead of string (#10723)

Signed-off-by: Khaled Emara <khaled.emara@nirmata.com>
Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
Khaled Emara 2024-07-29 16:46:11 +03:00 committed by GitHub
parent c2646f7a9d
commit 0aeb32df3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 55 additions and 41 deletions

View file

@ -1,9 +1,9 @@
package autogen
import (
"encoding/json"
"strings"
jsoniter "github.com/json-iterator/go"
"github.com/kyverno/kyverno/api/kyverno"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -190,23 +190,14 @@ func generateRules(spec *kyvernov1.Spec, controllers string) []kyvernov1.Rule {
}
func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) {
json := jsoniter.ConfigCompatibleWithStandardLibrary
if bytes, err := json.Marshal(rule); err != nil {
return nil, err
} else {
bytes = updateGenRuleByte(bytes, kind)
if err := json.Unmarshal(bytes, &rule); err != nil {
return nil, err
}
// CEL variables are object, oldObject, request, params and authorizer.
// Therefore CEL expressions can be either written as object.spec or request.object.spec
if rule.Validation != nil && rule.Validation.CEL != nil {
bytes = updateCELFields(bytes, kind)
if err := json.Unmarshal(bytes, &rule); err != nil {
return nil, err
}
bytes = updateFields(bytes, kind, rule.Validation != nil && rule.Validation.CEL != nil)
if err := json.Unmarshal(bytes, &rule); err != nil {
return nil, err
}
}

View file

@ -343,7 +343,7 @@ func TestUpdateGenRuleByte(t *testing.T) {
},
}
for _, tt := range tests {
got := updateGenRuleByte(tt.pbyte, tt.kind)
got := updateFields(tt.pbyte, tt.kind, false)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("updateGenRuleByte() = %v, want %v", string(got), string(tt.want))
}
@ -384,7 +384,7 @@ func TestUpdateCELFields(t *testing.T) {
},
}
for _, tt := range tests {
got := updateCELFields(tt.pbyte, tt.kind)
got := updateFields(tt.pbyte, tt.kind, true)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("updateCELFields() = %v, want %v", string(got), string(tt.want))
}

View file

@ -1,6 +1,7 @@
package autogen
import (
"bytes"
"sort"
"strings"
@ -312,34 +313,56 @@ func generateCronJobRule(rule *kyvernov1.Rule, controllers string) *kyvernov1.Ru
)
}
func updateGenRuleByte(pbyte []byte, kind string) (obj []byte) {
if kind == "Pod" {
obj = []byte(strings.ReplaceAll(string(pbyte), "request.object.spec", "request.object.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "request.oldObject.spec", "request.oldObject.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "request.object.metadata", "request.object.spec.template.metadata"))
obj = []byte(strings.ReplaceAll(string(obj), "request.oldObject.metadata", "request.oldObject.spec.template.metadata"))
var (
podReplacementRules [][2][]byte = [][2][]byte{
{[]byte("request.object.spec"), []byte("request.object.spec.template.spec")},
{[]byte("request.oldObject.spec"), []byte("request.oldObject.spec.template.spec")},
{[]byte("request.object.metadata"), []byte("request.object.spec.template.metadata")},
{[]byte("request.oldObject.metadata"), []byte("request.oldObject.spec.template.metadata")},
}
if kind == "Cronjob" {
obj = []byte(strings.ReplaceAll(string(pbyte), "request.object.spec", "request.object.spec.jobTemplate.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "request.oldObject.spec", "request.oldObject.spec.jobTemplate.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "request.object.metadata", "request.object.spec.jobTemplate.spec.template.metadata"))
obj = []byte(strings.ReplaceAll(string(obj), "request.oldObject.metadata", "request.oldObject.spec.jobTemplate.spec.template.metadata"))
podCELReplacementRules [][2][]byte = [][2][]byte{
{[]byte("object.spec"), []byte("object.spec.template.spec")},
{[]byte("oldObject.spec"), []byte("oldObject.spec.template.spec")},
{[]byte("object.metadata"), []byte("object.spec.template.metadata")},
{[]byte("oldObject.metadata"), []byte("oldObject.spec.template.metadata")},
}
return obj
}
cronJobReplacementRules [][2][]byte = [][2][]byte{
{[]byte("request.object.spec"), []byte("request.object.spec.jobTemplate.spec.template.spec")},
{[]byte("request.oldObject.spec"), []byte("request.oldObject.spec.jobTemplate.spec.template.spec")},
{[]byte("request.object.metadata"), []byte("request.object.spec.jobTemplate.spec.template.metadata")},
{[]byte("request.oldObject.metadata"), []byte("request.oldObject.spec.jobTemplate.spec.template.metadata")},
}
cronJobCELReplacementRules [][2][]byte = [][2][]byte{
{[]byte("object.spec"), []byte("object.spec.jobTemplate.spec.template.spec")},
{[]byte("oldObject.spec"), []byte("oldObject.spec.jobTemplate.spec.template.spec")},
{[]byte("object.metadata"), []byte("object.spec.jobTemplate.spec.template.metadata")},
{[]byte("oldObject.metadata"), []byte("oldObject.spec.jobTemplate.spec.template.metadata")},
}
)
func updateCELFields(pbyte []byte, kind string) (obj []byte) {
if kind == "Pod" {
obj = []byte(strings.ReplaceAll(string(pbyte), "object.spec", "object.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "oldObject.spec", "oldObject.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "object.metadata", "object.spec.template.metadata"))
obj = []byte(strings.ReplaceAll(string(obj), "oldObject.metadata", "oldObject.spec.template.metadata"))
func updateFields(data []byte, kind string, cel bool) []byte {
switch kind {
case "Pod":
if cel {
for _, replacement := range podCELReplacementRules {
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
}
} else {
for _, replacement := range podReplacementRules {
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
}
}
case "Cronjob":
if cel {
for _, replacement := range cronJobCELReplacementRules {
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
}
} else {
for _, replacement := range cronJobReplacementRules {
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
}
}
}
if kind == "Cronjob" {
obj = []byte(strings.ReplaceAll(string(pbyte), "object.spec", "object.spec.jobTemplate.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "oldObject.spec", "oldObject.spec.jobTemplate.spec.template.spec"))
obj = []byte(strings.ReplaceAll(string(obj), "object.metadata", "object.spec.jobTemplate.spec.template.metadata"))
obj = []byte(strings.ReplaceAll(string(obj), "oldObject.metadata", "oldObject.spec.jobTemplate.spec.template.metadata"))
}
return obj
return data
}