From 388ebfe7d0e453e047bd8f611fd05037acb530a9 Mon Sep 17 00:00:00 2001 From: Vinayak Goyal Date: Fri, 14 Feb 2020 17:04:47 -0800 Subject: [PATCH] append_or_replace_prefixed_line in /cluster/gce/gci/configure-helper.sh fails for prefixes that contain quotes and = sign. --- cluster/gce/gci/BUILD | 2 + .../append_or_replace_prefixed_line_test.go | 183 ++++++++++++++++++ cluster/gce/gci/configure-helper.sh | 2 +- 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 cluster/gce/gci/append_or_replace_prefixed_line_test.go diff --git a/cluster/gce/gci/BUILD b/cluster/gce/gci/BUILD index 9a44af695b6..9cf6153541e 100644 --- a/cluster/gce/gci/BUILD +++ b/cluster/gce/gci/BUILD @@ -7,6 +7,7 @@ go_test( srcs = [ "apiserver_etcd_test.go", "apiserver_kms_test.go", + "append_or_replace_prefixed_line_test.go", "audit_policy_test.go", "configure_helper_test.go", ], @@ -26,6 +27,7 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/audit/policy:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", + "//vendor/github.com/google/go-cmp/cmp:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library", ], diff --git a/cluster/gce/gci/append_or_replace_prefixed_line_test.go b/cluster/gce/gci/append_or_replace_prefixed_line_test.go new file mode 100644 index 00000000000..1e1f10fae39 --- /dev/null +++ b/cluster/gce/gci/append_or_replace_prefixed_line_test.go @@ -0,0 +1,183 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package gci + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestAppendOrReplacePrefix(t *testing.T) { + testCases := []struct { + desc string + prefix string + suffix string + initialFileContents string + want string + }{ + { + desc: "simple string and empty file", + prefix: "hello", + suffix: "world", + want: `helloworld +`, + }, + { + desc: "simple string and non empty file", + prefix: "hello", + suffix: "world", + initialFileContents: `jelloworld +chelloworld +`, + want: `jelloworld +chelloworld +helloworld +`, + }, + { + desc: "simple string and file already contains prefix", + prefix: "hello", + suffix: "world", + initialFileContents: `helloworld +helloworld +jelloworld +chelloworld +`, + want: `jelloworld +chelloworld +helloworld +`, + }, + { + desc: "simple string and file already contains prefix with content between the prefix and suffix", + prefix: "hello", + suffix: "world", + initialFileContents: `hellocontentsworld +jelloworld +chelloworld +`, + want: `jelloworld +chelloworld +helloworld +`, + }, + { + desc: "simple string and file already contains prefix with prefix == suffix", + prefix: "hello", + suffix: "world", + initialFileContents: `hellohello +jelloworld +chelloworld +`, + want: `jelloworld +chelloworld +helloworld +`, + }, + { + desc: "string with quotes and = and empty file", + prefix: `'"$argon2id$v=19"'`, + suffix: "admin", + want: `"$argon2id$v=19"admin +`, + }, + { + desc: "string with quotes and = and non empty file", + prefix: `'"$argon2id$v=19"'`, + suffix: "admin", + initialFileContents: `jelloworld +chelloworld +`, + want: `jelloworld +chelloworld +"$argon2id$v=19"admin +`, + }, + { + desc: "string with quotes and = and file already contains prefix", + prefix: `'"$argon2id$v=19"'`, + suffix: "admin", + initialFileContents: `"$argon2id$v=19"admin +"$argon2id$v=19"admin +helloworld +jelloworld +`, + want: `helloworld +jelloworld +"$argon2id$v=19"admin +`, + }, + { + desc: "string with quotes and = and file already contains prefix with content between the prefix and suffix", + prefix: `'"$argon2id$v=19"'`, + suffix: "admin", + initialFileContents: `"$argon2id$v=19"contentsadmin +helloworld +jelloworld +`, + want: `helloworld +jelloworld +"$argon2id$v=19"admin +`, + }, + { + desc: "string with quotes and = and file already contains prefix with prefix == suffix", + prefix: `'"$argon2id$v=19"'`, + suffix: "admin", + initialFileContents: `"$argon2id$v=19""$argon2id$v=19" +helloworld +jelloworld +`, + want: `helloworld +jelloworld +"$argon2id$v=19"admin +`, + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + f, err := ioutil.TempFile("", "append_or_replace_test") + if err != nil { + t.Fatalf("Failed to create temp file: %v", err) + } + defer os.Remove(f.Name()) + if _, err := f.WriteString(tc.initialFileContents); err != nil { + t.Fatalf("Failed to write to file: %v", err) + } + f.Close() + args := fmt.Sprintf("source configure-helper.sh; append_or_replace_prefixed_line %s %s %s", f.Name(), tc.prefix, tc.suffix) + cmd := exec.Command("bash", "-c", args) + stderr, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Failed to run command: %v: %s", err, stderr) + } + got, err := ioutil.ReadFile(f.Name()) + if err != nil { + t.Fatalf("Failed to read file contents: %v", err) + } + if diff := cmp.Diff(string(got), tc.want); diff != "" { + t.Errorf("File contents: got=%s, want=%s, diff=%s", got, tc.want, diff) + } + }) + } + +} diff --git a/cluster/gce/gci/configure-helper.sh b/cluster/gce/gci/configure-helper.sh index 481eb6b5b9d..394e1b4ea5a 100644 --- a/cluster/gce/gci/configure-helper.sh +++ b/cluster/gce/gci/configure-helper.sh @@ -464,7 +464,7 @@ function append_or_replace_prefixed_line { local -r tmpfile="$(mktemp -t filtered.XXXX --tmpdir=${dirname})" touch "${file}" - awk "substr(\$0,0,length(\"${prefix}\")) != \"${prefix}\" { print }" "${file}" > "${tmpfile}" + awk -v pfx="${prefix}" 'substr($0,1,length(pfx)) != pfx { print }' "${file}" > "${tmpfile}" echo "${prefix}${suffix}" >> "${tmpfile}" mv "${tmpfile}" "${file}" }