Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1289)

Delta Between Two Patch Sets: environs/openstack/config.go

Issue 6858052: Implemented the base of a juju openstack provider. (Closed)
Left Patch Set: Created 5 years, 1 month ago
Right Patch Set: Implemented the base of a juju openstack provider. Created 5 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 package openstack 1 package openstack
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "launchpad.net/juju-core/environs/config" 5 "launchpad.net/juju-core/environs/config"
6 "launchpad.net/juju-core/schema" 6 "launchpad.net/juju-core/schema"
7 "os" 7 "os"
8 ) 8 )
9 9
10 var configChecker = schema.StrictFieldMap( 10 var configChecker = schema.StrictFieldMap(
11 schema.Fields{ 11 schema.Fields{
12 » » "username": schema.String(), 12 » » "username": schema.String(),
13 » » "password": schema.String(), 13 » » "password": schema.String(),
14 » » "region": schema.String(), 14 » » "tenant-name": schema.String(),
15 » » "tenant-id": schema.String(), 15 » » "auth-url": schema.String(),
16 » » "identity-url": schema.String(), 16 » » "region": schema.String(),
gz 2012/11/21 17:28:20 Where possible, use the existing keys names that p
17 » » "container": schema.String(), 17 » » "container": schema.String(),
18 }, 18 },
19 schema.Defaults{ 19 schema.Defaults{
20 » » "username": "", 20 » » "username": "",
21 » » "password": "", 21 » » "password": "",
22 » » "region": "", 22 » » "tenant-name": "",
23 » » "tenant-id": "", 23 » » "auth-url": "",
24 » » "identity-url": "", 24 » » "region": "",
25 » » "container": "", 25 » » "container": "",
26 }, 26 },
27 ) 27 )
28 28
29 type environConfig struct { 29 type environConfig struct {
30 *config.Config 30 *config.Config
31 attrs map[string]interface{} 31 attrs map[string]interface{}
32 } 32 }
33 33
34 func (c *environConfig) region() string { 34 func (c *environConfig) region() string {
35 return c.attrs["region"].(string) 35 return c.attrs["region"].(string)
36 } 36 }
37 37
38 func (c *environConfig) username() string { 38 func (c *environConfig) username() string {
39 return c.attrs["username"].(string) 39 return c.attrs["username"].(string)
40 } 40 }
41 41
42 func (c *environConfig) password() string { 42 func (c *environConfig) password() string {
43 return c.attrs["password"].(string) 43 return c.attrs["password"].(string)
44 } 44 }
45 45
46 func (c *environConfig) tenantId() string { 46 func (c *environConfig) tenantName() string {
gz 2012/11/21 17:28:20 Using tenant-id vs. tenant-name is something we'll
jameinel 2012/11/22 07:19:49 Just to follow up on this, "tenant-name" is what w
47 » return c.attrs["tenant-id"].(string) 47 » return c.attrs["tenant-name"].(string)
48 } 48 }
49 49
50 func (c *environConfig) identityURL() string { 50 func (c *environConfig) authURL() string {
gz 2012/11/21 17:28:20 As above, 'auth-url' instead.
51 » return c.attrs["identity-url"].(string) 51 » return c.attrs["auth-url"].(string)
52 } 52 }
53 53
54 func (c *environConfig) container() string { 54 func (c *environConfig) container() string {
niemeyer 2012/11/22 12:54:14 As we discussed, let's use controlBucket/"control-
dimitern 2012/11/22 13:13:17 Done.
55 return c.attrs["container"].(string) 55 return c.attrs["container"].(string)
56 } 56 }
57 57
58 func (p environProvider) newConfig(cfg *config.Config) (*environConfig, error) { 58 func (p environProvider) newConfig(cfg *config.Config) (*environConfig, error) {
59 valid, err := p.Validate(cfg, nil) 59 valid, err := p.Validate(cfg, nil)
60 if err != nil { 60 if err != nil {
61 return nil, err 61 return nil, err
62 } 62 }
63 return &environConfig{valid, valid.UnknownAttrs()}, nil 63 return &environConfig{valid, valid.UnknownAttrs()}, nil
64 } 64 }
65 65
66 func (p environProvider) Validate(cfg, old *config.Config) (valid *config.Config , err error) { 66 func (p environProvider) Validate(cfg, old *config.Config) (valid *config.Config , err error) {
gz 2012/11/21 17:28:20 Having one big function in the style of the curren
67 v, err := configChecker.Coerce(cfg.UnknownAttrs(), nil) 67 v, err := configChecker.Coerce(cfg.UnknownAttrs(), nil)
68 if err != nil { 68 if err != nil {
69 return nil, err 69 return nil, err
70 } 70 }
71 ecfg := &environConfig{cfg, v.(map[string]interface{})} 71 ecfg := &environConfig{cfg, v.(map[string]interface{})}
72 if ecfg.username() == "" || 72 if ecfg.username() == "" ||
73 ecfg.password() == "" || 73 ecfg.password() == "" ||
74 » » ecfg.tenantId() == "" || 74 » » ecfg.tenantName() == "" ||
75 » » ecfg.identityURL() == "" { 75 » » ecfg.authURL() == "" {
niemeyer 2012/11/22 12:54:14 Can we please have these in the same line? We have
dimitern 2012/11/22 13:13:17 Done.
76 » » // TODO: get goose client to handle this 76 » » // TODO(dimitern): get goose client to handle this
77 auth, err := dummyEnvAuth() 77 auth, err := dummyEnvAuth()
78 » » if err != nil || 78 » » if err != nil {
79 » » » ecfg.username() != "" || 79 » » » return nil, fmt.Errorf("environment has no username, pas sword, tenant-name, or auth-url")
rog 2012/11/21 17:26:12 perhaps these checks should be in dummyEnvAuth, an
niemeyer 2012/11/22 12:54:14 "OpenStack environment requires options username,
dimitern 2012/11/22 13:13:17 Done.
80 » » » ecfg.password() != "" ||
81 » » » ecfg.tenantId() != "" ||
82 » » » ecfg.identityURL() != "" {
83 » » » return nil, fmt.Errorf("environment has no username, pas sword, tenant-id, or identity-url")
84 } 80 }
85 ecfg.attrs["username"] = auth.username 81 ecfg.attrs["username"] = auth.username
86 ecfg.attrs["password"] = auth.password 82 ecfg.attrs["password"] = auth.password
87 » » ecfg.attrs["tenant-id"] = auth.tenantId 83 » » ecfg.attrs["tenant-name"] = auth.tenantName
88 » » ecfg.attrs["identity-url"] = auth.identityURL 84 » » ecfg.attrs["auth-url"] = auth.authURL
89 } 85 }
90 // We cannot validate the region name, since each OS installation 86 // We cannot validate the region name, since each OS installation
91 // can have its own region names - only after authentication the 87 // can have its own region names - only after authentication the
92 // region names are known (from the service endpoints) 88 // region names are known (from the service endpoints)
93 89
94 if old != nil { 90 if old != nil {
95 attrs := old.UnknownAttrs() 91 attrs := old.UnknownAttrs()
96 if region, _ := attrs["region"].(string); ecfg.region() != regio n { 92 if region, _ := attrs["region"].(string); ecfg.region() != regio n {
97 return nil, fmt.Errorf("cannot change region from %q to %q", region, ecfg.region()) 93 return nil, fmt.Errorf("cannot change region from %q to %q", region, ecfg.region())
98 } 94 }
99 if container, _ := attrs["container"].(string); ecfg.container() != container { 95 if container, _ := attrs["container"].(string); ecfg.container() != container {
100 return nil, fmt.Errorf("cannot change container from %q to %q", container, ecfg.container()) 96 return nil, fmt.Errorf("cannot change container from %q to %q", container, ecfg.container())
101 } 97 }
102 } 98 }
103 99
104 switch cfg.FirewallMode() { 100 switch cfg.FirewallMode() {
105 case config.FwDefault: 101 case config.FwDefault:
106 ecfg.attrs["firewall-mode"] = config.FwInstance 102 ecfg.attrs["firewall-mode"] = config.FwInstance
107 case config.FwInstance, config.FwGlobal: 103 case config.FwInstance, config.FwGlobal:
108 default: 104 default:
109 return nil, fmt.Errorf("unsupported firewall mode: %q", cfg.Fire wallMode()) 105 return nil, fmt.Errorf("unsupported firewall mode: %q", cfg.Fire wallMode())
110 } 106 }
111 107
112 return cfg.Apply(ecfg.attrs) 108 return cfg.Apply(ecfg.attrs)
113 } 109 }
114 110
115 // TODO: temporarily here, until goose client handles this 111 // TODO(dimitern): temporarily here, until goose client handles this
gz 2012/11/21 17:28:20 You should be able to use Credentials from the ide
116 type dummyAuth struct { 112 type dummyAuth struct {
niemeyer 2012/11/22 12:54:14 Why dummy? This looks quite real. I think it shoul
dimitern 2012/11/22 13:13:17 This is here only because the goose identity packa
117 » username, password, tenantId, identityURL string 113 » username, password, tenantName, authURL string
118 } 114 }
119 115
120 func dummyEnvAuth() (dummyAuth, error) { 116 func dummyEnvAuth() (dummyAuth, error) {
gz 2012/11/21 17:28:20 Just use CredentialsFromEnv from the goose identit
niemeyer 2012/11/22 12:54:14 getEnvAuth?
dimitern 2012/11/22 13:13:17 Done.
121 » return dummyAuth{ 117 » auth := dummyAuth{
122 » » username: os.Getenv("OS_USERNAME"), 118 » » username: os.Getenv("OS_USERNAME"),
123 » » password: os.Getenv("OS_PASSWORD"), 119 » » password: os.Getenv("OS_PASSWORD"),
124 » » tenantId: os.Getenv("OS_TENANT_NAME"), 120 » » tenantName: os.Getenv("OS_TENANT_NAME"),
125 » » identityURL: os.Getenv("OS_AUTH_URL"), 121 » » authURL: os.Getenv("OS_AUTH_URL"),
126 » }, nil 122 » }
123 » if auth.username == "" ||
124 » » auth.password == "" ||
125 » » auth.tenantName == "" ||
126 » » auth.authURL == "" {
niemeyer 2012/11/22 12:54:14 Same line as well, please.
dimitern 2012/11/22 13:13:17 Done.
127 » » return auth, fmt.Errorf("missing username, password, tenant-name , or auth-url")
niemeyer 2012/11/22 12:54:14 This function can be simplified to return (auth en
128 » }
129 » return auth, nil
127 } 130 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld 204d58d