github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/core/description/storageconstraint.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 // StorageConstraintArgs is an argument struct used to create a new internal 12 // storageconstraint type that supports the StorageConstraint interface. 13 type StorageConstraintArgs struct { 14 Pool string 15 Size uint64 16 Count uint64 17 } 18 19 func newStorageConstraint(args StorageConstraintArgs) *storageconstraint { 20 return &storageconstraint{ 21 Version: 1, 22 Pool_: args.Pool, 23 Size_: args.Size, 24 Count_: args.Count, 25 } 26 } 27 28 type storageconstraint struct { 29 Version int `yaml:"version"` 30 31 Pool_ string `yaml:"pool"` 32 Size_ uint64 `yaml:"size"` 33 Count_ uint64 `yaml:"count"` 34 } 35 36 // Pool implements StorageConstraint. 37 func (s *storageconstraint) Pool() string { 38 return s.Pool_ 39 } 40 41 // Size implements StorageConstraint. 42 func (s *storageconstraint) Size() uint64 { 43 return s.Size_ 44 } 45 46 // Count implements StorageConstraint. 47 func (s *storageconstraint) Count() uint64 { 48 return s.Count_ 49 } 50 51 func importStorageConstraints(sourceMap map[string]interface{}) (map[string]*storageconstraint, error) { 52 result := make(map[string]*storageconstraint) 53 for key, value := range sourceMap { 54 source, ok := value.(map[string]interface{}) 55 if !ok { 56 return nil, errors.Errorf("unexpected value for storageconstraint %q, %T", key, value) 57 } 58 constraint, err := importStorageConstraint(source) 59 if err != nil { 60 return nil, errors.Trace(err) 61 } 62 result[key] = constraint 63 } 64 return result, nil 65 } 66 67 // importStorageConstraint constructs a new StorageConstraint from a map representing a serialised 68 // StorageConstraint instance. 69 func importStorageConstraint(source map[string]interface{}) (*storageconstraint, error) { 70 version, err := getVersion(source) 71 if err != nil { 72 return nil, errors.Annotate(err, "storageconstraint version schema check failed") 73 } 74 75 importFunc, ok := storageconstraintDeserializationFuncs[version] 76 if !ok { 77 return nil, errors.NotValidf("version %d", version) 78 } 79 80 return importFunc(source) 81 } 82 83 type storageconstraintDeserializationFunc func(map[string]interface{}) (*storageconstraint, error) 84 85 var storageconstraintDeserializationFuncs = map[int]storageconstraintDeserializationFunc{ 86 1: importStorageConstraintV1, 87 } 88 89 func importStorageConstraintV1(source map[string]interface{}) (*storageconstraint, error) { 90 fields := schema.Fields{ 91 "pool": schema.String(), 92 "size": schema.Uint(), 93 "count": schema.Uint(), 94 } 95 checker := schema.FieldMap(fields, nil) 96 97 coerced, err := checker.Coerce(source, nil) 98 if err != nil { 99 return nil, errors.Annotatef(err, "storageconstraint v1 schema check failed") 100 } 101 valid := coerced.(map[string]interface{}) 102 // From here we know that the map returned from the schema coercion 103 // contains fields of the right type. 104 105 return &storageconstraint{ 106 Version: 1, 107 Pool_: valid["pool"].(string), 108 Size_: valid["size"].(uint64), 109 Count_: valid["count"].(uint64), 110 }, nil 111 }