| OLD | NEW |
| 1 package ec2 | 1 package ec2 |
| 2 | 2 |
| 3 import ( | 3 import ( |
| 4 "fmt" | 4 "fmt" |
| 5 "launchpad.net/goamz/aws" | 5 "launchpad.net/goamz/aws" |
| 6 "launchpad.net/juju-core/environs" | 6 "launchpad.net/juju-core/environs" |
| 7 "launchpad.net/juju-core/environs/config" |
| 7 "launchpad.net/juju-core/schema" | 8 "launchpad.net/juju-core/schema" |
| 8 ) | 9 ) |
| 9 | 10 |
| 10 // providerConfig is a placeholder for any config information | 11 type environProvider struct{} |
| 11 // that we will have in a configuration file. | 12 |
| 12 type providerConfig struct { | 13 func init() { |
| 13 » name string | 14 » environs.RegisterProvider("ec2", environProvider{}) |
| 14 » region string | |
| 15 » auth aws.Auth | |
| 16 » bucket string | |
| 17 » publicBucket string | |
| 18 » authorizedKeys string | |
| 19 } | 15 } |
| 20 | 16 |
| 21 var configChecker = schema.StrictFieldMap( | 17 func (p environProvider) New(cfg *config.Config) (environs.Environ, error) { |
| 18 » env := &environ{} |
| 19 » if err := env.SetConfig(cfg); err != nil { |
| 20 » » return nil, err |
| 21 » } |
| 22 » return env, nil |
| 23 } |
| 24 |
| 25 func (environProvider) ComposeConfig(base *config.Config, changes map[string]int
erface{}) (new *config.Config, err error) { |
| 26 » // Create a fresh map. |
| 27 » final := map[string]interface{}{} |
| 28 » for k, v := range changes { |
| 29 » » final[k] = v |
| 30 » } |
| 31 |
| 32 » // Insert missing settings from base, if available. |
| 33 » if base != nil { |
| 34 » » m := base.Map() |
| 35 » » baseRegion := m["region"].(string) |
| 36 » » if region, ok := final["region"].(string); !ok { |
| 37 » » » final["region"] = baseRegion |
| 38 » » } else if region != baseRegion { |
| 39 » » » return nil, fmt.Errorf("mismatched regions") |
| 40 » » } |
| 41 » » baseBucket := m["control-bucket"].(string) |
| 42 » » if bucket, ok := final["control-bucket"].(string); !ok { |
| 43 » » » final["control-bucket"] = baseBucket |
| 44 » » } else if bucket != baseBucket { |
| 45 » » » return nil, fmt.Errorf("mismatched control-buckets") |
| 46 » » } |
| 47 » » if final["public-bucket"] == nil { |
| 48 » » » if publicBucket, found := m["public-bucket"]; found { |
| 49 » » » » final["public-bucket"] = publicBucket |
| 50 » » » } |
| 51 » » } |
| 52 » » if final["access-key"] == nil && final["secret-key"] == nil { |
| 53 » » » final["access-key"] = m["access-key"] |
| 54 » » » final["secret-key"] = m["secret-key"] |
| 55 » » } |
| 56 » } |
| 57 |
| 58 » // Insert default region if unset, and check region has endpoint. |
| 59 » if region, found := final["region"]; !found { |
| 60 » » final["region"] = "us-east-1" |
| 61 » } else if sregion, ok := region.(string); ok && sregion == "" { |
| 62 » » final["region"] = "us-east-1" |
| 63 » } else if ok { |
| 64 » » if awsRegion, found := aws.Regions[sregion]; found { |
| 65 » » » if awsRegion.EC2Endpoint == "" { |
| 66 » » » » return nil, fmt.Errorf("no EC2 endpoint found fo
r region %q", region) |
| 67 » » » } |
| 68 » » } else { |
| 69 » » » return nil, fmt.Errorf("unknown AWS region %q", region) |
| 70 » » } |
| 71 » } // else let the final checker deal with the gibberish consistently |
| 72 |
| 73 » // Insert default AWS auth if unset. |
| 74 » accessKey, _ := final["access-key"].(string) |
| 75 » secretKey, _ := final["secret-key"].(string) |
| 76 » if accessKey == "" || secretKey == "" { |
| 77 » » if accessKey != "" { |
| 78 » » » return nil, fmt.Errorf("environment has access-key but n
o secret-key") |
| 79 » » } |
| 80 » » if secretKey != "" { |
| 81 » » » return nil, fmt.Errorf("environment has secret-key but n
o access-key") |
| 82 » » } |
| 83 » » auth, err := aws.EnvAuth() |
| 84 » » if err != nil { |
| 85 » » » return nil, err |
| 86 » » } |
| 87 » » final["access-key"] = auth.AccessKey |
| 88 » » final["secret-key"] = auth.SecretKey |
| 89 » } |
| 90 » return config.Compose(base, final, checker) |
| 91 } |
| 92 |
| 93 var checker = config.Checker( |
| 22 schema.Fields{ | 94 schema.Fields{ |
| 23 » » "name": schema.String(), | 95 » » "type": schema.Const("ec2"), |
| 24 » » "type": schema.Const("ec2"), | 96 » » "region": schema.ContentString(), |
| 25 » » "access-key": schema.String(), | 97 » » "control-bucket": schema.ContentString(), |
| 26 » » "secret-key": schema.String(), | 98 » » "public-bucket": schema.String(), |
| 27 » » "region": schema.String(), | 99 » » "access-key": schema.ContentString(), |
| 28 » » "control-bucket": schema.String(), | 100 » » "secret-key": schema.ContentString(), |
| 29 » » "public-bucket": schema.String(), | 101 » }, |
| 30 » » "authorized-keys": schema.String(), | 102 » schema.Optional{ |
| 31 » » "authorized-keys-path": schema.String(), | |
| 32 » }, []string{ | |
| 33 » » "access-key", | |
| 34 » » "secret-key", | |
| 35 » » "region", | |
| 36 » » "authorized-keys", | |
| 37 » » "authorized-keys-path", | |
| 38 "public-bucket", | 103 "public-bucket", |
| 39 }, | 104 }, |
| 40 ) | 105 ) |
| 41 | |
| 42 func (p environProvider) NewConfig(config map[string]interface{}) (cfg environs.
EnvironConfig, err error) { | |
| 43 v, err := configChecker.Coerce(config, nil) | |
| 44 if err != nil { | |
| 45 return nil, err | |
| 46 } | |
| 47 m := v.(schema.MapType) | |
| 48 var c providerConfig | |
| 49 | |
| 50 c.name = m["name"].(string) | |
| 51 c.bucket = m["control-bucket"].(string) | |
| 52 c.publicBucket = maybeString(m["public-bucket"], "") | |
| 53 c.auth.AccessKey = maybeString(m["access-key"], "") | |
| 54 c.auth.SecretKey = maybeString(m["secret-key"], "") | |
| 55 if c.auth.AccessKey == "" || c.auth.SecretKey == "" { | |
| 56 if c.auth.AccessKey != "" { | |
| 57 return nil, fmt.Errorf("environment has access-key but n
o secret-key") | |
| 58 } | |
| 59 if c.auth.SecretKey != "" { | |
| 60 return nil, fmt.Errorf("environment has secret-key but n
o access-key") | |
| 61 } | |
| 62 c.auth, err = aws.EnvAuth() | |
| 63 if err != nil { | |
| 64 return | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 regionName := maybeString(m["region"], "us-east-1") | |
| 69 if _, ok := aws.Regions[regionName]; !ok { | |
| 70 return nil, fmt.Errorf("invalid region name %q", regionName) | |
| 71 } | |
| 72 c.region = regionName | |
| 73 c.authorizedKeys = maybeString(m["authorized-keys"], "") | |
| 74 authorizedKeysPath := maybeString(m["authorized-keys-path"], "") | |
| 75 if c.authorizedKeys == "" { | |
| 76 c.authorizedKeys, err = authorizedKeys(authorizedKeysPath) | |
| 77 if err != nil { | |
| 78 return nil, err | |
| 79 } | |
| 80 } else if authorizedKeysPath != "" { | |
| 81 return nil, fmt.Errorf("environment has both authorized-keys and
authorized-keys-path") | |
| 82 } | |
| 83 return &c, nil | |
| 84 } | |
| 85 | |
| 86 func maybeString(x interface{}, dflt string) string { | |
| 87 if x == nil { | |
| 88 return dflt | |
| 89 } | |
| 90 return x.(string) | |
| 91 } | |
| OLD | NEW |