github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/core/description/storagepool.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package description 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/schema" 9 ) 10 11 type storagepools struct { 12 Version int `yaml:"version"` 13 Pools_ []*storagepool `yaml:"pools"` 14 } 15 16 type storagepool struct { 17 Name_ string `yaml:"name"` 18 Provider_ string `yaml:"provider"` 19 Attributes_ map[string]interface{} `yaml:"attributes"` 20 } 21 22 // StoragePoolArgs is an argument struct used to add a storage pool to the 23 // Model. 24 type StoragePoolArgs struct { 25 Name string 26 Provider string 27 Attributes map[string]interface{} 28 } 29 30 func newStoragePool(args StoragePoolArgs) *storagepool { 31 return &storagepool{ 32 Name_: args.Name, 33 Provider_: args.Provider, 34 Attributes_: args.Attributes, 35 } 36 } 37 38 // Name implements StoragePool. 39 func (s *storagepool) Name() string { 40 return s.Name_ 41 } 42 43 // Provider implements StoragePool. 44 func (s *storagepool) Provider() string { 45 return s.Provider_ 46 } 47 48 // Name implements StoragePool. 49 func (s *storagepool) Attributes() map[string]interface{} { 50 return s.Attributes_ 51 } 52 53 func importStoragePools(source map[string]interface{}) ([]*storagepool, error) { 54 checker := versionedChecker("pools") 55 coerced, err := checker.Coerce(source, nil) 56 if err != nil { 57 return nil, errors.Annotatef(err, "storagepools version schema check failed") 58 } 59 valid := coerced.(map[string]interface{}) 60 61 version := int(valid["version"].(int64)) 62 importFunc, ok := storagePoolDeserializationFuncs[version] 63 if !ok { 64 return nil, errors.NotValidf("version %d", version) 65 } 66 sourceList := valid["pools"].([]interface{}) 67 return importStoragePoolList(sourceList, importFunc) 68 } 69 70 func importStoragePoolList(sourceList []interface{}, importFunc storagePoolDeserializationFunc) ([]*storagepool, error) { 71 result := make([]*storagepool, 0, len(sourceList)) 72 for i, value := range sourceList { 73 source, ok := value.(map[string]interface{}) 74 if !ok { 75 return nil, errors.Errorf("unexpected value for storagepool %d, %T", i, value) 76 } 77 pool, err := importFunc(source) 78 if err != nil { 79 return nil, errors.Annotatef(err, "storagepool %d", i) 80 } 81 result = append(result, pool) 82 } 83 return result, nil 84 } 85 86 type storagePoolDeserializationFunc func(map[string]interface{}) (*storagepool, error) 87 88 var storagePoolDeserializationFuncs = map[int]storagePoolDeserializationFunc{ 89 1: importStoragePoolV1, 90 } 91 92 func importStoragePoolV1(source map[string]interface{}) (*storagepool, error) { 93 fields := schema.Fields{ 94 "name": schema.String(), 95 "provider": schema.String(), 96 "attributes": schema.StringMap(schema.Any()), 97 } 98 99 checker := schema.FieldMap(fields, nil) // no defaults 100 101 coerced, err := checker.Coerce(source, nil) 102 if err != nil { 103 return nil, errors.Annotatef(err, "storagepool v1 schema check failed") 104 } 105 valid := coerced.(map[string]interface{}) 106 // From here we know that the map returned from the schema coercion 107 // contains fields of the right type. 108 result := &storagepool{ 109 Name_: valid["name"].(string), 110 Provider_: valid["provider"].(string), 111 Attributes_: valid["attributes"].(map[string]interface{}), 112 } 113 114 return result, nil 115 }