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  }