Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to improve code readability of var_kv #581

Merged
merged 6 commits into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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