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

Remove YAML multiline support in CM values (#3721)

* remove YAML multiline support in CM values

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove unused code

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
Jim Bugwadia 2022-05-02 00:57:35 -07:00 committed by GitHub
parent 4f8eab76ce
commit 3cb620499e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 1 additions and 120 deletions

View file

@ -3,8 +3,6 @@ package engine
import (
"encoding/json"
"fmt"
"strings"
"github.com/go-logr/logr"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
@ -39,13 +37,6 @@ func LoadContext(logger logr.Logger, contextEntries []kyverno.ContextEntry, ctx
if rule != nil && len(rule.Values) > 0 {
variables := rule.Values
for key, value := range variables {
if trimmedTypedValue := strings.Trim(value, "\n"); strings.Contains(trimmedTypedValue, "\n") {
tmp := map[string]interface{}{key: value}
tmp = parseMultilineBlockBody(tmp)
newVal, _ := json.Marshal(tmp[key])
value = string(newVal)
}
if err := ctx.JSONContext.AddVariable(key, value); err != nil {
return err
}
@ -383,9 +374,6 @@ func fetchConfigMap(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyC
unstructuredObj := obj.DeepCopy().Object
// update the unstructuredObj["data"] to delimit and split the string value (containing "\n") with "\n"
unstructuredObj["data"] = parseMultilineBlockBody(unstructuredObj["data"].(map[string]interface{}))
// extract configmap data
contextData["data"] = unstructuredObj["data"]
contextData["metadata"] = unstructuredObj["metadata"]
@ -396,29 +384,3 @@ func fetchConfigMap(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyC
return data, nil
}
// parseMultilineBlockBody recursively iterates through a map and updates its values to a list of strings
// if it encounters a string value containing newline delimiters "\n" and not in PEM format. This is done to
// allow specifying a list with newlines. Since PEM format keys can also contain newlines, an additional check
// is performed to skip splitting those into an array.
func parseMultilineBlockBody(m map[string]interface{}) map[string]interface{} {
for k, v := range m {
switch typedValue := v.(type) {
case string:
trimmedTypedValue := strings.Trim(typedValue, "\n")
if !pemFormat(trimmedTypedValue) && strings.Contains(trimmedTypedValue, "\n") {
m[k] = strings.Split(trimmedTypedValue, "\n")
} else {
m[k] = trimmedTypedValue // trimming a str if it has trailing newline characters
}
default:
continue
}
}
return m
}
// check for PEM header found in certs and public keys
func pemFormat(s string) bool {
return strings.Contains(s, "-----BEGIN")
}

View file

@ -1,79 +0,0 @@
package engine
import (
"bytes"
"encoding/json"
"testing"
"gotest.tools/assert"
)
func Test_parseMultilineBlockBody(t *testing.T) {
tcs := []struct {
multilineBlockRaw []byte
expectedMultilineBlockRaw []byte
expectedErr bool
}{
{
multilineBlockRaw: []byte(`{
"key1": "value",
"key2": "value2",
"key3": "word1\nword2\nword3",
"key4": "word4\n"
}`),
expectedMultilineBlockRaw: []byte(`{"key1":"value","key2":"value2","key3":["word1","word2","word3"],"key4":"word4"}`),
expectedErr: false,
},
{
multilineBlockRaw: []byte(`{
"key1": "value",
"key2": "value2",
"key3": "word1\nword2\nword3",
"key4": "word4"
}`),
expectedMultilineBlockRaw: []byte(`{"key1":"value","key2":"value2","key3":["word1","word2","word3"],"key4":"word4"}`),
expectedErr: false,
},
{
multilineBlockRaw: []byte(`{
"key1": "value1",
"key2": "value2\n",
"key3": "word1",
"key4": "word2"
}`),
expectedMultilineBlockRaw: []byte(`{"key1":"value1","key2":["value2",""]}`),
expectedErr: true,
},
{
multilineBlockRaw: []byte(`{
"key1": "value1",
"key2": "[\"cluster-admin\", \"cluster-operator\", \"tenant-admin\"]"
}`),
expectedMultilineBlockRaw: []byte(`{"key1":"value1","key2":"[\"cluster-admin\", \"cluster-operator\", \"tenant-admin\"]"}`),
expectedErr: false,
},
{
multilineBlockRaw: []byte(`{
"key1": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHMmDjK65krAyDaGaeyWNzgvIu155\nJI50B2vezCw8+3CVeE0lJTL5dbL3OP98Za0oAEBJcOxky8Riy/XcmfKZbw==\n-----END PUBLIC KEY-----"
}`),
expectedMultilineBlockRaw: []byte(`{"key1":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHMmDjK65krAyDaGaeyWNzgvIu155\nJI50B2vezCw8+3CVeE0lJTL5dbL3OP98Za0oAEBJcOxky8Riy/XcmfKZbw==\n-----END PUBLIC KEY-----"}`),
expectedErr: false,
},
}
for _, tc := range tcs {
var multilineBlock map[string]interface{}
err := json.Unmarshal(tc.multilineBlockRaw, &multilineBlock)
assert.NilError(t, err)
parsedMultilineBlock := parseMultilineBlockBody(multilineBlock)
parsedMultilineBlockRaw, err := json.Marshal(parsedMultilineBlock)
assert.NilError(t, err)
if tc.expectedErr {
assert.Assert(t, bytes.Compare(parsedMultilineBlockRaw, tc.expectedMultilineBlockRaw) != 0)
} else {
assert.Assert(t, bytes.Compare(parsedMultilineBlockRaw, tc.expectedMultilineBlockRaw) == 0)
}
}
}

View file

@ -33,9 +33,7 @@ policies:
rules:
- name: validate-blk-role-annotation
values:
roles-dictionary.data.allowed-roles: |-
app
test
roles-dictionary.data.allowed-roles: '["app", "test"]'
resources:
- name: test-blk-web
values: