mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Fix {{@}}
behavior (#1908)
* fixed {{@}} behavior Signed-off-by: Max Goncharenko <kacejot@fex.net> * removed white space from test Signed-off-by: Max Goncharenko <kacejot@fex.net>
This commit is contained in:
parent
adcb89a1b5
commit
158b58f819
3 changed files with 110 additions and 55 deletions
|
@ -186,8 +186,7 @@ func substituteVariablesIfAny(log logr.Logger, ctx context.EvalInterface) jsonUt
|
|||
variable := replaceBracesAndTrimSpaces(v)
|
||||
|
||||
if variable == "@" {
|
||||
currentPath := getJMESPath(data.Path)
|
||||
variable = strings.Replace(variable, "@", fmt.Sprintf("request.object%s", currentPath), -1)
|
||||
variable = strings.Replace(variable, "@", fmt.Sprintf("request.object.%s", getJMESPath(data.Path)), -1)
|
||||
}
|
||||
|
||||
operation, err := ctx.Query("request.operation")
|
||||
|
@ -235,7 +234,8 @@ func substituteVariablesIfAny(log logr.Logger, ctx context.EvalInterface) jsonUt
|
|||
|
||||
// getJMESPath converts path to JMES format
|
||||
func getJMESPath(rawPath string) string {
|
||||
path := strings.ReplaceAll(rawPath, "/", ".")
|
||||
tokens := strings.Split(rawPath, "/")[3:] // skip empty element and two non-resource (like mutate.overlay)
|
||||
path := strings.Join(tokens, ".")
|
||||
regex := regexp.MustCompile(`\.([\d])\.`)
|
||||
return string(regex.ReplaceAll([]byte(path), []byte("[$1].")))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package variables
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
@ -136,49 +137,83 @@ func Test_subVars_failed(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_subVars_with_JMESPath_At(t *testing.T) {
|
||||
patternMap := []byte(`
|
||||
{
|
||||
"kind": "{{@}}",
|
||||
"data": {
|
||||
"rules": [
|
||||
{
|
||||
"apiGroups": [
|
||||
"{{request.object.metadata.name}}"
|
||||
],
|
||||
"resources": [
|
||||
"namespaces"
|
||||
],
|
||||
"verbs": [
|
||||
"*"
|
||||
],
|
||||
"resourceNames": [
|
||||
"{{request.object.metadata.name}}"
|
||||
]
|
||||
patternMap := []byte(`{
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"kind": "{{@}}",
|
||||
"data": {
|
||||
"rules": [
|
||||
{
|
||||
"apiGroups": [
|
||||
"{{request.object.metadata.name}}"
|
||||
],
|
||||
"resources": [
|
||||
"namespaces"
|
||||
],
|
||||
"verbs": [
|
||||
"*"
|
||||
],
|
||||
"resourceNames": [
|
||||
"{{request.object.metadata.name}}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
}`)
|
||||
|
||||
resourceRaw := []byte(`
|
||||
{
|
||||
"kind": "foo",
|
||||
"name": "bar",
|
||||
"metadata": {
|
||||
"name": "temp",
|
||||
"namespace": "n1"
|
||||
},
|
||||
"spec": {
|
||||
"kind": "foo",
|
||||
"namespace": "n1",
|
||||
"name": "temp1"
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
expected := []byte(`{"data":{"rules":[{"apiGroups":["temp"],"resourceNames":["temp"],"resources":["namespaces"],"verbs":["*"]}]},"kind":"foo"}`)
|
||||
expectedRaw := []byte(`{
|
||||
"mutate":{
|
||||
"overlay":{
|
||||
"spec":{
|
||||
"data":{
|
||||
"rules":[
|
||||
{
|
||||
"apiGroups":[
|
||||
"temp"
|
||||
],
|
||||
"resourceNames":[
|
||||
"temp"
|
||||
],
|
||||
"resources":[
|
||||
"namespaces"
|
||||
],
|
||||
"verbs":[
|
||||
"*"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kind":"foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
var err error
|
||||
|
||||
expected := new(bytes.Buffer)
|
||||
err = json.Compact(expected, expectedRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
var pattern, resource interface{}
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
assert.NilError(t, err)
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
|
@ -192,34 +227,52 @@ func Test_subVars_with_JMESPath_At(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
out, err := json.Marshal(output)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, string(out), string(expected))
|
||||
assert.Equal(t, string(out), expected.String())
|
||||
}
|
||||
|
||||
func Test_subVars_withRegexMatch(t *testing.T) {
|
||||
patternMap := []byte(`
|
||||
{
|
||||
"port": "{{ regex_match('(443)', '{{@}}') }}",
|
||||
"name": "ns-owner-{{request.object.metadata.name}}"
|
||||
}
|
||||
`)
|
||||
patternMap := []byte(`{
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"port": "{{ regex_match('(443)', '{{@}}') }}",
|
||||
"name": "ns-owner-{{request.object.metadata.name}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
resourceRaw := []byte(`
|
||||
{
|
||||
"port": "443",
|
||||
"metadata": {
|
||||
"name": "temp",
|
||||
"namespace": "n1"
|
||||
},
|
||||
"spec": {
|
||||
"port": "443",
|
||||
"namespace": "n1",
|
||||
"name": "temp1"
|
||||
}
|
||||
}
|
||||
`)
|
||||
expected := []byte(`{"name":"ns-owner-temp","port":true}`)
|
||||
}`)
|
||||
|
||||
expectedRaw := []byte(`{
|
||||
"mutate":{
|
||||
"overlay":{
|
||||
"spec":{
|
||||
"name":"ns-owner-temp",
|
||||
"port":true
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
var err error
|
||||
|
||||
expected := new(bytes.Buffer)
|
||||
err = json.Compact(expected, expectedRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
var pattern, resource interface{}
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
assert.NilError(t, err)
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
|
@ -234,31 +287,33 @@ func Test_subVars_withRegexMatch(t *testing.T) {
|
|||
out, err := json.Marshal(output)
|
||||
assert.NilError(t, err)
|
||||
fmt.Print(string(out))
|
||||
assert.Equal(t, string(out), string(expected))
|
||||
assert.Equal(t, string(out), expected.String())
|
||||
}
|
||||
|
||||
func Test_subVars_withRegexReplaceAll(t *testing.T) {
|
||||
patternMap := []byte(`
|
||||
{
|
||||
"port": "{{ regex_replace_all_literal('.*', '{{@}}', '1313') }}",
|
||||
"name": "ns-owner-{{request.object.metadata.name}}"
|
||||
}
|
||||
`)
|
||||
patternMap := []byte(`{
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"port": "{{ regex_replace_all_literal('.*', '{{@}}', '1313') }}",
|
||||
"name": "ns-owner-{{request.object.metadata.name}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
resourceRaw := []byte(`
|
||||
{
|
||||
"port": "43123",
|
||||
resourceRaw := []byte(`{
|
||||
"metadata": {
|
||||
"name": "temp",
|
||||
"namespace": "n1"
|
||||
},
|
||||
"spec": {
|
||||
"port": "43123",
|
||||
"namespace": "n1",
|
||||
"name": "temp1"
|
||||
}
|
||||
}
|
||||
`)
|
||||
expected := []byte(`{"name":"ns-owner-temp","port":"1313"}`)
|
||||
}`)
|
||||
expected := []byte(`{"mutate":{"overlay":{"spec":{"name":"ns-owner-temp","port":"1313"}}}}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
var err error
|
||||
|
|
|
@ -7,5 +7,5 @@ import (
|
|||
// RegexVariables represents regex for '{{}}'
|
||||
var RegexVariables = regexp.MustCompile(`\{\{[^{}]*\}\}`)
|
||||
|
||||
// AllowedVariables represents regex for {{request.}} {{serviceAccountName}} and {{serviceAccountNamespace}}
|
||||
var AllowedVariables = regexp.MustCompile(`\{\{\s*[request\.|serviceAccountName|serviceAccountNamespace][^{}]*\}\}`)
|
||||
// AllowedVariables represents regex for {{request.}}, {{serviceAccountName}}, {{serviceAccountNamespace}} and {{@}}
|
||||
var AllowedVariables = regexp.MustCompile(`\{\{\s*[request\.|serviceAccountName|serviceAccountNamespace|@][^{}]*\}\}`)
|
||||
|
|
Loading…
Add table
Reference in a new issue