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 }