launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/provider/joyent/config.go (about)

     1  // Copyright 2013 Joyent Inc.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package joyent
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  
    10  	"launchpad.net/juju-core/environs/config"
    11  	"launchpad.net/juju-core/schema"
    12  	"launchpad.net/juju-core/utils"
    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  const boilerplateConfig = `joyent:
    18    type: joyent
    19  
    20    # SDC config
    21    # Can be set via env variables, or specified here
    22    # sdc-user: <secret>
    23    # Can be set via env variables, or specified here
    24    # sdc-key-id: <secret>
    25    # region defaults to us-west-1, override if required
    26    # sdc-region: us-west-1
    27  
    28    # Manta config
    29    # Can be set via env variables, or specified here
    30    # manta-user: <secret>
    31    # Can be set via env variables, or specified here
    32    # manta-key-id: <secret>
    33    # region defaults to us-east, override if required
    34    # manta-region: us-east
    35  `
    36  
    37  const (
    38  	SdcAccount = "SDC_ACCOUNT"
    39  	SdcKeyId   = "SDC_KEY_ID"
    40  	SdcUrl     = "SDC_URL"
    41  	MantaUser  = "MANTA_USER"
    42  	MantaKeyId = "MANTA_KEY_ID"
    43  	MantaUrl   = "MANTA_URL"
    44  )
    45  
    46  var environmentVariables = map[string]string{
    47  	"sdc-user":     SdcAccount,
    48  	"sdc-key-id":   SdcKeyId,
    49  	"manta-user":   MantaUser,
    50  	"manta-key-id": MantaKeyId,
    51  }
    52  
    53  var configFields = schema.Fields{
    54  	"sdc-user":     schema.String(),
    55  	"sdc-key-id":   schema.String(),
    56  	"sdc-region":   schema.String(),
    57  	"manta-user":   schema.String(),
    58  	"manta-key-id": schema.String(),
    59  	"manta-region": schema.String(),
    60  	"control-dir":  schema.String(),
    61  }
    62  
    63  var configDefaultFields = schema.Defaults{
    64  	"sdc-region":   "us-west-1",
    65  	"manta-region": "us-east",
    66  }
    67  
    68  var configSecretFields = []string{
    69  	"sdc-user",
    70  	"sdc-key-id",
    71  	"manta-user",
    72  	"manta-key-id",
    73  }
    74  
    75  var configImmutableFields = []string{
    76  	"sdc-region",
    77  	"manta-region",
    78  }
    79  
    80  func prepareConfig(cfg *config.Config) (*config.Config, error) {
    81  	// Turn an incomplete config into a valid one, if possible.
    82  	attrs := cfg.UnknownAttrs()
    83  
    84  	if _, ok := attrs["control-dir"]; !ok {
    85  		uuid, err := utils.NewUUID()
    86  		if err != nil {
    87  			return nil, err
    88  		}
    89  		attrs["control-bucket"] = fmt.Sprintf("%x", uuid.Raw())
    90  	}
    91  
    92  	// Read env variables
    93  	for _, field := range configSecretFields {
    94  		// If field is not set, get it from env variables
    95  		if attrs[field] == "" {
    96  			localEnvVariable := os.Getenv(environmentVariables[field])
    97  			if localEnvVariable != "" {
    98  				attrs[field] = localEnvVariable
    99  			} else {
   100  				return nil, fmt.Errorf("cannot get %s value from environment variables %s", field, environmentVariables[field])
   101  			}
   102  		}
   103  	}
   104  
   105  	return cfg.Apply(attrs)
   106  }
   107  
   108  func validateConfig(cfg *config.Config, old *environConfig) (*environConfig, error) {
   109  	// Check sanity of juju-level fields.
   110  	var oldCfg *config.Config
   111  	if old != nil {
   112  		oldCfg = old.Config
   113  	}
   114  	if err := config.Validate(cfg, oldCfg); err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	// Extract validated provider-specific fields. All of configFields will be
   119  	// present in validated, and defaults will be inserted if necessary. If the
   120  	// schema you passed in doesn't quite express what you need, you can make
   121  	// whatever checks you need here, before continuing.
   122  	// In particular, if you want to extract (say) credentials from the user's
   123  	// shell environment variables, you'll need to allow missing values to pass
   124  	// through the schema by setting a value of schema.Omit in the configFields
   125  	// map, and then to set and check them at this point. These values *must* be
   126  	// stored in newAttrs: a Config will be generated on the user's machine only
   127  	// to begin with, and will subsequently be used on a different machine that
   128  	// will probably not have those variables set.
   129  	newAttrs, err := cfg.ValidateUnknownAttrs(configFields, configDefaultFields)
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  	for field := range configFields {
   134  		if newAttrs[field] == "" {
   135  			return nil, fmt.Errorf("%s: must not be empty", field)
   136  		}
   137  	}
   138  
   139  	// If an old config was supplied, check any immutable fields have not changed.
   140  	if old != nil {
   141  		for _, field := range configImmutableFields {
   142  			if old.attrs[field] != newAttrs[field] {
   143  				return nil, fmt.Errorf(
   144  					"%s: cannot change from %v to %v",
   145  					field, old.attrs[field], newAttrs[field],
   146  				)
   147  			}
   148  		}
   149  	}
   150  
   151  	// Merge the validated provider-specific fields into the original config,
   152  	// to ensure the object we return is internally consistent.
   153  	newCfg, err := cfg.Apply(newAttrs)
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  	return &environConfig{
   158  		Config: newCfg,
   159  		attrs:  newAttrs,
   160  	}, nil
   161  }
   162  
   163  type environConfig struct {
   164  	*config.Config
   165  	attrs map[string]interface{}
   166  }
   167  
   168  func (ecfg *environConfig) sdcRegion() string {
   169  	return ecfg.attrs["sdc-region"].(string)
   170  }
   171  
   172  func (ecfg *environConfig) sdcUser() string {
   173  	return ecfg.attrs["sdc-user"].(string)
   174  }
   175  
   176  func (ecfg *environConfig) sdcKeyId() string {
   177  	return ecfg.attrs["sdc-key-id"].(string)
   178  }
   179  
   180  func (ecfg *environConfig) mantaRegion() string {
   181  	return ecfg.attrs["manta-region"].(string)
   182  }
   183  
   184  func (ecfg *environConfig) mantaUser() string {
   185  	return ecfg.attrs["manta-user"].(string)
   186  }
   187  
   188  func (ecfg *environConfig) mantaKeyId() string {
   189  	return ecfg.attrs["manta-key-id"].(string)
   190  }
   191  
   192  func (c *environConfig) controlDir() string {
   193  	return c.attrs["control-dir"].(string)
   194  }