Merge "Replacement transformer improvement"
This commit is contained in:
commit
e6a6a655e1
@ -91,3 +91,13 @@ type ErrIndexOutOfBound struct {
|
||||
func (e ErrIndexOutOfBound) Error() string {
|
||||
return fmt.Sprintf("index %v is out of bound", e.Index)
|
||||
}
|
||||
|
||||
// ErrMapNotFound returned if map specified in fieldRef option was not found in a list
|
||||
type ErrMapNotFound struct {
|
||||
Key, Value, ListKey string
|
||||
}
|
||||
|
||||
func (e ErrMapNotFound) Error() string {
|
||||
return fmt.Sprintf("unable to find map key '%s' with the value '%s' in list under '%s' key",
|
||||
e.Key, e.Value, e.ListKey)
|
||||
}
|
||||
|
@ -28,6 +28,10 @@ var (
|
||||
substringPatternRegex = regexp.MustCompile(`(\S+)%(\S+)%$`)
|
||||
)
|
||||
|
||||
const (
|
||||
dotReplacer = "$$$$"
|
||||
)
|
||||
|
||||
// GetGVK returns group, version, kind object used to register version
|
||||
// of the plugin
|
||||
func GetGVK() schema.GroupVersionKind {
|
||||
@ -151,7 +155,23 @@ func substitute(m resmap.ResMap, to *types.ReplTarget, replacement interface{})
|
||||
}
|
||||
for _, r := range resources {
|
||||
for _, p := range to.FieldRefs {
|
||||
// TODO (dukov) rework this using k8s.io/client-go/util/jsonpath
|
||||
parts := strings.Split(p, "[")
|
||||
var tmp []string
|
||||
for _, part := range parts {
|
||||
if strings.Contains(part, "]") {
|
||||
filter := strings.Split(part, "]")
|
||||
filter[0] = strings.ReplaceAll(filter[0], ".", dotReplacer)
|
||||
part = strings.Join(filter, "]")
|
||||
}
|
||||
tmp = append(tmp, part)
|
||||
}
|
||||
p = strings.Join(tmp, "[")
|
||||
|
||||
pathSlice := strings.Split(p, ".")
|
||||
for i, part := range pathSlice {
|
||||
pathSlice[i] = strings.ReplaceAll(part, dotReplacer, ".")
|
||||
}
|
||||
if err := updateField(r.Map(), pathSlice, replacement); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -246,15 +266,15 @@ func updateMapField(m map[string]interface{}, pathToField []string, replacement
|
||||
}
|
||||
switch typedV := v.(type) {
|
||||
case []interface{}:
|
||||
for _, item := range typedV {
|
||||
for i, item := range typedV {
|
||||
typedItem, ok := item.(map[string]interface{})
|
||||
if !ok {
|
||||
return ErrTypeMismatch{Actual: item, Expectation: fmt.Sprintf("is expected to be %T", typedItem)}
|
||||
}
|
||||
if actualValue, ok := typedItem[key]; ok {
|
||||
if value == actualValue {
|
||||
// TODO (dukov) should not we do 'item = replacement' here?
|
||||
typedItem[key] = value
|
||||
typedV[i] = replacement
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -273,7 +293,7 @@ func updateSliceField(m []interface{}, pathToField []string, replacement interfa
|
||||
if len(pathToField) == 0 {
|
||||
return nil
|
||||
}
|
||||
_, key, value, isArray := getFirstPathSegment(pathToField[0])
|
||||
path, key, value, isArray := getFirstPathSegment(pathToField[0])
|
||||
|
||||
if isArray {
|
||||
for _, item := range m {
|
||||
@ -287,6 +307,7 @@ func updateSliceField(m []interface{}, pathToField []string, replacement interfa
|
||||
}
|
||||
}
|
||||
}
|
||||
return ErrMapNotFound{Key: key, Value: value, ListKey: path}
|
||||
}
|
||||
|
||||
index, err := strconv.Atoi(pathToField[0])
|
||||
|
@ -89,7 +89,7 @@ replacements:
|
||||
objref:
|
||||
kind: Deployment
|
||||
fieldrefs:
|
||||
- spec.template.spec.containers[name=nginx-latest].image
|
||||
- spec.template.spec.containers[name=nginx.latest].image
|
||||
- source:
|
||||
value: postgres:latest
|
||||
target:
|
||||
@ -112,7 +112,7 @@ spec:
|
||||
- image: nginx:1.7.9
|
||||
name: nginx-tagged
|
||||
- image: nginx:latest
|
||||
name: nginx-latest
|
||||
name: nginx.latest
|
||||
- image: foobar:1
|
||||
name: replaced-with-digest
|
||||
- image: postgres:1.8.0
|
||||
@ -137,7 +137,7 @@ spec:
|
||||
- image: nginx:1.7.9
|
||||
name: nginx-tagged
|
||||
- image: nginx:newtag
|
||||
name: nginx-latest
|
||||
name: nginx.latest
|
||||
- image: foobar:1
|
||||
name: replaced-with-digest
|
||||
- image: postgres:latest
|
||||
@ -455,6 +455,65 @@ kind: ReplacementTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
replacements:
|
||||
- source:
|
||||
objref:
|
||||
kind: Pod
|
||||
name: pod
|
||||
fieldref: spec.containers[0]
|
||||
target:
|
||||
objref:
|
||||
kind: Deployment
|
||||
fieldrefs:
|
||||
- spec.template.spec.containers[name=myapp-container]`,
|
||||
in: `
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod
|
||||
spec:
|
||||
containers:
|
||||
- name: repl
|
||||
image: repl
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy2
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: busybox
|
||||
name: myapp-container
|
||||
`,
|
||||
expectedOut: `apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod
|
||||
spec:
|
||||
containers:
|
||||
- image: repl
|
||||
name: repl
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy2
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: repl
|
||||
name: repl
|
||||
`,
|
||||
},
|
||||
{
|
||||
cfg: `
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: ReplacementTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
replacements:
|
||||
- source:
|
||||
objref:
|
||||
kind: Pod
|
||||
@ -782,6 +841,44 @@ spec:
|
||||
name: nginx-latest`,
|
||||
expectedErr: "pattern 'TAG' is defined in configuration but was not found in target value nginx:latest",
|
||||
},
|
||||
{
|
||||
cfg: `
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: ReplacementTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
replacements:
|
||||
- source:
|
||||
value: 12345678
|
||||
target:
|
||||
objref:
|
||||
kind: KubeadmControlPlane
|
||||
fieldrefs:
|
||||
- spec.kubeadmConfigSpec.files[path=konfigadm].content%{k8s-version}%
|
||||
`,
|
||||
|
||||
in: `
|
||||
kind: KubeadmControlPlane
|
||||
metadata:
|
||||
name: cluster-controlplane
|
||||
spec:
|
||||
infrastructureTemplate:
|
||||
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
|
||||
kind: Metal3MachineTemplate
|
||||
name: $(cluster-name)
|
||||
kubeadmConfigSpec:
|
||||
files:
|
||||
- content: |
|
||||
kubernetes:
|
||||
version: {k8s-version}
|
||||
container_runtime:
|
||||
type: docker
|
||||
owner: root:root
|
||||
path: konfigadm_bug_
|
||||
permissions: "0640"
|
||||
`,
|
||||
expectedErr: "unable to find map key 'path' with the value 'konfigadm' in list under 'files' key",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
Loading…
x
Reference in New Issue
Block a user