func cleanse(input interface{}) (interface{}, error) {
	switch typedInput := input.(type) {
	// In this case, recurse in.
	case map[string]interface{}:
		newMap := make(map[string]interface{})
		for key, value := range typedInput {

			if prohibitedSchemaKeys[key] {
				return nil, fmt.Errorf("schema key %q not compatible with this version of juju", key)
			}

			newValue, err := cleanse(value)
			if err != nil {
				return nil, err
			}
			newMap[key] = newValue
		}
		return newMap, nil

	// Coerce keys to strings and error out if there's a problem; then recurse.
	case map[interface{}]interface{}:
		newMap := make(map[string]interface{})
		for key, value := range typedInput {
			typedKey, ok := key.(string)
			if !ok {
				return nil, errors.New("map keyed with non-string value")
			}
			newMap[typedKey] = value
		}
		return cleanse(newMap)

	// Recurse
	case []interface{}:
		newSlice := make([]interface{}, 0)
		for _, sliceValue := range typedInput {
			newSliceValue, err := cleanse(sliceValue)
			if err != nil {
				return nil, errors.New("map keyed with non-string value")
			}
			newSlice = append(newSlice, newSliceValue)
		}
		return newSlice, nil

	// Other kinds of values are OK.
	default:
		return input, nil
	}
}
// cleanse rejects schemas containing references or maps keyed with non-
// strings, and coerces acceptable maps to contain only maps with string keys.
cleanse rejects schemas containing references or maps keyed with non
strings, and coerces acceptable maps to contain only maps with string keys.
// cleanse rejects schemas containing references or maps keyed with non - // strings and coerces acceptable maps to contain only maps with string keys .
func cleanse(input interface{}) (interface{}, error) {
	switch typedInput := input.(type) {
	case map[string]interface{}:
		newMap := make(map[string]interface{})
		for key, value := range typedInput {
			if prohibitedSchemaKeys[key] {
				return nil, fmt.Errorf("schema key %q not compatible with this version of juju", key)
			}
			newValue, err := cleanse(value)
			if err != nil {
				return nil, err
			}
			newMap[key] = newValue
		}
		return newMap, nil
	case map[interface{}]interface{}:
		newMap := make(map[string]interface{})
		for key, value := range typedInput {
			typedKey, ok := key.(string)
			if !ok {
				return nil, errors.New("map keyed with non-string value")
			}
			newMap[typedKey] = value
		}
		return cleanse(newMap)
	case []interface{}:
		newSlice := make([]interface{}, 0)
		for _, sliceValue := range typedInput {
			newSliceValue, err := cleanse(sliceValue)
			if err != nil {
				return nil, errors.New("map keyed with non-string value")
			}
			newSlice = append(newSlice, newSliceValue)
		}
		return newSlice, nil
	default:
		return input, nil
	}
}
func cleanse ( input interface { } ) ( interface { } , error ) { switch typedInput := input . ( type ) { case map [ string ] interface { } : newMap := make ( map [ string ] interface { } ) for key , value := range typedInput { if prohibitedSchemaKeys [ key ] { return nil , fmt . Errorf ( " " , key ) } newValue , err := cleanse ( value ) if err != nil { return nil , err } newMap [ key ] = newValue } return newMap , nil case map [ interface { } ] interface { } : newMap := make ( map [ string ] interface { } ) for key , value := range typedInput { typedKey , ok := key . ( string ) if ! ok { return nil , errors . New ( " " ) } newMap [ typedKey ] = value } return cleanse ( newMap ) case [ ] interface { } : newSlice := make ( [ ] interface { } , 0 ) for _ , sliceValue := range typedInput { newSliceValue , err := cleanse ( sliceValue ) if err != nil { return nil , errors . New ( " " ) } newSlice = append ( newSlice , newSliceValue ) } return newSlice , nil default : return input , nil } }
cleanse rejects schemas containing references or maps keyed with non
strings, and coerces acceptable maps to contain only maps with string keys.
cleanse rejects schemas containing references or maps keyed with non strings and coerces acceptable maps to contain only maps with string keys .
// In this case, recurse in. // Coerce keys to strings and error out if there's a problem; then recurse. // Recurse // Other kinds of values are OK.