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  }