func (c *Config) ValidateUnknownAttrs(extrafields schema.Fields, defaults schema.Defaults) (map[string]interface{}, error) {
	attrs := c.UnknownAttrs()
	checker := schema.FieldMap(extrafields, defaults)
	coerced, err := checker.Coerce(attrs, nil)
	if err != nil {
		logger.Debugf("coercion failed attributes: %#v, checker: %#v, %v", attrs, checker, err)
		return nil, err
	}
	result := coerced.(map[string]interface{})
	for name, value := range attrs {
		if extrafields[name] == nil {
			// We know this name isn't in the global fields, or it wouldn't be
			// an UnknownAttr, it also appears to not be in the extra fields
			// that are provider specific.  Check to see if an alternative
			// spelling is in either the extra fields or the core fields.
			if val, isString := value.(string); isString && val != "" {
				// only warn about attributes with non-empty string values
				altName := strings.Replace(name, "_", "-", -1)
				if extrafields[altName] != nil || fields[altName] != nil {
					logger.Warningf("unknown config field %q, did you mean %q?", name, altName)
				} else {
					logger.Warningf("unknown config field %q", name)
				}
			}
			result[name] = value
			// The only allowed types for unknown attributes are string, int,
			// float, bool and []interface{} (which is really []string)
			switch t := value.(type) {
			case string:
				continue
			case int:
				continue
			case bool:
				continue
			case float32:
				continue
			case float64:
				continue
			case []interface{}:
				for _, val := range t {
					if _, ok := val.(string); !ok {
						return nil, errors.Errorf("%s: unknown type (%v)", name, value)
					}
				}
				continue
			default:
				return nil, errors.Errorf("%s: unknown type (%q)", name, value)
			}
		}
	}
	return result, nil
}
// ValidateUnknownAttrs checks the unknown attributes of the config against
// the supplied fields and defaults, and returns an error if any fails to
// validate. Unknown fields are warned about, but preserved, on the basis
// that they are reasonably likely to have been written by or for a version
// of juju that does recognise the fields, but that their presence is still
// anomalous to some degree and should be flagged (and that there is thereby
// a mechanism for observing fields that really are typos etc).
ValidateUnknownAttrs checks the unknown attributes of the config against
the supplied fields and defaults, and returns an error if any fails to
validate. Unknown fields are warned about, but preserved, on the basis
that they are reasonably likely to have been written by or for a version
of juju that does recognise the fields, but that their presence is still
anomalous to some degree and should be flagged (and that there is thereby
a mechanism for observing fields that really are typos etc).
// ValidateUnknownAttrs checks the unknown attributes of the config against // the supplied fields and defaults and returns an error if any fails to // validate . Unknown fields are warned about but preserved on the basis // that they are reasonably likely to have been written by or for a version // of juju that does recognise the fields but that their presence is still // anomalous to some degree and should be flagged ( and that there is thereby // a mechanism for observing fields that really are typos etc ) .
func (c *Config) ValidateUnknownAttrs(extrafields schema.Fields, defaults schema.Defaults) (map[string]interface{}, error) {
	attrs := c.UnknownAttrs()
	checker := schema.FieldMap(extrafields, defaults)
	coerced, err := checker.Coerce(attrs, nil)
	if err != nil {
		logger.Debugf("coercion failed attributes: %#v, checker: %#v, %v", attrs, checker, err)
		return nil, err
	}
	result := coerced.(map[string]interface{})
	for name, value := range attrs {
		if extrafields[name] == nil {
			if val, isString := value.(string); isString && val != "" {
				altName := strings.Replace(name, "_", "-", -1)
				if extrafields[altName] != nil || fields[altName] != nil {
					logger.Warningf("unknown config field %q, did you mean %q?", name, altName)
				} else {
					logger.Warningf("unknown config field %q", name)
				}
			}
			result[name] = value
			switch t := value.(type) {
			case string:
				continue
			case int:
				continue
			case bool:
				continue
			case float32:
				continue
			case float64:
				continue
			case []interface{}:
				for _, val := range t {
					if _, ok := val.(string); !ok {
						return nil, errors.Errorf("%s: unknown type (%v)", name, value)
					}
				}
				continue
			default:
				return nil, errors.Errorf("%s: unknown type (%q)", name, value)
			}
		}
	}
	return result, nil
}
func ( c * Config ) ValidateUnknownAttrs ( extrafields schema . Fields , defaults schema . Defaults ) ( map [ string ] interface { } , error ) { attrs := c . UnknownAttrs ( ) checker := schema . FieldMap ( extrafields , defaults ) coerced , err := checker . Coerce ( attrs , nil ) if err != nil { logger . Debugf ( " " , attrs , checker , err ) return nil , err } result := coerced . ( map [ string ] interface { } ) for name , value := range attrs { if extrafields [ name ] == nil { if val , isString := value . ( string ) ; isString && val != " " { altName := strings . Replace ( name , " " , " " , - 1 ) if extrafields [ altName ] != nil || fields [ altName ] != nil { logger . Warningf ( " " , name , altName ) } else { logger . Warningf ( " " , name ) } } result [ name ] = value switch t := value . ( type ) { case string : continue case int : continue case bool : continue case float32 : continue case float64 : continue case [ ] interface { } : for _ , val := range t { if _ , ok := val . ( string ) ; ! ok { return nil , errors . Errorf ( " " , name , value ) } } continue default : return nil , errors . Errorf ( " " , name , value ) } } } return result , nil }
ValidateUnknownAttrs checks the unknown attributes of the config against
the supplied fields and defaults, and returns an error if any fails to
validate.
ValidateUnknownAttrs checks the unknown attributes of the config against the supplied fields and defaults and returns an error if any fails to validate .
// We know this name isn't in the global fields, or it wouldn't be // an UnknownAttr, it also appears to not be in the extra fields // that are provider specific.  Check to see if an alternative // spelling is in either the extra fields or the core fields. // only warn about attributes with non-empty string values // The only allowed types for unknown attributes are string, int, // float, bool and []interface{} (which is really []string)