func NewConfig(controllerUUID, caCert string, attrs map[string]interface{}) (Config, error) {
	// TODO(wallyworld) - use core/config when it supports duration types
	for k, v := range attrs {
		field, ok := ConfigSchema[k]
		if !ok || field.Type != environschema.Tlist {
			continue
		}
		str, ok := v.(string)
		if !ok {
			continue
		}
		var coerced interface{}
		err := yaml.Unmarshal([]byte(str), &coerced)
		if err != nil {
			return Config{}, errors.NewNotValid(err, fmt.Sprintf("value %q for attribute %q not valid", str, k))
		}
		attrs[k] = coerced
	}
	coerced, err := configChecker.Coerce(attrs, nil)
	if err != nil {
		return Config{}, errors.Trace(err)
	}
	attrs = coerced.(map[string]interface{})
	attrs[ControllerUUIDKey] = controllerUUID
	attrs[CACertKey] = caCert
	config := Config(attrs)
	return config, config.Validate()
}
// NewConfig creates a new Config from the supplied attributes.
// Default values will be used where defaults are available.
//
// The controller UUID and CA certificate must be passed in.
// The UUID is typically generated by the immediate caller,
// and the CA certificate generated by environs/bootstrap.NewConfig.
NewConfig creates a new Config from the supplied attributes.
Default values will be used where defaults are available.

The controller UUID and CA certificate must be passed in.
The UUID is typically generated by the immediate caller,
and the CA certificate generated by environs/bootstrap.NewConfig.
// NewConfig creates a new Config from the supplied attributes . // Default values will be used where defaults are available . // // The controller UUID and CA certificate must be passed in . // The UUID is typically generated by the immediate caller // and the CA certificate generated by environs / bootstrap . NewConfig .
func NewConfig(controllerUUID, caCert string, attrs map[string]interface{}) (Config, error) {
	for k, v := range attrs {
		field, ok := ConfigSchema[k]
		if !ok || field.Type != environschema.Tlist {
			continue
		}
		str, ok := v.(string)
		if !ok {
			continue
		}
		var coerced interface{}
		err := yaml.Unmarshal([]byte(str), &coerced)
		if err != nil {
			return Config{}, errors.NewNotValid(err, fmt.Sprintf("value %q for attribute %q not valid", str, k))
		}
		attrs[k] = coerced
	}
	coerced, err := configChecker.Coerce(attrs, nil)
	if err != nil {
		return Config{}, errors.Trace(err)
	}
	attrs = coerced.(map[string]interface{})
	attrs[ControllerUUIDKey] = controllerUUID
	attrs[CACertKey] = caCert
	config := Config(attrs)
	return config, config.Validate()
}
func NewConfig ( controllerUUID , caCert string , attrs map [ string ] interface { } ) ( Config , error ) { for k , v := range attrs { field , ok := ConfigSchema [ k ] if ! ok || field . Type != environschema . Tlist { continue } str , ok := v . ( string ) if ! ok { continue } var coerced interface { } err := yaml . Unmarshal ( [ ] byte ( str ) , & coerced ) if err != nil { return Config { } , errors . NewNotValid ( err , fmt . Sprintf ( " " , str , k ) ) } attrs [ k ] = coerced } coerced , err := configChecker . Coerce ( attrs , nil ) if err != nil { return Config { } , errors . Trace ( err ) } attrs = coerced . ( map [ string ] interface { } ) attrs [ ControllerUUIDKey ] = controllerUUID attrs [ CACertKey ] = caCert config := Config ( attrs ) return config , config . Validate ( ) }
NewConfig creates a new Config from the supplied attributes.
NewConfig creates a new Config from the supplied attributes .
// TODO(wallyworld) - use core/config when it supports duration types