feat(*): warn on encountering unrecognized keys in cloud-config
This commit is contained in:
		| @@ -43,10 +43,35 @@ type CloudConfig struct { | ||||
| 	ManageEtcHosts EtcHosts `yaml:"manage_etc_hosts"` | ||||
| } | ||||
|  | ||||
| type warner func(format string, v ...interface{}) | ||||
|  | ||||
| func warnOnUnrecognizedKeys(contents string, warn warner) { | ||||
| 	// Generate a map of all understood cloud config options | ||||
| 	var cc map[string]interface{} | ||||
| 	b, _ := goyaml.Marshal(&CloudConfig{}) | ||||
| 	goyaml.Unmarshal(b, &cc) | ||||
| 	// Now unmarshal the entire provided contents | ||||
| 	var c map[string]interface{} | ||||
| 	goyaml.Unmarshal([]byte(contents), &c) | ||||
| 	// Check that every key in the contents exists in the cloud config | ||||
| 	for k, _ := range c { | ||||
| 		if _, ok := cc[k]; !ok { | ||||
| 			warn("Warning: unrecognized key %q in provided cloud config - ignoring section", k) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewCloudConfig instantiates a new CloudConfig from the given contents (a | ||||
| // string of YAML), returning any error encountered. It will ignore unknown | ||||
| // fields but log encountering them. | ||||
| func NewCloudConfig(contents string) (*CloudConfig, error) { | ||||
| 	var cfg CloudConfig | ||||
| 	err := goyaml.Unmarshal([]byte(contents), &cfg) | ||||
| 	return &cfg, err | ||||
| 	if err != nil { | ||||
| 		return &cfg, err | ||||
| 	} | ||||
| 	warnOnUnrecognizedKeys(contents, log.Printf) | ||||
| 	return &cfg, nil | ||||
| } | ||||
|  | ||||
| func (cc CloudConfig) String() string { | ||||
|   | ||||
| @@ -1,10 +1,50 @@ | ||||
| package initialize | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestCloudConfigUnknownKeys(t *testing.T) { | ||||
| 	contents := ` | ||||
| coreos:  | ||||
|   etcd: | ||||
|     discovery: "https://discovery.etcd.io/827c73219eeb2fa5530027c37bf18877" | ||||
| unknown: | ||||
|   dunno: | ||||
|     something | ||||
| foo: | ||||
|   bar | ||||
| hostname: | ||||
|   foo | ||||
| ` | ||||
| 	cfg, err := NewCloudConfig(contents) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("error instantiating CloudConfig with unknown keys: %v", err) | ||||
| 	} | ||||
| 	if cfg.Hostname != "foo" { | ||||
| 		t.Fatalf("hostname not correctly set when invalid keys are present") | ||||
| 	} | ||||
| 	if len(cfg.Coreos.Etcd) < 1 { | ||||
| 		t.Fatalf("etcd section not correctly set when invalid keys are present") | ||||
| 	} | ||||
|  | ||||
| 	var warnings string | ||||
| 	catchWarn := func(f string, v ...interface{}) { | ||||
| 		warnings += fmt.Sprintf(f, v...) | ||||
| 	} | ||||
|  | ||||
| 	warnOnUnrecognizedKeys(contents, catchWarn) | ||||
|  | ||||
| 	if !strings.Contains(warnings, "foo") { | ||||
| 		t.Errorf("warnings did not catch unrecognized key foo") | ||||
| 	} | ||||
| 	if !strings.Contains(warnings, "unknown") { | ||||
| 		t.Errorf("warnings did not catch unrecognized key unknown") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Assert that the parsing of a cloud config file "generally works" | ||||
| func TestCloudConfigEmpty(t *testing.T) { | ||||
| 	cfg, err := NewCloudConfig("") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user