Skip to content

Commit

Permalink
fix replacement with '.' issue
Browse files Browse the repository at this point in the history
  • Loading branch information
natasha41575 committed May 27, 2021
1 parent f0fbcb2 commit c9528ca
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 2 deletions.
26 changes: 25 additions & 1 deletion api/filters/replacement/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func rejectId(rejects []*types.Selector, id *resid.ResId) bool {

func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
for _, fp := range target.FieldPaths {
fieldPath := strings.Split(fp, ".")
fieldPath := getFieldPath(fp)
var t *yaml.RNode
var err error
if target.Options != nil && target.Options.Create {
Expand Down Expand Up @@ -178,3 +178,27 @@ func makeResId(n *yaml.RNode) *resid.ResId {
Namespace: n.GetNamespace(),
}
}

func getFieldPath(fieldPath string) []string {
var result []string
split := strings.Split(fieldPath, ".")

for i := 0; i < len(split); i=i+1 {
elem := split[i]
if strings.HasPrefix(elem, "[") && !strings.HasSuffix(elem, "]") {
// continue until we find the matching "]"
sequenceIndex := []string{elem}
for i < len(split)-1 {
i = i + 1
sequenceIndex = append(sequenceIndex, split[i])
if strings.HasSuffix(split[i], "]") {
break
}
}
result = append(result, strings.Join(sequenceIndex, "."))
} else {
result = append(result, elem)
}
}
return result
}
114 changes: 113 additions & 1 deletion api/filters/replacement/replacement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,73 @@ spec:
`,
expectedErr: "delimiter option can only be used with scalar nodes",
},
"list index contains '.' character": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: source
data:
value: example
---
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: some-secret
spec:
backendType: secretsManager
data:
- key: some-prefix-replaceme
name: .first
version: latest
property: first
- key: some-prefix-replaceme
name: second
version: latest
property: second
`,
replacements: `replacements:
- source:
kind: ConfigMap
version: v1
name: source
fieldPath: data.value
targets:
- select:
group: kubernetes-client.io
version: v1
kind: ExternalSecret
name: some-secret
fieldPaths:
- spec.data.[name=.first].key
- spec.data.[name=second].key
options:
delimiter: "-"
index: 2
`,
expected: `apiVersion: v1
kind: ConfigMap
metadata:
name: source
data:
value: example
---
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: some-secret
spec:
backendType: secretsManager
data:
- key: some-prefix-example
name: .first
version: latest
property: first
- key: some-prefix-example
name: second
version: latest
property: second`,
},

"multiple field paths in target": {
input: `apiVersion: v1
kind: ConfigMap
Expand Down Expand Up @@ -1429,7 +1496,7 @@ spec:
t.Errorf("unexpected error: %s\n", err.Error())
t.FailNow()
}
if !assert.Equal(t, tc.expectedErr, err.Error()) {
if !assert.Contains(t, err.Error(), tc.expectedErr) {
t.FailNow()
}
}
Expand All @@ -1439,3 +1506,48 @@ spec:
})
}
}

func TestGetFieldPath(t *testing.T) {
testCases := map[string]struct {
input string
expected []string
}{
"simple": {
input: "spec.replicas",
expected: []string{"spec", "replicas"},
},
"sequence": {
input: "spec.data.[name=first].key",
expected: []string{"spec", "data", "[name=first]", "key"},
},
"key, value with . prefix": {
input: "spec.data.[.name=.first].key",
expected: []string{"spec", "data", "[.name=.first]", "key"},
},
"key, value with . suffix": {
input: "spec.data.[name.=first.].key",
expected: []string{"spec", "data", "[name.=first.]", "key"},
},
"multiple '.' in value": {
input: "spec.data.[name=f.i.r.s.t.].key",
expected: []string{"spec", "data", "[name=f.i.r.s.t.]", "key"},
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
assert.True(t, stringSliceEquals(tc.expected, getFieldPath(tc.input)))
})
}
}

func stringSliceEquals(a []string, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}

0 comments on commit c9528ca

Please sign in to comment.