github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/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/altoros/gosigma"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/schema"
    10  	"github.com/juju/utils"
    11  
    12  	"github.com/juju/juju/environs/config"
    13  )
    14  
    15  // boilerplateConfig will be shown in help output, so please keep it up to
    16  // date when you change environment configuration below.
    17  var boilerplateConfig = `# https://juju.ubuntu.com/docs/config-cloudsigma.html
    18  cloudsigma:
    19      type: cloudsigma
    20  
    21      # region holds the cloudsigma region (zrh, lvs, ...).
    22      #
    23      # region: <your region>
    24  
    25      # credentials for CloudSigma account
    26      #
    27      # username: <your username>
    28      # password: <secret>
    29  `
    30  
    31  const (
    32  	defaultStoragePort = 8040
    33  )
    34  
    35  var configFields = schema.Fields{
    36  	"username": schema.String(),
    37  	"password": schema.String(),
    38  	"region":   schema.String(),
    39  }
    40  
    41  var configDefaultFields = schema.Defaults{
    42  	"username": "",
    43  	"password": "",
    44  	"region":   gosigma.DefaultRegion,
    45  }
    46  
    47  var configSecretFields = []string{
    48  	"password",
    49  }
    50  
    51  var configImmutableFields = []string{
    52  	"region",
    53  }
    54  
    55  func prepareConfig(cfg *config.Config) (*config.Config, error) {
    56  	// Turn an incomplete config into a valid one, if possible.
    57  	attrs := cfg.AllAttrs()
    58  
    59  	if _, ok := attrs["uuid"]; !ok {
    60  		uuid, err := utils.NewUUID()
    61  		if err != nil {
    62  			return nil, errors.Trace(err)
    63  		}
    64  		attrs["uuid"] = uuid.String()
    65  	}
    66  
    67  	return cfg.Apply(attrs)
    68  }
    69  
    70  func validateConfig(cfg *config.Config, old *environConfig) (*environConfig, error) {
    71  	// Check sanity of juju-level fields.
    72  	var oldCfg *config.Config
    73  	if old != nil {
    74  		oldCfg = old.Config
    75  	}
    76  	if err := config.Validate(cfg, oldCfg); err != nil {
    77  		return nil, errors.Trace(err)
    78  	}
    79  
    80  	// Extract validated provider-specific fields. All of configFields will be
    81  	// present in validated, and defaults will be inserted if necessary. If the
    82  	// schema you passed in doesn't quite express what you need, you can make
    83  	// whatever checks you need here, before continuing.
    84  	// In particular, if you want to extract (say) credentials from the user's
    85  	// shell environment variables, you'll need to allow missing values to pass
    86  	// through the schema by setting a value of schema.Omit in the configFields
    87  	// map, and then to set and check them at this point. These values *must* be
    88  	// stored in newAttrs: a Config will be generated on the user's machine only
    89  	// to begin with, and will subsequently be used on a different machine that
    90  	// will probably not have those variables set.
    91  	newAttrs, err := cfg.ValidateUnknownAttrs(configFields, configDefaultFields)
    92  	if err != nil {
    93  		return nil, errors.Trace(err)
    94  	}
    95  	for field := range configFields {
    96  		if newAttrs[field] == "" {
    97  			return nil, errors.Errorf("%s: must not be empty", field)
    98  		}
    99  	}
   100  
   101  	// If an old config was supplied, check any immutable fields have not changed.
   102  	if old != nil {
   103  		for _, field := range configImmutableFields {
   104  			if old.attrs[field] != newAttrs[field] {
   105  				return nil, errors.Errorf(
   106  					"%s: cannot change from %v to %v",
   107  					field, old.attrs[field], newAttrs[field],
   108  				)
   109  			}
   110  		}
   111  	}
   112  
   113  	// Merge the validated provider-specific fields into the original config,
   114  	// to ensure the object we return is internally consistent.
   115  	newCfg, err := cfg.Apply(newAttrs)
   116  	if err != nil {
   117  		return nil, errors.Trace(err)
   118  	}
   119  	ecfg := &environConfig{
   120  		Config: newCfg,
   121  		attrs:  newAttrs,
   122  	}
   123  
   124  	return ecfg, nil
   125  }
   126  
   127  // configChanged checks if CloudSigma client environment configuration is changed
   128  func (c environConfig) clientConfigChanged(newConfig *environConfig) bool {
   129  	// compare
   130  	if newConfig.region() != c.region() || newConfig.username() != c.username() ||
   131  		newConfig.password() != c.password() {
   132  		return true
   133  	}
   134  
   135  	return false
   136  }
   137  
   138  type environConfig struct {
   139  	*config.Config
   140  	attrs map[string]interface{}
   141  }
   142  
   143  func (c environConfig) region() string {
   144  	return c.attrs["region"].(string)
   145  }
   146  
   147  func (c environConfig) username() string {
   148  	return c.attrs["username"].(string)
   149  }
   150  
   151  func (c environConfig) password() string {
   152  	return c.attrs["password"].(string)
   153  }