github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/gce/config.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package gce 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/schema" 9 "gopkg.in/juju/environschema.v1" 10 11 "github.com/juju/juju/environs/config" 12 ) 13 14 // TODO(ericsnow) While not strictly config-related, we could use some 15 // mechanism by which we can validate the values we've hard-coded in 16 // this provider match up with the external authoritative sources. One 17 // example of this is the data stored in instancetypes.go. Similarly 18 // we should also ensure the cloud-images metadata is correct and 19 // up-to-date, though that is more the responsibility of that team. 20 // Regardless, it may be useful to include a tool somewhere in juju 21 // that we can use to validate this provider's potentially out-of-date 22 // data. 23 24 var configSchema = environschema.Fields{} 25 26 // configFields is the spec for each GCE config value's type. 27 var configFields = func() schema.Fields { 28 fs, _, err := configSchema.ValidationSchema() 29 if err != nil { 30 panic(err) 31 } 32 return fs 33 }() 34 35 var configImmutableFields = []string{} 36 37 var configDefaults = schema.Defaults{} 38 39 type environConfig struct { 40 config *config.Config 41 attrs map[string]interface{} 42 } 43 44 // newConfig builds a new environConfig from the provided Config 45 // filling in default values, if any. It returns an error if the 46 // resulting configuration is not valid. 47 func newConfig(cfg, old *config.Config) (*environConfig, error) { 48 // Ensure that the provided config is valid. 49 if err := config.Validate(cfg, old); err != nil { 50 return nil, errors.Trace(err) 51 } 52 attrs, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) 53 if err != nil { 54 return nil, errors.Trace(err) 55 } 56 57 if old != nil { 58 // There's an old configuration. Validate it so that any 59 // default values are correctly coerced for when we check 60 // the old values later. 61 oldEcfg, err := newConfig(old, nil) 62 if err != nil { 63 return nil, errors.Annotatef(err, "invalid base config") 64 } 65 for _, attr := range configImmutableFields { 66 oldv, newv := oldEcfg.attrs[attr], attrs[attr] 67 if oldv != newv { 68 return nil, errors.Errorf( 69 "%s: cannot change from %v to %v", 70 attr, oldv, newv, 71 ) 72 } 73 } 74 } 75 76 ecfg := &environConfig{ 77 config: cfg, 78 attrs: attrs, 79 } 80 return ecfg, nil 81 }