github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/provider/cloudsigma/config.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloudsigma 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/schema" 9 10 "github.com/juju/juju/environs/config" 11 ) 12 13 var configFields = schema.Fields{} 14 15 var configDefaultFields = schema.Defaults{} 16 17 var configImmutableFields = []string{} 18 19 func validateConfig(cfg *config.Config, old *environConfig) (*environConfig, error) { 20 // Check sanity of juju-level fields. 21 var oldCfg *config.Config 22 if old != nil { 23 oldCfg = old.Config 24 } 25 if err := config.Validate(cfg, oldCfg); err != nil { 26 return nil, errors.Trace(err) 27 } 28 29 // Extract validated provider-specific fields. All of configFields will be 30 // present in validated, and defaults will be inserted if necessary. If the 31 // schema you passed in doesn't quite express what you need, you can make 32 // whatever checks you need here, before continuing. 33 // In particular, if you want to extract (say) credentials from the user's 34 // shell environment variables, you'll need to allow missing values to pass 35 // through the schema by setting a value of schema.Omit in the configFields 36 // map, and then to set and check them at this point. These values *must* be 37 // stored in newAttrs: a Config will be generated on the user's machine only 38 // to begin with, and will subsequently be used on a different machine that 39 // will probably not have those variables set. 40 newAttrs, err := cfg.ValidateUnknownAttrs(configFields, configDefaultFields) 41 if err != nil { 42 return nil, errors.Trace(err) 43 } 44 for field := range configFields { 45 if newAttrs[field] == "" { 46 return nil, errors.Errorf("%s: must not be empty", field) 47 } 48 } 49 50 // If an old config was supplied, check any immutable fields have not changed. 51 if old != nil { 52 for _, field := range configImmutableFields { 53 if old.attrs[field] != newAttrs[field] { 54 return nil, errors.Errorf( 55 "%s: cannot change from %v to %v", 56 field, old.attrs[field], newAttrs[field], 57 ) 58 } 59 } 60 } 61 62 // Merge the validated provider-specific fields into the original config, 63 // to ensure the object we return is internally consistent. 64 newCfg, err := cfg.Apply(newAttrs) 65 if err != nil { 66 return nil, errors.Trace(err) 67 } 68 ecfg := &environConfig{ 69 Config: newCfg, 70 attrs: newAttrs, 71 } 72 73 return ecfg, nil 74 } 75 76 type environConfig struct { 77 *config.Config 78 attrs map[string]interface{} 79 }