github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/provider/ec2/config.go (about) 1 // Copyright 2011, 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package ec2 5 6 import ( 7 "fmt" 8 9 "github.com/juju/schema" 10 "gopkg.in/amz.v3/aws" 11 "gopkg.in/juju/environschema.v1" 12 13 "github.com/juju/juju/environs/config" 14 ) 15 16 const boilerplateConfig = ` 17 # https://juju.ubuntu.com/docs/config-aws.html 18 amazon: 19 type: ec2 20 21 # region specifies the EC2 region. It defaults to us-east-1. 22 # 23 # region: us-east-1 24 25 # access-key holds the EC2 access key. It defaults to the 26 # environment variable AWS_ACCESS_KEY_ID. 27 # 28 # access-key: <secret> 29 30 # secret-key holds the EC2 secret key. It defaults to the 31 # environment variable AWS_SECRET_ACCESS_KEY. 32 # 33 # secret-key: <secret> 34 35 # image-stream chooses a simplestreams stream from which to select 36 # OS images, for example daily or released images (or any other stream 37 # available on simplestreams). 38 # 39 # image-stream: "released" 40 41 # agent-stream chooses a simplestreams stream from which to select tools, 42 # for example released or proposed tools (or any other stream available 43 # on simplestreams). 44 # 45 # agent-stream: "released" 46 47 # Whether or not to refresh the list of available updates for an 48 # OS. The default option of true is recommended for use in 49 # production systems, but disabling this can speed up local 50 # deployments for development or testing. 51 # 52 # enable-os-refresh-update: true 53 54 # Whether or not to perform OS upgrades when machines are 55 # provisioned. The default option of true is recommended for use 56 # in production systems, but disabling this can speed up local 57 # deployments for development or testing. 58 # 59 # enable-os-upgrade: true 60 61 ` 62 63 var configSchema = environschema.Fields{ 64 "access-key": { 65 Description: "The EC2 access key", 66 EnvVar: "AWS_ACCESS_KEY_ID", 67 Type: environschema.Tstring, 68 Mandatory: true, 69 Group: environschema.AccountGroup, 70 }, 71 "secret-key": { 72 Description: "The EC2 secret key", 73 EnvVar: "AWS_SECRET_ACCESS_KEY", 74 Type: environschema.Tstring, 75 Mandatory: true, 76 Secret: true, 77 Group: environschema.AccountGroup, 78 }, 79 "region": { 80 Description: "The EC2 region to use", 81 Type: environschema.Tstring, 82 }, 83 "control-bucket": { 84 Description: "The S3 bucket used to store environment metadata", 85 Type: environschema.Tstring, 86 }, 87 } 88 89 var configFields = func() schema.Fields { 90 fs, _, err := configSchema.ValidationSchema() 91 if err != nil { 92 panic(err) 93 } 94 return fs 95 }() 96 97 var configDefaults = schema.Defaults{ 98 "access-key": "", 99 "secret-key": "", 100 "region": "us-east-1", 101 "control-bucket": "", 102 } 103 104 type environConfig struct { 105 *config.Config 106 attrs map[string]interface{} 107 } 108 109 func (c *environConfig) region() string { 110 return c.attrs["region"].(string) 111 } 112 113 func (c *environConfig) controlBucket() string { 114 return c.attrs["control-bucket"].(string) 115 } 116 117 func (c *environConfig) accessKey() string { 118 return c.attrs["access-key"].(string) 119 } 120 121 func (c *environConfig) secretKey() string { 122 return c.attrs["secret-key"].(string) 123 } 124 125 func (p environProvider) newConfig(cfg *config.Config) (*environConfig, error) { 126 valid, err := p.Validate(cfg, nil) 127 if err != nil { 128 return nil, err 129 } 130 return &environConfig{valid, valid.UnknownAttrs()}, nil 131 } 132 133 // Schema returns the configuration schema for an environment. 134 func (environProvider) Schema() environschema.Fields { 135 fields, err := config.Schema(configSchema) 136 if err != nil { 137 panic(err) 138 } 139 return fields 140 } 141 142 func validateConfig(cfg, old *config.Config) (*environConfig, error) { 143 // Check for valid changes for the base config values. 144 if err := config.Validate(cfg, old); err != nil { 145 return nil, err 146 } 147 validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) 148 if err != nil { 149 return nil, err 150 } 151 152 // Add EC2 specific defaults. 153 providerDefaults := make(map[string]interface{}) 154 155 // Storage. 156 if _, ok := cfg.StorageDefaultBlockSource(); !ok { 157 providerDefaults[config.StorageDefaultBlockSourceKey] = EBS_ProviderType 158 } 159 if len(providerDefaults) > 0 { 160 if cfg, err = cfg.Apply(providerDefaults); err != nil { 161 return nil, err 162 } 163 } 164 ecfg := &environConfig{cfg, validated} 165 166 if ecfg.accessKey() == "" || ecfg.secretKey() == "" { 167 auth, err := aws.EnvAuth() 168 if err != nil || ecfg.accessKey() != "" || ecfg.secretKey() != "" { 169 return nil, fmt.Errorf("environment has no access-key or secret-key") 170 } 171 ecfg.attrs["access-key"] = auth.AccessKey 172 ecfg.attrs["secret-key"] = auth.SecretKey 173 } 174 if _, ok := aws.Regions[ecfg.region()]; !ok { 175 return nil, fmt.Errorf("invalid region name %q", ecfg.region()) 176 } 177 178 if old != nil { 179 attrs := old.UnknownAttrs() 180 if region, _ := attrs["region"].(string); ecfg.region() != region { 181 return nil, fmt.Errorf("cannot change region from %q to %q", region, ecfg.region()) 182 } 183 if bucket, _ := attrs["control-bucket"].(string); ecfg.controlBucket() != bucket { 184 return nil, fmt.Errorf("cannot change control-bucket from %q to %q", bucket, ecfg.controlBucket()) 185 } 186 } 187 188 // ssl-hostname-verification cannot be disabled 189 if !ecfg.SSLHostnameVerification() { 190 return nil, fmt.Errorf("disabling ssh-hostname-verification is not supported") 191 } 192 return ecfg, nil 193 }