diff --git a/config/validate/rules.go b/config/validate/rules.go index f8397dc..abce8aa 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -31,6 +31,7 @@ type rule func(config node, report *Report) // Rules contains all of the validation rules. var Rules []rule = []rule{ checkDiscoveryUrl, + checkEncoding, checkStructure, checkValidity, checkWriteFiles, @@ -49,6 +50,22 @@ func checkDiscoveryUrl(cfg node, report *Report) { } } +// checkEncoding validates that, for each file under 'write_files', the +// content can be decoded given the specified encoding. +func checkEncoding(cfg node, report *Report) { + for _, f := range cfg.Child("write_files").children { + e := f.Child("encoding") + if !e.IsValid() { + continue + } + + c := f.Child("contents") + if _, err := config.DecodeContent(c.String(), e.String()); err != nil { + report.Error(c.line, fmt.Sprintf("contents cannot be decoded as %q", e.String())) + } + } +} + // checkStructure compares the provided config to the empty config.CloudConfig // structure. Each node is checked to make sure that it exists in the known // structure and that its type is compatible. diff --git a/config/validate/rules_test.go b/config/validate/rules_test.go index d37c181..85dffae 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -54,6 +54,52 @@ func TestCheckDiscoveryUrl(t *testing.T) { } } +func TestCheckEncoding(t *testing.T) { + tests := []struct { + config string + + entries []Entry + }{ + {}, + { + config: "write_files:\n - encoding: base64\n contents: aGVsbG8K", + }, + { + config: "write_files:\n - contents: !!binary aGVsbG8K", + }, + { + config: "write_files:\n - encoding: base64\n contents: !!binary aGVsbG8K", + entries: []Entry{{entryError, `contents cannot be decoded as "base64"`, 3}}, + }, + { + config: "write_files:\n - encoding: base64\n contents: !!binary YUdWc2JHOEsK", + }, + { + config: "write_files:\n - encoding: gzip\n contents: !!binary H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", + }, + { + config: "write_files:\n - encoding: gzip+base64\n contents: H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", + }, + { + config: "write_files:\n - encoding: custom\n contents: hello", + entries: []Entry{{entryError, `contents cannot be decoded as "custom"`, 3}}, + }, + } + + for i, tt := range tests { + r := Report{} + n, err := parseCloudConfig([]byte(tt.config), &r) + if err != nil { + panic(err) + } + checkEncoding(n, &r) + + if e := r.Entries(); !reflect.DeepEqual(tt.entries, e) { + t.Errorf("bad report (%d, %q): want %#v, got %#v", i, tt.config, tt.entries, e) + } + } +} + func TestCheckStructure(t *testing.T) { tests := []struct { config string