Skip to content

Commit

Permalink
Merge pull request #581 from cloudfoundry/refactor_allow_newlines_in_var
Browse files Browse the repository at this point in the history
Try to improve code readability of var_kv
  • Loading branch information
lnguyen authored Dec 17, 2021
2 parents 02f0378 + ab3ef17 commit e04501b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
30 changes: 19 additions & 11 deletions director/template/var_kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,41 @@ type VarKV struct {
Value interface{}
}

func trimWrappingQuotes(s string) string {
if (s[0] == '"' && s[len(s)-1] == '"') || (s[0] == '\'' && s[len(s)-1] == '\'') {
s = s[1 : len(s)-1]
s = trimWrappingQuotes(s)
}
return s
}
func (a *VarKV) UnmarshalFlag(data string) error {
pieces := strings.SplitN(data, "=", 2)
const nameIndex, valueIndex = 0, 1
if len(pieces) != 2 {
return bosherr.Errorf("Expected var '%s' to be in format 'name=value'", data)
}

if len(pieces[0]) == 0 {
if len(pieces[nameIndex]) == 0 {
return bosherr.Errorf("Expected var '%s' to specify non-empty name", data)
}

if len(pieces[1]) == 0 {
if len(pieces[valueIndex]) == 0 {
return bosherr.Errorf("Expected var '%s' to specify non-empty value", data)
}

var vars interface{}

err := yaml.Unmarshal([]byte(pieces[1]), &vars)
if err != nil {
return bosherr.WrapErrorf(err, "Deserializing variables '%s'", data)
}

err := yaml.Unmarshal([]byte(pieces[valueIndex]), &vars)
//If for whatever reason YAML unmarshal fails, treat the second part of pieces as a string
//yaml.Unmarshal returns a string if the input is not valid yaml.
//in that case, we pass through the string itself as the Unmarshal process strips newlines.
if _, ok := vars.(string); ok {
*a = VarKV{Name: pieces[0], Value: pieces[1]}
if _, ok := vars.(string); ok || err != nil {
//in that case, we return the initial flag value as the Unmarshal
//process strips newlines. Stripping the quotes is required to keep
//backwards compability (YAML unmarshal also removed wrapping quotes from the value).
*a = VarKV{Name: pieces[nameIndex], Value: trimWrappingQuotes(pieces[valueIndex])}
} else {
*a = VarKV{Name: pieces[0], Value: vars}
//otherwise, return the parsed YAML object
*a = VarKV{Name: pieces[nameIndex], Value: vars}
}

return nil
Expand Down
27 changes: 27 additions & 0 deletions director/template/var_kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,33 @@ var _ = Describe("VarKV", func() {
Expect(arg).To(Equal(VarKV{Name: "name", Value: "val"}))
})

It("reverts to the old (incorrect) bevaviour and removes the wrapping double quotes if the value is a string", func() {
err := (&arg).UnmarshalFlag(`name="val"`)
Expect(err).ToNot(HaveOccurred())
Expect(arg).To(Equal(VarKV{Name: "name", Value: "val"}))
})
It("reverts to the old (incorrect) bevaviour and removes the wrapping single quotes if the value is a string", func() {
err := (&arg).UnmarshalFlag(`name='val'`)
Expect(err).ToNot(HaveOccurred())
Expect(arg).To(Equal(VarKV{Name: "name", Value: "val"}))
})
It("only removes wrapping quotes", func() {
err := (&arg).UnmarshalFlag(`name="'val""val'"`)
Expect(err).ToNot(HaveOccurred())
Expect(arg).To(Equal(VarKV{Name: "name", Value: `val""val`}))

err = (&arg).UnmarshalFlag(`name="val''val"`)
Expect(err).ToNot(HaveOccurred())
Expect(arg).To(Equal(VarKV{Name: "name", Value: `val''val`}))

err = (&arg).UnmarshalFlag(`name='"some-data'"`)
Expect(err).ToNot(HaveOccurred())
Expect(arg).To(Equal(VarKV{Name: "name", Value: `'"some-data'"`}))

err = (&arg).UnmarshalFlag(`name="'some-data"'`)
Expect(err).ToNot(HaveOccurred())
Expect(arg).To(Equal(VarKV{Name: "name", Value: `"'some-data"'`}))
})
It("sets name and value when value contains a `=`", func() {
err := (&arg).UnmarshalFlag("public_key=ssh-rsa G4/+VHa1aw==")
Expect(err).ToNot(HaveOccurred())
Expand Down

0 comments on commit e04501b

Please sign in to comment.