diff --git a/config/validate/rules.go b/config/validate/rules.go index 459877d..416e6ec 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -18,6 +18,7 @@ package validate import ( "fmt" + "net/url" "path" "reflect" "strings" @@ -29,11 +30,24 @@ type rule func(config node, report *Report) // Rules contains all of the validation rules. var Rules []rule = []rule{ + checkDiscoveryUrl, checkStructure, checkValidity, checkWriteFiles, } +// checkDiscoveryUrl verifies that the string is a valid url. +func checkDiscoveryUrl(cfg node, report *Report) { + c := cfg.Child("coreos").Child("etcd").Child("discovery") + if !c.IsValid() { + return + } + + if _, err := url.ParseRequestURI(c.String()); err != nil { + report.Warning(c.line, "discovery URL is not valid") + } +} + // 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 55f4387..c767dff 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -21,6 +21,39 @@ import ( "testing" ) +func TestCheckDiscoveryUrl(t *testing.T) { + tests := []struct { + config string + + entries []Entry + }{ + {}, + { + config: "coreos:\n etcd:\n discovery: https://discovery.etcd.io/00000000000000000000000000000000", + }, + { + config: "coreos:\n etcd:\n discovery: http://custom.domain/mytoken", + }, + { + config: "coreos:\n etcd:\n discovery: disco", + entries: []Entry{{entryWarning, "discovery URL is not valid", 3}}, + }, + } + + for i, tt := range tests { + r := Report{} + n, err := parseCloudConfig([]byte(tt.config), &r) + if err != nil { + panic(err) + } + checkDiscoveryUrl(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