Status: | Merged |
---|---|
Approved by: | John A Meinel |
Approved revision: | 99 |
Merge reported by: | John A Meinel |
Merged at revision: | not available |
Proposed branch: | lp:goose |
Merge into: | lp:~go-bot/goose/test |
Diff against target: |
2679 lines (+931/-386) 32 files modified
client/client.go (+2/-0) client/client_test.go (+5/-3) client/live_test.go (+5/-5) client/local_test.go (+10/-2) goose.go (+3/-0) http/client.go (+1/-0) http/client_test.go (+51/-7) identity/identity.go (+9/-3) identity/identity_test.go (+51/-0) identity/keypair.go (+41/-0) identity/keystone.go (+89/-0) identity/local_test.go (+22/-1) identity/userpass.go (+1/-75) nova/json.go (+167/-66) nova/json_test.go (+1/-1) nova/local_test.go (+7/-5) nova/nova.go (+19/-24) nova/nova_test.go (+2/-2) swift/local_test.go (+2/-1) testservices/identityservice/identityservice.go (+1/-0) testservices/identityservice/keypair.go (+123/-0) testservices/identityservice/keypair_test.go (+130/-0) testservices/identityservice/legacy.go (+4/-0) testservices/identityservice/userpass.go (+5/-3) testservices/novaservice/service.go (+38/-38) testservices/novaservice/service_http.go (+12/-35) testservices/novaservice/service_http_test.go (+34/-49) testservices/novaservice/service_test.go (+61/-61) testservices/openstackservice/openstack.go (+27/-3) tools/secgroup-delete-all/main_test.go (+2/-2) version.go (+3/-0) version_test.go (+3/-0) |
To merge this branch: | bzr merge lp:goose |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+163468@code.launchpad.net |
Commit message
Merge trunk into test branch.
Description of the change
Seeing if we get proper test hook triggers.
To post a comment you must log in.
Revision history for this message
Go Bot (go-bot) wrote : | # |
Revision history for this message
Go Bot (go-bot) wrote : | # |
There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'client/client.go' | |||
2 | --- client/client.go 2013-03-28 12:36:12 +0000 | |||
3 | +++ client/client.go 2013-07-01 07:24:26 +0000 | |||
4 | @@ -106,6 +106,8 @@ | |||
5 | 106 | client.authMode = &identity.Legacy{} | 106 | client.authMode = &identity.Legacy{} |
6 | 107 | case identity.AuthUserPass: | 107 | case identity.AuthUserPass: |
7 | 108 | client.authMode = &identity.UserPass{} | 108 | client.authMode = &identity.UserPass{} |
8 | 109 | case identity.AuthKeyPair: | ||
9 | 110 | client.authMode = &identity.KeyPair{} | ||
10 | 109 | } | 111 | } |
11 | 110 | return &client | 112 | return &client |
12 | 111 | } | 113 | } |
13 | 112 | 114 | ||
14 | === modified file 'client/client_test.go' | |||
15 | --- client/client_test.go 2013-02-04 01:01:12 +0000 | |||
16 | +++ client/client_test.go 2013-07-01 07:24:26 +0000 | |||
17 | @@ -9,10 +9,10 @@ | |||
18 | 9 | 9 | ||
19 | 10 | var live = flag.Bool("live", false, "Include live OpenStack (Canonistack) tests") | 10 | var live = flag.Bool("live", false, "Include live OpenStack (Canonistack) tests") |
20 | 11 | var liveAuthMode = flag.String( | 11 | var liveAuthMode = flag.String( |
22 | 12 | "live-auth-mode", "userpass", "The authentication mode to use when running live tests [all|legacy|userpass]") | 12 | "live-auth-mode", "userpass", "The authentication mode to use when running live tests [all|legacy|userpass|keypair]") |
23 | 13 | 13 | ||
24 | 14 | func Test(t *testing.T) { | 14 | func Test(t *testing.T) { |
26 | 15 | var allAuthModes = []identity.AuthMode{identity.AuthLegacy, identity.AuthUserPass} | 15 | var allAuthModes = []identity.AuthMode{identity.AuthLegacy, identity.AuthUserPass, identity.AuthKeyPair} |
27 | 16 | var liveAuthModes []identity.AuthMode | 16 | var liveAuthModes []identity.AuthMode |
28 | 17 | switch *liveAuthMode { | 17 | switch *liveAuthMode { |
29 | 18 | default: | 18 | default: |
30 | @@ -20,6 +20,8 @@ | |||
31 | 20 | case "all": | 20 | case "all": |
32 | 21 | liveAuthModes = allAuthModes | 21 | liveAuthModes = allAuthModes |
33 | 22 | case "": | 22 | case "": |
34 | 23 | case "keypair": | ||
35 | 24 | liveAuthModes = []identity.AuthMode{identity.AuthKeyPair} | ||
36 | 23 | case "userpass": | 25 | case "userpass": |
37 | 24 | liveAuthModes = []identity.AuthMode{identity.AuthUserPass} | 26 | liveAuthModes = []identity.AuthMode{identity.AuthUserPass} |
38 | 25 | case "legacy": | 27 | case "legacy": |
39 | @@ -29,7 +31,7 @@ | |||
40 | 29 | if *live { | 31 | if *live { |
41 | 30 | cred, err := identity.CompleteCredentialsFromEnv() | 32 | cred, err := identity.CompleteCredentialsFromEnv() |
42 | 31 | if err != nil { | 33 | if err != nil { |
44 | 32 | t.Fatalf("Error setting up test suite: %s", err.Error()) | 34 | t.Fatalf("Error setting up test suite: %v", err) |
45 | 33 | } | 35 | } |
46 | 34 | registerOpenStackTests(cred, liveAuthModes) | 36 | registerOpenStackTests(cred, liveAuthModes) |
47 | 35 | } | 37 | } |
48 | 36 | 38 | ||
49 | === modified file 'client/live_test.go' | |||
50 | --- client/live_test.go 2013-03-28 09:06:20 +0000 | |||
51 | +++ client/live_test.go 2013-07-01 07:24:26 +0000 | |||
52 | @@ -48,16 +48,16 @@ | |||
53 | 48 | } | 48 | } |
54 | 49 | 49 | ||
55 | 50 | func (s *LiveTests) TestAuthenticate(c *C) { | 50 | func (s *LiveTests) TestAuthenticate(c *C) { |
58 | 51 | client := client.NewClient(s.cred, s.authMode, nil) | 51 | cl := client.NewClient(s.cred, s.authMode, nil) |
59 | 52 | err := client.Authenticate() | 52 | err := cl.Authenticate() |
60 | 53 | c.Assert(err, IsNil) | 53 | c.Assert(err, IsNil) |
62 | 54 | c.Assert(client.IsAuthenticated(), Equals, true) | 54 | c.Assert(cl.IsAuthenticated(), Equals, true) |
63 | 55 | 55 | ||
64 | 56 | // Check service endpoints are discovered | 56 | // Check service endpoints are discovered |
66 | 57 | url, err := client.MakeServiceURL("compute", nil) | 57 | url, err := cl.MakeServiceURL("compute", nil) |
67 | 58 | c.Check(err, IsNil) | 58 | c.Check(err, IsNil) |
68 | 59 | c.Check(url, NotNil) | 59 | c.Check(url, NotNil) |
70 | 60 | url, err = client.MakeServiceURL("object-store", nil) | 60 | url, err = cl.MakeServiceURL("object-store", nil) |
71 | 61 | c.Check(err, IsNil) | 61 | c.Check(err, IsNil) |
72 | 62 | c.Check(url, NotNil) | 62 | c.Check(url, NotNil) |
73 | 63 | } | 63 | } |
74 | 64 | 64 | ||
75 | === modified file 'client/local_test.go' | |||
76 | --- client/local_test.go 2013-03-28 12:36:12 +0000 | |||
77 | +++ client/local_test.go 2013-07-01 07:24:26 +0000 | |||
78 | @@ -49,14 +49,22 @@ | |||
79 | 49 | switch s.authMode { | 49 | switch s.authMode { |
80 | 50 | default: | 50 | default: |
81 | 51 | panic("Invalid authentication method") | 51 | panic("Invalid authentication method") |
82 | 52 | case identity.AuthKeyPair: | ||
83 | 53 | // The openstack test service sets up keypair authentication. | ||
84 | 54 | s.service = openstackservice.New(s.cred, identity.AuthKeyPair) | ||
85 | 55 | // Add an additional endpoint so region filtering can be properly tested. | ||
86 | 56 | serviceDef := identityservice.Service{"nova", "compute", []identityservice.Endpoint{ | ||
87 | 57 | identityservice.Endpoint{PublicURL: "http://nova2", Region: "zone2.RegionOne"}, | ||
88 | 58 | }} | ||
89 | 59 | s.service.(*openstackservice.Openstack).Identity.AddService(serviceDef) | ||
90 | 52 | case identity.AuthUserPass: | 60 | case identity.AuthUserPass: |
91 | 53 | // The openstack test service sets up userpass authentication. | 61 | // The openstack test service sets up userpass authentication. |
93 | 54 | s.service = openstackservice.New(s.cred) | 62 | s.service = openstackservice.New(s.cred, identity.AuthUserPass) |
94 | 55 | // Add an additional endpoint so region filtering can be properly tested. | 63 | // Add an additional endpoint so region filtering can be properly tested. |
95 | 56 | serviceDef := identityservice.Service{"nova", "compute", []identityservice.Endpoint{ | 64 | serviceDef := identityservice.Service{"nova", "compute", []identityservice.Endpoint{ |
96 | 57 | identityservice.Endpoint{PublicURL: "http://nova2", Region: "zone2.RegionOne"}, | 65 | identityservice.Endpoint{PublicURL: "http://nova2", Region: "zone2.RegionOne"}, |
97 | 58 | }} | 66 | }} |
99 | 59 | s.service.(*openstackservice.Openstack).Identity.(*identityservice.UserPass).AddService(serviceDef) | 67 | s.service.(*openstackservice.Openstack).Identity.AddService(serviceDef) |
100 | 60 | 68 | ||
101 | 61 | case identity.AuthLegacy: | 69 | case identity.AuthLegacy: |
102 | 62 | legacy := identityservice.NewLegacy() | 70 | legacy := identityservice.NewLegacy() |
103 | 63 | 71 | ||
104 | === modified file 'goose.go' | |||
105 | --- goose.go 2012-10-31 15:50:00 +0000 | |||
106 | +++ goose.go 2013-07-01 07:24:26 +0000 | |||
107 | @@ -1,1 +1,4 @@ | |||
108 | 1 | // Copyright 2013 Canonical Ltd. | ||
109 | 2 | // Licensed under the LGPLv3, see COPYING and COPYING.LESSER file for details. | ||
110 | 3 | |||
111 | 1 | package goose | 4 | package goose |
112 | 2 | 5 | ||
113 | === modified file 'http/client.go' | |||
114 | --- http/client.go 2013-04-19 09:19:53 +0000 | |||
115 | +++ http/client.go 2013-07-01 07:24:26 +0000 | |||
116 | @@ -209,6 +209,7 @@ | |||
117 | 209 | req.Header.Add(header, value) | 209 | req.Header.Add(header, value) |
118 | 210 | } | 210 | } |
119 | 211 | } | 211 | } |
120 | 212 | req.ContentLength = int64(len(reqData)) | ||
121 | 212 | resp, err = c.Do(req) | 213 | resp, err = c.Do(req) |
122 | 213 | if err != nil { | 214 | if err != nil { |
123 | 214 | return nil, errors.Newf(err, "failed executing the request %s", URL) | 215 | return nil, errors.Newf(err, "failed executing the request %s", URL) |
124 | 215 | 216 | ||
125 | === modified file 'http/client_test.go' | |||
126 | --- http/client_test.go 2013-02-22 00:36:43 +0000 | |||
127 | +++ http/client_test.go 2013-07-01 07:24:26 +0000 | |||
128 | @@ -1,6 +1,9 @@ | |||
129 | 1 | package http | 1 | package http |
130 | 2 | 2 | ||
131 | 3 | import ( | 3 | import ( |
132 | 4 | "bytes" | ||
133 | 5 | "fmt" | ||
134 | 6 | "io/ioutil" | ||
135 | 4 | . "launchpad.net/gocheck" | 7 | . "launchpad.net/gocheck" |
136 | 5 | "launchpad.net/goose/testing/httpsuite" | 8 | "launchpad.net/goose/testing/httpsuite" |
137 | 6 | "net/http" | 9 | "net/http" |
138 | @@ -52,21 +55,25 @@ | |||
139 | 52 | http.Header{"Foo": []string{"Bar"}, "Content-Type": contentTypes, "Accept": contentTypes, "User-Agent": []string{gooseAgent()}}) | 55 | http.Header{"Foo": []string{"Bar"}, "Content-Type": contentTypes, "Accept": contentTypes, "User-Agent": []string{gooseAgent()}}) |
140 | 53 | } | 56 | } |
141 | 54 | 57 | ||
144 | 55 | func (s *HTTPClientTestSuite) setupLoopbackRequest() (*http.Header, *Client) { | 58 | func (s *HTTPClientTestSuite) setupLoopbackRequest() (*http.Header, chan string, *Client) { |
145 | 56 | headers := http.Header{} | 59 | var headers http.Header |
146 | 60 | bodyChan := make(chan string, 1) | ||
147 | 57 | handler := func(resp http.ResponseWriter, req *http.Request) { | 61 | handler := func(resp http.ResponseWriter, req *http.Request) { |
148 | 58 | headers = req.Header | 62 | headers = req.Header |
149 | 63 | bodyBytes, _ := ioutil.ReadAll(req.Body) | ||
150 | 64 | req.Body.Close() | ||
151 | 65 | bodyChan <- string(bodyBytes) | ||
152 | 59 | resp.Header().Add("Content-Length", "0") | 66 | resp.Header().Add("Content-Length", "0") |
153 | 60 | resp.WriteHeader(http.StatusNoContent) | 67 | resp.WriteHeader(http.StatusNoContent) |
154 | 61 | resp.Write([]byte{}) | 68 | resp.Write([]byte{}) |
155 | 62 | } | 69 | } |
156 | 63 | s.Mux.HandleFunc("/", handler) | 70 | s.Mux.HandleFunc("/", handler) |
157 | 64 | client := New() | 71 | client := New() |
159 | 65 | return &headers, client | 72 | return &headers, bodyChan, client |
160 | 66 | } | 73 | } |
161 | 67 | 74 | ||
162 | 68 | func (s *HTTPClientTestSuite) TestBinaryRequestSetsUserAgent(c *C) { | 75 | func (s *HTTPClientTestSuite) TestBinaryRequestSetsUserAgent(c *C) { |
164 | 69 | headers, client := s.setupLoopbackRequest() | 76 | headers, _, client := s.setupLoopbackRequest() |
165 | 70 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} | 77 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} |
166 | 71 | err := client.BinaryRequest("POST", s.Server.URL, "", req, nil) | 78 | err := client.BinaryRequest("POST", s.Server.URL, "", req, nil) |
167 | 72 | c.Assert(err, IsNil) | 79 | c.Assert(err, IsNil) |
168 | @@ -76,7 +83,7 @@ | |||
169 | 76 | } | 83 | } |
170 | 77 | 84 | ||
171 | 78 | func (s *HTTPClientTestSuite) TestJSONRequestSetsUserAgent(c *C) { | 85 | func (s *HTTPClientTestSuite) TestJSONRequestSetsUserAgent(c *C) { |
173 | 79 | headers, client := s.setupLoopbackRequest() | 86 | headers, _, client := s.setupLoopbackRequest() |
174 | 80 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} | 87 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} |
175 | 81 | err := client.JsonRequest("POST", s.Server.URL, "", req, nil) | 88 | err := client.JsonRequest("POST", s.Server.URL, "", req, nil) |
176 | 82 | c.Assert(err, IsNil) | 89 | c.Assert(err, IsNil) |
177 | @@ -85,8 +92,45 @@ | |||
178 | 85 | c.Check(agent, Equals, gooseAgent()) | 92 | c.Check(agent, Equals, gooseAgent()) |
179 | 86 | } | 93 | } |
180 | 87 | 94 | ||
181 | 95 | func (s *HTTPClientTestSuite) TestBinaryRequestSetsContentLength(c *C) { | ||
182 | 96 | headers, bodyChan, client := s.setupLoopbackRequest() | ||
183 | 97 | content := "binary\ncontent\n" | ||
184 | 98 | req := &RequestData{ | ||
185 | 99 | ExpectedStatus: []int{http.StatusNoContent}, | ||
186 | 100 | ReqReader: bytes.NewBufferString(content), | ||
187 | 101 | ReqLength: len(content), | ||
188 | 102 | } | ||
189 | 103 | err := client.BinaryRequest("POST", s.Server.URL, "", req, nil) | ||
190 | 104 | c.Assert(err, IsNil) | ||
191 | 105 | encoding := headers.Get("Transfer-Encoding") | ||
192 | 106 | c.Check(encoding, Equals, "") | ||
193 | 107 | length := headers.Get("Content-Length") | ||
194 | 108 | c.Check(length, Equals, fmt.Sprintf("%d", len(content))) | ||
195 | 109 | body, ok := <-bodyChan | ||
196 | 110 | c.Assert(ok, Equals, true) | ||
197 | 111 | c.Check(body, Equals, content) | ||
198 | 112 | } | ||
199 | 113 | |||
200 | 114 | func (s *HTTPClientTestSuite) TestJSONRequestSetsContentLength(c *C) { | ||
201 | 115 | headers, bodyChan, client := s.setupLoopbackRequest() | ||
202 | 116 | reqMap := map[string]string{"key": "value"} | ||
203 | 117 | req := &RequestData{ | ||
204 | 118 | ExpectedStatus: []int{http.StatusNoContent}, | ||
205 | 119 | ReqValue: reqMap, | ||
206 | 120 | } | ||
207 | 121 | err := client.JsonRequest("POST", s.Server.URL, "", req, nil) | ||
208 | 122 | c.Assert(err, IsNil) | ||
209 | 123 | encoding := headers.Get("Transfer-Encoding") | ||
210 | 124 | c.Check(encoding, Equals, "") | ||
211 | 125 | length := headers.Get("Content-Length") | ||
212 | 126 | body, ok := <-bodyChan | ||
213 | 127 | c.Assert(ok, Equals, true) | ||
214 | 128 | c.Check(body, Not(Equals), "") | ||
215 | 129 | c.Check(length, Equals, fmt.Sprintf("%d", len(body))) | ||
216 | 130 | } | ||
217 | 131 | |||
218 | 88 | func (s *HTTPClientTestSuite) TestBinaryRequestSetsToken(c *C) { | 132 | func (s *HTTPClientTestSuite) TestBinaryRequestSetsToken(c *C) { |
220 | 89 | headers, client := s.setupLoopbackRequest() | 133 | headers, _, client := s.setupLoopbackRequest() |
221 | 90 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} | 134 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} |
222 | 91 | err := client.BinaryRequest("POST", s.Server.URL, "token", req, nil) | 135 | err := client.BinaryRequest("POST", s.Server.URL, "token", req, nil) |
223 | 92 | c.Assert(err, IsNil) | 136 | c.Assert(err, IsNil) |
224 | @@ -95,7 +139,7 @@ | |||
225 | 95 | } | 139 | } |
226 | 96 | 140 | ||
227 | 97 | func (s *HTTPClientTestSuite) TestJSONRequestSetsToken(c *C) { | 141 | func (s *HTTPClientTestSuite) TestJSONRequestSetsToken(c *C) { |
229 | 98 | headers, client := s.setupLoopbackRequest() | 142 | headers, _, client := s.setupLoopbackRequest() |
230 | 99 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} | 143 | req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}} |
231 | 100 | err := client.JsonRequest("POST", s.Server.URL, "token", req, nil) | 144 | err := client.JsonRequest("POST", s.Server.URL, "token", req, nil) |
232 | 101 | c.Assert(err, IsNil) | 145 | c.Assert(err, IsNil) |
233 | 102 | 146 | ||
234 | === modified file 'identity/identity.go' | |||
235 | --- identity/identity.go 2013-02-12 01:47:38 +0000 | |||
236 | +++ identity/identity.go 2013-07-01 07:24:26 +0000 | |||
237 | @@ -15,10 +15,13 @@ | |||
238 | 15 | const ( | 15 | const ( |
239 | 16 | AuthLegacy = AuthMode(iota) // Legacy authentication | 16 | AuthLegacy = AuthMode(iota) // Legacy authentication |
240 | 17 | AuthUserPass // Username + password authentication | 17 | AuthUserPass // Username + password authentication |
241 | 18 | AuthKeyPair // Access/secret key pair authentication | ||
242 | 18 | ) | 19 | ) |
243 | 19 | 20 | ||
244 | 20 | func (a AuthMode) String() string { | 21 | func (a AuthMode) String() string { |
245 | 21 | switch a { | 22 | switch a { |
246 | 23 | case AuthKeyPair: | ||
247 | 24 | return "Access/Secret Key Authentication" | ||
248 | 22 | case AuthLegacy: | 25 | case AuthLegacy: |
249 | 23 | return "Legacy Authentication" | 26 | return "Legacy Authentication" |
250 | 24 | case AuthUserPass: | 27 | case AuthUserPass: |
251 | @@ -69,9 +72,12 @@ | |||
252 | 69 | // environment variables. | 72 | // environment variables. |
253 | 70 | func CredentialsFromEnv() *Credentials { | 73 | func CredentialsFromEnv() *Credentials { |
254 | 71 | return &Credentials{ | 74 | return &Credentials{ |
258 | 72 | URL: getConfig("OS_AUTH_URL"), | 75 | URL: getConfig("OS_AUTH_URL"), |
259 | 73 | User: getConfig("OS_USERNAME", "NOVA_USERNAME"), | 76 | User: getConfig("OS_USERNAME", "NOVA_USERNAME", |
260 | 74 | Secrets: getConfig("OS_PASSWORD", "NOVA_PASSWORD"), | 77 | "OS_ACCESS_KEY", "NOVA_API_KEY"), |
261 | 78 | Secrets: getConfig("OS_PASSWORD", "NOVA_PASSWORD", | ||
262 | 79 | "OS_SECRET_KEY", "EC2_SECRET_KEYS", | ||
263 | 80 | "AWS_SECRET_ACCESS_KEY"), | ||
264 | 75 | Region: getConfig("OS_REGION_NAME", "NOVA_REGION"), | 81 | Region: getConfig("OS_REGION_NAME", "NOVA_REGION"), |
265 | 76 | TenantName: getConfig("OS_TENANT_NAME", "NOVA_PROJECT_ID"), | 82 | TenantName: getConfig("OS_TENANT_NAME", "NOVA_PROJECT_ID"), |
266 | 77 | } | 83 | } |
267 | 78 | 84 | ||
268 | === modified file 'identity/identity_test.go' | |||
269 | --- identity/identity_test.go 2013-02-11 05:01:34 +0000 | |||
270 | +++ identity/identity_test.go 2013-07-01 07:24:26 +0000 | |||
271 | @@ -27,6 +27,8 @@ | |||
272 | 27 | env: map[string]string{ | 27 | env: map[string]string{ |
273 | 28 | "NOVA_USERNAME": "test-user", | 28 | "NOVA_USERNAME": "test-user", |
274 | 29 | "NOVA_PASSWORD": "test-pass", | 29 | "NOVA_PASSWORD": "test-pass", |
275 | 30 | "NOVA_API_KEY": "test-access-key", | ||
276 | 31 | "EC2_SECRET_KEYS": "test-secret-key", | ||
277 | 30 | "NOVA_PROJECT_ID": "tenant-name", | 32 | "NOVA_PROJECT_ID": "tenant-name", |
278 | 31 | "NOVA_REGION": "region", | 33 | "NOVA_REGION": "region", |
279 | 32 | }, | 34 | }, |
280 | @@ -39,6 +41,8 @@ | |||
281 | 39 | env: map[string]string{ | 41 | env: map[string]string{ |
282 | 40 | "OS_USERNAME": "test-user", | 42 | "OS_USERNAME": "test-user", |
283 | 41 | "OS_PASSWORD": "test-pass", | 43 | "OS_PASSWORD": "test-pass", |
284 | 44 | "OS_ACCESS_KEY": "test-access-key", | ||
285 | 45 | "OS_SECRET_KEY": "test-secret-key", | ||
286 | 42 | "OS_TENANT_NAME": "tenant-name", | 46 | "OS_TENANT_NAME": "tenant-name", |
287 | 43 | "OS_REGION_NAME": "region", | 47 | "OS_REGION_NAME": "region", |
288 | 44 | }, | 48 | }, |
289 | @@ -66,6 +70,8 @@ | |||
290 | 66 | "OS_AUTH_URL": "http://auth", | 70 | "OS_AUTH_URL": "http://auth", |
291 | 67 | "OS_USERNAME": "test-user", | 71 | "OS_USERNAME": "test-user", |
292 | 68 | "OS_PASSWORD": "test-pass", | 72 | "OS_PASSWORD": "test-pass", |
293 | 73 | "OS_ACCESS_KEY": "test-access-key", | ||
294 | 74 | "OS_SECRET_KEY": "test-secret-key", | ||
295 | 69 | "OS_TENANT_NAME": "tenant-name", | 75 | "OS_TENANT_NAME": "tenant-name", |
296 | 70 | "OS_REGION_NAME": "region", | 76 | "OS_REGION_NAME": "region", |
297 | 71 | } | 77 | } |
298 | @@ -86,6 +92,7 @@ | |||
299 | 86 | env := map[string]string{ | 92 | env := map[string]string{ |
300 | 87 | "OS_AUTH_URL": "http://auth", | 93 | "OS_AUTH_URL": "http://auth", |
301 | 88 | "OS_USERNAME": "test-user", | 94 | "OS_USERNAME": "test-user", |
302 | 95 | "OS_ACCESS_KEY": "test-access-key", | ||
303 | 89 | "OS_TENANT_NAME": "tenant-name", | 96 | "OS_TENANT_NAME": "tenant-name", |
304 | 90 | "OS_REGION_NAME": "region", | 97 | "OS_REGION_NAME": "region", |
305 | 91 | } | 98 | } |
306 | @@ -96,3 +103,47 @@ | |||
307 | 96 | c.Assert(err, Not(IsNil)) | 103 | c.Assert(err, Not(IsNil)) |
308 | 97 | c.Assert(err.Error(), Matches, "required environment variable not set.*: Secrets") | 104 | c.Assert(err.Error(), Matches, "required environment variable not set.*: Secrets") |
309 | 98 | } | 105 | } |
310 | 106 | |||
311 | 107 | func (s *CredentialsTestSuite) TestCompleteCredentialsFromEnvKeypair(c *C) { | ||
312 | 108 | env := map[string]string{ | ||
313 | 109 | "OS_AUTH_URL": "http://auth", | ||
314 | 110 | "OS_USERNAME": "", | ||
315 | 111 | "OS_PASSWORD": "", | ||
316 | 112 | "OS_ACCESS_KEY": "test-access-key", | ||
317 | 113 | "OS_SECRET_KEY": "test-secret-key", | ||
318 | 114 | "OS_TENANT_NAME": "tenant-name", | ||
319 | 115 | "OS_REGION_NAME": "region", | ||
320 | 116 | } | ||
321 | 117 | for key, value := range env { | ||
322 | 118 | os.Setenv(key, value) | ||
323 | 119 | } | ||
324 | 120 | creds, err := CompleteCredentialsFromEnv() | ||
325 | 121 | c.Assert(err, IsNil) | ||
326 | 122 | c.Check(creds.URL, Equals, "http://auth") | ||
327 | 123 | c.Check(creds.User, Equals, "test-access-key") | ||
328 | 124 | c.Check(creds.Secrets, Equals, "test-secret-key") | ||
329 | 125 | c.Check(creds.Region, Equals, "region") | ||
330 | 126 | c.Check(creds.TenantName, Equals, "tenant-name") | ||
331 | 127 | } | ||
332 | 128 | |||
333 | 129 | func (s *CredentialsTestSuite) TestCompleteCredentialsFromEnvKeypairCompatibleEnvVars(c *C) { | ||
334 | 130 | env := map[string]string{ | ||
335 | 131 | "OS_AUTH_URL": "http://auth", | ||
336 | 132 | "OS_USERNAME": "", | ||
337 | 133 | "OS_PASSWORD": "", | ||
338 | 134 | "NOVA_API_KEY": "test-access-key", | ||
339 | 135 | "EC2_SECRET_KEYS": "test-secret-key", | ||
340 | 136 | "OS_TENANT_NAME": "tenant-name", | ||
341 | 137 | "OS_REGION_NAME": "region", | ||
342 | 138 | } | ||
343 | 139 | for key, value := range env { | ||
344 | 140 | os.Setenv(key, value) | ||
345 | 141 | } | ||
346 | 142 | creds, err := CompleteCredentialsFromEnv() | ||
347 | 143 | c.Assert(err, IsNil) | ||
348 | 144 | c.Check(creds.URL, Equals, "http://auth") | ||
349 | 145 | c.Check(creds.User, Equals, "test-access-key") | ||
350 | 146 | c.Check(creds.Secrets, Equals, "test-secret-key") | ||
351 | 147 | c.Check(creds.Region, Equals, "region") | ||
352 | 148 | c.Check(creds.TenantName, Equals, "tenant-name") | ||
353 | 149 | } | ||
354 | 99 | 150 | ||
355 | === added file 'identity/keypair.go' | |||
356 | --- identity/keypair.go 1970-01-01 00:00:00 +0000 | |||
357 | +++ identity/keypair.go 2013-07-01 07:24:26 +0000 | |||
358 | @@ -0,0 +1,41 @@ | |||
359 | 1 | package identity | ||
360 | 2 | |||
361 | 3 | import ( | ||
362 | 4 | goosehttp "launchpad.net/goose/http" | ||
363 | 5 | ) | ||
364 | 6 | |||
365 | 7 | // KeyPair allows OpenStack cloud authentication using an access and | ||
366 | 8 | // secret key. | ||
367 | 9 | // | ||
368 | 10 | // It implements Authenticator interface by providing the Auth method. | ||
369 | 11 | type KeyPair struct { | ||
370 | 12 | client *goosehttp.Client | ||
371 | 13 | } | ||
372 | 14 | |||
373 | 15 | type keypairCredentials struct { | ||
374 | 16 | AccessKey string `json:"accessKey"` | ||
375 | 17 | SecretKey string `json:"secretKey"` | ||
376 | 18 | } | ||
377 | 19 | |||
378 | 20 | type authKeypairRequest struct { | ||
379 | 21 | KeypairCredentials keypairCredentials `json:"apiAccessKeyCredentials"` | ||
380 | 22 | TenantName string `json:"tenantName"` | ||
381 | 23 | } | ||
382 | 24 | |||
383 | 25 | type authKeypairWrapper struct { | ||
384 | 26 | Auth authKeypairRequest `json:"auth"` | ||
385 | 27 | } | ||
386 | 28 | |||
387 | 29 | func (u *KeyPair) Auth(creds *Credentials) (*AuthDetails, error) { | ||
388 | 30 | if u.client == nil { | ||
389 | 31 | u.client = goosehttp.New() | ||
390 | 32 | } | ||
391 | 33 | auth := authKeypairWrapper{Auth: authKeypairRequest{ | ||
392 | 34 | KeypairCredentials: keypairCredentials{ | ||
393 | 35 | AccessKey: creds.User, | ||
394 | 36 | SecretKey: creds.Secrets, | ||
395 | 37 | }, | ||
396 | 38 | TenantName: creds.TenantName}} | ||
397 | 39 | |||
398 | 40 | return keystoneAuth(u.client, auth, creds.URL) | ||
399 | 41 | } | ||
400 | 0 | 42 | ||
401 | === added file 'identity/keystone.go' | |||
402 | --- identity/keystone.go 1970-01-01 00:00:00 +0000 | |||
403 | +++ identity/keystone.go 2013-07-01 07:24:26 +0000 | |||
404 | @@ -0,0 +1,89 @@ | |||
405 | 1 | package identity | ||
406 | 2 | |||
407 | 3 | import ( | ||
408 | 4 | "fmt" | ||
409 | 5 | goosehttp "launchpad.net/goose/http" | ||
410 | 6 | ) | ||
411 | 7 | |||
412 | 8 | type endpoint struct { | ||
413 | 9 | AdminURL string `json:"adminURL"` | ||
414 | 10 | InternalURL string `json:"internalURL"` | ||
415 | 11 | PublicURL string `json:"publicURL"` | ||
416 | 12 | Region string `json:"region"` | ||
417 | 13 | } | ||
418 | 14 | |||
419 | 15 | type serviceResponse struct { | ||
420 | 16 | Name string `json:"name"` | ||
421 | 17 | Type string `json:"type"` | ||
422 | 18 | Endpoints []endpoint | ||
423 | 19 | } | ||
424 | 20 | |||
425 | 21 | type tokenResponse struct { | ||
426 | 22 | Expires string `json:"expires"` | ||
427 | 23 | Id string `json:"id"` // Actual token string | ||
428 | 24 | Tenant struct { | ||
429 | 25 | Id string `json:"id"` | ||
430 | 26 | Name string `json:"name"` | ||
431 | 27 | // Description is a pointer since it may be null and this breaks Go < 1.1 | ||
432 | 28 | Description *string `json:"description"` | ||
433 | 29 | Enabled bool `json:"enabled"` | ||
434 | 30 | } `json:"tenant"` | ||
435 | 31 | } | ||
436 | 32 | |||
437 | 33 | type roleResponse struct { | ||
438 | 34 | Id string `json:"id"` | ||
439 | 35 | Name string `json:"name"` | ||
440 | 36 | TenantId string `json:"tenantId"` | ||
441 | 37 | } | ||
442 | 38 | |||
443 | 39 | type userResponse struct { | ||
444 | 40 | Id string `json:"id"` | ||
445 | 41 | Name string `json:"name"` | ||
446 | 42 | Roles []roleResponse `json:"roles"` | ||
447 | 43 | } | ||
448 | 44 | |||
449 | 45 | type accessWrapper struct { | ||
450 | 46 | Access accessResponse `json:"access"` | ||
451 | 47 | } | ||
452 | 48 | |||
453 | 49 | type accessResponse struct { | ||
454 | 50 | ServiceCatalog []serviceResponse `json:"serviceCatalog"` | ||
455 | 51 | Token tokenResponse `json:"token"` | ||
456 | 52 | User userResponse `json:"user"` | ||
457 | 53 | } | ||
458 | 54 | |||
459 | 55 | // keystoneAuth authenticates to OpenStack cloud using keystone v2 authentication. | ||
460 | 56 | // | ||
461 | 57 | // Uses `client` to submit HTTP requests to `URL` | ||
462 | 58 | // and posts `auth_data` as JSON. | ||
463 | 59 | func keystoneAuth(client *goosehttp.Client, auth_data interface{}, URL string) (*AuthDetails, error) { | ||
464 | 60 | |||
465 | 61 | var accessWrapper accessWrapper | ||
466 | 62 | requestData := goosehttp.RequestData{ReqValue: auth_data, RespValue: &accessWrapper} | ||
467 | 63 | err := client.JsonRequest("POST", URL, "", &requestData, nil) | ||
468 | 64 | if err != nil { | ||
469 | 65 | return nil, err | ||
470 | 66 | } | ||
471 | 67 | |||
472 | 68 | details := &AuthDetails{} | ||
473 | 69 | access := accessWrapper.Access | ||
474 | 70 | respToken := access.Token | ||
475 | 71 | if respToken.Id == "" { | ||
476 | 72 | return nil, fmt.Errorf("authentication failed") | ||
477 | 73 | } | ||
478 | 74 | details.Token = respToken.Id | ||
479 | 75 | details.TenantId = respToken.Tenant.Id | ||
480 | 76 | details.UserId = access.User.Id | ||
481 | 77 | details.RegionServiceURLs = make(map[string]ServiceURLs, len(access.ServiceCatalog)) | ||
482 | 78 | for _, service := range access.ServiceCatalog { | ||
483 | 79 | for i, e := range service.Endpoints { | ||
484 | 80 | endpointURLs, ok := details.RegionServiceURLs[e.Region] | ||
485 | 81 | if !ok { | ||
486 | 82 | endpointURLs = make(ServiceURLs) | ||
487 | 83 | details.RegionServiceURLs[e.Region] = endpointURLs | ||
488 | 84 | } | ||
489 | 85 | endpointURLs[service.Type] = service.Endpoints[i].PublicURL | ||
490 | 86 | } | ||
491 | 87 | } | ||
492 | 88 | return details, nil | ||
493 | 89 | } | ||
494 | 0 | 90 | ||
495 | === modified file 'identity/local_test.go' | |||
496 | --- identity/local_test.go 2013-02-12 01:47:38 +0000 | |||
497 | +++ identity/local_test.go 2013-07-01 07:24:26 +0000 | |||
498 | @@ -6,6 +6,8 @@ | |||
499 | 6 | "launchpad.net/goose/testservices/openstackservice" | 6 | "launchpad.net/goose/testservices/openstackservice" |
500 | 7 | "net/http" | 7 | "net/http" |
501 | 8 | "net/http/httptest" | 8 | "net/http/httptest" |
502 | 9 | "net/url" | ||
503 | 10 | "strings" | ||
504 | 9 | ) | 11 | ) |
505 | 10 | 12 | ||
506 | 11 | func registerLocalTests() { | 13 | func registerLocalTests() { |
507 | @@ -39,7 +41,7 @@ | |||
508 | 39 | Region: "zone1.some region", | 41 | Region: "zone1.some region", |
509 | 40 | TenantName: "tenant", | 42 | TenantName: "tenant", |
510 | 41 | } | 43 | } |
512 | 42 | openstack := openstackservice.New(s.cred) | 44 | openstack := openstackservice.New(s.cred, identity.AuthUserPass) |
513 | 43 | openstack.SetupHTTP(s.Mux) | 45 | openstack.SetupHTTP(s.Mux) |
514 | 44 | 46 | ||
515 | 45 | s.LiveTests.SetUpSuite(c) | 47 | s.LiveTests.SetUpSuite(c) |
516 | @@ -61,3 +63,22 @@ | |||
517 | 61 | } | 63 | } |
518 | 62 | 64 | ||
519 | 63 | // Additional tests to be run against the service double only go here. | 65 | // Additional tests to be run against the service double only go here. |
520 | 66 | |||
521 | 67 | func (s *localLiveSuite) TestProductStreamsEndpoint(c *C) { | ||
522 | 68 | err := s.client.Authenticate() | ||
523 | 69 | c.Assert(err, IsNil) | ||
524 | 70 | serviceURL, err := s.client.MakeServiceURL("product-streams", nil) | ||
525 | 71 | c.Assert(err, IsNil) | ||
526 | 72 | _, err = url.Parse(serviceURL) | ||
527 | 73 | c.Assert(err, IsNil) | ||
528 | 74 | c.Assert(strings.HasSuffix(serviceURL, "/imagemetadata"), Equals, true) | ||
529 | 75 | } | ||
530 | 76 | |||
531 | 77 | func (s *localLiveSuite) TestJujuToolsEndpoint(c *C) { | ||
532 | 78 | err := s.client.Authenticate() | ||
533 | 79 | c.Assert(err, IsNil) | ||
534 | 80 | serviceURL, err := s.client.MakeServiceURL("juju-tools", nil) | ||
535 | 81 | c.Assert(err, IsNil) | ||
536 | 82 | _, err = url.Parse(serviceURL) | ||
537 | 83 | c.Assert(err, IsNil) | ||
538 | 84 | } | ||
539 | 64 | 85 | ||
540 | === modified file 'identity/userpass.go' | |||
541 | --- identity/userpass.go 2013-02-20 02:30:14 +0000 | |||
542 | +++ identity/userpass.go 2013-07-01 07:24:26 +0000 | |||
543 | @@ -1,7 +1,6 @@ | |||
544 | 1 | package identity | 1 | package identity |
545 | 2 | 2 | ||
546 | 3 | import ( | 3 | import ( |
547 | 4 | "fmt" | ||
548 | 5 | goosehttp "launchpad.net/goose/http" | 4 | goosehttp "launchpad.net/goose/http" |
549 | 6 | ) | 5 | ) |
550 | 7 | 6 | ||
551 | @@ -19,52 +18,6 @@ | |||
552 | 19 | Auth authRequest `json:"auth"` | 18 | Auth authRequest `json:"auth"` |
553 | 20 | } | 19 | } |
554 | 21 | 20 | ||
555 | 22 | type endpoint struct { | ||
556 | 23 | AdminURL string `json:"adminURL"` | ||
557 | 24 | InternalURL string `json:"internalURL"` | ||
558 | 25 | PublicURL string `json:"publicURL"` | ||
559 | 26 | Region string `json:"region"` | ||
560 | 27 | } | ||
561 | 28 | |||
562 | 29 | type serviceResponse struct { | ||
563 | 30 | Name string `json:"name"` | ||
564 | 31 | Type string `json:"type"` | ||
565 | 32 | Endpoints []endpoint | ||
566 | 33 | } | ||
567 | 34 | |||
568 | 35 | type tokenResponse struct { | ||
569 | 36 | Expires string `json:"expires"` // should this be a date object? | ||
570 | 37 | Id string `json:"id"` // Actual token string | ||
571 | 38 | Tenant struct { | ||
572 | 39 | Id string `json:"id"` | ||
573 | 40 | Name string `json:"name"` | ||
574 | 41 | Description string `json:"description"` | ||
575 | 42 | Enabled bool `json:"enabled"` | ||
576 | 43 | } `json:"tenant"` | ||
577 | 44 | } | ||
578 | 45 | |||
579 | 46 | type roleResponse struct { | ||
580 | 47 | Id string `json:"id"` | ||
581 | 48 | Name string `json:"name"` | ||
582 | 49 | TenantId string `json:"tenantId"` | ||
583 | 50 | } | ||
584 | 51 | |||
585 | 52 | type userResponse struct { | ||
586 | 53 | Id string `json:"id"` | ||
587 | 54 | Name string `json:"name"` | ||
588 | 55 | Roles []roleResponse `json:"roles"` | ||
589 | 56 | } | ||
590 | 57 | |||
591 | 58 | type accessWrapper struct { | ||
592 | 59 | Access accessResponse `json:"access"` | ||
593 | 60 | } | ||
594 | 61 | |||
595 | 62 | type accessResponse struct { | ||
596 | 63 | ServiceCatalog []serviceResponse `json:"serviceCatalog"` | ||
597 | 64 | Token tokenResponse `json:"token"` | ||
598 | 65 | User userResponse `json:"user"` | ||
599 | 66 | } | ||
600 | 67 | |||
601 | 68 | type UserPass struct { | 21 | type UserPass struct { |
602 | 69 | client *goosehttp.Client | 22 | client *goosehttp.Client |
603 | 70 | } | 23 | } |
604 | @@ -80,32 +33,5 @@ | |||
605 | 80 | }, | 33 | }, |
606 | 81 | TenantName: creds.TenantName}} | 34 | TenantName: creds.TenantName}} |
607 | 82 | 35 | ||
636 | 83 | var accessWrapper accessWrapper | 36 | return keystoneAuth(u.client, auth, creds.URL) |
609 | 84 | requestData := goosehttp.RequestData{ReqValue: auth, RespValue: &accessWrapper} | ||
610 | 85 | err := u.client.JsonRequest("POST", creds.URL, "", &requestData, nil) | ||
611 | 86 | if err != nil { | ||
612 | 87 | return nil, err | ||
613 | 88 | } | ||
614 | 89 | |||
615 | 90 | details := &AuthDetails{} | ||
616 | 91 | access := accessWrapper.Access | ||
617 | 92 | respToken := access.Token | ||
618 | 93 | if respToken.Id == "" { | ||
619 | 94 | return nil, fmt.Errorf("Did not get valid Token from auth request") | ||
620 | 95 | } | ||
621 | 96 | details.Token = respToken.Id | ||
622 | 97 | details.TenantId = respToken.Tenant.Id | ||
623 | 98 | details.UserId = access.User.Id | ||
624 | 99 | details.RegionServiceURLs = make(map[string]ServiceURLs, len(access.ServiceCatalog)) | ||
625 | 100 | for _, service := range access.ServiceCatalog { | ||
626 | 101 | for i, e := range service.Endpoints { | ||
627 | 102 | endpointURLs, ok := details.RegionServiceURLs[e.Region] | ||
628 | 103 | if !ok { | ||
629 | 104 | endpointURLs = make(ServiceURLs) | ||
630 | 105 | details.RegionServiceURLs[e.Region] = endpointURLs | ||
631 | 106 | } | ||
632 | 107 | endpointURLs[service.Type] = service.Endpoints[i].PublicURL | ||
633 | 108 | } | ||
634 | 109 | } | ||
635 | 110 | return details, nil | ||
637 | 111 | } | 37 | } |
638 | 112 | 38 | ||
639 | === modified file 'nova/json.go' | |||
640 | --- nova/json.go 2013-03-21 04:52:22 +0000 | |||
641 | +++ nova/json.go 2013-07-01 07:24:26 +0000 | |||
642 | @@ -14,19 +14,12 @@ | |||
643 | 14 | "strconv" | 14 | "strconv" |
644 | 15 | ) | 15 | ) |
645 | 16 | 16 | ||
659 | 17 | type genericId struct { | 17 | const ( |
660 | 18 | Id interface{} `json:"id"` | 18 | idTag = "id" |
661 | 19 | } | 19 | instanceIdTag = "instance_id" |
662 | 20 | 20 | groupIdTag = "group_id" | |
663 | 21 | func (id genericId) String() string { | 21 | parentGroupIdTag = "parent_group_id" |
664 | 22 | if id.Id == nil { | 22 | ) |
652 | 23 | return "" | ||
653 | 24 | } | ||
654 | 25 | if fid, ok := id.Id.(float64); ok { | ||
655 | 26 | return fmt.Sprint(int(fid)) | ||
656 | 27 | } | ||
657 | 28 | return fmt.Sprint(id.Id) | ||
658 | 29 | } | ||
665 | 30 | 23 | ||
666 | 31 | var useNumericIds bool = false | 24 | var useNumericIds bool = false |
667 | 32 | 25 | ||
668 | @@ -43,6 +36,25 @@ | |||
669 | 43 | return result | 36 | return result |
670 | 44 | } | 37 | } |
671 | 45 | 38 | ||
672 | 39 | // getIdAsString extracts the field with the specified tag from the json data | ||
673 | 40 | // and returns it converted to a string. | ||
674 | 41 | func getIdAsString(b []byte, tag string) (string, error) { | ||
675 | 42 | var out map[string]interface{} | ||
676 | 43 | if err := json.Unmarshal(b, &out); err != nil { | ||
677 | 44 | return "", err | ||
678 | 45 | } | ||
679 | 46 | if val, ok := out[tag]; !ok { | ||
680 | 47 | return "", nil | ||
681 | 48 | } else { | ||
682 | 49 | if floatVal, ok := val.(float64); ok { | ||
683 | 50 | return fmt.Sprint(int(floatVal)), nil | ||
684 | 51 | } else { | ||
685 | 52 | return fmt.Sprint(val), nil | ||
686 | 53 | } | ||
687 | 54 | } | ||
688 | 55 | panic("unreachable") | ||
689 | 56 | } | ||
690 | 57 | |||
691 | 46 | // appendJSON marshals the given attribute value and appends it as an encoded value to the given json data. | 58 | // appendJSON marshals the given attribute value and appends it as an encoded value to the given json data. |
692 | 47 | // The newly encode (attr, value) is inserted just before the closing "}" in the json data. | 59 | // The newly encode (attr, value) is inserted just before the closing "}" in the json data. |
693 | 48 | func appendJSON(data []byte, attr string, value interface{}) ([]byte, error) { | 60 | func appendJSON(data []byte, attr string, value interface{}) ([]byte, error) { |
694 | @@ -59,14 +71,13 @@ | |||
695 | 59 | 71 | ||
696 | 60 | func (entity *Entity) UnmarshalJSON(b []byte) error { | 72 | func (entity *Entity) UnmarshalJSON(b []byte) error { |
697 | 61 | var je jsonEntity = jsonEntity(*entity) | 73 | var je jsonEntity = jsonEntity(*entity) |
706 | 62 | if err := json.Unmarshal(b, &je); err != nil { | 74 | var err error |
707 | 63 | return err | 75 | if err = json.Unmarshal(b, &je); err != nil { |
708 | 64 | } | 76 | return err |
709 | 65 | var id genericId | 77 | } |
710 | 66 | if err := json.Unmarshal(b, &id); err != nil { | 78 | if je.Id, err = getIdAsString(b, idTag); err != nil { |
711 | 67 | return err | 79 | return err |
712 | 68 | } | 80 | } |
705 | 69 | je.Id = id.String() | ||
713 | 70 | *entity = Entity(je) | 81 | *entity = Entity(je) |
714 | 71 | return nil | 82 | return nil |
715 | 72 | } | 83 | } |
716 | @@ -78,21 +89,20 @@ | |||
717 | 78 | return nil, err | 89 | return nil, err |
718 | 79 | } | 90 | } |
719 | 80 | id := convertId(entity.Id) | 91 | id := convertId(entity.Id) |
721 | 81 | return appendJSON(data, "Id", id) | 92 | return appendJSON(data, idTag, id) |
722 | 82 | } | 93 | } |
723 | 83 | 94 | ||
724 | 84 | type jsonFlavorDetail FlavorDetail | 95 | type jsonFlavorDetail FlavorDetail |
725 | 85 | 96 | ||
726 | 86 | func (flavorDetail *FlavorDetail) UnmarshalJSON(b []byte) error { | 97 | func (flavorDetail *FlavorDetail) UnmarshalJSON(b []byte) error { |
727 | 87 | var jfd jsonFlavorDetail = jsonFlavorDetail(*flavorDetail) | 98 | var jfd jsonFlavorDetail = jsonFlavorDetail(*flavorDetail) |
736 | 88 | if err := json.Unmarshal(b, &jfd); err != nil { | 99 | var err error |
737 | 89 | return err | 100 | if err = json.Unmarshal(b, &jfd); err != nil { |
738 | 90 | } | 101 | return err |
739 | 91 | var id genericId | 102 | } |
740 | 92 | if err := json.Unmarshal(b, &id); err != nil { | 103 | if jfd.Id, err = getIdAsString(b, idTag); err != nil { |
741 | 93 | return err | 104 | return err |
742 | 94 | } | 105 | } |
735 | 95 | jfd.Id = id.String() | ||
743 | 96 | *flavorDetail = FlavorDetail(jfd) | 106 | *flavorDetail = FlavorDetail(jfd) |
744 | 97 | return nil | 107 | return nil |
745 | 98 | } | 108 | } |
746 | @@ -104,21 +114,20 @@ | |||
747 | 104 | return nil, err | 114 | return nil, err |
748 | 105 | } | 115 | } |
749 | 106 | id := convertId(flavorDetail.Id) | 116 | id := convertId(flavorDetail.Id) |
751 | 107 | return appendJSON(data, "Id", id) | 117 | return appendJSON(data, idTag, id) |
752 | 108 | } | 118 | } |
753 | 109 | 119 | ||
754 | 110 | type jsonServerDetail ServerDetail | 120 | type jsonServerDetail ServerDetail |
755 | 111 | 121 | ||
756 | 112 | func (serverDetail *ServerDetail) UnmarshalJSON(b []byte) error { | 122 | func (serverDetail *ServerDetail) UnmarshalJSON(b []byte) error { |
757 | 113 | var jsd jsonServerDetail = jsonServerDetail(*serverDetail) | 123 | var jsd jsonServerDetail = jsonServerDetail(*serverDetail) |
766 | 114 | if err := json.Unmarshal(b, &jsd); err != nil { | 124 | var err error |
767 | 115 | return err | 125 | if err = json.Unmarshal(b, &jsd); err != nil { |
768 | 116 | } | 126 | return err |
769 | 117 | var id genericId | 127 | } |
770 | 118 | if err := json.Unmarshal(b, &id); err != nil { | 128 | if jsd.Id, err = getIdAsString(b, idTag); err != nil { |
771 | 119 | return err | 129 | return err |
772 | 120 | } | 130 | } |
765 | 121 | jsd.Id = id.String() | ||
773 | 122 | *serverDetail = ServerDetail(jsd) | 131 | *serverDetail = ServerDetail(jsd) |
774 | 123 | return nil | 132 | return nil |
775 | 124 | } | 133 | } |
776 | @@ -130,39 +139,26 @@ | |||
777 | 130 | return nil, err | 139 | return nil, err |
778 | 131 | } | 140 | } |
779 | 132 | id := convertId(serverDetail.Id) | 141 | id := convertId(serverDetail.Id) |
795 | 133 | return appendJSON(data, "Id", id) | 142 | return appendJSON(data, idTag, id) |
781 | 134 | } | ||
782 | 135 | |||
783 | 136 | type genericInstanceId struct { | ||
784 | 137 | InstanceId interface{} `json:"instance_id"` | ||
785 | 138 | } | ||
786 | 139 | |||
787 | 140 | func (id genericInstanceId) String() string { | ||
788 | 141 | if id.InstanceId == nil { | ||
789 | 142 | return "" | ||
790 | 143 | } | ||
791 | 144 | if fid, ok := id.InstanceId.(float64); ok { | ||
792 | 145 | return fmt.Sprint(int(fid)) | ||
793 | 146 | } | ||
794 | 147 | return fmt.Sprint(id.InstanceId) | ||
796 | 148 | } | 143 | } |
797 | 149 | 144 | ||
798 | 150 | type jsonFloatingIP FloatingIP | 145 | type jsonFloatingIP FloatingIP |
799 | 151 | 146 | ||
800 | 152 | func (floatingIP *FloatingIP) UnmarshalJSON(b []byte) error { | 147 | func (floatingIP *FloatingIP) UnmarshalJSON(b []byte) error { |
801 | 153 | var jfip jsonFloatingIP = jsonFloatingIP(*floatingIP) | 148 | var jfip jsonFloatingIP = jsonFloatingIP(*floatingIP) |
812 | 154 | if err := json.Unmarshal(b, &jfip); err != nil { | 149 | var err error |
813 | 155 | return err | 150 | if err = json.Unmarshal(b, &jfip); err != nil { |
814 | 156 | } | 151 | return err |
815 | 157 | var id genericInstanceId | 152 | } |
816 | 158 | if err := json.Unmarshal(b, &id); err != nil { | 153 | if instIdStr, err := getIdAsString(b, instanceIdTag); err != nil { |
817 | 159 | return err | 154 | return err |
818 | 160 | } | 155 | } else if instIdStr != "" { |
819 | 161 | instId := id.String() | 156 | strId := instIdStr |
810 | 162 | if instId != "" { | ||
811 | 163 | strId := instId | ||
820 | 164 | jfip.InstanceId = &strId | 157 | jfip.InstanceId = &strId |
821 | 165 | } | 158 | } |
822 | 159 | if jfip.Id, err = getIdAsString(b, idTag); err != nil { | ||
823 | 160 | return err | ||
824 | 161 | } | ||
825 | 166 | *floatingIP = FloatingIP(jfip) | 162 | *floatingIP = FloatingIP(jfip) |
826 | 167 | return nil | 163 | return nil |
827 | 168 | } | 164 | } |
828 | @@ -173,9 +169,114 @@ | |||
829 | 173 | if err != nil { | 169 | if err != nil { |
830 | 174 | return nil, err | 170 | return nil, err |
831 | 175 | } | 171 | } |
832 | 172 | id := convertId(floatingIP.Id) | ||
833 | 173 | data, err = appendJSON(data, idTag, id) | ||
834 | 174 | if err != nil { | ||
835 | 175 | return nil, err | ||
836 | 176 | } | ||
837 | 176 | if floatingIP.InstanceId == nil { | 177 | if floatingIP.InstanceId == nil { |
838 | 177 | return data, nil | 178 | return data, nil |
839 | 178 | } | 179 | } |
842 | 179 | id := convertId(*floatingIP.InstanceId) | 180 | instId := convertId(*floatingIP.InstanceId) |
843 | 180 | return appendJSON(data, "instance_id", id) | 181 | return appendJSON(data, instanceIdTag, instId) |
844 | 182 | } | ||
845 | 183 | |||
846 | 184 | type jsonSecurityGroup SecurityGroup | ||
847 | 185 | |||
848 | 186 | func (securityGroup *SecurityGroup) UnmarshalJSON(b []byte) error { | ||
849 | 187 | var jsg jsonSecurityGroup = jsonSecurityGroup(*securityGroup) | ||
850 | 188 | var err error | ||
851 | 189 | if err = json.Unmarshal(b, &jsg); err != nil { | ||
852 | 190 | return err | ||
853 | 191 | } | ||
854 | 192 | if jsg.Id, err = getIdAsString(b, idTag); err != nil { | ||
855 | 193 | return err | ||
856 | 194 | } | ||
857 | 195 | *securityGroup = SecurityGroup(jsg) | ||
858 | 196 | return nil | ||
859 | 197 | } | ||
860 | 198 | |||
861 | 199 | func (securityGroup SecurityGroup) MarshalJSON() ([]byte, error) { | ||
862 | 200 | var jsg jsonSecurityGroup = jsonSecurityGroup(securityGroup) | ||
863 | 201 | data, err := json.Marshal(&jsg) | ||
864 | 202 | if err != nil { | ||
865 | 203 | return nil, err | ||
866 | 204 | } | ||
867 | 205 | id := convertId(securityGroup.Id) | ||
868 | 206 | return appendJSON(data, idTag, id) | ||
869 | 207 | } | ||
870 | 208 | |||
871 | 209 | type jsonSecurityGroupRule SecurityGroupRule | ||
872 | 210 | |||
873 | 211 | func (securityGroupRule *SecurityGroupRule) UnmarshalJSON(b []byte) error { | ||
874 | 212 | var jsgr jsonSecurityGroupRule = jsonSecurityGroupRule(*securityGroupRule) | ||
875 | 213 | var err error | ||
876 | 214 | if err = json.Unmarshal(b, &jsgr); err != nil { | ||
877 | 215 | return err | ||
878 | 216 | } | ||
879 | 217 | if jsgr.Id, err = getIdAsString(b, idTag); err != nil { | ||
880 | 218 | return err | ||
881 | 219 | } | ||
882 | 220 | if jsgr.ParentGroupId, err = getIdAsString(b, parentGroupIdTag); err != nil { | ||
883 | 221 | return err | ||
884 | 222 | } | ||
885 | 223 | *securityGroupRule = SecurityGroupRule(jsgr) | ||
886 | 224 | return nil | ||
887 | 225 | } | ||
888 | 226 | |||
889 | 227 | func (securityGroupRule SecurityGroupRule) MarshalJSON() ([]byte, error) { | ||
890 | 228 | var jsgr jsonSecurityGroupRule = jsonSecurityGroupRule(securityGroupRule) | ||
891 | 229 | data, err := json.Marshal(&jsgr) | ||
892 | 230 | if err != nil { | ||
893 | 231 | return nil, err | ||
894 | 232 | } | ||
895 | 233 | id := convertId(securityGroupRule.Id) | ||
896 | 234 | data, err = appendJSON(data, idTag, id) | ||
897 | 235 | if err != nil { | ||
898 | 236 | return nil, err | ||
899 | 237 | } | ||
900 | 238 | if securityGroupRule.ParentGroupId == "" { | ||
901 | 239 | return data, nil | ||
902 | 240 | } | ||
903 | 241 | id = convertId(securityGroupRule.ParentGroupId) | ||
904 | 242 | return appendJSON(data, parentGroupIdTag, id) | ||
905 | 243 | } | ||
906 | 244 | |||
907 | 245 | type jsonRuleInfo RuleInfo | ||
908 | 246 | |||
909 | 247 | func (ruleInfo *RuleInfo) UnmarshalJSON(b []byte) error { | ||
910 | 248 | var jri jsonRuleInfo = jsonRuleInfo(*ruleInfo) | ||
911 | 249 | var err error | ||
912 | 250 | if err = json.Unmarshal(b, &jri); err != nil { | ||
913 | 251 | return err | ||
914 | 252 | } | ||
915 | 253 | if jri.ParentGroupId, err = getIdAsString(b, parentGroupIdTag); err != nil { | ||
916 | 254 | return err | ||
917 | 255 | } | ||
918 | 256 | if groupId, err := getIdAsString(b, groupIdTag); err != nil { | ||
919 | 257 | return err | ||
920 | 258 | } else if groupId != "" { | ||
921 | 259 | strId := groupId | ||
922 | 260 | jri.GroupId = &strId | ||
923 | 261 | } | ||
924 | 262 | *ruleInfo = RuleInfo(jri) | ||
925 | 263 | return nil | ||
926 | 264 | } | ||
927 | 265 | |||
928 | 266 | func (ruleInfo RuleInfo) MarshalJSON() ([]byte, error) { | ||
929 | 267 | var jri jsonRuleInfo = jsonRuleInfo(ruleInfo) | ||
930 | 268 | data, err := json.Marshal(&jri) | ||
931 | 269 | if err != nil { | ||
932 | 270 | return nil, err | ||
933 | 271 | } | ||
934 | 272 | id := convertId(ruleInfo.ParentGroupId) | ||
935 | 273 | data, err = appendJSON(data, parentGroupIdTag, id) | ||
936 | 274 | if err != nil { | ||
937 | 275 | return nil, err | ||
938 | 276 | } | ||
939 | 277 | if ruleInfo.GroupId == nil { | ||
940 | 278 | return data, nil | ||
941 | 279 | } | ||
942 | 280 | id = convertId(*ruleInfo.GroupId) | ||
943 | 281 | return appendJSON(data, groupIdTag, id) | ||
944 | 181 | } | 282 | } |
945 | 182 | 283 | ||
946 | === modified file 'nova/json_test.go' | |||
947 | --- nova/json_test.go 2013-03-21 11:43:56 +0000 | |||
948 | +++ nova/json_test.go 2013-07-01 07:24:26 +0000 | |||
949 | @@ -52,7 +52,7 @@ | |||
950 | 52 | 52 | ||
951 | 53 | func (s *JsonSuite) TestMarshallFloatingIPLargeIntId(c *C) { | 53 | func (s *JsonSuite) TestMarshallFloatingIPLargeIntId(c *C) { |
952 | 54 | id := "3000000" | 54 | id := "3000000" |
954 | 55 | fip := nova.FloatingIP{Id: 2000000, InstanceId: &id} | 55 | fip := nova.FloatingIP{Id: "2000000", InstanceId: &id} |
955 | 56 | var unmarshalled nova.FloatingIP | 56 | var unmarshalled nova.FloatingIP |
956 | 57 | s.assertMarshallRoundtrip(c, &fip, &unmarshalled) | 57 | s.assertMarshallRoundtrip(c, &fip, &unmarshalled) |
957 | 58 | } | 58 | } |
958 | 59 | 59 | ||
959 | === modified file 'nova/local_test.go' | |||
960 | --- nova/local_test.go 2013-03-28 09:06:20 +0000 | |||
961 | +++ nova/local_test.go 2013-07-01 07:24:26 +0000 | |||
962 | @@ -71,7 +71,7 @@ | |||
963 | 71 | Region: "some region", | 71 | Region: "some region", |
964 | 72 | TenantName: "tenant", | 72 | TenantName: "tenant", |
965 | 73 | } | 73 | } |
967 | 74 | s.openstack = openstackservice.New(s.cred) | 74 | s.openstack = openstackservice.New(s.cred, identity.AuthUserPass) |
968 | 75 | s.openstack.SetupHTTP(s.Mux) | 75 | s.openstack.SetupHTTP(s.Mux) |
969 | 76 | 76 | ||
970 | 77 | s.testFlavor = "m1.small" | 77 | s.testFlavor = "m1.small" |
971 | @@ -172,8 +172,8 @@ | |||
972 | 172 | fips, err := novaClient.ListFloatingIPs() | 172 | fips, err := novaClient.ListFloatingIPs() |
973 | 173 | c.Assert(err, IsNil) | 173 | c.Assert(err, IsNil) |
974 | 174 | c.Assert(fips, HasLen, 0) | 174 | c.Assert(fips, HasLen, 0) |
977 | 175 | s.openstack.Nova.RegisterControlPoint("addFloatingIP", s.addFloatingIPHook(s.openstack.Nova)) | 175 | cleanup := s.openstack.Nova.RegisterControlPoint("addFloatingIP", s.addFloatingIPHook(s.openstack.Nova)) |
978 | 176 | defer s.openstack.Nova.RegisterControlPoint("addFloatingIP", nil) | 176 | defer cleanup() |
979 | 177 | s.noMoreIPs = true | 177 | s.noMoreIPs = true |
980 | 178 | fip, err := novaClient.AllocateFloatingIP() | 178 | fip, err := novaClient.AllocateFloatingIP() |
981 | 179 | c.Assert(err, ErrorMatches, "(.|\n)*Zero floating ips available.*") | 179 | c.Assert(err, ErrorMatches, "(.|\n)*Zero floating ips available.*") |
982 | @@ -203,7 +203,8 @@ | |||
983 | 203 | func (s *localLiveSuite) TestReauthenticate(c *C) { | 203 | func (s *localLiveSuite) TestReauthenticate(c *C) { |
984 | 204 | novaClient := s.setupClient(c, nil) | 204 | novaClient := s.setupClient(c, nil) |
985 | 205 | up := s.openstack.Identity.(*identityservice.UserPass) | 205 | up := s.openstack.Identity.(*identityservice.UserPass) |
987 | 206 | defer up.RegisterControlPoint("authorisation", s.authHook(up)) | 206 | cleanup := up.RegisterControlPoint("authorisation", s.authHook(up)) |
988 | 207 | defer cleanup() | ||
989 | 207 | 208 | ||
990 | 208 | // An invalid token is returned after the first authentication step, resulting in the ListServers call | 209 | // An invalid token is returned after the first authentication step, resulting in the ListServers call |
991 | 209 | // returning a 401. Subsequent authentication calls return the correct token so the auth retry does it's job. | 210 | // returning a 401. Subsequent authentication calls return the correct token so the auth retry does it's job. |
992 | @@ -215,7 +216,8 @@ | |||
993 | 215 | func (s *localLiveSuite) TestReauthenticateFailure(c *C) { | 216 | func (s *localLiveSuite) TestReauthenticateFailure(c *C) { |
994 | 216 | novaClient := s.setupClient(c, nil) | 217 | novaClient := s.setupClient(c, nil) |
995 | 217 | up := s.openstack.Identity.(*identityservice.UserPass) | 218 | up := s.openstack.Identity.(*identityservice.UserPass) |
997 | 218 | defer up.RegisterControlPoint("authorisation", s.authHook(up)) | 219 | cleanup := up.RegisterControlPoint("authorisation", s.authHook(up)) |
998 | 220 | defer cleanup() | ||
999 | 219 | 221 | ||
1000 | 220 | // If the re-authentication fails, ensure an Unauthorised error is returned. | 222 | // If the re-authentication fails, ensure an Unauthorised error is returned. |
1001 | 221 | s.badTokens = 2 | 223 | s.badTokens = 2 |
1002 | 222 | 224 | ||
1003 | === modified file 'nova/nova.go' | |||
1004 | --- nova/nova.go 2013-04-23 00:19:57 +0000 | |||
1005 | +++ nova/nova.go 2013-07-01 07:24:26 +0000 | |||
1006 | @@ -11,7 +11,6 @@ | |||
1007 | 11 | "net/http" | 11 | "net/http" |
1008 | 12 | "net/url" | 12 | "net/url" |
1009 | 13 | "reflect" | 13 | "reflect" |
1010 | 14 | "strconv" | ||
1011 | 15 | ) | 14 | ) |
1012 | 16 | 15 | ||
1013 | 17 | // API URL parts. | 16 | // API URL parts. |
1014 | @@ -327,9 +326,9 @@ | |||
1015 | 327 | FromPort *int `json:"from_port"` // Can be nil | 326 | FromPort *int `json:"from_port"` // Can be nil |
1016 | 328 | IPProtocol *string `json:"ip_protocol"` // Can be nil | 327 | IPProtocol *string `json:"ip_protocol"` // Can be nil |
1017 | 329 | ToPort *int `json:"to_port"` // Can be nil | 328 | ToPort *int `json:"to_port"` // Can be nil |
1019 | 330 | ParentGroupId int `json:"parent_group_id"` | 329 | ParentGroupId string `json:"-"` |
1020 | 331 | IPRange map[string]string `json:"ip_range"` // Can be empty | 330 | IPRange map[string]string `json:"ip_range"` // Can be empty |
1022 | 332 | Id int | 331 | Id string `json:"-"` |
1023 | 333 | Group SecurityGroupRef | 332 | Group SecurityGroupRef |
1024 | 334 | } | 333 | } |
1025 | 335 | 334 | ||
1026 | @@ -337,7 +336,7 @@ | |||
1027 | 337 | type SecurityGroup struct { | 336 | type SecurityGroup struct { |
1028 | 338 | Rules []SecurityGroupRule | 337 | Rules []SecurityGroupRule |
1029 | 339 | TenantId string `json:"tenant_id"` | 338 | TenantId string `json:"tenant_id"` |
1031 | 340 | Id int | 339 | Id string `json:"-"` |
1032 | 341 | Name string | 340 | Name string |
1033 | 342 | Description string | 341 | Description string |
1034 | 343 | } | 342 | } |
1035 | @@ -389,12 +388,8 @@ | |||
1036 | 389 | if err == nil { | 388 | if err == nil { |
1037 | 390 | result := make([]SecurityGroup, len(serverDetails.Groups)) | 389 | result := make([]SecurityGroup, len(serverDetails.Groups)) |
1038 | 391 | for i, e := range serverDetails.Groups { | 390 | for i, e := range serverDetails.Groups { |
1039 | 392 | id, err := strconv.Atoi(e.Id) | ||
1040 | 393 | if err != nil { | ||
1041 | 394 | return nil, errors.Newf(err, "failed to parse security group id %s", e.Id) | ||
1042 | 395 | } | ||
1043 | 396 | result[i] = SecurityGroup{ | 391 | result[i] = SecurityGroup{ |
1045 | 397 | Id: id, | 392 | Id: e.Id, |
1046 | 398 | Name: e.Name, | 393 | Name: e.Name, |
1047 | 399 | } | 394 | } |
1048 | 400 | } | 395 | } |
1049 | @@ -429,8 +424,8 @@ | |||
1050 | 429 | } | 424 | } |
1051 | 430 | 425 | ||
1052 | 431 | // DeleteSecurityGroup deletes the specified security group. | 426 | // DeleteSecurityGroup deletes the specified security group. |
1055 | 432 | func (c *Client) DeleteSecurityGroup(groupId int) error { | 427 | func (c *Client) DeleteSecurityGroup(groupId string) error { |
1056 | 433 | url := fmt.Sprintf("%s/%d", apiSecurityGroups, groupId) | 428 | url := fmt.Sprintf("%s/%s", apiSecurityGroups, groupId) |
1057 | 434 | requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}} | 429 | requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}} |
1058 | 435 | err := c.client.SendRequest(client.DELETE, "compute", url, &requestData) | 430 | err := c.client.SendRequest(client.DELETE, "compute", url, &requestData) |
1059 | 436 | if err != nil { | 431 | if err != nil { |
1060 | @@ -473,14 +468,14 @@ | |||
1061 | 473 | // Cidr cannot be specified with GroupId. Ingress rules need a valid | 468 | // Cidr cannot be specified with GroupId. Ingress rules need a valid |
1062 | 474 | // subnet mast in CIDR format here, while if GroupID is specifed, it | 469 | // subnet mast in CIDR format here, while if GroupID is specifed, it |
1063 | 475 | // means you're adding a group rule, specifying source group ID, which | 470 | // means you're adding a group rule, specifying source group ID, which |
1065 | 476 | // must exists already and can be equal to ParentGroupId). | 471 | // must exist already and can be equal to ParentGroupId). |
1066 | 477 | // need Cidr, while | 472 | // need Cidr, while |
1069 | 478 | Cidr string `json:"cidr"` | 473 | Cidr string `json:"cidr"` |
1070 | 479 | GroupId *int `json:"group_id"` | 474 | GroupId *string `json:"-"` |
1071 | 480 | 475 | ||
1072 | 481 | // ParentGroupId is always required and specifies the group to which | 476 | // ParentGroupId is always required and specifies the group to which |
1073 | 482 | // the rule is added. | 477 | // the rule is added. |
1075 | 483 | ParentGroupId int `json:"parent_group_id"` | 478 | ParentGroupId string `json:"-"` |
1076 | 484 | } | 479 | } |
1077 | 485 | 480 | ||
1078 | 486 | // CreateSecurityGroupRule creates a security group rule. | 481 | // CreateSecurityGroupRule creates a security group rule. |
1079 | @@ -505,8 +500,8 @@ | |||
1080 | 505 | } | 500 | } |
1081 | 506 | 501 | ||
1082 | 507 | // DeleteSecurityGroupRule deletes the specified security group rule. | 502 | // DeleteSecurityGroupRule deletes the specified security group rule. |
1085 | 508 | func (c *Client) DeleteSecurityGroupRule(ruleId int) error { | 503 | func (c *Client) DeleteSecurityGroupRule(ruleId string) error { |
1086 | 509 | url := fmt.Sprintf("%s/%d", apiSecurityGroupRules, ruleId) | 504 | url := fmt.Sprintf("%s/%s", apiSecurityGroupRules, ruleId) |
1087 | 510 | requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}} | 505 | requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}} |
1088 | 511 | err := c.client.SendRequest(client.DELETE, "compute", url, &requestData) | 506 | err := c.client.SendRequest(client.DELETE, "compute", url, &requestData) |
1089 | 512 | if err != nil { | 507 | if err != nil { |
1090 | @@ -556,7 +551,7 @@ | |||
1091 | 556 | type FloatingIP struct { | 551 | type FloatingIP struct { |
1092 | 557 | // FixedIP holds the private IP address of the machine (when assigned) | 552 | // FixedIP holds the private IP address of the machine (when assigned) |
1093 | 558 | FixedIP *string `json:"fixed_ip"` | 553 | FixedIP *string `json:"fixed_ip"` |
1095 | 559 | Id int `json:"id"` | 554 | Id string `json:"-"` |
1096 | 560 | // InstanceId holds the instance id of the machine, if this FIP is assigned to one | 555 | // InstanceId holds the instance id of the machine, if this FIP is assigned to one |
1097 | 561 | InstanceId *string `json:"-"` | 556 | InstanceId *string `json:"-"` |
1098 | 562 | IP string `json:"ip"` | 557 | IP string `json:"ip"` |
1099 | @@ -578,16 +573,16 @@ | |||
1100 | 578 | } | 573 | } |
1101 | 579 | 574 | ||
1102 | 580 | // GetFloatingIP lists details of the floating IP address associated with specified id. | 575 | // GetFloatingIP lists details of the floating IP address associated with specified id. |
1104 | 581 | func (c *Client) GetFloatingIP(ipId int) (*FloatingIP, error) { | 576 | func (c *Client) GetFloatingIP(ipId string) (*FloatingIP, error) { |
1105 | 582 | var resp struct { | 577 | var resp struct { |
1106 | 583 | FloatingIP FloatingIP `json:"floating_ip"` | 578 | FloatingIP FloatingIP `json:"floating_ip"` |
1107 | 584 | } | 579 | } |
1108 | 585 | 580 | ||
1110 | 586 | url := fmt.Sprintf("%s/%d", apiFloatingIPs, ipId) | 581 | url := fmt.Sprintf("%s/%s", apiFloatingIPs, ipId) |
1111 | 587 | requestData := goosehttp.RequestData{RespValue: &resp} | 582 | requestData := goosehttp.RequestData{RespValue: &resp} |
1112 | 588 | err := c.client.SendRequest(client.GET, "compute", url, &requestData) | 583 | err := c.client.SendRequest(client.GET, "compute", url, &requestData) |
1113 | 589 | if err != nil { | 584 | if err != nil { |
1115 | 590 | return nil, errors.Newf(err, "failed to get floating ip %d details", ipId) | 585 | return nil, errors.Newf(err, "failed to get floating ip %s details", ipId) |
1116 | 591 | } | 586 | } |
1117 | 592 | return &resp.FloatingIP, nil | 587 | return &resp.FloatingIP, nil |
1118 | 593 | } | 588 | } |
1119 | @@ -607,12 +602,12 @@ | |||
1120 | 607 | } | 602 | } |
1121 | 608 | 603 | ||
1122 | 609 | // DeleteFloatingIP deallocates the floating IP address associated with the specified id. | 604 | // DeleteFloatingIP deallocates the floating IP address associated with the specified id. |
1125 | 610 | func (c *Client) DeleteFloatingIP(ipId int) error { | 605 | func (c *Client) DeleteFloatingIP(ipId string) error { |
1126 | 611 | url := fmt.Sprintf("%s/%d", apiFloatingIPs, ipId) | 606 | url := fmt.Sprintf("%s/%s", apiFloatingIPs, ipId) |
1127 | 612 | requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}} | 607 | requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}} |
1128 | 613 | err := c.client.SendRequest(client.DELETE, "compute", url, &requestData) | 608 | err := c.client.SendRequest(client.DELETE, "compute", url, &requestData) |
1129 | 614 | if err != nil { | 609 | if err != nil { |
1131 | 615 | err = errors.Newf(err, "failed to delete floating ip %d details", ipId) | 610 | err = errors.Newf(err, "failed to delete floating ip %s details", ipId) |
1132 | 616 | } | 611 | } |
1133 | 617 | return err | 612 | return err |
1134 | 618 | } | 613 | } |
1135 | 619 | 614 | ||
1136 | === modified file 'nova/nova_test.go' | |||
1137 | --- nova/nova_test.go 2013-02-06 06:15:09 +0000 | |||
1138 | +++ nova/nova_test.go 2013-07-01 07:24:26 +0000 | |||
1139 | @@ -18,9 +18,9 @@ | |||
1140 | 18 | // Out-of-the-box, we support live testing using Canonistack or HP Cloud. | 18 | // Out-of-the-box, we support live testing using Canonistack or HP Cloud. |
1141 | 19 | var testConstraints = map[string]imageDetails{ | 19 | var testConstraints = map[string]imageDetails{ |
1142 | 20 | "canonistack": imageDetails{ | 20 | "canonistack": imageDetails{ |
1144 | 21 | flavor: "m1.tiny", imageId: "c876e5fe-abb0-41f0-8f29-f0b47481f523"}, | 21 | flavor: "m1.tiny", imageId: "f2ca48ce-30d5-4f1f-9075-12e64510368d"}, |
1145 | 22 | "hpcloud": imageDetails{ | 22 | "hpcloud": imageDetails{ |
1147 | 23 | flavor: "standard.xsmall", imageId: "75845"}, | 23 | flavor: "standard.xsmall", imageId: "81078"}, |
1148 | 24 | } | 24 | } |
1149 | 25 | 25 | ||
1150 | 26 | var live = flag.Bool("live", false, "Include live OpenStack tests") | 26 | var live = flag.Bool("live", false, "Include live OpenStack tests") |
1151 | 27 | 27 | ||
1152 | === modified file 'swift/local_test.go' | |||
1153 | --- swift/local_test.go 2013-01-29 00:45:31 +0000 | |||
1154 | +++ swift/local_test.go 2013-07-01 07:24:26 +0000 | |||
1155 | @@ -33,7 +33,8 @@ | |||
1156 | 33 | TenantName: "tenant", | 33 | TenantName: "tenant", |
1157 | 34 | } | 34 | } |
1158 | 35 | s.LiveTestsPublicContainer.cred = s.LiveTests.cred | 35 | s.LiveTestsPublicContainer.cred = s.LiveTests.cred |
1160 | 36 | s.openstack = openstackservice.New(s.LiveTests.cred) | 36 | s.openstack = openstackservice.New(s.LiveTests.cred, |
1161 | 37 | identity.AuthUserPass) | ||
1162 | 37 | 38 | ||
1163 | 38 | s.LiveTests.SetUpSuite(c) | 39 | s.LiveTests.SetUpSuite(c) |
1164 | 39 | s.LiveTestsPublicContainer.SetUpSuite(c) | 40 | s.LiveTestsPublicContainer.SetUpSuite(c) |
1165 | 40 | 41 | ||
1166 | === modified file 'testservices/identityservice/identityservice.go' | |||
1167 | --- testservices/identityservice/identityservice.go 2013-01-24 03:15:19 +0000 | |||
1168 | +++ testservices/identityservice/identityservice.go 2013-07-01 07:24:26 +0000 | |||
1169 | @@ -7,6 +7,7 @@ | |||
1170 | 7 | AddUser(user, secret, tenant string) *UserInfo | 7 | AddUser(user, secret, tenant string) *UserInfo |
1171 | 8 | FindUser(token string) (*UserInfo, error) | 8 | FindUser(token string) (*UserInfo, error) |
1172 | 9 | RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider) | 9 | RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider) |
1173 | 10 | AddService(service Service) | ||
1174 | 10 | SetupHTTP(mux *http.ServeMux) | 11 | SetupHTTP(mux *http.ServeMux) |
1175 | 11 | } | 12 | } |
1176 | 12 | 13 | ||
1177 | 13 | 14 | ||
1178 | === added file 'testservices/identityservice/keypair.go' | |||
1179 | --- testservices/identityservice/keypair.go 1970-01-01 00:00:00 +0000 | |||
1180 | +++ testservices/identityservice/keypair.go 2013-07-01 07:24:26 +0000 | |||
1181 | @@ -0,0 +1,123 @@ | |||
1182 | 1 | package identityservice | ||
1183 | 2 | |||
1184 | 3 | import ( | ||
1185 | 4 | "encoding/json" | ||
1186 | 5 | "fmt" | ||
1187 | 6 | "io/ioutil" | ||
1188 | 7 | "launchpad.net/goose/testservices/hook" | ||
1189 | 8 | "net/http" | ||
1190 | 9 | ) | ||
1191 | 10 | |||
1192 | 11 | // Implement the v2 Key Pair form of identity based on Keystone | ||
1193 | 12 | |||
1194 | 13 | type KeyPairRequest struct { | ||
1195 | 14 | Auth struct { | ||
1196 | 15 | ApiAccessKeyCredentials struct { | ||
1197 | 16 | AccessKey string `json:"accessKey"` | ||
1198 | 17 | SecretKey string `json:"secretKey"` | ||
1199 | 18 | } `json:"apiAccessKeyCredentials"` | ||
1200 | 19 | TenantName string `json:"tenantName"` | ||
1201 | 20 | } `json:"auth"` | ||
1202 | 21 | } | ||
1203 | 22 | |||
1204 | 23 | type KeyPair struct { | ||
1205 | 24 | hook.TestService | ||
1206 | 25 | Users | ||
1207 | 26 | services []Service | ||
1208 | 27 | } | ||
1209 | 28 | |||
1210 | 29 | func NewKeyPair() *KeyPair { | ||
1211 | 30 | return &KeyPair{ | ||
1212 | 31 | Users: Users{ | ||
1213 | 32 | users: make(map[string]UserInfo), | ||
1214 | 33 | tenants: make(map[string]string), | ||
1215 | 34 | }, | ||
1216 | 35 | } | ||
1217 | 36 | } | ||
1218 | 37 | |||
1219 | 38 | func (u *KeyPair) RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider) { | ||
1220 | 39 | service := Service{name, serviceType, serviceProvider.Endpoints()} | ||
1221 | 40 | u.AddService(service) | ||
1222 | 41 | } | ||
1223 | 42 | |||
1224 | 43 | func (u *KeyPair) AddService(service Service) { | ||
1225 | 44 | u.services = append(u.services, service) | ||
1226 | 45 | } | ||
1227 | 46 | |||
1228 | 47 | func (u *KeyPair) ReturnFailure(w http.ResponseWriter, status int, message string) { | ||
1229 | 48 | e := ErrorWrapper{ | ||
1230 | 49 | Error: ErrorResponse{ | ||
1231 | 50 | Message: message, | ||
1232 | 51 | Code: status, | ||
1233 | 52 | Title: http.StatusText(status), | ||
1234 | 53 | }, | ||
1235 | 54 | } | ||
1236 | 55 | if content, err := json.Marshal(e); err != nil { | ||
1237 | 56 | w.Header().Set("Content-Length", fmt.Sprintf("%d", len(internalError))) | ||
1238 | 57 | w.WriteHeader(http.StatusInternalServerError) | ||
1239 | 58 | w.Write(internalError) | ||
1240 | 59 | } else { | ||
1241 | 60 | w.Header().Set("Content-Length", fmt.Sprintf("%d", len(content))) | ||
1242 | 61 | w.WriteHeader(status) | ||
1243 | 62 | w.Write(content) | ||
1244 | 63 | } | ||
1245 | 64 | } | ||
1246 | 65 | |||
1247 | 66 | func (u *KeyPair) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||
1248 | 67 | var req KeyPairRequest | ||
1249 | 68 | // Testing against Canonistack, all responses are application/json, even failures | ||
1250 | 69 | w.Header().Set("Content-Type", "application/json") | ||
1251 | 70 | if r.Header.Get("Content-Type") != "application/json" { | ||
1252 | 71 | u.ReturnFailure(w, http.StatusBadRequest, notJSON) | ||
1253 | 72 | return | ||
1254 | 73 | } | ||
1255 | 74 | if content, err := ioutil.ReadAll(r.Body); err != nil { | ||
1256 | 75 | w.WriteHeader(http.StatusBadRequest) | ||
1257 | 76 | return | ||
1258 | 77 | } else { | ||
1259 | 78 | if err := json.Unmarshal(content, &req); err != nil { | ||
1260 | 79 | u.ReturnFailure(w, http.StatusBadRequest, notJSON) | ||
1261 | 80 | return | ||
1262 | 81 | } | ||
1263 | 82 | } | ||
1264 | 83 | userInfo, errmsg := u.authenticate(req.Auth.ApiAccessKeyCredentials.AccessKey, req.Auth.ApiAccessKeyCredentials.SecretKey) | ||
1265 | 84 | if errmsg != "" { | ||
1266 | 85 | u.ReturnFailure(w, http.StatusUnauthorized, errmsg) | ||
1267 | 86 | return | ||
1268 | 87 | } | ||
1269 | 88 | res, err := u.generateAccessResponse(userInfo) | ||
1270 | 89 | if err != nil { | ||
1271 | 90 | u.ReturnFailure(w, http.StatusInternalServerError, err.Error()) | ||
1272 | 91 | return | ||
1273 | 92 | } | ||
1274 | 93 | if content, err := json.Marshal(res); err != nil { | ||
1275 | 94 | u.ReturnFailure(w, http.StatusInternalServerError, err.Error()) | ||
1276 | 95 | return | ||
1277 | 96 | } else { | ||
1278 | 97 | w.WriteHeader(http.StatusOK) | ||
1279 | 98 | w.Write(content) | ||
1280 | 99 | return | ||
1281 | 100 | } | ||
1282 | 101 | panic("unreachable") | ||
1283 | 102 | } | ||
1284 | 103 | |||
1285 | 104 | func (u *KeyPair) generateAccessResponse(userInfo *UserInfo) (*AccessResponse, error) { | ||
1286 | 105 | res := AccessResponse{} | ||
1287 | 106 | // We pre-populate the response with genuine entries so that it looks sane. | ||
1288 | 107 | if err := json.Unmarshal([]byte(exampleResponse), &res); err != nil { | ||
1289 | 108 | return nil, err | ||
1290 | 109 | } | ||
1291 | 110 | res.Access.ServiceCatalog = u.services | ||
1292 | 111 | res.Access.Token.Id = userInfo.Token | ||
1293 | 112 | res.Access.Token.Tenant.Id = userInfo.TenantId | ||
1294 | 113 | res.Access.User.Id = userInfo.Id | ||
1295 | 114 | if err := u.ProcessControlHook("authorisation", u, &res, userInfo); err != nil { | ||
1296 | 115 | return nil, err | ||
1297 | 116 | } | ||
1298 | 117 | return &res, nil | ||
1299 | 118 | } | ||
1300 | 119 | |||
1301 | 120 | // setupHTTP attaches all the needed handlers to provide the HTTP API. | ||
1302 | 121 | func (u *KeyPair) SetupHTTP(mux *http.ServeMux) { | ||
1303 | 122 | mux.Handle("/tokens", u) | ||
1304 | 123 | } | ||
1305 | 0 | 124 | ||
1306 | === added file 'testservices/identityservice/keypair_test.go' | |||
1307 | --- testservices/identityservice/keypair_test.go 1970-01-01 00:00:00 +0000 | |||
1308 | +++ testservices/identityservice/keypair_test.go 2013-07-01 07:24:26 +0000 | |||
1309 | @@ -0,0 +1,130 @@ | |||
1310 | 1 | package identityservice | ||
1311 | 2 | |||
1312 | 3 | import ( | ||
1313 | 4 | "encoding/json" | ||
1314 | 5 | "fmt" | ||
1315 | 6 | "io/ioutil" | ||
1316 | 7 | . "launchpad.net/gocheck" | ||
1317 | 8 | "launchpad.net/goose/testing/httpsuite" | ||
1318 | 9 | "net/http" | ||
1319 | 10 | "strings" | ||
1320 | 11 | ) | ||
1321 | 12 | |||
1322 | 13 | type KeyPairSuite struct { | ||
1323 | 14 | httpsuite.HTTPSuite | ||
1324 | 15 | } | ||
1325 | 16 | |||
1326 | 17 | var _ = Suite(&KeyPairSuite{}) | ||
1327 | 18 | |||
1328 | 19 | func makeKeyPair(user, secret string) (identity *KeyPair) { | ||
1329 | 20 | identity = NewKeyPair() | ||
1330 | 21 | // Ensure that it conforms to the interface | ||
1331 | 22 | var _ IdentityService = identity | ||
1332 | 23 | if user != "" { | ||
1333 | 24 | identity.AddUser(user, secret, "tenant") | ||
1334 | 25 | } | ||
1335 | 26 | return | ||
1336 | 27 | } | ||
1337 | 28 | |||
1338 | 29 | func (s *KeyPairSuite) setupKeyPair(user, secret string) { | ||
1339 | 30 | var identity *KeyPair | ||
1340 | 31 | identity = makeKeyPair(user, secret) | ||
1341 | 32 | identity.SetupHTTP(s.Mux) | ||
1342 | 33 | return | ||
1343 | 34 | } | ||
1344 | 35 | |||
1345 | 36 | func (s *KeyPairSuite) setupKeyPairWithServices(user, secret string, services []Service) { | ||
1346 | 37 | var identity *KeyPair | ||
1347 | 38 | identity = makeKeyPair(user, secret) | ||
1348 | 39 | for _, service := range services { | ||
1349 | 40 | identity.AddService(service) | ||
1350 | 41 | } | ||
1351 | 42 | identity.SetupHTTP(s.Mux) | ||
1352 | 43 | return | ||
1353 | 44 | } | ||
1354 | 45 | |||
1355 | 46 | const authKeyPairTemplate = `{ | ||
1356 | 47 | "auth": { | ||
1357 | 48 | "tenantName": "tenant-something", | ||
1358 | 49 | "apiAccessKeyCredentials": { | ||
1359 | 50 | "accessKey": "%s", | ||
1360 | 51 | "secretKey": "%s" | ||
1361 | 52 | } | ||
1362 | 53 | } | ||
1363 | 54 | }` | ||
1364 | 55 | |||
1365 | 56 | func keyPairAuthRequest(URL, access, secret string) (*http.Response, error) { | ||
1366 | 57 | client := &http.DefaultClient | ||
1367 | 58 | body := strings.NewReader(fmt.Sprintf(authKeyPairTemplate, access, secret)) | ||
1368 | 59 | request, err := http.NewRequest("POST", URL+"/tokens", body) | ||
1369 | 60 | request.Header.Set("Content-Type", "application/json") | ||
1370 | 61 | if err != nil { | ||
1371 | 62 | return nil, err | ||
1372 | 63 | } | ||
1373 | 64 | return client.Do(request) | ||
1374 | 65 | } | ||
1375 | 66 | |||
1376 | 67 | func (s *KeyPairSuite) TestNotJSON(c *C) { | ||
1377 | 68 | // We do everything in keyPairAuthRequest, except set the Content-Type | ||
1378 | 69 | s.setupKeyPair("user", "secret") | ||
1379 | 70 | client := &http.DefaultClient | ||
1380 | 71 | body := strings.NewReader(fmt.Sprintf(authTemplate, "user", "secret")) | ||
1381 | 72 | request, err := http.NewRequest("POST", s.Server.URL+"/tokens", body) | ||
1382 | 73 | c.Assert(err, IsNil) | ||
1383 | 74 | res, err := client.Do(request) | ||
1384 | 75 | defer res.Body.Close() | ||
1385 | 76 | c.Assert(err, IsNil) | ||
1386 | 77 | CheckErrorResponse(c, res, http.StatusBadRequest, notJSON) | ||
1387 | 78 | } | ||
1388 | 79 | |||
1389 | 80 | func (s *KeyPairSuite) TestBadJSON(c *C) { | ||
1390 | 81 | // We do everything in keyPairAuthRequest, except set the Content-Type | ||
1391 | 82 | s.setupKeyPair("user", "secret") | ||
1392 | 83 | res, err := keyPairAuthRequest(s.Server.URL, `garbage"in`, "secret") | ||
1393 | 84 | defer res.Body.Close() | ||
1394 | 85 | c.Assert(err, IsNil) | ||
1395 | 86 | CheckErrorResponse(c, res, http.StatusBadRequest, notJSON) | ||
1396 | 87 | } | ||
1397 | 88 | |||
1398 | 89 | func (s *KeyPairSuite) TestNoSuchUser(c *C) { | ||
1399 | 90 | s.setupKeyPair("user", "secret") | ||
1400 | 91 | res, err := keyPairAuthRequest(s.Server.URL, "not-user", "secret") | ||
1401 | 92 | defer res.Body.Close() | ||
1402 | 93 | c.Assert(err, IsNil) | ||
1403 | 94 | CheckErrorResponse(c, res, http.StatusUnauthorized, notAuthorized) | ||
1404 | 95 | } | ||
1405 | 96 | |||
1406 | 97 | func (s *KeyPairSuite) TestBadPassword(c *C) { | ||
1407 | 98 | s.setupKeyPair("user", "secret") | ||
1408 | 99 | res, err := keyPairAuthRequest(s.Server.URL, "user", "not-secret") | ||
1409 | 100 | defer res.Body.Close() | ||
1410 | 101 | c.Assert(err, IsNil) | ||
1411 | 102 | CheckErrorResponse(c, res, http.StatusUnauthorized, invalidUser) | ||
1412 | 103 | } | ||
1413 | 104 | |||
1414 | 105 | func (s *KeyPairSuite) TestValidAuthorization(c *C) { | ||
1415 | 106 | compute_url := "http://testing.invalid/compute" | ||
1416 | 107 | s.setupKeyPairWithServices("user", "secret", []Service{ | ||
1417 | 108 | {"nova", "compute", []Endpoint{ | ||
1418 | 109 | {PublicURL: compute_url}, | ||
1419 | 110 | }}}) | ||
1420 | 111 | res, err := keyPairAuthRequest(s.Server.URL, "user", "secret") | ||
1421 | 112 | defer res.Body.Close() | ||
1422 | 113 | c.Assert(err, IsNil) | ||
1423 | 114 | c.Check(res.StatusCode, Equals, http.StatusOK) | ||
1424 | 115 | c.Check(res.Header.Get("Content-Type"), Equals, "application/json") | ||
1425 | 116 | content, err := ioutil.ReadAll(res.Body) | ||
1426 | 117 | c.Assert(err, IsNil) | ||
1427 | 118 | var response AccessResponse | ||
1428 | 119 | err = json.Unmarshal(content, &response) | ||
1429 | 120 | c.Assert(err, IsNil) | ||
1430 | 121 | c.Check(response.Access.Token.Id, NotNil) | ||
1431 | 122 | novaURL := "" | ||
1432 | 123 | for _, service := range response.Access.ServiceCatalog { | ||
1433 | 124 | if service.Type == "compute" { | ||
1434 | 125 | novaURL = service.Endpoints[0].PublicURL | ||
1435 | 126 | break | ||
1436 | 127 | } | ||
1437 | 128 | } | ||
1438 | 129 | c.Assert(novaURL, Equals, compute_url) | ||
1439 | 130 | } | ||
1440 | 0 | 131 | ||
1441 | === modified file 'testservices/identityservice/legacy.go' | |||
1442 | --- testservices/identityservice/legacy.go 2013-01-24 01:01:35 +0000 | |||
1443 | +++ testservices/identityservice/legacy.go 2013-07-01 07:24:26 +0000 | |||
1444 | @@ -20,6 +20,10 @@ | |||
1445 | 20 | // NOOP for legacy identity service. | 20 | // NOOP for legacy identity service. |
1446 | 21 | } | 21 | } |
1447 | 22 | 22 | ||
1448 | 23 | func (lis *Legacy) AddService(service Service) { | ||
1449 | 24 | // NOOP for legacy identity service. | ||
1450 | 25 | } | ||
1451 | 26 | |||
1452 | 23 | func (lis *Legacy) SetManagementURL(URL string) { | 27 | func (lis *Legacy) SetManagementURL(URL string) { |
1453 | 24 | lis.managementURL = URL | 28 | lis.managementURL = URL |
1454 | 25 | } | 29 | } |
1455 | 26 | 30 | ||
1456 | === modified file 'testservices/identityservice/userpass.go' | |||
1457 | --- testservices/identityservice/userpass.go 2013-02-20 06:00:49 +0000 | |||
1458 | +++ testservices/identityservice/userpass.go 2013-07-01 07:24:26 +0000 | |||
1459 | @@ -47,8 +47,9 @@ | |||
1460 | 47 | Expires string `json:"expires"` // should this be a date object? | 47 | Expires string `json:"expires"` // should this be a date object? |
1461 | 48 | Id string `json:"id"` // Actual token string | 48 | Id string `json:"id"` // Actual token string |
1462 | 49 | Tenant struct { | 49 | Tenant struct { |
1465 | 50 | Id string `json:"id"` | 50 | Id string `json:"id"` |
1466 | 51 | Name string `json:"name"` | 51 | Name string `json:"name"` |
1467 | 52 | Description *string `json:"description"` | ||
1468 | 52 | } `json:"tenant"` | 53 | } `json:"tenant"` |
1469 | 53 | } | 54 | } |
1470 | 54 | 55 | ||
1471 | @@ -118,7 +119,8 @@ | |||
1472 | 118 | "id": "5df9d45d-d198-4222-9b4c-7a280aa35666", | 119 | "id": "5df9d45d-d198-4222-9b4c-7a280aa35666", |
1473 | 119 | "tenant": { | 120 | "tenant": { |
1474 | 120 | "id": "1", | 121 | "id": "1", |
1476 | 121 | "name": "admin" | 122 | "name": "admin", |
1477 | 123 | "description": null | ||
1478 | 122 | } | 124 | } |
1479 | 123 | }, | 125 | }, |
1480 | 124 | "user": { | 126 | "user": { |
1481 | 125 | 127 | ||
1482 | === modified file 'testservices/novaservice/service.go' | |||
1483 | --- testservices/novaservice/service.go 2013-04-22 23:20:03 +0000 | |||
1484 | +++ testservices/novaservice/service.go 2013-07-01 07:24:26 +0000 | |||
1485 | @@ -21,11 +21,11 @@ | |||
1486 | 21 | testservices.ServiceInstance | 21 | testservices.ServiceInstance |
1487 | 22 | flavors map[string]nova.FlavorDetail | 22 | flavors map[string]nova.FlavorDetail |
1488 | 23 | servers map[string]nova.ServerDetail | 23 | servers map[string]nova.ServerDetail |
1494 | 24 | groups map[int]nova.SecurityGroup | 24 | groups map[string]nova.SecurityGroup |
1495 | 25 | rules map[int]nova.SecurityGroupRule | 25 | rules map[string]nova.SecurityGroupRule |
1496 | 26 | floatingIPs map[int]nova.FloatingIP | 26 | floatingIPs map[string]nova.FloatingIP |
1497 | 27 | serverGroups map[string][]int | 27 | serverGroups map[string][]string |
1498 | 28 | serverIPs map[string][]int | 28 | serverIPs map[string][]string |
1499 | 29 | nextServerId int | 29 | nextServerId int |
1500 | 30 | nextGroupId int | 30 | nextGroupId int |
1501 | 31 | nextRuleId int | 31 | nextRuleId int |
1502 | @@ -74,16 +74,16 @@ | |||
1503 | 74 | } | 74 | } |
1504 | 75 | // Real openstack instances have a default security group "out of the box". So we add it here. | 75 | // Real openstack instances have a default security group "out of the box". So we add it here. |
1505 | 76 | defaultSecurityGroups := []nova.SecurityGroup{ | 76 | defaultSecurityGroups := []nova.SecurityGroup{ |
1507 | 77 | {Id: 999, Name: "default", Description: "default group"}, | 77 | {Id: "999", Name: "default", Description: "default group"}, |
1508 | 78 | } | 78 | } |
1509 | 79 | novaService := &Nova{ | 79 | novaService := &Nova{ |
1510 | 80 | flavors: make(map[string]nova.FlavorDetail), | 80 | flavors: make(map[string]nova.FlavorDetail), |
1511 | 81 | servers: make(map[string]nova.ServerDetail), | 81 | servers: make(map[string]nova.ServerDetail), |
1517 | 82 | groups: make(map[int]nova.SecurityGroup), | 82 | groups: make(map[string]nova.SecurityGroup), |
1518 | 83 | rules: make(map[int]nova.SecurityGroupRule), | 83 | rules: make(map[string]nova.SecurityGroupRule), |
1519 | 84 | floatingIPs: make(map[int]nova.FloatingIP), | 84 | floatingIPs: make(map[string]nova.FloatingIP), |
1520 | 85 | serverGroups: make(map[string][]int), | 85 | serverGroups: make(map[string][]string), |
1521 | 86 | serverIPs: make(map[string][]int), | 86 | serverIPs: make(map[string][]string), |
1522 | 87 | ServiceInstance: testservices.ServiceInstance{ | 87 | ServiceInstance: testservices.ServiceInstance{ |
1523 | 88 | IdentityService: identityService, | 88 | IdentityService: identityService, |
1524 | 89 | Hostname: hostname, | 89 | Hostname: hostname, |
1525 | @@ -368,7 +368,7 @@ | |||
1526 | 368 | return err | 368 | return err |
1527 | 369 | } | 369 | } |
1528 | 370 | if _, err := n.securityGroup(group.Id); err == nil { | 370 | if _, err := n.securityGroup(group.Id); err == nil { |
1530 | 371 | return fmt.Errorf("a security group with id %d already exists", group.Id) | 371 | return fmt.Errorf("a security group with id %s already exists", group.Id) |
1531 | 372 | } | 372 | } |
1532 | 373 | group.TenantId = n.TenantId | 373 | group.TenantId = n.TenantId |
1533 | 374 | if group.Rules == nil { | 374 | if group.Rules == nil { |
1534 | @@ -379,13 +379,13 @@ | |||
1535 | 379 | } | 379 | } |
1536 | 380 | 380 | ||
1537 | 381 | // securityGroup retrieves an existing group by ID. | 381 | // securityGroup retrieves an existing group by ID. |
1539 | 382 | func (n *Nova) securityGroup(groupId int) (*nova.SecurityGroup, error) { | 382 | func (n *Nova) securityGroup(groupId string) (*nova.SecurityGroup, error) { |
1540 | 383 | if err := n.ProcessFunctionHook(n, groupId); err != nil { | 383 | if err := n.ProcessFunctionHook(n, groupId); err != nil { |
1541 | 384 | return nil, err | 384 | return nil, err |
1542 | 385 | } | 385 | } |
1543 | 386 | group, ok := n.groups[groupId] | 386 | group, ok := n.groups[groupId] |
1544 | 387 | if !ok { | 387 | if !ok { |
1546 | 388 | return nil, fmt.Errorf("no such security group %d", groupId) | 388 | return nil, fmt.Errorf("no such security group %s", groupId) |
1547 | 389 | } | 389 | } |
1548 | 390 | return &group, nil | 390 | return &group, nil |
1549 | 391 | } | 391 | } |
1550 | @@ -413,7 +413,7 @@ | |||
1551 | 413 | } | 413 | } |
1552 | 414 | 414 | ||
1553 | 415 | // removeSecurityGroup deletes an existing group. | 415 | // removeSecurityGroup deletes an existing group. |
1555 | 416 | func (n *Nova) removeSecurityGroup(groupId int) error { | 416 | func (n *Nova) removeSecurityGroup(groupId string) error { |
1556 | 417 | if err := n.ProcessFunctionHook(n, groupId); err != nil { | 417 | if err := n.ProcessFunctionHook(n, groupId); err != nil { |
1557 | 418 | return err | 418 | return err |
1558 | 419 | } | 419 | } |
1559 | @@ -427,12 +427,12 @@ | |||
1560 | 427 | // addSecurityGroupRule creates a new rule in an existing group. | 427 | // addSecurityGroupRule creates a new rule in an existing group. |
1561 | 428 | // This can be either an ingress or a group rule (see the notes | 428 | // This can be either an ingress or a group rule (see the notes |
1562 | 429 | // about nova.RuleInfo). | 429 | // about nova.RuleInfo). |
1564 | 430 | func (n *Nova) addSecurityGroupRule(ruleId int, rule nova.RuleInfo) error { | 430 | func (n *Nova) addSecurityGroupRule(ruleId string, rule nova.RuleInfo) error { |
1565 | 431 | if err := n.ProcessFunctionHook(n, ruleId, rule); err != nil { | 431 | if err := n.ProcessFunctionHook(n, ruleId, rule); err != nil { |
1566 | 432 | return err | 432 | return err |
1567 | 433 | } | 433 | } |
1568 | 434 | if _, err := n.securityGroupRule(ruleId); err == nil { | 434 | if _, err := n.securityGroupRule(ruleId); err == nil { |
1570 | 435 | return fmt.Errorf("a security group rule with id %d already exists", ruleId) | 435 | return fmt.Errorf("a security group rule with id %s already exists", ruleId) |
1571 | 436 | } | 436 | } |
1572 | 437 | group, err := n.securityGroup(rule.ParentGroupId) | 437 | group, err := n.securityGroup(rule.ParentGroupId) |
1573 | 438 | if err != nil { | 438 | if err != nil { |
1574 | @@ -440,7 +440,7 @@ | |||
1575 | 440 | } | 440 | } |
1576 | 441 | for _, ru := range group.Rules { | 441 | for _, ru := range group.Rules { |
1577 | 442 | if ru.Id == ruleId { | 442 | if ru.Id == ruleId { |
1579 | 443 | return fmt.Errorf("cannot add twice rule %d to security group %d", ru.Id, group.Id) | 443 | return fmt.Errorf("cannot add twice rule %s to security group %s", ru.Id, group.Id) |
1580 | 444 | } | 444 | } |
1581 | 445 | } | 445 | } |
1582 | 446 | var zeroSecurityGroupRef nova.SecurityGroupRef | 446 | var zeroSecurityGroupRef nova.SecurityGroupRef |
1583 | @@ -452,7 +452,7 @@ | |||
1584 | 452 | if rule.GroupId != nil { | 452 | if rule.GroupId != nil { |
1585 | 453 | sourceGroup, err := n.securityGroup(*rule.GroupId) | 453 | sourceGroup, err := n.securityGroup(*rule.GroupId) |
1586 | 454 | if err != nil { | 454 | if err != nil { |
1588 | 455 | return fmt.Errorf("unknown source security group %d", *rule.GroupId) | 455 | return fmt.Errorf("unknown source security group %s", *rule.GroupId) |
1589 | 456 | } | 456 | } |
1590 | 457 | newrule.Group = nova.SecurityGroupRef{ | 457 | newrule.Group = nova.SecurityGroupRef{ |
1591 | 458 | TenantId: sourceGroup.TenantId, | 458 | TenantId: sourceGroup.TenantId, |
1592 | @@ -480,27 +480,27 @@ | |||
1593 | 480 | } | 480 | } |
1594 | 481 | 481 | ||
1595 | 482 | // hasSecurityGroupRule returns whether the given group contains the given rule, | 482 | // hasSecurityGroupRule returns whether the given group contains the given rule, |
1598 | 483 | // or (when groupId=-1) whether the given rule exists. | 483 | // or (when groupId="-1") whether the given rule exists. |
1599 | 484 | func (n *Nova) hasSecurityGroupRule(groupId, ruleId int) bool { | 484 | func (n *Nova) hasSecurityGroupRule(groupId, ruleId string) bool { |
1600 | 485 | rule, ok := n.rules[ruleId] | 485 | rule, ok := n.rules[ruleId] |
1601 | 486 | _, err := n.securityGroup(groupId) | 486 | _, err := n.securityGroup(groupId) |
1603 | 487 | return ok && (groupId == -1 || (err == nil && rule.ParentGroupId == groupId)) | 487 | return ok && (groupId == "-1" || (err == nil && rule.ParentGroupId == groupId)) |
1604 | 488 | } | 488 | } |
1605 | 489 | 489 | ||
1606 | 490 | // securityGroupRule retrieves an existing rule by ID. | 490 | // securityGroupRule retrieves an existing rule by ID. |
1608 | 491 | func (n *Nova) securityGroupRule(ruleId int) (*nova.SecurityGroupRule, error) { | 491 | func (n *Nova) securityGroupRule(ruleId string) (*nova.SecurityGroupRule, error) { |
1609 | 492 | if err := n.ProcessFunctionHook(n, ruleId); err != nil { | 492 | if err := n.ProcessFunctionHook(n, ruleId); err != nil { |
1610 | 493 | return nil, err | 493 | return nil, err |
1611 | 494 | } | 494 | } |
1612 | 495 | rule, ok := n.rules[ruleId] | 495 | rule, ok := n.rules[ruleId] |
1613 | 496 | if !ok { | 496 | if !ok { |
1615 | 497 | return nil, fmt.Errorf("no such security group rule %d", ruleId) | 497 | return nil, fmt.Errorf("no such security group rule %s", ruleId) |
1616 | 498 | } | 498 | } |
1617 | 499 | return &rule, nil | 499 | return &rule, nil |
1618 | 500 | } | 500 | } |
1619 | 501 | 501 | ||
1620 | 502 | // removeSecurityGroupRule deletes an existing rule from its group. | 502 | // removeSecurityGroupRule deletes an existing rule from its group. |
1622 | 503 | func (n *Nova) removeSecurityGroupRule(ruleId int) error { | 503 | func (n *Nova) removeSecurityGroupRule(ruleId string) error { |
1623 | 504 | if err := n.ProcessFunctionHook(n, ruleId); err != nil { | 504 | if err := n.ProcessFunctionHook(n, ruleId); err != nil { |
1624 | 505 | return err | 505 | return err |
1625 | 506 | } | 506 | } |
1626 | @@ -528,7 +528,7 @@ | |||
1627 | 528 | } | 528 | } |
1628 | 529 | 529 | ||
1629 | 530 | // addServerSecurityGroup attaches an existing server to a group. | 530 | // addServerSecurityGroup attaches an existing server to a group. |
1631 | 531 | func (n *Nova) addServerSecurityGroup(serverId string, groupId int) error { | 531 | func (n *Nova) addServerSecurityGroup(serverId string, groupId string) error { |
1632 | 532 | if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil { | 532 | if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil { |
1633 | 533 | return err | 533 | return err |
1634 | 534 | } | 534 | } |
1635 | @@ -542,7 +542,7 @@ | |||
1636 | 542 | if ok { | 542 | if ok { |
1637 | 543 | for _, gid := range groups { | 543 | for _, gid := range groups { |
1638 | 544 | if gid == groupId { | 544 | if gid == groupId { |
1640 | 545 | return fmt.Errorf("server %q already belongs to group %d", serverId, groupId) | 545 | return fmt.Errorf("server %q already belongs to group %s", serverId, groupId) |
1641 | 546 | } | 546 | } |
1642 | 547 | } | 547 | } |
1643 | 548 | } | 548 | } |
1644 | @@ -552,7 +552,7 @@ | |||
1645 | 552 | } | 552 | } |
1646 | 553 | 553 | ||
1647 | 554 | // hasServerSecurityGroup returns whether the given server belongs to the group. | 554 | // hasServerSecurityGroup returns whether the given server belongs to the group. |
1649 | 555 | func (n *Nova) hasServerSecurityGroup(serverId string, groupId int) bool { | 555 | func (n *Nova) hasServerSecurityGroup(serverId string, groupId string) bool { |
1650 | 556 | if _, err := n.server(serverId); err != nil { | 556 | if _, err := n.server(serverId); err != nil { |
1651 | 557 | return false | 557 | return false |
1652 | 558 | } | 558 | } |
1653 | @@ -586,7 +586,7 @@ | |||
1654 | 586 | } | 586 | } |
1655 | 587 | 587 | ||
1656 | 588 | // removeServerSecurityGroup detaches an existing server from a group. | 588 | // removeServerSecurityGroup detaches an existing server from a group. |
1658 | 589 | func (n *Nova) removeServerSecurityGroup(serverId string, groupId int) error { | 589 | func (n *Nova) removeServerSecurityGroup(serverId string, groupId string) error { |
1659 | 590 | if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil { | 590 | if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil { |
1660 | 591 | return err | 591 | return err |
1661 | 592 | } | 592 | } |
1662 | @@ -608,7 +608,7 @@ | |||
1663 | 608 | } | 608 | } |
1664 | 609 | } | 609 | } |
1665 | 610 | if idx == -1 { | 610 | if idx == -1 { |
1667 | 611 | return fmt.Errorf("server %q does not belong to group %d", serverId, groupId) | 611 | return fmt.Errorf("server %q does not belong to group %s", serverId, groupId) |
1668 | 612 | } | 612 | } |
1669 | 613 | groups = append(groups[:idx], groups[idx+1:]...) | 613 | groups = append(groups[:idx], groups[idx+1:]...) |
1670 | 614 | n.serverGroups[serverId] = groups | 614 | n.serverGroups[serverId] = groups |
1671 | @@ -621,7 +621,7 @@ | |||
1672 | 621 | return err | 621 | return err |
1673 | 622 | } | 622 | } |
1674 | 623 | if _, err := n.floatingIP(ip.Id); err == nil { | 623 | if _, err := n.floatingIP(ip.Id); err == nil { |
1676 | 624 | return fmt.Errorf("a floating IP with id %d already exists", ip.Id) | 624 | return fmt.Errorf("a floating IP with id %s already exists", ip.Id) |
1677 | 625 | } | 625 | } |
1678 | 626 | n.floatingIPs[ip.Id] = ip | 626 | n.floatingIPs[ip.Id] = ip |
1679 | 627 | return nil | 627 | return nil |
1680 | @@ -641,13 +641,13 @@ | |||
1681 | 641 | } | 641 | } |
1682 | 642 | 642 | ||
1683 | 643 | // floatingIP retrieves the floating IP by ID. | 643 | // floatingIP retrieves the floating IP by ID. |
1685 | 644 | func (n *Nova) floatingIP(ipId int) (*nova.FloatingIP, error) { | 644 | func (n *Nova) floatingIP(ipId string) (*nova.FloatingIP, error) { |
1686 | 645 | if err := n.ProcessFunctionHook(n, ipId); err != nil { | 645 | if err := n.ProcessFunctionHook(n, ipId); err != nil { |
1687 | 646 | return nil, err | 646 | return nil, err |
1688 | 647 | } | 647 | } |
1689 | 648 | ip, ok := n.floatingIPs[ipId] | 648 | ip, ok := n.floatingIPs[ipId] |
1690 | 649 | if !ok { | 649 | if !ok { |
1692 | 650 | return nil, fmt.Errorf("no such floating IP %d", ipId) | 650 | return nil, fmt.Errorf("no such floating IP %s", ipId) |
1693 | 651 | } | 651 | } |
1694 | 652 | return &ip, nil | 652 | return &ip, nil |
1695 | 653 | } | 653 | } |
1696 | @@ -675,7 +675,7 @@ | |||
1697 | 675 | } | 675 | } |
1698 | 676 | 676 | ||
1699 | 677 | // removeFloatingIP deletes an existing floating IP by ID. | 677 | // removeFloatingIP deletes an existing floating IP by ID. |
1701 | 678 | func (n *Nova) removeFloatingIP(ipId int) error { | 678 | func (n *Nova) removeFloatingIP(ipId string) error { |
1702 | 679 | if err := n.ProcessFunctionHook(n, ipId); err != nil { | 679 | if err := n.ProcessFunctionHook(n, ipId); err != nil { |
1703 | 680 | return err | 680 | return err |
1704 | 681 | } | 681 | } |
1705 | @@ -687,7 +687,7 @@ | |||
1706 | 687 | } | 687 | } |
1707 | 688 | 688 | ||
1708 | 689 | // addServerFloatingIP attaches an existing floating IP to a server. | 689 | // addServerFloatingIP attaches an existing floating IP to a server. |
1710 | 690 | func (n *Nova) addServerFloatingIP(serverId string, ipId int) error { | 690 | func (n *Nova) addServerFloatingIP(serverId string, ipId string) error { |
1711 | 691 | if err := n.ProcessFunctionHook(n, serverId, ipId); err != nil { | 691 | if err := n.ProcessFunctionHook(n, serverId, ipId); err != nil { |
1712 | 692 | return err | 692 | return err |
1713 | 693 | } | 693 | } |
1714 | @@ -706,7 +706,7 @@ | |||
1715 | 706 | if ok { | 706 | if ok { |
1716 | 707 | for _, fipId := range fips { | 707 | for _, fipId := range fips { |
1717 | 708 | if fipId == ipId { | 708 | if fipId == ipId { |
1719 | 709 | return fmt.Errorf("server %q already has floating IP %d", serverId, ipId) | 709 | return fmt.Errorf("server %q already has floating IP %s", serverId, ipId) |
1720 | 710 | } | 710 | } |
1721 | 711 | } | 711 | } |
1722 | 712 | } | 712 | } |
1723 | @@ -734,7 +734,7 @@ | |||
1724 | 734 | } | 734 | } |
1725 | 735 | 735 | ||
1726 | 736 | // removeServerFloatingIP deletes an attached floating IP from a server. | 736 | // removeServerFloatingIP deletes an attached floating IP from a server. |
1728 | 737 | func (n *Nova) removeServerFloatingIP(serverId string, ipId int) error { | 737 | func (n *Nova) removeServerFloatingIP(serverId string, ipId string) error { |
1729 | 738 | if err := n.ProcessFunctionHook(n, serverId); err != nil { | 738 | if err := n.ProcessFunctionHook(n, serverId); err != nil { |
1730 | 739 | return err | 739 | return err |
1731 | 740 | } | 740 | } |
1732 | @@ -760,7 +760,7 @@ | |||
1733 | 760 | } | 760 | } |
1734 | 761 | } | 761 | } |
1735 | 762 | if idx == -1 { | 762 | if idx == -1 { |
1737 | 763 | return fmt.Errorf("server %q does not have floating IP %d", serverId, ipId) | 763 | return fmt.Errorf("server %q does not have floating IP %s", serverId, ipId) |
1738 | 764 | } | 764 | } |
1739 | 765 | fips = append(fips[:idx], fips[idx+1:]...) | 765 | fips = append(fips[:idx], fips[idx+1:]...) |
1740 | 766 | n.serverIPs[serverId] = fips | 766 | n.serverIPs[serverId] = fips |
1741 | 767 | 767 | ||
1742 | === modified file 'testservices/novaservice/service_http.go' | |||
1743 | --- testservices/novaservice/service_http.go 2013-02-25 07:16:32 +0000 | |||
1744 | +++ testservices/novaservice/service_http.go 2013-07-01 07:24:26 +0000 | |||
1745 | @@ -114,14 +114,6 @@ | |||
1746 | 114 | nil, | 114 | nil, |
1747 | 115 | nil, | 115 | nil, |
1748 | 116 | } | 116 | } |
1749 | 117 | errBadRequestSG = &errorResponse{ | ||
1750 | 118 | http.StatusBadRequest, | ||
1751 | 119 | `{"badRequest": {"message": "Security group id should be integer", "code": 400}}`, | ||
1752 | 120 | "application/json; charset=UTF-8", | ||
1753 | 121 | "bad security group id type", | ||
1754 | 122 | nil, | ||
1755 | 123 | nil, | ||
1756 | 124 | } | ||
1757 | 125 | errNotFound = &errorResponse{ | 117 | errNotFound = &errorResponse{ |
1758 | 126 | http.StatusNotFound, | 118 | http.StatusNotFound, |
1759 | 127 | `404 Not Found | 119 | `404 Not Found |
1760 | @@ -567,7 +559,7 @@ | |||
1761 | 567 | if err != nil { | 559 | if err != nil { |
1762 | 568 | return err | 560 | return err |
1763 | 569 | } | 561 | } |
1765 | 570 | var groups []int | 562 | var groups []string |
1766 | 571 | if len(req.Server.SecurityGroups) > 0 { | 563 | if len(req.Server.SecurityGroups) > 0 { |
1767 | 572 | for _, group := range req.Server.SecurityGroups { | 564 | for _, group := range req.Server.SecurityGroups { |
1768 | 573 | groupName := group["name"] | 565 | groupName := group["name"] |
1769 | @@ -772,11 +764,7 @@ | |||
1770 | 772 | // If there was no group id specified in the path, it returns errNoGroupId | 764 | // If there was no group id specified in the path, it returns errNoGroupId |
1771 | 773 | func (n *Nova) processGroupId(w http.ResponseWriter, r *http.Request) (*nova.SecurityGroup, error) { | 765 | func (n *Nova) processGroupId(w http.ResponseWriter, r *http.Request) (*nova.SecurityGroup, error) { |
1772 | 774 | if groupId := path.Base(r.URL.Path); groupId != "os-security-groups" { | 766 | if groupId := path.Base(r.URL.Path); groupId != "os-security-groups" { |
1778 | 775 | id, err := strconv.Atoi(groupId) | 767 | group, err := n.securityGroup(groupId) |
1774 | 776 | if err != nil { | ||
1775 | 777 | return nil, errBadRequestSG | ||
1776 | 778 | } | ||
1777 | 779 | group, err := n.securityGroup(id) | ||
1779 | 780 | if err != nil { | 768 | if err != nil { |
1780 | 781 | return nil, errNotFoundJSONSG | 769 | return nil, errNotFoundJSONSG |
1781 | 782 | } | 770 | } |
1782 | @@ -829,7 +817,7 @@ | |||
1783 | 829 | return errBadRequestDuplicateValue | 817 | return errBadRequestDuplicateValue |
1784 | 830 | } | 818 | } |
1785 | 831 | n.nextGroupId++ | 819 | n.nextGroupId++ |
1787 | 832 | nextId := n.nextGroupId | 820 | nextId := strconv.Itoa(n.nextGroupId) |
1788 | 833 | err = n.addSecurityGroup(nova.SecurityGroup{ | 821 | err = n.addSecurityGroup(nova.SecurityGroup{ |
1789 | 834 | Id: nextId, | 822 | Id: nextId, |
1790 | 835 | Name: req.Group.Name, | 823 | Name: req.Group.Name, |
1791 | @@ -912,7 +900,7 @@ | |||
1792 | 912 | } | 900 | } |
1793 | 913 | } | 901 | } |
1794 | 914 | n.nextRuleId++ | 902 | n.nextRuleId++ |
1796 | 915 | nextId := n.nextRuleId | 903 | nextId := strconv.Itoa(n.nextRuleId) |
1797 | 916 | err = n.addSecurityGroupRule(nextId, req.Rule) | 904 | err = n.addSecurityGroupRule(nextId, req.Rule) |
1798 | 917 | if err != nil { | 905 | if err != nil { |
1799 | 918 | return err | 906 | return err |
1800 | @@ -933,15 +921,10 @@ | |||
1801 | 933 | return errNotFound | 921 | return errNotFound |
1802 | 934 | case "DELETE": | 922 | case "DELETE": |
1803 | 935 | if ruleId := path.Base(r.URL.Path); ruleId != "os-security-group-rules" { | 923 | if ruleId := path.Base(r.URL.Path); ruleId != "os-security-group-rules" { |
1810 | 936 | id, err := strconv.Atoi(ruleId) | 924 | if _, err := n.securityGroupRule(ruleId); err != nil { |
1805 | 937 | if err != nil { | ||
1806 | 938 | // weird, but this is how nova responds | ||
1807 | 939 | return errBadRequestSG | ||
1808 | 940 | } | ||
1809 | 941 | if _, err = n.securityGroupRule(id); err != nil { | ||
1811 | 942 | return errNotFoundJSONSGR | 925 | return errNotFoundJSONSGR |
1812 | 943 | } | 926 | } |
1814 | 944 | if err = n.removeSecurityGroupRule(id); err != nil { | 927 | if err := n.removeSecurityGroupRule(ruleId); err != nil { |
1815 | 945 | return err | 928 | return err |
1816 | 946 | } | 929 | } |
1817 | 947 | writeResponse(w, http.StatusAccepted, nil) | 930 | writeResponse(w, http.StatusAccepted, nil) |
1818 | @@ -957,11 +940,7 @@ | |||
1819 | 957 | switch r.Method { | 940 | switch r.Method { |
1820 | 958 | case "GET": | 941 | case "GET": |
1821 | 959 | if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" { | 942 | if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" { |
1827 | 960 | nId, err := strconv.Atoi(ipId) | 943 | fip, err := n.floatingIP(ipId) |
1823 | 961 | if err != nil { | ||
1824 | 962 | return errNotFoundJSON | ||
1825 | 963 | } | ||
1826 | 964 | fip, err := n.floatingIP(nId) | ||
1828 | 965 | if err != nil { | 944 | if err != nil { |
1829 | 966 | return errNotFoundJSON | 945 | return errNotFoundJSON |
1830 | 967 | } | 946 | } |
1831 | @@ -983,8 +962,8 @@ | |||
1832 | 983 | return errNotFound | 962 | return errNotFound |
1833 | 984 | } | 963 | } |
1834 | 985 | n.nextIPId++ | 964 | n.nextIPId++ |
1837 | 986 | nextId := n.nextIPId | 965 | addr := fmt.Sprintf("10.0.0.%d", n.nextIPId) |
1838 | 987 | addr := fmt.Sprintf("10.0.0.%d", nextId) | 966 | nextId := strconv.Itoa(n.nextIPId) |
1839 | 988 | fip := nova.FloatingIP{Id: nextId, IP: addr, Pool: "nova"} | 967 | fip := nova.FloatingIP{Id: nextId, IP: addr, Pool: "nova"} |
1840 | 989 | err := n.addFloatingIP(fip) | 968 | err := n.addFloatingIP(fip) |
1841 | 990 | if err != nil { | 969 | if err != nil { |
1842 | @@ -1001,11 +980,9 @@ | |||
1843 | 1001 | return errNotFound | 980 | return errNotFound |
1844 | 1002 | case "DELETE": | 981 | case "DELETE": |
1845 | 1003 | if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" { | 982 | if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" { |
1851 | 1004 | if nId, err := strconv.Atoi(ipId); err == nil { | 983 | if err := n.removeFloatingIP(ipId); err == nil { |
1852 | 1005 | if err := n.removeFloatingIP(nId); err == nil { | 984 | writeResponse(w, http.StatusAccepted, nil) |
1853 | 1006 | writeResponse(w, http.StatusAccepted, nil) | 985 | return nil |
1849 | 1007 | return nil | ||
1850 | 1008 | } | ||
1854 | 1009 | } | 986 | } |
1855 | 1010 | return errNotFoundJSON | 987 | return errNotFoundJSON |
1856 | 1011 | } | 988 | } |
1857 | 1012 | 989 | ||
1858 | === modified file 'testservices/novaservice/service_http_test.go' | |||
1859 | --- testservices/novaservice/service_http_test.go 2013-04-23 00:19:57 +0000 | |||
1860 | +++ testservices/novaservice/service_http_test.go 2013-07-01 07:24:26 +0000 | |||
1861 | @@ -322,11 +322,6 @@ | |||
1862 | 322 | }, | 322 | }, |
1863 | 323 | { | 323 | { |
1864 | 324 | method: "GET", | 324 | method: "GET", |
1865 | 325 | url: "/os-security-groups/invalid", | ||
1866 | 326 | expect: errBadRequestSG, | ||
1867 | 327 | }, | ||
1868 | 328 | { | ||
1869 | 329 | method: "GET", | ||
1870 | 330 | url: "/os-security-groups/42", | 325 | url: "/os-security-groups/42", |
1871 | 331 | expect: errNotFoundJSONSG, | 326 | expect: errNotFoundJSONSG, |
1872 | 332 | }, | 327 | }, |
1873 | @@ -357,11 +352,6 @@ | |||
1874 | 357 | }, | 352 | }, |
1875 | 358 | { | 353 | { |
1876 | 359 | method: "DELETE", | 354 | method: "DELETE", |
1877 | 360 | url: "/os-security-groups/invalid", | ||
1878 | 361 | expect: errBadRequestSG, | ||
1879 | 362 | }, | ||
1880 | 363 | { | ||
1881 | 364 | method: "DELETE", | ||
1882 | 365 | url: "/os-security-groups/42", | 355 | url: "/os-security-groups/42", |
1883 | 366 | expect: errNotFoundJSONSG, | 356 | expect: errNotFoundJSONSG, |
1884 | 367 | }, | 357 | }, |
1885 | @@ -404,11 +394,6 @@ | |||
1886 | 404 | method: "DELETE", | 394 | method: "DELETE", |
1887 | 405 | url: "/os-security-group-rules", | 395 | url: "/os-security-group-rules", |
1888 | 406 | expect: errNotFound, | 396 | expect: errNotFound, |
1889 | 407 | }, | ||
1890 | 408 | { | ||
1891 | 409 | method: "DELETE", | ||
1892 | 410 | url: "/os-security-group-rules/invalid", | ||
1893 | 411 | expect: errBadRequestSG, // sic; should've been rule-specific | ||
1894 | 412 | }, | 397 | }, |
1895 | 413 | { | 398 | { |
1896 | 414 | method: "DELETE", | 399 | method: "DELETE", |
1897 | @@ -676,12 +661,12 @@ | |||
1898 | 676 | {"name": "group1"}, | 661 | {"name": "group1"}, |
1899 | 677 | {"name": "group2"}, | 662 | {"name": "group2"}, |
1900 | 678 | } | 663 | } |
1907 | 679 | err = s.service.addSecurityGroup(nova.SecurityGroup{Id: 1, Name: "group1"}) | 664 | err = s.service.addSecurityGroup(nova.SecurityGroup{Id: "1", Name: "group1"}) |
1908 | 680 | c.Assert(err, IsNil) | 665 | c.Assert(err, IsNil) |
1909 | 681 | defer s.service.removeSecurityGroup(1) | 666 | defer s.service.removeSecurityGroup("1") |
1910 | 682 | err = s.service.addSecurityGroup(nova.SecurityGroup{Id: 2, Name: "group2"}) | 667 | err = s.service.addSecurityGroup(nova.SecurityGroup{Id: "2", Name: "group2"}) |
1911 | 683 | c.Assert(err, IsNil) | 668 | c.Assert(err, IsNil) |
1912 | 684 | defer s.service.removeSecurityGroup(2) | 669 | defer s.service.removeSecurityGroup("2") |
1913 | 685 | resp, err = s.jsonRequest("POST", "/servers", req, nil) | 670 | resp, err = s.jsonRequest("POST", "/servers", req, nil) |
1914 | 686 | c.Assert(err, IsNil) | 671 | c.Assert(err, IsNil) |
1915 | 687 | c.Assert(resp.StatusCode, Equals, http.StatusAccepted) | 672 | c.Assert(resp.StatusCode, Equals, http.StatusAccepted) |
1916 | @@ -689,12 +674,12 @@ | |||
1917 | 689 | c.Assert(expected.Server.SecurityGroups, DeepEquals, req.Server.SecurityGroups) | 674 | c.Assert(expected.Server.SecurityGroups, DeepEquals, req.Server.SecurityGroups) |
1918 | 690 | srv, err = s.service.server(expected.Server.Id) | 675 | srv, err = s.service.server(expected.Server.Id) |
1919 | 691 | c.Assert(err, IsNil) | 676 | c.Assert(err, IsNil) |
1926 | 692 | ok := s.service.hasServerSecurityGroup(srv.Id, 1) | 677 | ok := s.service.hasServerSecurityGroup(srv.Id, "1") |
1927 | 693 | c.Assert(ok, Equals, true) | 678 | c.Assert(ok, Equals, true) |
1928 | 694 | ok = s.service.hasServerSecurityGroup(srv.Id, 2) | 679 | ok = s.service.hasServerSecurityGroup(srv.Id, "2") |
1929 | 695 | c.Assert(ok, Equals, true) | 680 | c.Assert(ok, Equals, true) |
1930 | 696 | s.service.removeServerSecurityGroup(srv.Id, 1) | 681 | s.service.removeServerSecurityGroup(srv.Id, "1") |
1931 | 697 | s.service.removeServerSecurityGroup(srv.Id, 2) | 682 | s.service.removeServerSecurityGroup(srv.Id, "2") |
1932 | 698 | s.service.removeServer(srv.Id) | 683 | s.service.removeServer(srv.Id) |
1933 | 699 | } | 684 | } |
1934 | 700 | 685 | ||
1935 | @@ -794,13 +779,13 @@ | |||
1936 | 794 | c.Assert(expected.Groups, HasLen, 1) | 779 | c.Assert(expected.Groups, HasLen, 1) |
1937 | 795 | groups = []nova.SecurityGroup{ | 780 | groups = []nova.SecurityGroup{ |
1938 | 796 | { | 781 | { |
1940 | 797 | Id: 1, | 782 | Id: "1", |
1941 | 798 | Name: "group 1", | 783 | Name: "group 1", |
1942 | 799 | TenantId: s.service.TenantId, | 784 | TenantId: s.service.TenantId, |
1943 | 800 | Rules: []nova.SecurityGroupRule{}, | 785 | Rules: []nova.SecurityGroupRule{}, |
1944 | 801 | }, | 786 | }, |
1945 | 802 | { | 787 | { |
1947 | 803 | Id: 2, | 788 | Id: "2", |
1948 | 804 | Name: "group 2", | 789 | Name: "group 2", |
1949 | 805 | TenantId: s.service.TenantId, | 790 | TenantId: s.service.TenantId, |
1950 | 806 | Rules: []nova.SecurityGroupRule{}, | 791 | Rules: []nova.SecurityGroupRule{}, |
1951 | @@ -829,7 +814,7 @@ | |||
1952 | 829 | 814 | ||
1953 | 830 | func (s *NovaHTTPSuite) TestAddSecurityGroup(c *C) { | 815 | func (s *NovaHTTPSuite) TestAddSecurityGroup(c *C) { |
1954 | 831 | group := nova.SecurityGroup{ | 816 | group := nova.SecurityGroup{ |
1956 | 832 | Id: 1, | 817 | Id: "1", |
1957 | 833 | Name: "group 1", | 818 | Name: "group 1", |
1958 | 834 | Description: "desc", | 819 | Description: "desc", |
1959 | 835 | TenantId: s.service.TenantId, | 820 | TenantId: s.service.TenantId, |
1960 | @@ -858,7 +843,7 @@ | |||
1961 | 858 | } | 843 | } |
1962 | 859 | 844 | ||
1963 | 860 | func (s *NovaHTTPSuite) TestDeleteSecurityGroup(c *C) { | 845 | func (s *NovaHTTPSuite) TestDeleteSecurityGroup(c *C) { |
1965 | 861 | group := nova.SecurityGroup{Id: 1, Name: "group 1"} | 846 | group := nova.SecurityGroup{Id: "1", Name: "group 1"} |
1966 | 862 | _, err := s.service.securityGroup(group.Id) | 847 | _, err := s.service.securityGroup(group.Id) |
1967 | 863 | c.Assert(err, NotNil) | 848 | c.Assert(err, NotNil) |
1968 | 864 | err = s.service.addSecurityGroup(group) | 849 | err = s.service.addSecurityGroup(group) |
1969 | @@ -872,8 +857,8 @@ | |||
1970 | 872 | } | 857 | } |
1971 | 873 | 858 | ||
1972 | 874 | func (s *NovaHTTPSuite) TestAddSecurityGroupRule(c *C) { | 859 | func (s *NovaHTTPSuite) TestAddSecurityGroupRule(c *C) { |
1975 | 875 | group1 := nova.SecurityGroup{Id: 1, Name: "src"} | 860 | group1 := nova.SecurityGroup{Id: "1", Name: "src"} |
1976 | 876 | group2 := nova.SecurityGroup{Id: 2, Name: "tgt"} | 861 | group2 := nova.SecurityGroup{Id: "2", Name: "tgt"} |
1977 | 877 | err := s.service.addSecurityGroup(group1) | 862 | err := s.service.addSecurityGroup(group1) |
1978 | 878 | c.Assert(err, IsNil) | 863 | c.Assert(err, IsNil) |
1979 | 879 | defer s.service.removeSecurityGroup(group1.Id) | 864 | defer s.service.removeSecurityGroup(group1.Id) |
1980 | @@ -881,7 +866,7 @@ | |||
1981 | 881 | c.Assert(err, IsNil) | 866 | c.Assert(err, IsNil) |
1982 | 882 | defer s.service.removeSecurityGroup(group2.Id) | 867 | defer s.service.removeSecurityGroup(group2.Id) |
1983 | 883 | riIngress := nova.RuleInfo{ | 868 | riIngress := nova.RuleInfo{ |
1985 | 884 | ParentGroupId: 1, | 869 | ParentGroupId: "1", |
1986 | 885 | FromPort: 1234, | 870 | FromPort: 1234, |
1987 | 886 | ToPort: 4321, | 871 | ToPort: 4321, |
1988 | 887 | IPProtocol: "tcp", | 872 | IPProtocol: "tcp", |
1989 | @@ -894,7 +879,7 @@ | |||
1990 | 894 | iprange := make(map[string]string) | 879 | iprange := make(map[string]string) |
1991 | 895 | iprange["cidr"] = riIngress.Cidr | 880 | iprange["cidr"] = riIngress.Cidr |
1992 | 896 | rule1 := nova.SecurityGroupRule{ | 881 | rule1 := nova.SecurityGroupRule{ |
1994 | 897 | Id: 1, | 882 | Id: "1", |
1995 | 898 | ParentGroupId: group1.Id, | 883 | ParentGroupId: group1.Id, |
1996 | 899 | FromPort: &riIngress.FromPort, | 884 | FromPort: &riIngress.FromPort, |
1997 | 900 | ToPort: &riIngress.ToPort, | 885 | ToPort: &riIngress.ToPort, |
1998 | @@ -902,7 +887,7 @@ | |||
1999 | 902 | IPRange: iprange, | 887 | IPRange: iprange, |
2000 | 903 | } | 888 | } |
2001 | 904 | rule2 := nova.SecurityGroupRule{ | 889 | rule2 := nova.SecurityGroupRule{ |
2003 | 905 | Id: 2, | 890 | Id: "2", |
2004 | 906 | ParentGroupId: group2.Id, | 891 | ParentGroupId: group2.Id, |
2005 | 907 | Group: nova.SecurityGroupRef{ | 892 | Group: nova.SecurityGroupRef{ |
2006 | 908 | Name: group1.Name, | 893 | Name: group1.Name, |
2007 | @@ -945,8 +930,8 @@ | |||
2008 | 945 | } | 930 | } |
2009 | 946 | 931 | ||
2010 | 947 | func (s *NovaHTTPSuite) TestDeleteSecurityGroupRule(c *C) { | 932 | func (s *NovaHTTPSuite) TestDeleteSecurityGroupRule(c *C) { |
2013 | 948 | group1 := nova.SecurityGroup{Id: 1, Name: "src"} | 933 | group1 := nova.SecurityGroup{Id: "1", Name: "src"} |
2014 | 949 | group2 := nova.SecurityGroup{Id: 2, Name: "tgt"} | 934 | group2 := nova.SecurityGroup{Id: "2", Name: "tgt"} |
2015 | 950 | err := s.service.addSecurityGroup(group1) | 935 | err := s.service.addSecurityGroup(group1) |
2016 | 951 | c.Assert(err, IsNil) | 936 | c.Assert(err, IsNil) |
2017 | 952 | defer s.service.removeSecurityGroup(group1.Id) | 937 | defer s.service.removeSecurityGroup(group1.Id) |
2018 | @@ -958,7 +943,7 @@ | |||
2019 | 958 | GroupId: &group1.Id, | 943 | GroupId: &group1.Id, |
2020 | 959 | } | 944 | } |
2021 | 960 | rule := nova.SecurityGroupRule{ | 945 | rule := nova.SecurityGroupRule{ |
2023 | 961 | Id: 1, | 946 | Id: "1", |
2024 | 962 | ParentGroupId: group2.Id, | 947 | ParentGroupId: group2.Id, |
2025 | 963 | Group: nova.SecurityGroupRef{ | 948 | Group: nova.SecurityGroupRef{ |
2026 | 964 | Name: group1.Name, | 949 | Name: group1.Name, |
2027 | @@ -975,7 +960,7 @@ | |||
2028 | 975 | } | 960 | } |
2029 | 976 | 961 | ||
2030 | 977 | func (s *NovaHTTPSuite) TestAddServerSecurityGroup(c *C) { | 962 | func (s *NovaHTTPSuite) TestAddServerSecurityGroup(c *C) { |
2032 | 978 | group := nova.SecurityGroup{Id: 1, Name: "group"} | 963 | group := nova.SecurityGroup{Id: "1", Name: "group"} |
2033 | 979 | err := s.service.addSecurityGroup(group) | 964 | err := s.service.addSecurityGroup(group) |
2034 | 980 | c.Assert(err, IsNil) | 965 | c.Assert(err, IsNil) |
2035 | 981 | defer s.service.removeSecurityGroup(group.Id) | 966 | defer s.service.removeSecurityGroup(group.Id) |
2036 | @@ -1004,13 +989,13 @@ | |||
2037 | 1004 | server := nova.ServerDetail{Id: "sr1"} | 989 | server := nova.ServerDetail{Id: "sr1"} |
2038 | 1005 | groups := []nova.SecurityGroup{ | 990 | groups := []nova.SecurityGroup{ |
2039 | 1006 | { | 991 | { |
2041 | 1007 | Id: 1, | 992 | Id: "1", |
2042 | 1008 | Name: "group1", | 993 | Name: "group1", |
2043 | 1009 | TenantId: s.service.TenantId, | 994 | TenantId: s.service.TenantId, |
2044 | 1010 | Rules: []nova.SecurityGroupRule{}, | 995 | Rules: []nova.SecurityGroupRule{}, |
2045 | 1011 | }, | 996 | }, |
2046 | 1012 | { | 997 | { |
2048 | 1013 | Id: 2, | 998 | Id: "2", |
2049 | 1014 | Name: "group2", | 999 | Name: "group2", |
2050 | 1015 | TenantId: s.service.TenantId, | 1000 | TenantId: s.service.TenantId, |
2051 | 1016 | Rules: []nova.SecurityGroupRule{}, | 1001 | Rules: []nova.SecurityGroupRule{}, |
2052 | @@ -1040,7 +1025,7 @@ | |||
2053 | 1040 | } | 1025 | } |
2054 | 1041 | 1026 | ||
2055 | 1042 | func (s *NovaHTTPSuite) TestDeleteServerSecurityGroup(c *C) { | 1027 | func (s *NovaHTTPSuite) TestDeleteServerSecurityGroup(c *C) { |
2057 | 1043 | group := nova.SecurityGroup{Id: 1, Name: "group"} | 1028 | group := nova.SecurityGroup{Id: "1", Name: "group"} |
2058 | 1044 | err := s.service.addSecurityGroup(group) | 1029 | err := s.service.addSecurityGroup(group) |
2059 | 1045 | c.Assert(err, IsNil) | 1030 | c.Assert(err, IsNil) |
2060 | 1046 | defer s.service.removeSecurityGroup(group.Id) | 1031 | defer s.service.removeSecurityGroup(group.Id) |
2061 | @@ -1066,7 +1051,7 @@ | |||
2062 | 1066 | } | 1051 | } |
2063 | 1067 | 1052 | ||
2064 | 1068 | func (s *NovaHTTPSuite) TestPostFloatingIP(c *C) { | 1053 | func (s *NovaHTTPSuite) TestPostFloatingIP(c *C) { |
2066 | 1069 | fip := nova.FloatingIP{Id: 1, IP: "10.0.0.1", Pool: "nova"} | 1054 | fip := nova.FloatingIP{Id: "1", IP: "10.0.0.1", Pool: "nova"} |
2067 | 1070 | c.Assert(s.service.allFloatingIPs(), HasLen, 0) | 1055 | c.Assert(s.service.allFloatingIPs(), HasLen, 0) |
2068 | 1071 | var expected struct { | 1056 | var expected struct { |
2069 | 1072 | IP nova.FloatingIP `json:"floating_ip"` | 1057 | IP nova.FloatingIP `json:"floating_ip"` |
2070 | @@ -1091,8 +1076,8 @@ | |||
2071 | 1091 | assertJSON(c, resp, &expected) | 1076 | assertJSON(c, resp, &expected) |
2072 | 1092 | c.Assert(expected.IPs, HasLen, 0) | 1077 | c.Assert(expected.IPs, HasLen, 0) |
2073 | 1093 | fips := []nova.FloatingIP{ | 1078 | fips := []nova.FloatingIP{ |
2076 | 1094 | {Id: 1, IP: "1.2.3.4", Pool: "nova"}, | 1079 | {Id: "1", IP: "1.2.3.4", Pool: "nova"}, |
2077 | 1095 | {Id: 2, IP: "4.3.2.1", Pool: "nova"}, | 1080 | {Id: "2", IP: "4.3.2.1", Pool: "nova"}, |
2078 | 1096 | } | 1081 | } |
2079 | 1097 | for _, fip := range fips { | 1082 | for _, fip := range fips { |
2080 | 1098 | err := s.service.addFloatingIP(fip) | 1083 | err := s.service.addFloatingIP(fip) |
2081 | @@ -1118,7 +1103,7 @@ | |||
2082 | 1118 | } | 1103 | } |
2083 | 1119 | 1104 | ||
2084 | 1120 | func (s *NovaHTTPSuite) TestDeleteFloatingIP(c *C) { | 1105 | func (s *NovaHTTPSuite) TestDeleteFloatingIP(c *C) { |
2086 | 1121 | fip := nova.FloatingIP{Id: 1, IP: "10.0.0.1", Pool: "nova"} | 1106 | fip := nova.FloatingIP{Id: "1", IP: "10.0.0.1", Pool: "nova"} |
2087 | 1122 | err := s.service.addFloatingIP(fip) | 1107 | err := s.service.addFloatingIP(fip) |
2088 | 1123 | c.Assert(err, IsNil) | 1108 | c.Assert(err, IsNil) |
2089 | 1124 | defer s.service.removeFloatingIP(fip.Id) | 1109 | defer s.service.removeFloatingIP(fip.Id) |
2090 | @@ -1130,7 +1115,7 @@ | |||
2091 | 1130 | } | 1115 | } |
2092 | 1131 | 1116 | ||
2093 | 1132 | func (s *NovaHTTPSuite) TestAddServerFloatingIP(c *C) { | 1117 | func (s *NovaHTTPSuite) TestAddServerFloatingIP(c *C) { |
2095 | 1133 | fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"} | 1118 | fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"} |
2096 | 1134 | server := nova.ServerDetail{Id: "sr1"} | 1119 | server := nova.ServerDetail{Id: "sr1"} |
2097 | 1135 | err := s.service.addFloatingIP(fip) | 1120 | err := s.service.addFloatingIP(fip) |
2098 | 1136 | c.Assert(err, IsNil) | 1121 | c.Assert(err, IsNil) |
2099 | @@ -1154,7 +1139,7 @@ | |||
2100 | 1154 | } | 1139 | } |
2101 | 1155 | 1140 | ||
2102 | 1156 | func (s *NovaHTTPSuite) TestRemoveServerFloatingIP(c *C) { | 1141 | func (s *NovaHTTPSuite) TestRemoveServerFloatingIP(c *C) { |
2104 | 1157 | fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"} | 1142 | fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"} |
2105 | 1158 | server := nova.ServerDetail{Id: "sr1"} | 1143 | server := nova.ServerDetail{Id: "sr1"} |
2106 | 1159 | err := s.service.addFloatingIP(fip) | 1144 | err := s.service.addFloatingIP(fip) |
2107 | 1160 | c.Assert(err, IsNil) | 1145 | c.Assert(err, IsNil) |
2108 | 1161 | 1146 | ||
2109 | === modified file 'testservices/novaservice/service_test.go' | |||
2110 | --- testservices/novaservice/service_test.go 2013-04-23 00:19:57 +0000 | |||
2111 | +++ testservices/novaservice/service_test.go 2013-07-01 07:24:26 +0000 | |||
2112 | @@ -36,17 +36,17 @@ | |||
2113 | 36 | 36 | ||
2114 | 37 | func (s *NovaSuite) ensureNoGroup(c *C, group nova.SecurityGroup) { | 37 | func (s *NovaSuite) ensureNoGroup(c *C, group nova.SecurityGroup) { |
2115 | 38 | _, err := s.service.securityGroup(group.Id) | 38 | _, err := s.service.securityGroup(group.Id) |
2117 | 39 | c.Assert(err, ErrorMatches, fmt.Sprintf("no such security group %d", group.Id)) | 39 | c.Assert(err, ErrorMatches, fmt.Sprintf("no such security group %s", group.Id)) |
2118 | 40 | } | 40 | } |
2119 | 41 | 41 | ||
2120 | 42 | func (s *NovaSuite) ensureNoRule(c *C, rule nova.SecurityGroupRule) { | 42 | func (s *NovaSuite) ensureNoRule(c *C, rule nova.SecurityGroupRule) { |
2121 | 43 | _, err := s.service.securityGroupRule(rule.Id) | 43 | _, err := s.service.securityGroupRule(rule.Id) |
2123 | 44 | c.Assert(err, ErrorMatches, fmt.Sprintf("no such security group rule %d", rule.Id)) | 44 | c.Assert(err, ErrorMatches, fmt.Sprintf("no such security group rule %s", rule.Id)) |
2124 | 45 | } | 45 | } |
2125 | 46 | 46 | ||
2126 | 47 | func (s *NovaSuite) ensureNoIP(c *C, ip nova.FloatingIP) { | 47 | func (s *NovaSuite) ensureNoIP(c *C, ip nova.FloatingIP) { |
2127 | 48 | _, err := s.service.floatingIP(ip.Id) | 48 | _, err := s.service.floatingIP(ip.Id) |
2129 | 49 | c.Assert(err, ErrorMatches, fmt.Sprintf("no such floating IP %d", ip.Id)) | 49 | c.Assert(err, ErrorMatches, fmt.Sprintf("no such floating IP %s", ip.Id)) |
2130 | 50 | } | 50 | } |
2131 | 51 | 51 | ||
2132 | 52 | func (s *NovaSuite) createFlavor(c *C, flavor nova.FlavorDetail) { | 52 | func (s *NovaSuite) createFlavor(c *C, flavor nova.FlavorDetail) { |
2133 | @@ -520,19 +520,19 @@ | |||
2134 | 520 | } | 520 | } |
2135 | 521 | 521 | ||
2136 | 522 | func (s *NovaSuite) TestAddRemoveSecurityGroup(c *C) { | 522 | func (s *NovaSuite) TestAddRemoveSecurityGroup(c *C) { |
2138 | 523 | group := nova.SecurityGroup{Id: 1} | 523 | group := nova.SecurityGroup{Id: "1"} |
2139 | 524 | s.createGroup(c, group) | 524 | s.createGroup(c, group) |
2140 | 525 | s.deleteGroup(c, group) | 525 | s.deleteGroup(c, group) |
2141 | 526 | } | 526 | } |
2142 | 527 | 527 | ||
2143 | 528 | func (s *NovaSuite) TestAddSecurityGroupWithRules(c *C) { | 528 | func (s *NovaSuite) TestAddSecurityGroupWithRules(c *C) { |
2144 | 529 | group := nova.SecurityGroup{ | 529 | group := nova.SecurityGroup{ |
2146 | 530 | Id: 1, | 530 | Id: "1", |
2147 | 531 | Name: "test", | 531 | Name: "test", |
2148 | 532 | TenantId: s.service.TenantId, | 532 | TenantId: s.service.TenantId, |
2149 | 533 | Rules: []nova.SecurityGroupRule{ | 533 | Rules: []nova.SecurityGroupRule{ |
2152 | 534 | {Id: 10, ParentGroupId: 1}, | 534 | {Id: "10", ParentGroupId: "1"}, |
2153 | 535 | {Id: 20, ParentGroupId: 1}, | 535 | {Id: "20", ParentGroupId: "1"}, |
2154 | 536 | }, | 536 | }, |
2155 | 537 | } | 537 | } |
2156 | 538 | s.createGroup(c, group) | 538 | s.createGroup(c, group) |
2157 | @@ -542,7 +542,7 @@ | |||
2158 | 542 | } | 542 | } |
2159 | 543 | 543 | ||
2160 | 544 | func (s *NovaSuite) TestAddSecurityGroupTwiceFails(c *C) { | 544 | func (s *NovaSuite) TestAddSecurityGroupTwiceFails(c *C) { |
2162 | 545 | group := nova.SecurityGroup{Id: 1, Name: "test"} | 545 | group := nova.SecurityGroup{Id: "1", Name: "test"} |
2163 | 546 | s.createGroup(c, group) | 546 | s.createGroup(c, group) |
2164 | 547 | defer s.deleteGroup(c, group) | 547 | defer s.deleteGroup(c, group) |
2165 | 548 | err := s.service.addSecurityGroup(group) | 548 | err := s.service.addSecurityGroup(group) |
2166 | @@ -550,7 +550,7 @@ | |||
2167 | 550 | } | 550 | } |
2168 | 551 | 551 | ||
2169 | 552 | func (s *NovaSuite) TestRemoveSecurityGroupTwiceFails(c *C) { | 552 | func (s *NovaSuite) TestRemoveSecurityGroupTwiceFails(c *C) { |
2171 | 553 | group := nova.SecurityGroup{Id: 1, Name: "test"} | 553 | group := nova.SecurityGroup{Id: "1", Name: "test"} |
2172 | 554 | s.createGroup(c, group) | 554 | s.createGroup(c, group) |
2173 | 555 | s.deleteGroup(c, group) | 555 | s.deleteGroup(c, group) |
2174 | 556 | err := s.service.removeSecurityGroup(group.Id) | 556 | err := s.service.removeSecurityGroup(group.Id) |
2175 | @@ -563,13 +563,13 @@ | |||
2176 | 563 | c.Assert(groups, HasLen, 1) | 563 | c.Assert(groups, HasLen, 1) |
2177 | 564 | groups = []nova.SecurityGroup{ | 564 | groups = []nova.SecurityGroup{ |
2178 | 565 | { | 565 | { |
2180 | 566 | Id: 1, | 566 | Id: "1", |
2181 | 567 | Name: "one", | 567 | Name: "one", |
2182 | 568 | TenantId: s.service.TenantId, | 568 | TenantId: s.service.TenantId, |
2183 | 569 | Rules: []nova.SecurityGroupRule{}, | 569 | Rules: []nova.SecurityGroupRule{}, |
2184 | 570 | }, | 570 | }, |
2185 | 571 | { | 571 | { |
2187 | 572 | Id: 2, | 572 | Id: "2", |
2188 | 573 | Name: "two", | 573 | Name: "two", |
2189 | 574 | TenantId: s.service.TenantId, | 574 | TenantId: s.service.TenantId, |
2190 | 575 | Rules: []nova.SecurityGroupRule{}, | 575 | Rules: []nova.SecurityGroupRule{}, |
2191 | @@ -586,7 +586,7 @@ | |||
2192 | 586 | 586 | ||
2193 | 587 | func (s *NovaSuite) TestGetSecurityGroup(c *C) { | 587 | func (s *NovaSuite) TestGetSecurityGroup(c *C) { |
2194 | 588 | group := nova.SecurityGroup{ | 588 | group := nova.SecurityGroup{ |
2196 | 589 | Id: 42, | 589 | Id: "42", |
2197 | 590 | TenantId: s.service.TenantId, | 590 | TenantId: s.service.TenantId, |
2198 | 591 | Name: "group", | 591 | Name: "group", |
2199 | 592 | Description: "desc", | 592 | Description: "desc", |
2200 | @@ -600,7 +600,7 @@ | |||
2201 | 600 | 600 | ||
2202 | 601 | func (s *NovaSuite) TestGetSecurityGroupByName(c *C) { | 601 | func (s *NovaSuite) TestGetSecurityGroupByName(c *C) { |
2203 | 602 | group := nova.SecurityGroup{ | 602 | group := nova.SecurityGroup{ |
2205 | 603 | Id: 1, | 603 | Id: "1", |
2206 | 604 | Name: "test", | 604 | Name: "test", |
2207 | 605 | TenantId: s.service.TenantId, | 605 | TenantId: s.service.TenantId, |
2208 | 606 | Rules: []nova.SecurityGroupRule{}, | 606 | Rules: []nova.SecurityGroupRule{}, |
2209 | @@ -616,9 +616,9 @@ | |||
2210 | 616 | } | 616 | } |
2211 | 617 | 617 | ||
2212 | 618 | func (s *NovaSuite) TestAddHasRemoveSecurityGroupRule(c *C) { | 618 | func (s *NovaSuite) TestAddHasRemoveSecurityGroupRule(c *C) { |
2214 | 619 | group := nova.SecurityGroup{Id: 1} | 619 | group := nova.SecurityGroup{Id: "1"} |
2215 | 620 | ri := nova.RuleInfo{ParentGroupId: group.Id} | 620 | ri := nova.RuleInfo{ParentGroupId: group.Id} |
2217 | 621 | rule := nova.SecurityGroupRule{Id: 10, ParentGroupId: group.Id} | 621 | rule := nova.SecurityGroupRule{Id: "10", ParentGroupId: group.Id} |
2218 | 622 | s.ensureNoGroup(c, group) | 622 | s.ensureNoGroup(c, group) |
2219 | 623 | s.ensureNoRule(c, rule) | 623 | s.ensureNoRule(c, rule) |
2220 | 624 | ok := s.service.hasSecurityGroupRule(group.Id, rule.Id) | 624 | ok := s.service.hasSecurityGroupRule(group.Id, rule.Id) |
2221 | @@ -629,17 +629,17 @@ | |||
2222 | 629 | ok = s.service.hasSecurityGroupRule(group.Id, rule.Id) | 629 | ok = s.service.hasSecurityGroupRule(group.Id, rule.Id) |
2223 | 630 | c.Assert(ok, Equals, true) | 630 | c.Assert(ok, Equals, true) |
2224 | 631 | s.deleteGroup(c, group) | 631 | s.deleteGroup(c, group) |
2226 | 632 | ok = s.service.hasSecurityGroupRule(-1, rule.Id) | 632 | ok = s.service.hasSecurityGroupRule("-1", rule.Id) |
2227 | 633 | c.Assert(ok, Equals, true) | 633 | c.Assert(ok, Equals, true) |
2228 | 634 | ok = s.service.hasSecurityGroupRule(group.Id, rule.Id) | 634 | ok = s.service.hasSecurityGroupRule(group.Id, rule.Id) |
2229 | 635 | c.Assert(ok, Equals, false) | 635 | c.Assert(ok, Equals, false) |
2230 | 636 | s.deleteRule(c, rule) | 636 | s.deleteRule(c, rule) |
2232 | 637 | ok = s.service.hasSecurityGroupRule(-1, rule.Id) | 637 | ok = s.service.hasSecurityGroupRule("-1", rule.Id) |
2233 | 638 | c.Assert(ok, Equals, false) | 638 | c.Assert(ok, Equals, false) |
2234 | 639 | } | 639 | } |
2235 | 640 | 640 | ||
2236 | 641 | func (s *NovaSuite) TestAddGetIngressSecurityGroupRule(c *C) { | 641 | func (s *NovaSuite) TestAddGetIngressSecurityGroupRule(c *C) { |
2238 | 642 | group := nova.SecurityGroup{Id: 1} | 642 | group := nova.SecurityGroup{Id: "1"} |
2239 | 643 | s.createGroup(c, group) | 643 | s.createGroup(c, group) |
2240 | 644 | defer s.deleteGroup(c, group) | 644 | defer s.deleteGroup(c, group) |
2241 | 645 | ri := nova.RuleInfo{ | 645 | ri := nova.RuleInfo{ |
2242 | @@ -650,7 +650,7 @@ | |||
2243 | 650 | ParentGroupId: group.Id, | 650 | ParentGroupId: group.Id, |
2244 | 651 | } | 651 | } |
2245 | 652 | rule := nova.SecurityGroupRule{ | 652 | rule := nova.SecurityGroupRule{ |
2247 | 653 | Id: 10, | 653 | Id: "10", |
2248 | 654 | ParentGroupId: group.Id, | 654 | ParentGroupId: group.Id, |
2249 | 655 | FromPort: &ri.FromPort, | 655 | FromPort: &ri.FromPort, |
2250 | 656 | ToPort: &ri.ToPort, | 656 | ToPort: &ri.ToPort, |
2251 | @@ -673,8 +673,8 @@ | |||
2252 | 673 | } | 673 | } |
2253 | 674 | 674 | ||
2254 | 675 | func (s *NovaSuite) TestAddGetGroupSecurityGroupRule(c *C) { | 675 | func (s *NovaSuite) TestAddGetGroupSecurityGroupRule(c *C) { |
2257 | 676 | srcGroup := nova.SecurityGroup{Id: 1, Name: "source", TenantId: s.service.TenantId} | 676 | srcGroup := nova.SecurityGroup{Id: "1", Name: "source", TenantId: s.service.TenantId} |
2258 | 677 | tgtGroup := nova.SecurityGroup{Id: 2, Name: "target"} | 677 | tgtGroup := nova.SecurityGroup{Id: "2", Name: "target"} |
2259 | 678 | s.createGroup(c, srcGroup) | 678 | s.createGroup(c, srcGroup) |
2260 | 679 | defer s.deleteGroup(c, srcGroup) | 679 | defer s.deleteGroup(c, srcGroup) |
2261 | 680 | s.createGroup(c, tgtGroup) | 680 | s.createGroup(c, tgtGroup) |
2262 | @@ -687,7 +687,7 @@ | |||
2263 | 687 | ParentGroupId: tgtGroup.Id, | 687 | ParentGroupId: tgtGroup.Id, |
2264 | 688 | } | 688 | } |
2265 | 689 | rule := nova.SecurityGroupRule{ | 689 | rule := nova.SecurityGroupRule{ |
2267 | 690 | Id: 10, | 690 | Id: "10", |
2268 | 691 | ParentGroupId: tgtGroup.Id, | 691 | ParentGroupId: tgtGroup.Id, |
2269 | 692 | FromPort: &ri.FromPort, | 692 | FromPort: &ri.FromPort, |
2270 | 693 | ToPort: &ri.ToPort, | 693 | ToPort: &ri.ToPort, |
2271 | @@ -712,11 +712,11 @@ | |||
2272 | 712 | } | 712 | } |
2273 | 713 | 713 | ||
2274 | 714 | func (s *NovaSuite) TestAddSecurityGroupRuleTwiceFails(c *C) { | 714 | func (s *NovaSuite) TestAddSecurityGroupRuleTwiceFails(c *C) { |
2276 | 715 | group := nova.SecurityGroup{Id: 1} | 715 | group := nova.SecurityGroup{Id: "1"} |
2277 | 716 | s.createGroup(c, group) | 716 | s.createGroup(c, group) |
2278 | 717 | defer s.deleteGroup(c, group) | 717 | defer s.deleteGroup(c, group) |
2279 | 718 | ri := nova.RuleInfo{ParentGroupId: group.Id} | 718 | ri := nova.RuleInfo{ParentGroupId: group.Id} |
2281 | 719 | rule := nova.SecurityGroupRule{Id: 10} | 719 | rule := nova.SecurityGroupRule{Id: "10"} |
2282 | 720 | s.ensureNoRule(c, rule) | 720 | s.ensureNoRule(c, rule) |
2283 | 721 | err := s.service.addSecurityGroupRule(rule.Id, ri) | 721 | err := s.service.addSecurityGroupRule(rule.Id, ri) |
2284 | 722 | c.Assert(err, IsNil) | 722 | c.Assert(err, IsNil) |
2285 | @@ -727,39 +727,39 @@ | |||
2286 | 727 | 727 | ||
2287 | 728 | func (s *NovaSuite) TestAddSecurityGroupRuleToParentTwiceFails(c *C) { | 728 | func (s *NovaSuite) TestAddSecurityGroupRuleToParentTwiceFails(c *C) { |
2288 | 729 | group := nova.SecurityGroup{ | 729 | group := nova.SecurityGroup{ |
2290 | 730 | Id: 1, | 730 | Id: "1", |
2291 | 731 | Rules: []nova.SecurityGroupRule{ | 731 | Rules: []nova.SecurityGroupRule{ |
2293 | 732 | {Id: 10}, | 732 | {Id: "10"}, |
2294 | 733 | }, | 733 | }, |
2295 | 734 | } | 734 | } |
2296 | 735 | s.createGroup(c, group) | 735 | s.createGroup(c, group) |
2297 | 736 | defer s.deleteGroup(c, group) | 736 | defer s.deleteGroup(c, group) |
2298 | 737 | ri := nova.RuleInfo{ParentGroupId: group.Id} | 737 | ri := nova.RuleInfo{ParentGroupId: group.Id} |
2300 | 738 | rule := nova.SecurityGroupRule{Id: 10} | 738 | rule := nova.SecurityGroupRule{Id: "10"} |
2301 | 739 | err := s.service.addSecurityGroupRule(rule.Id, ri) | 739 | err := s.service.addSecurityGroupRule(rule.Id, ri) |
2302 | 740 | c.Assert(err, ErrorMatches, "cannot add twice rule 10 to security group 1") | 740 | c.Assert(err, ErrorMatches, "cannot add twice rule 10 to security group 1") |
2303 | 741 | } | 741 | } |
2304 | 742 | 742 | ||
2305 | 743 | func (s *NovaSuite) TestAddSecurityGroupRuleWithInvalidParentFails(c *C) { | 743 | func (s *NovaSuite) TestAddSecurityGroupRuleWithInvalidParentFails(c *C) { |
2307 | 744 | invalidGroup := nova.SecurityGroup{Id: 1} | 744 | invalidGroup := nova.SecurityGroup{Id: "1"} |
2308 | 745 | s.ensureNoGroup(c, invalidGroup) | 745 | s.ensureNoGroup(c, invalidGroup) |
2309 | 746 | ri := nova.RuleInfo{ParentGroupId: invalidGroup.Id} | 746 | ri := nova.RuleInfo{ParentGroupId: invalidGroup.Id} |
2311 | 747 | rule := nova.SecurityGroupRule{Id: 10} | 747 | rule := nova.SecurityGroupRule{Id: "10"} |
2312 | 748 | s.ensureNoRule(c, rule) | 748 | s.ensureNoRule(c, rule) |
2313 | 749 | err := s.service.addSecurityGroupRule(rule.Id, ri) | 749 | err := s.service.addSecurityGroupRule(rule.Id, ri) |
2314 | 750 | c.Assert(err, ErrorMatches, "no such security group 1") | 750 | c.Assert(err, ErrorMatches, "no such security group 1") |
2315 | 751 | } | 751 | } |
2316 | 752 | 752 | ||
2317 | 753 | func (s *NovaSuite) TestAddGroupSecurityGroupRuleWithInvalidSourceFails(c *C) { | 753 | func (s *NovaSuite) TestAddGroupSecurityGroupRuleWithInvalidSourceFails(c *C) { |
2319 | 754 | group := nova.SecurityGroup{Id: 1} | 754 | group := nova.SecurityGroup{Id: "1"} |
2320 | 755 | s.createGroup(c, group) | 755 | s.createGroup(c, group) |
2321 | 756 | defer s.deleteGroup(c, group) | 756 | defer s.deleteGroup(c, group) |
2323 | 757 | invalidGroupId := 42 | 757 | invalidGroupId := "42" |
2324 | 758 | ri := nova.RuleInfo{ | 758 | ri := nova.RuleInfo{ |
2325 | 759 | ParentGroupId: group.Id, | 759 | ParentGroupId: group.Id, |
2326 | 760 | GroupId: &invalidGroupId, | 760 | GroupId: &invalidGroupId, |
2327 | 761 | } | 761 | } |
2329 | 762 | rule := nova.SecurityGroupRule{Id: 10} | 762 | rule := nova.SecurityGroupRule{Id: "10"} |
2330 | 763 | s.ensureNoRule(c, rule) | 763 | s.ensureNoRule(c, rule) |
2331 | 764 | err := s.service.addSecurityGroupRule(rule.Id, ri) | 764 | err := s.service.addSecurityGroupRule(rule.Id, ri) |
2332 | 765 | c.Assert(err, ErrorMatches, "unknown source security group 42") | 765 | c.Assert(err, ErrorMatches, "unknown source security group 42") |
2333 | @@ -767,7 +767,7 @@ | |||
2334 | 767 | 767 | ||
2335 | 768 | func (s *NovaSuite) TestAddSecurityGroupRuleUpdatesParent(c *C) { | 768 | func (s *NovaSuite) TestAddSecurityGroupRuleUpdatesParent(c *C) { |
2336 | 769 | group := nova.SecurityGroup{ | 769 | group := nova.SecurityGroup{ |
2338 | 770 | Id: 1, | 770 | Id: "1", |
2339 | 771 | Name: "test", | 771 | Name: "test", |
2340 | 772 | TenantId: s.service.TenantId, | 772 | TenantId: s.service.TenantId, |
2341 | 773 | } | 773 | } |
2342 | @@ -775,7 +775,7 @@ | |||
2343 | 775 | defer s.deleteGroup(c, group) | 775 | defer s.deleteGroup(c, group) |
2344 | 776 | ri := nova.RuleInfo{ParentGroupId: group.Id} | 776 | ri := nova.RuleInfo{ParentGroupId: group.Id} |
2345 | 777 | rule := nova.SecurityGroupRule{ | 777 | rule := nova.SecurityGroupRule{ |
2347 | 778 | Id: 10, | 778 | Id: "10", |
2348 | 779 | ParentGroupId: group.Id, | 779 | ParentGroupId: group.Id, |
2349 | 780 | Group: nova.SecurityGroupRef{}, | 780 | Group: nova.SecurityGroupRef{}, |
2350 | 781 | } | 781 | } |
2351 | @@ -791,7 +791,7 @@ | |||
2352 | 791 | 791 | ||
2353 | 792 | func (s *NovaSuite) TestAddSecurityGroupRuleKeepsNegativePort(c *C) { | 792 | func (s *NovaSuite) TestAddSecurityGroupRuleKeepsNegativePort(c *C) { |
2354 | 793 | group := nova.SecurityGroup{ | 793 | group := nova.SecurityGroup{ |
2356 | 794 | Id: 1, | 794 | Id: "1", |
2357 | 795 | Name: "test", | 795 | Name: "test", |
2358 | 796 | TenantId: s.service.TenantId, | 796 | TenantId: s.service.TenantId, |
2359 | 797 | } | 797 | } |
2360 | @@ -805,7 +805,7 @@ | |||
2361 | 805 | ParentGroupId: group.Id, | 805 | ParentGroupId: group.Id, |
2362 | 806 | } | 806 | } |
2363 | 807 | rule := nova.SecurityGroupRule{ | 807 | rule := nova.SecurityGroupRule{ |
2365 | 808 | Id: 10, | 808 | Id: "10", |
2366 | 809 | ParentGroupId: group.Id, | 809 | ParentGroupId: group.Id, |
2367 | 810 | FromPort: &ri.FromPort, | 810 | FromPort: &ri.FromPort, |
2368 | 811 | ToPort: &ri.ToPort, | 811 | ToPort: &ri.ToPort, |
2369 | @@ -822,11 +822,11 @@ | |||
2370 | 822 | } | 822 | } |
2371 | 823 | 823 | ||
2372 | 824 | func (s *NovaSuite) TestRemoveSecurityGroupRuleTwiceFails(c *C) { | 824 | func (s *NovaSuite) TestRemoveSecurityGroupRuleTwiceFails(c *C) { |
2374 | 825 | group := nova.SecurityGroup{Id: 1} | 825 | group := nova.SecurityGroup{Id: "1"} |
2375 | 826 | s.createGroup(c, group) | 826 | s.createGroup(c, group) |
2376 | 827 | defer s.deleteGroup(c, group) | 827 | defer s.deleteGroup(c, group) |
2377 | 828 | ri := nova.RuleInfo{ParentGroupId: group.Id} | 828 | ri := nova.RuleInfo{ParentGroupId: group.Id} |
2379 | 829 | rule := nova.SecurityGroupRule{Id: 10} | 829 | rule := nova.SecurityGroupRule{Id: "10"} |
2380 | 830 | s.ensureNoRule(c, rule) | 830 | s.ensureNoRule(c, rule) |
2381 | 831 | err := s.service.addSecurityGroupRule(rule.Id, ri) | 831 | err := s.service.addSecurityGroupRule(rule.Id, ri) |
2382 | 832 | c.Assert(err, IsNil) | 832 | c.Assert(err, IsNil) |
2383 | @@ -837,7 +837,7 @@ | |||
2384 | 837 | 837 | ||
2385 | 838 | func (s *NovaSuite) TestAddHasRemoveServerSecurityGroup(c *C) { | 838 | func (s *NovaSuite) TestAddHasRemoveServerSecurityGroup(c *C) { |
2386 | 839 | server := nova.ServerDetail{Id: "sr1"} | 839 | server := nova.ServerDetail{Id: "sr1"} |
2388 | 840 | group := nova.SecurityGroup{Id: 1} | 840 | group := nova.SecurityGroup{Id: "1"} |
2389 | 841 | s.ensureNoServer(c, server) | 841 | s.ensureNoServer(c, server) |
2390 | 842 | s.ensureNoGroup(c, group) | 842 | s.ensureNoGroup(c, group) |
2391 | 843 | ok := s.service.hasServerSecurityGroup(server.Id, group.Id) | 843 | ok := s.service.hasServerSecurityGroup(server.Id, group.Id) |
2392 | @@ -862,7 +862,7 @@ | |||
2393 | 862 | 862 | ||
2394 | 863 | func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidServerFails(c *C) { | 863 | func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidServerFails(c *C) { |
2395 | 864 | server := nova.ServerDetail{Id: "sr1"} | 864 | server := nova.ServerDetail{Id: "sr1"} |
2397 | 865 | group := nova.SecurityGroup{Id: 1} | 865 | group := nova.SecurityGroup{Id: "1"} |
2398 | 866 | s.ensureNoServer(c, server) | 866 | s.ensureNoServer(c, server) |
2399 | 867 | s.createGroup(c, group) | 867 | s.createGroup(c, group) |
2400 | 868 | defer s.deleteGroup(c, group) | 868 | defer s.deleteGroup(c, group) |
2401 | @@ -871,7 +871,7 @@ | |||
2402 | 871 | } | 871 | } |
2403 | 872 | 872 | ||
2404 | 873 | func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidGroupFails(c *C) { | 873 | func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidGroupFails(c *C) { |
2406 | 874 | group := nova.SecurityGroup{Id: 1} | 874 | group := nova.SecurityGroup{Id: "1"} |
2407 | 875 | server := nova.ServerDetail{Id: "sr1"} | 875 | server := nova.ServerDetail{Id: "sr1"} |
2408 | 876 | s.ensureNoGroup(c, group) | 876 | s.ensureNoGroup(c, group) |
2409 | 877 | s.createServer(c, server) | 877 | s.createServer(c, server) |
2410 | @@ -882,7 +882,7 @@ | |||
2411 | 882 | 882 | ||
2412 | 883 | func (s *NovaSuite) TestAddServerSecurityGroupTwiceFails(c *C) { | 883 | func (s *NovaSuite) TestAddServerSecurityGroupTwiceFails(c *C) { |
2413 | 884 | server := nova.ServerDetail{Id: "sr1"} | 884 | server := nova.ServerDetail{Id: "sr1"} |
2415 | 885 | group := nova.SecurityGroup{Id: 1} | 885 | group := nova.SecurityGroup{Id: "1"} |
2416 | 886 | s.createServer(c, server) | 886 | s.createServer(c, server) |
2417 | 887 | defer s.deleteServer(c, server) | 887 | defer s.deleteServer(c, server) |
2418 | 888 | s.createGroup(c, group) | 888 | s.createGroup(c, group) |
2419 | @@ -903,13 +903,13 @@ | |||
2420 | 903 | defer s.deleteServer(c, server) | 903 | defer s.deleteServer(c, server) |
2421 | 904 | groups := []nova.SecurityGroup{ | 904 | groups := []nova.SecurityGroup{ |
2422 | 905 | { | 905 | { |
2424 | 906 | Id: 1, | 906 | Id: "1", |
2425 | 907 | Name: "gr1", | 907 | Name: "gr1", |
2426 | 908 | TenantId: s.service.TenantId, | 908 | TenantId: s.service.TenantId, |
2427 | 909 | Rules: []nova.SecurityGroupRule{}, | 909 | Rules: []nova.SecurityGroupRule{}, |
2428 | 910 | }, | 910 | }, |
2429 | 911 | { | 911 | { |
2431 | 912 | Id: 2, | 912 | Id: "2", |
2432 | 913 | Name: "gr2", | 913 | Name: "gr2", |
2433 | 914 | TenantId: s.service.TenantId, | 914 | TenantId: s.service.TenantId, |
2434 | 915 | Rules: []nova.SecurityGroupRule{}, | 915 | Rules: []nova.SecurityGroupRule{}, |
2435 | @@ -932,7 +932,7 @@ | |||
2436 | 932 | 932 | ||
2437 | 933 | func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidServerFails(c *C) { | 933 | func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidServerFails(c *C) { |
2438 | 934 | server := nova.ServerDetail{Id: "sr1"} | 934 | server := nova.ServerDetail{Id: "sr1"} |
2440 | 935 | group := nova.SecurityGroup{Id: 1} | 935 | group := nova.SecurityGroup{Id: "1"} |
2441 | 936 | s.createServer(c, server) | 936 | s.createServer(c, server) |
2442 | 937 | s.createGroup(c, group) | 937 | s.createGroup(c, group) |
2443 | 938 | defer s.deleteGroup(c, group) | 938 | defer s.deleteGroup(c, group) |
2444 | @@ -948,7 +948,7 @@ | |||
2445 | 948 | } | 948 | } |
2446 | 949 | 949 | ||
2447 | 950 | func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidGroupFails(c *C) { | 950 | func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidGroupFails(c *C) { |
2449 | 951 | group := nova.SecurityGroup{Id: 1} | 951 | group := nova.SecurityGroup{Id: "1"} |
2450 | 952 | server := nova.ServerDetail{Id: "sr1"} | 952 | server := nova.ServerDetail{Id: "sr1"} |
2451 | 953 | s.createGroup(c, group) | 953 | s.createGroup(c, group) |
2452 | 954 | s.createServer(c, server) | 954 | s.createServer(c, server) |
2453 | @@ -966,7 +966,7 @@ | |||
2454 | 966 | 966 | ||
2455 | 967 | func (s *NovaSuite) TestRemoveServerSecurityGroupTwiceFails(c *C) { | 967 | func (s *NovaSuite) TestRemoveServerSecurityGroupTwiceFails(c *C) { |
2456 | 968 | server := nova.ServerDetail{Id: "sr1"} | 968 | server := nova.ServerDetail{Id: "sr1"} |
2458 | 969 | group := nova.SecurityGroup{Id: 1} | 969 | group := nova.SecurityGroup{Id: "1"} |
2459 | 970 | s.createServer(c, server) | 970 | s.createServer(c, server) |
2460 | 971 | defer s.deleteServer(c, server) | 971 | defer s.deleteServer(c, server) |
2461 | 972 | s.createGroup(c, group) | 972 | s.createGroup(c, group) |
2462 | @@ -980,7 +980,7 @@ | |||
2463 | 980 | } | 980 | } |
2464 | 981 | 981 | ||
2465 | 982 | func (s *NovaSuite) TestAddHasRemoveFloatingIP(c *C) { | 982 | func (s *NovaSuite) TestAddHasRemoveFloatingIP(c *C) { |
2467 | 983 | ip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"} | 983 | ip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"} |
2468 | 984 | s.ensureNoIP(c, ip) | 984 | s.ensureNoIP(c, ip) |
2469 | 985 | ok := s.service.hasFloatingIP(ip.IP) | 985 | ok := s.service.hasFloatingIP(ip.IP) |
2470 | 986 | c.Assert(ok, Equals, false) | 986 | c.Assert(ok, Equals, false) |
2471 | @@ -995,7 +995,7 @@ | |||
2472 | 995 | } | 995 | } |
2473 | 996 | 996 | ||
2474 | 997 | func (s *NovaSuite) TestAddFloatingIPTwiceFails(c *C) { | 997 | func (s *NovaSuite) TestAddFloatingIPTwiceFails(c *C) { |
2476 | 998 | ip := nova.FloatingIP{Id: 1} | 998 | ip := nova.FloatingIP{Id: "1"} |
2477 | 999 | s.createIP(c, ip) | 999 | s.createIP(c, ip) |
2478 | 1000 | defer s.deleteIP(c, ip) | 1000 | defer s.deleteIP(c, ip) |
2479 | 1001 | err := s.service.addFloatingIP(ip) | 1001 | err := s.service.addFloatingIP(ip) |
2480 | @@ -1003,7 +1003,7 @@ | |||
2481 | 1003 | } | 1003 | } |
2482 | 1004 | 1004 | ||
2483 | 1005 | func (s *NovaSuite) TestRemoveFloatingIPTwiceFails(c *C) { | 1005 | func (s *NovaSuite) TestRemoveFloatingIPTwiceFails(c *C) { |
2485 | 1006 | ip := nova.FloatingIP{Id: 1} | 1006 | ip := nova.FloatingIP{Id: "1"} |
2486 | 1007 | s.createIP(c, ip) | 1007 | s.createIP(c, ip) |
2487 | 1008 | s.deleteIP(c, ip) | 1008 | s.deleteIP(c, ip) |
2488 | 1009 | err := s.service.removeFloatingIP(ip.Id) | 1009 | err := s.service.removeFloatingIP(ip.Id) |
2489 | @@ -1014,8 +1014,8 @@ | |||
2490 | 1014 | fips := s.service.allFloatingIPs() | 1014 | fips := s.service.allFloatingIPs() |
2491 | 1015 | c.Assert(fips, HasLen, 0) | 1015 | c.Assert(fips, HasLen, 0) |
2492 | 1016 | fips = []nova.FloatingIP{ | 1016 | fips = []nova.FloatingIP{ |
2495 | 1017 | {Id: 1}, | 1017 | {Id: "1"}, |
2496 | 1018 | {Id: 2}, | 1018 | {Id: "2"}, |
2497 | 1019 | } | 1019 | } |
2498 | 1020 | s.createIP(c, fips[0]) | 1020 | s.createIP(c, fips[0]) |
2499 | 1021 | defer s.deleteIP(c, fips[0]) | 1021 | defer s.deleteIP(c, fips[0]) |
2500 | @@ -1033,7 +1033,7 @@ | |||
2501 | 1033 | inst := "sr1" | 1033 | inst := "sr1" |
2502 | 1034 | fixedIP := "4.3.2.1" | 1034 | fixedIP := "4.3.2.1" |
2503 | 1035 | fip := nova.FloatingIP{ | 1035 | fip := nova.FloatingIP{ |
2505 | 1036 | Id: 1, | 1036 | Id: "1", |
2506 | 1037 | IP: "1.2.3.4", | 1037 | IP: "1.2.3.4", |
2507 | 1038 | Pool: "pool", | 1038 | Pool: "pool", |
2508 | 1039 | InstanceId: &inst, | 1039 | InstanceId: &inst, |
2509 | @@ -1046,7 +1046,7 @@ | |||
2510 | 1046 | } | 1046 | } |
2511 | 1047 | 1047 | ||
2512 | 1048 | func (s *NovaSuite) TestGetFloatingIPByAddr(c *C) { | 1048 | func (s *NovaSuite) TestGetFloatingIPByAddr(c *C) { |
2514 | 1049 | fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"} | 1049 | fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"} |
2515 | 1050 | s.ensureNoIP(c, fip) | 1050 | s.ensureNoIP(c, fip) |
2516 | 1051 | ip, err := s.service.floatingIPByAddr(fip.IP) | 1051 | ip, err := s.service.floatingIPByAddr(fip.IP) |
2517 | 1052 | c.Assert(err, NotNil) | 1052 | c.Assert(err, NotNil) |
2518 | @@ -1061,7 +1061,7 @@ | |||
2519 | 1061 | 1061 | ||
2520 | 1062 | func (s *NovaSuite) TestAddHasRemoveServerFloatingIP(c *C) { | 1062 | func (s *NovaSuite) TestAddHasRemoveServerFloatingIP(c *C) { |
2521 | 1063 | server := nova.ServerDetail{Id: "sr1"} | 1063 | server := nova.ServerDetail{Id: "sr1"} |
2523 | 1064 | fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"} | 1064 | fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"} |
2524 | 1065 | s.ensureNoServer(c, server) | 1065 | s.ensureNoServer(c, server) |
2525 | 1066 | s.ensureNoIP(c, fip) | 1066 | s.ensureNoIP(c, fip) |
2526 | 1067 | ok := s.service.hasServerFloatingIP(server.Id, fip.IP) | 1067 | ok := s.service.hasServerFloatingIP(server.Id, fip.IP) |
2527 | @@ -1086,7 +1086,7 @@ | |||
2528 | 1086 | 1086 | ||
2529 | 1087 | func (s *NovaSuite) TestAddServerFloatingIPWithInvalidServerFails(c *C) { | 1087 | func (s *NovaSuite) TestAddServerFloatingIPWithInvalidServerFails(c *C) { |
2530 | 1088 | server := nova.ServerDetail{Id: "sr1"} | 1088 | server := nova.ServerDetail{Id: "sr1"} |
2532 | 1089 | fip := nova.FloatingIP{Id: 1} | 1089 | fip := nova.FloatingIP{Id: "1"} |
2533 | 1090 | s.ensureNoServer(c, server) | 1090 | s.ensureNoServer(c, server) |
2534 | 1091 | s.createIP(c, fip) | 1091 | s.createIP(c, fip) |
2535 | 1092 | defer s.deleteIP(c, fip) | 1092 | defer s.deleteIP(c, fip) |
2536 | @@ -1095,7 +1095,7 @@ | |||
2537 | 1095 | } | 1095 | } |
2538 | 1096 | 1096 | ||
2539 | 1097 | func (s *NovaSuite) TestAddServerFloatingIPWithInvalidIPFails(c *C) { | 1097 | func (s *NovaSuite) TestAddServerFloatingIPWithInvalidIPFails(c *C) { |
2541 | 1098 | fip := nova.FloatingIP{Id: 1} | 1098 | fip := nova.FloatingIP{Id: "1"} |
2542 | 1099 | server := nova.ServerDetail{Id: "sr1"} | 1099 | server := nova.ServerDetail{Id: "sr1"} |
2543 | 1100 | s.ensureNoIP(c, fip) | 1100 | s.ensureNoIP(c, fip) |
2544 | 1101 | s.createServer(c, server) | 1101 | s.createServer(c, server) |
2545 | @@ -1106,7 +1106,7 @@ | |||
2546 | 1106 | 1106 | ||
2547 | 1107 | func (s *NovaSuite) TestAddServerFloatingIPTwiceFails(c *C) { | 1107 | func (s *NovaSuite) TestAddServerFloatingIPTwiceFails(c *C) { |
2548 | 1108 | server := nova.ServerDetail{Id: "sr1"} | 1108 | server := nova.ServerDetail{Id: "sr1"} |
2550 | 1109 | fip := nova.FloatingIP{Id: 1} | 1109 | fip := nova.FloatingIP{Id: "1"} |
2551 | 1110 | s.createServer(c, server) | 1110 | s.createServer(c, server) |
2552 | 1111 | defer s.deleteServer(c, server) | 1111 | defer s.deleteServer(c, server) |
2553 | 1112 | s.createIP(c, fip) | 1112 | s.createIP(c, fip) |
2554 | @@ -1121,7 +1121,7 @@ | |||
2555 | 1121 | 1121 | ||
2556 | 1122 | func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidServerFails(c *C) { | 1122 | func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidServerFails(c *C) { |
2557 | 1123 | server := nova.ServerDetail{Id: "sr1"} | 1123 | server := nova.ServerDetail{Id: "sr1"} |
2559 | 1124 | fip := nova.FloatingIP{Id: 1} | 1124 | fip := nova.FloatingIP{Id: "1"} |
2560 | 1125 | s.createServer(c, server) | 1125 | s.createServer(c, server) |
2561 | 1126 | s.createIP(c, fip) | 1126 | s.createIP(c, fip) |
2562 | 1127 | defer s.deleteIP(c, fip) | 1127 | defer s.deleteIP(c, fip) |
2563 | @@ -1137,7 +1137,7 @@ | |||
2564 | 1137 | } | 1137 | } |
2565 | 1138 | 1138 | ||
2566 | 1139 | func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidIPFails(c *C) { | 1139 | func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidIPFails(c *C) { |
2568 | 1140 | fip := nova.FloatingIP{Id: 1} | 1140 | fip := nova.FloatingIP{Id: "1"} |
2569 | 1141 | server := nova.ServerDetail{Id: "sr1"} | 1141 | server := nova.ServerDetail{Id: "sr1"} |
2570 | 1142 | s.createIP(c, fip) | 1142 | s.createIP(c, fip) |
2571 | 1143 | s.createServer(c, server) | 1143 | s.createServer(c, server) |
2572 | @@ -1155,7 +1155,7 @@ | |||
2573 | 1155 | 1155 | ||
2574 | 1156 | func (s *NovaSuite) TestRemoveServerFloatingIPTwiceFails(c *C) { | 1156 | func (s *NovaSuite) TestRemoveServerFloatingIPTwiceFails(c *C) { |
2575 | 1157 | server := nova.ServerDetail{Id: "sr1"} | 1157 | server := nova.ServerDetail{Id: "sr1"} |
2577 | 1158 | fip := nova.FloatingIP{Id: 1} | 1158 | fip := nova.FloatingIP{Id: "1"} |
2578 | 1159 | s.createServer(c, server) | 1159 | s.createServer(c, server) |
2579 | 1160 | defer s.deleteServer(c, server) | 1160 | defer s.deleteServer(c, server) |
2580 | 1161 | s.createIP(c, fip) | 1161 | s.createIP(c, fip) |
2581 | 1162 | 1162 | ||
2582 | === modified file 'testservices/openstackservice/openstack.go' | |||
2583 | --- testservices/openstackservice/openstack.go 2013-02-08 02:23:27 +0000 | |||
2584 | +++ testservices/openstackservice/openstack.go 2013-07-01 07:24:26 +0000 | |||
2585 | @@ -1,6 +1,7 @@ | |||
2586 | 1 | package openstackservice | 1 | package openstackservice |
2587 | 2 | 2 | ||
2588 | 3 | import ( | 3 | import ( |
2589 | 4 | "fmt" | ||
2590 | 4 | "launchpad.net/goose/identity" | 5 | "launchpad.net/goose/identity" |
2591 | 5 | "launchpad.net/goose/testservices/identityservice" | 6 | "launchpad.net/goose/testservices/identityservice" |
2592 | 6 | "launchpad.net/goose/testservices/novaservice" | 7 | "launchpad.net/goose/testservices/novaservice" |
2593 | @@ -18,9 +19,16 @@ | |||
2594 | 18 | 19 | ||
2595 | 19 | // New creates an instance of a full Openstack service double. | 20 | // New creates an instance of a full Openstack service double. |
2596 | 20 | // An initial user with the specified credentials is registered with the identity service. | 21 | // An initial user with the specified credentials is registered with the identity service. |
2600 | 21 | func New(cred *identity.Credentials) *Openstack { | 22 | func New(cred *identity.Credentials, authMode identity.AuthMode) *Openstack { |
2601 | 22 | openstack := Openstack{ | 23 | var openstack Openstack |
2602 | 23 | Identity: identityservice.NewUserPass(), | 24 | if authMode == identity.AuthKeyPair { |
2603 | 25 | openstack = Openstack{ | ||
2604 | 26 | Identity: identityservice.NewKeyPair(), | ||
2605 | 27 | } | ||
2606 | 28 | } else { | ||
2607 | 29 | openstack = Openstack{ | ||
2608 | 30 | Identity: identityservice.NewUserPass(), | ||
2609 | 31 | } | ||
2610 | 24 | } | 32 | } |
2611 | 25 | userInfo := openstack.Identity.AddUser(cred.User, cred.Secrets, cred.TenantName) | 33 | userInfo := openstack.Identity.AddUser(cred.User, cred.Secrets, cred.TenantName) |
2612 | 26 | if cred.TenantName == "" { | 34 | if cred.TenantName == "" { |
2613 | @@ -31,6 +39,22 @@ | |||
2614 | 31 | regionParts := strings.Split(cred.Region, ".") | 39 | regionParts := strings.Split(cred.Region, ".") |
2615 | 32 | baseRegion := regionParts[len(regionParts)-1] | 40 | baseRegion := regionParts[len(regionParts)-1] |
2616 | 33 | openstack.Swift = swiftservice.New(cred.URL, "v1", userInfo.TenantId, baseRegion, openstack.Identity) | 41 | openstack.Swift = swiftservice.New(cred.URL, "v1", userInfo.TenantId, baseRegion, openstack.Identity) |
2617 | 42 | // Create container and add image metadata endpoint so that product-streams URLs are included | ||
2618 | 43 | // in the keystone catalog. | ||
2619 | 44 | err := openstack.Swift.AddContainer("imagemetadata") | ||
2620 | 45 | if err != nil { | ||
2621 | 46 | panic(fmt.Errorf("setting up image metadata container: %v", err)) | ||
2622 | 47 | } | ||
2623 | 48 | url := openstack.Swift.Endpoints()[0].PublicURL | ||
2624 | 49 | serviceDef := identityservice.Service{"simplestreams", "product-streams", []identityservice.Endpoint{ | ||
2625 | 50 | identityservice.Endpoint{PublicURL: url + "/imagemetadata", Region: cred.Region}, | ||
2626 | 51 | }} | ||
2627 | 52 | openstack.Identity.AddService(serviceDef) | ||
2628 | 53 | // Add public bucket endpoint so that juju-tools URLs are included in the keystone catalog. | ||
2629 | 54 | serviceDef = identityservice.Service{"juju", "juju-tools", []identityservice.Endpoint{ | ||
2630 | 55 | identityservice.Endpoint{PublicURL: url, Region: cred.Region}, | ||
2631 | 56 | }} | ||
2632 | 57 | openstack.Identity.AddService(serviceDef) | ||
2633 | 34 | return &openstack | 58 | return &openstack |
2634 | 35 | } | 59 | } |
2635 | 36 | 60 | ||
2636 | 37 | 61 | ||
2637 | === modified file 'tools/secgroup-delete-all/main_test.go' | |||
2638 | --- tools/secgroup-delete-all/main_test.go 2013-02-20 06:00:49 +0000 | |||
2639 | +++ tools/secgroup-delete-all/main_test.go 2013-07-01 07:24:26 +0000 | |||
2640 | @@ -46,7 +46,7 @@ | |||
2641 | 46 | Region: region, | 46 | Region: region, |
2642 | 47 | TenantName: tenant, | 47 | TenantName: tenant, |
2643 | 48 | } | 48 | } |
2645 | 49 | openstack := openstackservice.New(creds) | 49 | openstack := openstackservice.New(creds, identity.AuthUserPass) |
2646 | 50 | openstack.SetupHTTP(s.Mux) | 50 | openstack.SetupHTTP(s.Mux) |
2647 | 51 | return openstack, createNovaClient(creds) | 51 | return openstack, createNovaClient(creds) |
2648 | 52 | } | 52 | } |
2649 | @@ -74,7 +74,7 @@ | |||
2650 | 74 | 74 | ||
2651 | 75 | // deleteGroupError hook raises an error if a group with id 2 is deleted. | 75 | // deleteGroupError hook raises an error if a group with id 2 is deleted. |
2652 | 76 | func deleteGroupError(s hook.ServiceControl, args ...interface{}) error { | 76 | func deleteGroupError(s hook.ServiceControl, args ...interface{}) error { |
2654 | 77 | groupId := args[0].(int) | 77 | groupId := args[0].(string) |
2655 | 78 | if groupId == doNotDelete.Id { | 78 | if groupId == doNotDelete.Id { |
2656 | 79 | return fmt.Errorf("cannot delete group %d", groupId) | 79 | return fmt.Errorf("cannot delete group %d", groupId) |
2657 | 80 | } | 80 | } |
2658 | 81 | 81 | ||
2659 | === modified file 'version.go' | |||
2660 | --- version.go 2013-02-05 13:22:51 +0000 | |||
2661 | +++ version.go 2013-07-01 07:24:26 +0000 | |||
2662 | @@ -1,3 +1,6 @@ | |||
2663 | 1 | // Copyright 2013 Canonical Ltd. | ||
2664 | 2 | // Licensed under the LGPLv3, see COPYING and COPYING.LESSER file for details. | ||
2665 | 3 | |||
2666 | 1 | package goose | 4 | package goose |
2667 | 2 | 5 | ||
2668 | 3 | import ( | 6 | import ( |
2669 | 4 | 7 | ||
2670 | === modified file 'version_test.go' | |||
2671 | --- version_test.go 2013-02-05 13:37:45 +0000 | |||
2672 | +++ version_test.go 2013-07-01 07:24:26 +0000 | |||
2673 | @@ -1,3 +1,6 @@ | |||
2674 | 1 | // Copyright 2013 Canonical Ltd. | ||
2675 | 2 | // Licensed under the LGPLv3, see COPYING and COPYING.LESSER file for details. | ||
2676 | 3 | |||
2677 | 1 | package goose | 4 | package goose |
2678 | 2 | 5 | ||
2679 | 3 | import ( | 6 | import ( |
The attempt to merge lp:goose into lp:~go-bot/goose/test failed. Below is the output from the failed tests.
cd /home/tarmac/ trees/src/ launchpad. net/juju- core trees/src/ launchpad. net/juju- core trees/src/ launchpad. net/juju- core trees/src/ labix.org/ v2/mgo trees/src/ labix.org/ v2/mgo trees/src/ labix.org/ v2/mgo trees/src/ launchpad. net/goyaml trees/src/ launchpad. net/goyaml trees/src/ launchpad. net/goyaml trees/src/ launchpad. net/gnuflag trees/src/ launchpad. net/gnuflag trees/src/ launchpad. net/gnuflag trees/src/ code.google. com/p/go. net trees/src/ code.google. com/p/go. net trees/src/ code.google. com/p/go. net trees/src/ code.google. com/p/go. net trees/src/ launchpad. net/goamz trees/src/ launchpad. net/goamz trees/src/ launchpad. net/goamz trees/src/ launchpad. net/gomaasapi trees/src/ launchpad. net/gomaasapi trees/src/ launchpad. net/gomaasapi trees/src/ launchpad. net/goose trees/src/ launchpad. net/tomb trees/src/ launchpad. net/tomb trees/src/ launchpad. net/tomb trees/src/ launchpad. net/lpad trees/src/ launchpad. net/lpad trees/src/ launchpad. net/lpad trees/src/ launchpad. net/gocheck trees/src/ launchpad. net/gocheck trees/src/ launchpad. net/gocheck
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r go1
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
cd /home/tarmac/
hg pull
cd /home/tarmac/
hg tags
cd /home/tarmac/
hg branches
cd /home/tarmac/
hg update default
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
cd /home/tarmac/
bzr pull --overwrite
cd /home/tarmac/
bzr tags
cd /home/tarmac/
bzr update -r revno:-1
------- ------- ------- ------- ------- ------- ------- ------- ------- ------- SetUpSuite
PANIC: local_test.go:39: localLiveSuite.
Using identity service test double .IdentityServic e is *identityservic e.KeyPair, not *identityservic e.UserPass (PC=0x4112F8)
... Panic: interface conversion: identityservice
/build/ buildd/ golang- 1/src/pkg/ runtime/ proc.c: 1443 buildd/ golang- 1/src/pkg/ runtime/ iface.c: 247 buildd/ golang- 1/src/pkg/ runtime/ iface.c: 227 trees/src/ launchpad. net/goose/ testservices/ openstackservic e/openstack. go:52 SetUpSuite net/goose/ client 0.025s net/goose/ errors 0.007s net/goose/ glance 0.012s net/goose/ http 0.014s net/goose/ identity 0.021s net/goose/ nova 0.093s net/goose/ swift 0.051s net/goose/ sync 0....
in panic
/build/
in assertI2Tret
/build/
in assertI2T
/home/tarmac/
in New
local_test.go:54
in localLiveSuite.
OOPS: 16 passed, 4 skipped, 1 FIXTURE-PANICKED, 10 MISSED
--- FAIL: Test (0.01 seconds)
FAIL
FAIL launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.