github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/vsphere/config.go (about)

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