From e76b84ef6edba6ef9001d382f911b184db1fbe5c Mon Sep 17 00:00:00 2001 From: Jim Ramsay Date: Fri, 25 Feb 2022 12:47:21 -0500 Subject: [PATCH] Preserve scalar types when using the replacement filter Erasing the scalar type tag leads to unfortunate circumstances, in that the resulting yaml code is valid yaml, but will not meet the object spec. For example, using the replacement transformer to take a port number as a string from a ConfigMap and set a Pod port would previously end up with: - port: "8080" when the spec requires that this is not a string: - port: 8080 Signed-off-by: Jim Ramsay --- api/filters/replacement/replacement.go | 7 +- api/filters/replacement/replacement_test.go | 102 +++++++++++++++++++- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/api/filters/replacement/replacement.go b/api/filters/replacement/replacement.go index 0cf269419f2..f4627ddbcb8 100644 --- a/api/filters/replacement/replacement.go +++ b/api/filters/replacement/replacement.go @@ -174,7 +174,12 @@ func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNod value.YNode().Value = strings.Join(tv, options.Delimiter) } - t.SetYNode(value.YNode()) + if t.YNode().Kind == yaml.ScalarNode { + // For scalar, only copy the value (leave any type intact to auto-convert int->string or string->int) + t.YNode().Value = value.YNode().Value + } else { + t.SetYNode(value.YNode()) + } return nil } diff --git a/api/filters/replacement/replacement_test.go b/api/filters/replacement/replacement_test.go index e5077b93f69..3f84e08f8f9 100644 --- a/api/filters/replacement/replacement_test.go +++ b/api/filters/replacement/replacement_test.go @@ -205,13 +205,13 @@ spec: command: ["printenv"] args: - example.com - - 8080 + - "8080" - name: busybox image: busybox:latest args: - echo - example.com - - 8080 + - "8080" --- apiVersion: v1 kind: ConfigMap @@ -2011,6 +2011,104 @@ spec: name: nginx-tagged - image: postgres:1.8.0 name: postgresdb +`, + }, + "string source -> integer target": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: config +data: + PORT: "8080" +--- +apiVersion: apps/v1 +kind: Pod +metadata: + name: pod +spec: + containers: + - image: busybox + name: myapp-container + ports: + - port: 80 +`, + replacements: `replacements: +- source: + kind: ConfigMap + name: config + fieldPath: data.PORT + targets: + - select: + kind: Pod + fieldPaths: + - spec.containers.0.ports.0.port +`, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: config +data: + PORT: "8080" +--- +apiVersion: apps/v1 +kind: Pod +metadata: + name: pod +spec: + containers: + - image: busybox + name: myapp-container + ports: + - port: 8080 +`, + }, + "integer source -> string target": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: config +data: + PORT: "8080" +--- +apiVersion: apps/v1 +kind: Pod +metadata: + name: pod +spec: + containers: + - image: busybox + name: myapp-container + ports: + - port: 80 +`, + replacements: `replacements: +- source: + kind: Pod + name: pod + fieldPath: spec.containers.0.ports.0.port + targets: + - select: + kind: ConfigMap + fieldPaths: + - data.PORT +`, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: config +data: + PORT: "80" +--- +apiVersion: apps/v1 +kind: Pod +metadata: + name: pod +spec: + containers: + - image: busybox + name: myapp-container + ports: + - port: 80 `, }, }