github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/provider/vsphere/config.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // +build !gccgo
     5  
     6  package vsphere
     7  
     8  import (
     9  	"github.com/juju/errors"
    10  	"github.com/juju/schema"
    11  
    12  	"github.com/juju/juju/environs/config"
    13  )
    14  
    15  // The vmware-specific config keys.
    16  const (
    17  	cfgExternalNetwork = "external-network"
    18  )
    19  
    20  // configFields is the spec for each vmware config value's type.
    21  var (
    22  	configFields = schema.Fields{
    23  		cfgExternalNetwork: schema.String(),
    24  	}
    25  
    26  	requiredFields = []string{}
    27  
    28  	configDefaults = schema.Defaults{
    29  		cfgExternalNetwork: "",
    30  	}
    31  
    32  	configImmutableFields = []string{}
    33  )
    34  
    35  type environConfig struct {
    36  	*config.Config
    37  	attrs map[string]interface{}
    38  }
    39  
    40  // newConfig builds a new environConfig from the provided Config and
    41  // returns it.
    42  func newConfig(cfg *config.Config) *environConfig {
    43  	return &environConfig{
    44  		Config: cfg,
    45  		attrs:  cfg.UnknownAttrs(),
    46  	}
    47  }
    48  
    49  // newValidConfig builds a new environConfig from the provided Config
    50  // and returns it. The resulting config values are validated.
    51  func newValidConfig(cfg *config.Config, defaults map[string]interface{}) (*environConfig, error) {
    52  	// Ensure that the provided config is valid.
    53  	if err := config.Validate(cfg, nil); err != nil {
    54  		return nil, errors.Trace(err)
    55  	}
    56  
    57  	// Apply the defaults and coerce/validate the custom config attrs.
    58  	validated, err := cfg.ValidateUnknownAttrs(configFields, defaults)
    59  	if err != nil {
    60  		return nil, errors.Trace(err)
    61  	}
    62  	validCfg, err := cfg.Apply(validated)
    63  	if err != nil {
    64  		return nil, errors.Trace(err)
    65  	}
    66  
    67  	// Build the config.
    68  	ecfg := newConfig(validCfg)
    69  
    70  	// Do final validation.
    71  	if err := ecfg.validate(); err != nil {
    72  		return nil, errors.Trace(err)
    73  	}
    74  
    75  	return ecfg, nil
    76  }
    77  
    78  func (c *environConfig) externalNetwork() string {
    79  	return c.attrs[cfgExternalNetwork].(string)
    80  }
    81  
    82  // validate checks vmware-specific config values.
    83  func (c environConfig) validate() error {
    84  	// All fields must be populated, even with just the default.
    85  	for _, field := range requiredFields {
    86  		if c.attrs[field].(string) == "" {
    87  			return errors.Errorf("%s: must not be empty", field)
    88  		}
    89  	}
    90  	return nil
    91  }
    92  
    93  // update applies changes from the provided config to the env config.
    94  // Changes to any immutable attributes result in an error.
    95  func (c *environConfig) update(cfg *config.Config) error {
    96  	// Validate the updates. newValidConfig does not modify the "known"
    97  	// config attributes so it is safe to call Validate here first.
    98  	if err := config.Validate(cfg, c.Config); err != nil {
    99  		return errors.Trace(err)
   100  	}
   101  
   102  	updates, err := newValidConfig(cfg, configDefaults)
   103  	if err != nil {
   104  		return errors.Trace(err)
   105  	}
   106  
   107  	// Check that no immutable fields have changed.
   108  	attrs := updates.UnknownAttrs()
   109  	for _, field := range configImmutableFields {
   110  		if attrs[field] != c.attrs[field] {
   111  			return errors.Errorf("%s: cannot change from %v to %v", field, c.attrs[field], attrs[field])
   112  		}
   113  	}
   114  
   115  	// Apply the updates.
   116  	c.Config = cfg
   117  	c.attrs = cfg.UnknownAttrs()
   118  	return nil
   119  }