Merge lp:goose into lp:~go-bot/goose/test

Proposed by John A Meinel
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
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 :
Download full text (4.9 KiB)

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
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/juju-core
bzr tags
cd /home/tarmac/trees/src/launchpad.net/juju-core
bzr update -r revno:-1
cd /home/tarmac/trees/src/labix.org/v2/mgo
bzr pull --overwrite
cd /home/tarmac/trees/src/labix.org/v2/mgo
bzr tags
cd /home/tarmac/trees/src/labix.org/v2/mgo
bzr update -r go1
cd /home/tarmac/trees/src/launchpad.net/goyaml
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/goyaml
bzr tags
cd /home/tarmac/trees/src/launchpad.net/goyaml
bzr update -r revno:-1
cd /home/tarmac/trees/src/launchpad.net/gnuflag
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/gnuflag
bzr tags
cd /home/tarmac/trees/src/launchpad.net/gnuflag
bzr update -r revno:-1
cd /home/tarmac/trees/src/code.google.com/p/go.net
hg pull
cd /home/tarmac/trees/src/code.google.com/p/go.net
hg tags
cd /home/tarmac/trees/src/code.google.com/p/go.net
hg branches
cd /home/tarmac/trees/src/code.google.com/p/go.net
hg update default
cd /home/tarmac/trees/src/launchpad.net/goamz
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/goamz
bzr tags
cd /home/tarmac/trees/src/launchpad.net/goamz
bzr update -r revno:-1
cd /home/tarmac/trees/src/launchpad.net/gomaasapi
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/gomaasapi
bzr tags
cd /home/tarmac/trees/src/launchpad.net/gomaasapi
bzr update -r revno:-1
cd /home/tarmac/trees/src/launchpad.net/goose
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/tomb
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/tomb
bzr tags
cd /home/tarmac/trees/src/launchpad.net/tomb
bzr update -r revno:-1
cd /home/tarmac/trees/src/launchpad.net/lpad
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/lpad
bzr tags
cd /home/tarmac/trees/src/launchpad.net/lpad
bzr update -r revno:-1
cd /home/tarmac/trees/src/launchpad.net/gocheck
bzr pull --overwrite
cd /home/tarmac/trees/src/launchpad.net/gocheck
bzr tags
cd /home/tarmac/trees/src/launchpad.net/gocheck
bzr update -r revno:-1

----------------------------------------------------------------------
PANIC: local_test.go:39: localLiveSuite.SetUpSuite

Using identity service test double
... Panic: interface conversion: identityservice.IdentityService is *identityservice.KeyPair, not *identityservice.UserPass (PC=0x4112F8)

/build/buildd/golang-1/src/pkg/runtime/proc.c:1443
  in panic
/build/buildd/golang-1/src/pkg/runtime/iface.c:247
  in assertI2Tret
/build/buildd/golang-1/src/pkg/runtime/iface.c:227
  in assertI2T
/home/tarmac/trees/src/launchpad.net/goose/testservices/openstackservice/openstack.go:52
  in New
local_test.go:54
  in localLiveSuite.SetUpSuite
OOPS: 16 passed, 4 skipped, 1 FIXTURE-PANICKED, 10 MISSED
--- FAIL: Test (0.01 seconds)
FAIL
FAIL launchpad.net/goose/client 0.025s
ok launchpad.net/goose/errors 0.007s
ok launchpad.net/goose/glance 0.012s
ok launchpad.net/goose/http 0.014s
ok launchpad.net/goose/identity 0.021s
ok launchpad.net/goose/nova 0.093s
ok launchpad.net/goose/swift 0.051s
ok launchpad.net/goose/sync 0....

Read more...

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
=== modified file 'client/client.go'
--- client/client.go 2013-03-28 12:36:12 +0000
+++ client/client.go 2013-07-01 07:24:26 +0000
@@ -106,6 +106,8 @@
106 client.authMode = &identity.Legacy{}106 client.authMode = &identity.Legacy{}
107 case identity.AuthUserPass:107 case identity.AuthUserPass:
108 client.authMode = &identity.UserPass{}108 client.authMode = &identity.UserPass{}
109 case identity.AuthKeyPair:
110 client.authMode = &identity.KeyPair{}
109 }111 }
110 return &client112 return &client
111}113}
112114
=== modified file 'client/client_test.go'
--- client/client_test.go 2013-02-04 01:01:12 +0000
+++ client/client_test.go 2013-07-01 07:24:26 +0000
@@ -9,10 +9,10 @@
99
10var live = flag.Bool("live", false, "Include live OpenStack (Canonistack) tests")10var live = flag.Bool("live", false, "Include live OpenStack (Canonistack) tests")
11var liveAuthMode = flag.String(11var liveAuthMode = flag.String(
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]")
1313
14func Test(t *testing.T) {14func Test(t *testing.T) {
15 var allAuthModes = []identity.AuthMode{identity.AuthLegacy, identity.AuthUserPass}15 var allAuthModes = []identity.AuthMode{identity.AuthLegacy, identity.AuthUserPass, identity.AuthKeyPair}
16 var liveAuthModes []identity.AuthMode16 var liveAuthModes []identity.AuthMode
17 switch *liveAuthMode {17 switch *liveAuthMode {
18 default:18 default:
@@ -20,6 +20,8 @@
20 case "all":20 case "all":
21 liveAuthModes = allAuthModes21 liveAuthModes = allAuthModes
22 case "":22 case "":
23 case "keypair":
24 liveAuthModes = []identity.AuthMode{identity.AuthKeyPair}
23 case "userpass":25 case "userpass":
24 liveAuthModes = []identity.AuthMode{identity.AuthUserPass}26 liveAuthModes = []identity.AuthMode{identity.AuthUserPass}
25 case "legacy":27 case "legacy":
@@ -29,7 +31,7 @@
29 if *live {31 if *live {
30 cred, err := identity.CompleteCredentialsFromEnv()32 cred, err := identity.CompleteCredentialsFromEnv()
31 if err != nil {33 if err != nil {
32 t.Fatalf("Error setting up test suite: %s", err.Error())34 t.Fatalf("Error setting up test suite: %v", err)
33 }35 }
34 registerOpenStackTests(cred, liveAuthModes)36 registerOpenStackTests(cred, liveAuthModes)
35 }37 }
3638
=== modified file 'client/live_test.go'
--- client/live_test.go 2013-03-28 09:06:20 +0000
+++ client/live_test.go 2013-07-01 07:24:26 +0000
@@ -48,16 +48,16 @@
48}48}
4949
50func (s *LiveTests) TestAuthenticate(c *C) {50func (s *LiveTests) TestAuthenticate(c *C) {
51 client := client.NewClient(s.cred, s.authMode, nil)51 cl := client.NewClient(s.cred, s.authMode, nil)
52 err := client.Authenticate()52 err := cl.Authenticate()
53 c.Assert(err, IsNil)53 c.Assert(err, IsNil)
54 c.Assert(client.IsAuthenticated(), Equals, true)54 c.Assert(cl.IsAuthenticated(), Equals, true)
5555
56 // Check service endpoints are discovered56 // Check service endpoints are discovered
57 url, err := client.MakeServiceURL("compute", nil)57 url, err := cl.MakeServiceURL("compute", nil)
58 c.Check(err, IsNil)58 c.Check(err, IsNil)
59 c.Check(url, NotNil)59 c.Check(url, NotNil)
60 url, err = client.MakeServiceURL("object-store", nil)60 url, err = cl.MakeServiceURL("object-store", nil)
61 c.Check(err, IsNil)61 c.Check(err, IsNil)
62 c.Check(url, NotNil)62 c.Check(url, NotNil)
63}63}
6464
=== modified file 'client/local_test.go'
--- client/local_test.go 2013-03-28 12:36:12 +0000
+++ client/local_test.go 2013-07-01 07:24:26 +0000
@@ -49,14 +49,22 @@
49 switch s.authMode {49 switch s.authMode {
50 default:50 default:
51 panic("Invalid authentication method")51 panic("Invalid authentication method")
52 case identity.AuthKeyPair:
53 // The openstack test service sets up keypair authentication.
54 s.service = openstackservice.New(s.cred, identity.AuthKeyPair)
55 // Add an additional endpoint so region filtering can be properly tested.
56 serviceDef := identityservice.Service{"nova", "compute", []identityservice.Endpoint{
57 identityservice.Endpoint{PublicURL: "http://nova2", Region: "zone2.RegionOne"},
58 }}
59 s.service.(*openstackservice.Openstack).Identity.AddService(serviceDef)
52 case identity.AuthUserPass:60 case identity.AuthUserPass:
53 // The openstack test service sets up userpass authentication.61 // The openstack test service sets up userpass authentication.
54 s.service = openstackservice.New(s.cred)62 s.service = openstackservice.New(s.cred, identity.AuthUserPass)
55 // Add an additional endpoint so region filtering can be properly tested.63 // Add an additional endpoint so region filtering can be properly tested.
56 serviceDef := identityservice.Service{"nova", "compute", []identityservice.Endpoint{64 serviceDef := identityservice.Service{"nova", "compute", []identityservice.Endpoint{
57 identityservice.Endpoint{PublicURL: "http://nova2", Region: "zone2.RegionOne"},65 identityservice.Endpoint{PublicURL: "http://nova2", Region: "zone2.RegionOne"},
58 }}66 }}
59 s.service.(*openstackservice.Openstack).Identity.(*identityservice.UserPass).AddService(serviceDef)67 s.service.(*openstackservice.Openstack).Identity.AddService(serviceDef)
6068
61 case identity.AuthLegacy:69 case identity.AuthLegacy:
62 legacy := identityservice.NewLegacy()70 legacy := identityservice.NewLegacy()
6371
=== modified file 'goose.go'
--- goose.go 2012-10-31 15:50:00 +0000
+++ goose.go 2013-07-01 07:24:26 +0000
@@ -1,1 +1,4 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the LGPLv3, see COPYING and COPYING.LESSER file for details.
3
1package goose4package goose
25
=== modified file 'http/client.go'
--- http/client.go 2013-04-19 09:19:53 +0000
+++ http/client.go 2013-07-01 07:24:26 +0000
@@ -209,6 +209,7 @@
209 req.Header.Add(header, value)209 req.Header.Add(header, value)
210 }210 }
211 }211 }
212 req.ContentLength = int64(len(reqData))
212 resp, err = c.Do(req)213 resp, err = c.Do(req)
213 if err != nil {214 if err != nil {
214 return nil, errors.Newf(err, "failed executing the request %s", URL)215 return nil, errors.Newf(err, "failed executing the request %s", URL)
215216
=== modified file 'http/client_test.go'
--- http/client_test.go 2013-02-22 00:36:43 +0000
+++ http/client_test.go 2013-07-01 07:24:26 +0000
@@ -1,6 +1,9 @@
1package http1package http
22
3import (3import (
4 "bytes"
5 "fmt"
6 "io/ioutil"
4 . "launchpad.net/gocheck"7 . "launchpad.net/gocheck"
5 "launchpad.net/goose/testing/httpsuite"8 "launchpad.net/goose/testing/httpsuite"
6 "net/http"9 "net/http"
@@ -52,21 +55,25 @@
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()}})
53}56}
5457
55func (s *HTTPClientTestSuite) setupLoopbackRequest() (*http.Header, *Client) {58func (s *HTTPClientTestSuite) setupLoopbackRequest() (*http.Header, chan string, *Client) {
56 headers := http.Header{}59 var headers http.Header
60 bodyChan := make(chan string, 1)
57 handler := func(resp http.ResponseWriter, req *http.Request) {61 handler := func(resp http.ResponseWriter, req *http.Request) {
58 headers = req.Header62 headers = req.Header
63 bodyBytes, _ := ioutil.ReadAll(req.Body)
64 req.Body.Close()
65 bodyChan <- string(bodyBytes)
59 resp.Header().Add("Content-Length", "0")66 resp.Header().Add("Content-Length", "0")
60 resp.WriteHeader(http.StatusNoContent)67 resp.WriteHeader(http.StatusNoContent)
61 resp.Write([]byte{})68 resp.Write([]byte{})
62 }69 }
63 s.Mux.HandleFunc("/", handler)70 s.Mux.HandleFunc("/", handler)
64 client := New()71 client := New()
65 return &headers, client72 return &headers, bodyChan, client
66}73}
6774
68func (s *HTTPClientTestSuite) TestBinaryRequestSetsUserAgent(c *C) {75func (s *HTTPClientTestSuite) TestBinaryRequestSetsUserAgent(c *C) {
69 headers, client := s.setupLoopbackRequest()76 headers, _, client := s.setupLoopbackRequest()
70 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}77 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
71 err := client.BinaryRequest("POST", s.Server.URL, "", req, nil)78 err := client.BinaryRequest("POST", s.Server.URL, "", req, nil)
72 c.Assert(err, IsNil)79 c.Assert(err, IsNil)
@@ -76,7 +83,7 @@
76}83}
7784
78func (s *HTTPClientTestSuite) TestJSONRequestSetsUserAgent(c *C) {85func (s *HTTPClientTestSuite) TestJSONRequestSetsUserAgent(c *C) {
79 headers, client := s.setupLoopbackRequest()86 headers, _, client := s.setupLoopbackRequest()
80 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}87 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
81 err := client.JsonRequest("POST", s.Server.URL, "", req, nil)88 err := client.JsonRequest("POST", s.Server.URL, "", req, nil)
82 c.Assert(err, IsNil)89 c.Assert(err, IsNil)
@@ -85,8 +92,45 @@
85 c.Check(agent, Equals, gooseAgent())92 c.Check(agent, Equals, gooseAgent())
86}93}
8794
95func (s *HTTPClientTestSuite) TestBinaryRequestSetsContentLength(c *C) {
96 headers, bodyChan, client := s.setupLoopbackRequest()
97 content := "binary\ncontent\n"
98 req := &RequestData{
99 ExpectedStatus: []int{http.StatusNoContent},
100 ReqReader: bytes.NewBufferString(content),
101 ReqLength: len(content),
102 }
103 err := client.BinaryRequest("POST", s.Server.URL, "", req, nil)
104 c.Assert(err, IsNil)
105 encoding := headers.Get("Transfer-Encoding")
106 c.Check(encoding, Equals, "")
107 length := headers.Get("Content-Length")
108 c.Check(length, Equals, fmt.Sprintf("%d", len(content)))
109 body, ok := <-bodyChan
110 c.Assert(ok, Equals, true)
111 c.Check(body, Equals, content)
112}
113
114func (s *HTTPClientTestSuite) TestJSONRequestSetsContentLength(c *C) {
115 headers, bodyChan, client := s.setupLoopbackRequest()
116 reqMap := map[string]string{"key": "value"}
117 req := &RequestData{
118 ExpectedStatus: []int{http.StatusNoContent},
119 ReqValue: reqMap,
120 }
121 err := client.JsonRequest("POST", s.Server.URL, "", req, nil)
122 c.Assert(err, IsNil)
123 encoding := headers.Get("Transfer-Encoding")
124 c.Check(encoding, Equals, "")
125 length := headers.Get("Content-Length")
126 body, ok := <-bodyChan
127 c.Assert(ok, Equals, true)
128 c.Check(body, Not(Equals), "")
129 c.Check(length, Equals, fmt.Sprintf("%d", len(body)))
130}
131
88func (s *HTTPClientTestSuite) TestBinaryRequestSetsToken(c *C) {132func (s *HTTPClientTestSuite) TestBinaryRequestSetsToken(c *C) {
89 headers, client := s.setupLoopbackRequest()133 headers, _, client := s.setupLoopbackRequest()
90 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}134 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
91 err := client.BinaryRequest("POST", s.Server.URL, "token", req, nil)135 err := client.BinaryRequest("POST", s.Server.URL, "token", req, nil)
92 c.Assert(err, IsNil)136 c.Assert(err, IsNil)
@@ -95,7 +139,7 @@
95}139}
96140
97func (s *HTTPClientTestSuite) TestJSONRequestSetsToken(c *C) {141func (s *HTTPClientTestSuite) TestJSONRequestSetsToken(c *C) {
98 headers, client := s.setupLoopbackRequest()142 headers, _, client := s.setupLoopbackRequest()
99 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}143 req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
100 err := client.JsonRequest("POST", s.Server.URL, "token", req, nil)144 err := client.JsonRequest("POST", s.Server.URL, "token", req, nil)
101 c.Assert(err, IsNil)145 c.Assert(err, IsNil)
102146
=== modified file 'identity/identity.go'
--- identity/identity.go 2013-02-12 01:47:38 +0000
+++ identity/identity.go 2013-07-01 07:24:26 +0000
@@ -15,10 +15,13 @@
15const (15const (
16 AuthLegacy = AuthMode(iota) // Legacy authentication16 AuthLegacy = AuthMode(iota) // Legacy authentication
17 AuthUserPass // Username + password authentication17 AuthUserPass // Username + password authentication
18 AuthKeyPair // Access/secret key pair authentication
18)19)
1920
20func (a AuthMode) String() string {21func (a AuthMode) String() string {
21 switch a {22 switch a {
23 case AuthKeyPair:
24 return "Access/Secret Key Authentication"
22 case AuthLegacy:25 case AuthLegacy:
23 return "Legacy Authentication"26 return "Legacy Authentication"
24 case AuthUserPass:27 case AuthUserPass:
@@ -69,9 +72,12 @@
69// environment variables.72// environment variables.
70func CredentialsFromEnv() *Credentials {73func CredentialsFromEnv() *Credentials {
71 return &Credentials{74 return &Credentials{
72 URL: getConfig("OS_AUTH_URL"),75 URL: getConfig("OS_AUTH_URL"),
73 User: getConfig("OS_USERNAME", "NOVA_USERNAME"),76 User: getConfig("OS_USERNAME", "NOVA_USERNAME",
74 Secrets: getConfig("OS_PASSWORD", "NOVA_PASSWORD"),77 "OS_ACCESS_KEY", "NOVA_API_KEY"),
78 Secrets: getConfig("OS_PASSWORD", "NOVA_PASSWORD",
79 "OS_SECRET_KEY", "EC2_SECRET_KEYS",
80 "AWS_SECRET_ACCESS_KEY"),
75 Region: getConfig("OS_REGION_NAME", "NOVA_REGION"),81 Region: getConfig("OS_REGION_NAME", "NOVA_REGION"),
76 TenantName: getConfig("OS_TENANT_NAME", "NOVA_PROJECT_ID"),82 TenantName: getConfig("OS_TENANT_NAME", "NOVA_PROJECT_ID"),
77 }83 }
7884
=== modified file 'identity/identity_test.go'
--- identity/identity_test.go 2013-02-11 05:01:34 +0000
+++ identity/identity_test.go 2013-07-01 07:24:26 +0000
@@ -27,6 +27,8 @@
27 env: map[string]string{27 env: map[string]string{
28 "NOVA_USERNAME": "test-user",28 "NOVA_USERNAME": "test-user",
29 "NOVA_PASSWORD": "test-pass",29 "NOVA_PASSWORD": "test-pass",
30 "NOVA_API_KEY": "test-access-key",
31 "EC2_SECRET_KEYS": "test-secret-key",
30 "NOVA_PROJECT_ID": "tenant-name",32 "NOVA_PROJECT_ID": "tenant-name",
31 "NOVA_REGION": "region",33 "NOVA_REGION": "region",
32 },34 },
@@ -39,6 +41,8 @@
39 env: map[string]string{41 env: map[string]string{
40 "OS_USERNAME": "test-user",42 "OS_USERNAME": "test-user",
41 "OS_PASSWORD": "test-pass",43 "OS_PASSWORD": "test-pass",
44 "OS_ACCESS_KEY": "test-access-key",
45 "OS_SECRET_KEY": "test-secret-key",
42 "OS_TENANT_NAME": "tenant-name",46 "OS_TENANT_NAME": "tenant-name",
43 "OS_REGION_NAME": "region",47 "OS_REGION_NAME": "region",
44 },48 },
@@ -66,6 +70,8 @@
66 "OS_AUTH_URL": "http://auth",70 "OS_AUTH_URL": "http://auth",
67 "OS_USERNAME": "test-user",71 "OS_USERNAME": "test-user",
68 "OS_PASSWORD": "test-pass",72 "OS_PASSWORD": "test-pass",
73 "OS_ACCESS_KEY": "test-access-key",
74 "OS_SECRET_KEY": "test-secret-key",
69 "OS_TENANT_NAME": "tenant-name",75 "OS_TENANT_NAME": "tenant-name",
70 "OS_REGION_NAME": "region",76 "OS_REGION_NAME": "region",
71 }77 }
@@ -86,6 +92,7 @@
86 env := map[string]string{92 env := map[string]string{
87 "OS_AUTH_URL": "http://auth",93 "OS_AUTH_URL": "http://auth",
88 "OS_USERNAME": "test-user",94 "OS_USERNAME": "test-user",
95 "OS_ACCESS_KEY": "test-access-key",
89 "OS_TENANT_NAME": "tenant-name",96 "OS_TENANT_NAME": "tenant-name",
90 "OS_REGION_NAME": "region",97 "OS_REGION_NAME": "region",
91 }98 }
@@ -96,3 +103,47 @@
96 c.Assert(err, Not(IsNil))103 c.Assert(err, Not(IsNil))
97 c.Assert(err.Error(), Matches, "required environment variable not set.*: Secrets")104 c.Assert(err.Error(), Matches, "required environment variable not set.*: Secrets")
98}105}
106
107func (s *CredentialsTestSuite) TestCompleteCredentialsFromEnvKeypair(c *C) {
108 env := map[string]string{
109 "OS_AUTH_URL": "http://auth",
110 "OS_USERNAME": "",
111 "OS_PASSWORD": "",
112 "OS_ACCESS_KEY": "test-access-key",
113 "OS_SECRET_KEY": "test-secret-key",
114 "OS_TENANT_NAME": "tenant-name",
115 "OS_REGION_NAME": "region",
116 }
117 for key, value := range env {
118 os.Setenv(key, value)
119 }
120 creds, err := CompleteCredentialsFromEnv()
121 c.Assert(err, IsNil)
122 c.Check(creds.URL, Equals, "http://auth")
123 c.Check(creds.User, Equals, "test-access-key")
124 c.Check(creds.Secrets, Equals, "test-secret-key")
125 c.Check(creds.Region, Equals, "region")
126 c.Check(creds.TenantName, Equals, "tenant-name")
127}
128
129func (s *CredentialsTestSuite) TestCompleteCredentialsFromEnvKeypairCompatibleEnvVars(c *C) {
130 env := map[string]string{
131 "OS_AUTH_URL": "http://auth",
132 "OS_USERNAME": "",
133 "OS_PASSWORD": "",
134 "NOVA_API_KEY": "test-access-key",
135 "EC2_SECRET_KEYS": "test-secret-key",
136 "OS_TENANT_NAME": "tenant-name",
137 "OS_REGION_NAME": "region",
138 }
139 for key, value := range env {
140 os.Setenv(key, value)
141 }
142 creds, err := CompleteCredentialsFromEnv()
143 c.Assert(err, IsNil)
144 c.Check(creds.URL, Equals, "http://auth")
145 c.Check(creds.User, Equals, "test-access-key")
146 c.Check(creds.Secrets, Equals, "test-secret-key")
147 c.Check(creds.Region, Equals, "region")
148 c.Check(creds.TenantName, Equals, "tenant-name")
149}
99150
=== added file 'identity/keypair.go'
--- identity/keypair.go 1970-01-01 00:00:00 +0000
+++ identity/keypair.go 2013-07-01 07:24:26 +0000
@@ -0,0 +1,41 @@
1package identity
2
3import (
4 goosehttp "launchpad.net/goose/http"
5)
6
7// KeyPair allows OpenStack cloud authentication using an access and
8// secret key.
9//
10// It implements Authenticator interface by providing the Auth method.
11type KeyPair struct {
12 client *goosehttp.Client
13}
14
15type keypairCredentials struct {
16 AccessKey string `json:"accessKey"`
17 SecretKey string `json:"secretKey"`
18}
19
20type authKeypairRequest struct {
21 KeypairCredentials keypairCredentials `json:"apiAccessKeyCredentials"`
22 TenantName string `json:"tenantName"`
23}
24
25type authKeypairWrapper struct {
26 Auth authKeypairRequest `json:"auth"`
27}
28
29func (u *KeyPair) Auth(creds *Credentials) (*AuthDetails, error) {
30 if u.client == nil {
31 u.client = goosehttp.New()
32 }
33 auth := authKeypairWrapper{Auth: authKeypairRequest{
34 KeypairCredentials: keypairCredentials{
35 AccessKey: creds.User,
36 SecretKey: creds.Secrets,
37 },
38 TenantName: creds.TenantName}}
39
40 return keystoneAuth(u.client, auth, creds.URL)
41}
042
=== added file 'identity/keystone.go'
--- identity/keystone.go 1970-01-01 00:00:00 +0000
+++ identity/keystone.go 2013-07-01 07:24:26 +0000
@@ -0,0 +1,89 @@
1package identity
2
3import (
4 "fmt"
5 goosehttp "launchpad.net/goose/http"
6)
7
8type endpoint struct {
9 AdminURL string `json:"adminURL"`
10 InternalURL string `json:"internalURL"`
11 PublicURL string `json:"publicURL"`
12 Region string `json:"region"`
13}
14
15type serviceResponse struct {
16 Name string `json:"name"`
17 Type string `json:"type"`
18 Endpoints []endpoint
19}
20
21type tokenResponse struct {
22 Expires string `json:"expires"`
23 Id string `json:"id"` // Actual token string
24 Tenant struct {
25 Id string `json:"id"`
26 Name string `json:"name"`
27 // Description is a pointer since it may be null and this breaks Go < 1.1
28 Description *string `json:"description"`
29 Enabled bool `json:"enabled"`
30 } `json:"tenant"`
31}
32
33type roleResponse struct {
34 Id string `json:"id"`
35 Name string `json:"name"`
36 TenantId string `json:"tenantId"`
37}
38
39type userResponse struct {
40 Id string `json:"id"`
41 Name string `json:"name"`
42 Roles []roleResponse `json:"roles"`
43}
44
45type accessWrapper struct {
46 Access accessResponse `json:"access"`
47}
48
49type accessResponse struct {
50 ServiceCatalog []serviceResponse `json:"serviceCatalog"`
51 Token tokenResponse `json:"token"`
52 User userResponse `json:"user"`
53}
54
55// keystoneAuth authenticates to OpenStack cloud using keystone v2 authentication.
56//
57// Uses `client` to submit HTTP requests to `URL`
58// and posts `auth_data` as JSON.
59func keystoneAuth(client *goosehttp.Client, auth_data interface{}, URL string) (*AuthDetails, error) {
60
61 var accessWrapper accessWrapper
62 requestData := goosehttp.RequestData{ReqValue: auth_data, RespValue: &accessWrapper}
63 err := client.JsonRequest("POST", URL, "", &requestData, nil)
64 if err != nil {
65 return nil, err
66 }
67
68 details := &AuthDetails{}
69 access := accessWrapper.Access
70 respToken := access.Token
71 if respToken.Id == "" {
72 return nil, fmt.Errorf("authentication failed")
73 }
74 details.Token = respToken.Id
75 details.TenantId = respToken.Tenant.Id
76 details.UserId = access.User.Id
77 details.RegionServiceURLs = make(map[string]ServiceURLs, len(access.ServiceCatalog))
78 for _, service := range access.ServiceCatalog {
79 for i, e := range service.Endpoints {
80 endpointURLs, ok := details.RegionServiceURLs[e.Region]
81 if !ok {
82 endpointURLs = make(ServiceURLs)
83 details.RegionServiceURLs[e.Region] = endpointURLs
84 }
85 endpointURLs[service.Type] = service.Endpoints[i].PublicURL
86 }
87 }
88 return details, nil
89}
090
=== modified file 'identity/local_test.go'
--- identity/local_test.go 2013-02-12 01:47:38 +0000
+++ identity/local_test.go 2013-07-01 07:24:26 +0000
@@ -6,6 +6,8 @@
6 "launchpad.net/goose/testservices/openstackservice"6 "launchpad.net/goose/testservices/openstackservice"
7 "net/http"7 "net/http"
8 "net/http/httptest"8 "net/http/httptest"
9 "net/url"
10 "strings"
9)11)
1012
11func registerLocalTests() {13func registerLocalTests() {
@@ -39,7 +41,7 @@
39 Region: "zone1.some region",41 Region: "zone1.some region",
40 TenantName: "tenant",42 TenantName: "tenant",
41 }43 }
42 openstack := openstackservice.New(s.cred)44 openstack := openstackservice.New(s.cred, identity.AuthUserPass)
43 openstack.SetupHTTP(s.Mux)45 openstack.SetupHTTP(s.Mux)
4446
45 s.LiveTests.SetUpSuite(c)47 s.LiveTests.SetUpSuite(c)
@@ -61,3 +63,22 @@
61}63}
6264
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.
66
67func (s *localLiveSuite) TestProductStreamsEndpoint(c *C) {
68 err := s.client.Authenticate()
69 c.Assert(err, IsNil)
70 serviceURL, err := s.client.MakeServiceURL("product-streams", nil)
71 c.Assert(err, IsNil)
72 _, err = url.Parse(serviceURL)
73 c.Assert(err, IsNil)
74 c.Assert(strings.HasSuffix(serviceURL, "/imagemetadata"), Equals, true)
75}
76
77func (s *localLiveSuite) TestJujuToolsEndpoint(c *C) {
78 err := s.client.Authenticate()
79 c.Assert(err, IsNil)
80 serviceURL, err := s.client.MakeServiceURL("juju-tools", nil)
81 c.Assert(err, IsNil)
82 _, err = url.Parse(serviceURL)
83 c.Assert(err, IsNil)
84}
6485
=== modified file 'identity/userpass.go'
--- identity/userpass.go 2013-02-20 02:30:14 +0000
+++ identity/userpass.go 2013-07-01 07:24:26 +0000
@@ -1,7 +1,6 @@
1package identity1package identity
22
3import (3import (
4 "fmt"
5 goosehttp "launchpad.net/goose/http"4 goosehttp "launchpad.net/goose/http"
6)5)
76
@@ -19,52 +18,6 @@
19 Auth authRequest `json:"auth"`18 Auth authRequest `json:"auth"`
20}19}
2120
22type endpoint struct {
23 AdminURL string `json:"adminURL"`
24 InternalURL string `json:"internalURL"`
25 PublicURL string `json:"publicURL"`
26 Region string `json:"region"`
27}
28
29type serviceResponse struct {
30 Name string `json:"name"`
31 Type string `json:"type"`
32 Endpoints []endpoint
33}
34
35type tokenResponse struct {
36 Expires string `json:"expires"` // should this be a date object?
37 Id string `json:"id"` // Actual token string
38 Tenant struct {
39 Id string `json:"id"`
40 Name string `json:"name"`
41 Description string `json:"description"`
42 Enabled bool `json:"enabled"`
43 } `json:"tenant"`
44}
45
46type roleResponse struct {
47 Id string `json:"id"`
48 Name string `json:"name"`
49 TenantId string `json:"tenantId"`
50}
51
52type userResponse struct {
53 Id string `json:"id"`
54 Name string `json:"name"`
55 Roles []roleResponse `json:"roles"`
56}
57
58type accessWrapper struct {
59 Access accessResponse `json:"access"`
60}
61
62type accessResponse struct {
63 ServiceCatalog []serviceResponse `json:"serviceCatalog"`
64 Token tokenResponse `json:"token"`
65 User userResponse `json:"user"`
66}
67
68type UserPass struct {21type UserPass struct {
69 client *goosehttp.Client22 client *goosehttp.Client
70}23}
@@ -80,32 +33,5 @@
80 },33 },
81 TenantName: creds.TenantName}}34 TenantName: creds.TenantName}}
8235
83 var accessWrapper accessWrapper36 return keystoneAuth(u.client, auth, creds.URL)
84 requestData := goosehttp.RequestData{ReqValue: auth, RespValue: &accessWrapper}
85 err := u.client.JsonRequest("POST", creds.URL, "", &requestData, nil)
86 if err != nil {
87 return nil, err
88 }
89
90 details := &AuthDetails{}
91 access := accessWrapper.Access
92 respToken := access.Token
93 if respToken.Id == "" {
94 return nil, fmt.Errorf("Did not get valid Token from auth request")
95 }
96 details.Token = respToken.Id
97 details.TenantId = respToken.Tenant.Id
98 details.UserId = access.User.Id
99 details.RegionServiceURLs = make(map[string]ServiceURLs, len(access.ServiceCatalog))
100 for _, service := range access.ServiceCatalog {
101 for i, e := range service.Endpoints {
102 endpointURLs, ok := details.RegionServiceURLs[e.Region]
103 if !ok {
104 endpointURLs = make(ServiceURLs)
105 details.RegionServiceURLs[e.Region] = endpointURLs
106 }
107 endpointURLs[service.Type] = service.Endpoints[i].PublicURL
108 }
109 }
110 return details, nil
111}37}
11238
=== modified file 'nova/json.go'
--- nova/json.go 2013-03-21 04:52:22 +0000
+++ nova/json.go 2013-07-01 07:24:26 +0000
@@ -14,19 +14,12 @@
14 "strconv"14 "strconv"
15)15)
1616
17type genericId struct {17const (
18 Id interface{} `json:"id"`18 idTag = "id"
19}19 instanceIdTag = "instance_id"
2020 groupIdTag = "group_id"
21func (id genericId) String() string {21 parentGroupIdTag = "parent_group_id"
22 if id.Id == nil {22)
23 return ""
24 }
25 if fid, ok := id.Id.(float64); ok {
26 return fmt.Sprint(int(fid))
27 }
28 return fmt.Sprint(id.Id)
29}
3023
31var useNumericIds bool = false24var useNumericIds bool = false
3225
@@ -43,6 +36,25 @@
43 return result36 return result
44}37}
4538
39// getIdAsString extracts the field with the specified tag from the json data
40// and returns it converted to a string.
41func getIdAsString(b []byte, tag string) (string, error) {
42 var out map[string]interface{}
43 if err := json.Unmarshal(b, &out); err != nil {
44 return "", err
45 }
46 if val, ok := out[tag]; !ok {
47 return "", nil
48 } else {
49 if floatVal, ok := val.(float64); ok {
50 return fmt.Sprint(int(floatVal)), nil
51 } else {
52 return fmt.Sprint(val), nil
53 }
54 }
55 panic("unreachable")
56}
57
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.
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.
48func appendJSON(data []byte, attr string, value interface{}) ([]byte, error) {60func appendJSON(data []byte, attr string, value interface{}) ([]byte, error) {
@@ -59,14 +71,13 @@
5971
60func (entity *Entity) UnmarshalJSON(b []byte) error {72func (entity *Entity) UnmarshalJSON(b []byte) error {
61 var je jsonEntity = jsonEntity(*entity)73 var je jsonEntity = jsonEntity(*entity)
62 if err := json.Unmarshal(b, &je); err != nil {74 var err error
63 return err75 if err = json.Unmarshal(b, &je); err != nil {
64 }76 return err
65 var id genericId77 }
66 if err := json.Unmarshal(b, &id); err != nil {78 if je.Id, err = getIdAsString(b, idTag); err != nil {
67 return err79 return err
68 }80 }
69 je.Id = id.String()
70 *entity = Entity(je)81 *entity = Entity(je)
71 return nil82 return nil
72}83}
@@ -78,21 +89,20 @@
78 return nil, err89 return nil, err
79 }90 }
80 id := convertId(entity.Id)91 id := convertId(entity.Id)
81 return appendJSON(data, "Id", id)92 return appendJSON(data, idTag, id)
82}93}
8394
84type jsonFlavorDetail FlavorDetail95type jsonFlavorDetail FlavorDetail
8596
86func (flavorDetail *FlavorDetail) UnmarshalJSON(b []byte) error {97func (flavorDetail *FlavorDetail) UnmarshalJSON(b []byte) error {
87 var jfd jsonFlavorDetail = jsonFlavorDetail(*flavorDetail)98 var jfd jsonFlavorDetail = jsonFlavorDetail(*flavorDetail)
88 if err := json.Unmarshal(b, &jfd); err != nil {99 var err error
89 return err100 if err = json.Unmarshal(b, &jfd); err != nil {
90 }101 return err
91 var id genericId102 }
92 if err := json.Unmarshal(b, &id); err != nil {103 if jfd.Id, err = getIdAsString(b, idTag); err != nil {
93 return err104 return err
94 }105 }
95 jfd.Id = id.String()
96 *flavorDetail = FlavorDetail(jfd)106 *flavorDetail = FlavorDetail(jfd)
97 return nil107 return nil
98}108}
@@ -104,21 +114,20 @@
104 return nil, err114 return nil, err
105 }115 }
106 id := convertId(flavorDetail.Id)116 id := convertId(flavorDetail.Id)
107 return appendJSON(data, "Id", id)117 return appendJSON(data, idTag, id)
108}118}
109119
110type jsonServerDetail ServerDetail120type jsonServerDetail ServerDetail
111121
112func (serverDetail *ServerDetail) UnmarshalJSON(b []byte) error {122func (serverDetail *ServerDetail) UnmarshalJSON(b []byte) error {
113 var jsd jsonServerDetail = jsonServerDetail(*serverDetail)123 var jsd jsonServerDetail = jsonServerDetail(*serverDetail)
114 if err := json.Unmarshal(b, &jsd); err != nil {124 var err error
115 return err125 if err = json.Unmarshal(b, &jsd); err != nil {
116 }126 return err
117 var id genericId127 }
118 if err := json.Unmarshal(b, &id); err != nil {128 if jsd.Id, err = getIdAsString(b, idTag); err != nil {
119 return err129 return err
120 }130 }
121 jsd.Id = id.String()
122 *serverDetail = ServerDetail(jsd)131 *serverDetail = ServerDetail(jsd)
123 return nil132 return nil
124}133}
@@ -130,39 +139,26 @@
130 return nil, err139 return nil, err
131 }140 }
132 id := convertId(serverDetail.Id)141 id := convertId(serverDetail.Id)
133 return appendJSON(data, "Id", id)142 return appendJSON(data, idTag, id)
134}
135
136type genericInstanceId struct {
137 InstanceId interface{} `json:"instance_id"`
138}
139
140func (id genericInstanceId) String() string {
141 if id.InstanceId == nil {
142 return ""
143 }
144 if fid, ok := id.InstanceId.(float64); ok {
145 return fmt.Sprint(int(fid))
146 }
147 return fmt.Sprint(id.InstanceId)
148}143}
149144
150type jsonFloatingIP FloatingIP145type jsonFloatingIP FloatingIP
151146
152func (floatingIP *FloatingIP) UnmarshalJSON(b []byte) error {147func (floatingIP *FloatingIP) UnmarshalJSON(b []byte) error {
153 var jfip jsonFloatingIP = jsonFloatingIP(*floatingIP)148 var jfip jsonFloatingIP = jsonFloatingIP(*floatingIP)
154 if err := json.Unmarshal(b, &jfip); err != nil {149 var err error
155 return err150 if err = json.Unmarshal(b, &jfip); err != nil {
156 }151 return err
157 var id genericInstanceId152 }
158 if err := json.Unmarshal(b, &id); err != nil {153 if instIdStr, err := getIdAsString(b, instanceIdTag); err != nil {
159 return err154 return err
160 }155 } else if instIdStr != "" {
161 instId := id.String()156 strId := instIdStr
162 if instId != "" {
163 strId := instId
164 jfip.InstanceId = &strId157 jfip.InstanceId = &strId
165 }158 }
159 if jfip.Id, err = getIdAsString(b, idTag); err != nil {
160 return err
161 }
166 *floatingIP = FloatingIP(jfip)162 *floatingIP = FloatingIP(jfip)
167 return nil163 return nil
168}164}
@@ -173,9 +169,114 @@
173 if err != nil {169 if err != nil {
174 return nil, err170 return nil, err
175 }171 }
172 id := convertId(floatingIP.Id)
173 data, err = appendJSON(data, idTag, id)
174 if err != nil {
175 return nil, err
176 }
176 if floatingIP.InstanceId == nil {177 if floatingIP.InstanceId == nil {
177 return data, nil178 return data, nil
178 }179 }
179 id := convertId(*floatingIP.InstanceId)180 instId := convertId(*floatingIP.InstanceId)
180 return appendJSON(data, "instance_id", id)181 return appendJSON(data, instanceIdTag, instId)
182}
183
184type jsonSecurityGroup SecurityGroup
185
186func (securityGroup *SecurityGroup) UnmarshalJSON(b []byte) error {
187 var jsg jsonSecurityGroup = jsonSecurityGroup(*securityGroup)
188 var err error
189 if err = json.Unmarshal(b, &jsg); err != nil {
190 return err
191 }
192 if jsg.Id, err = getIdAsString(b, idTag); err != nil {
193 return err
194 }
195 *securityGroup = SecurityGroup(jsg)
196 return nil
197}
198
199func (securityGroup SecurityGroup) MarshalJSON() ([]byte, error) {
200 var jsg jsonSecurityGroup = jsonSecurityGroup(securityGroup)
201 data, err := json.Marshal(&jsg)
202 if err != nil {
203 return nil, err
204 }
205 id := convertId(securityGroup.Id)
206 return appendJSON(data, idTag, id)
207}
208
209type jsonSecurityGroupRule SecurityGroupRule
210
211func (securityGroupRule *SecurityGroupRule) UnmarshalJSON(b []byte) error {
212 var jsgr jsonSecurityGroupRule = jsonSecurityGroupRule(*securityGroupRule)
213 var err error
214 if err = json.Unmarshal(b, &jsgr); err != nil {
215 return err
216 }
217 if jsgr.Id, err = getIdAsString(b, idTag); err != nil {
218 return err
219 }
220 if jsgr.ParentGroupId, err = getIdAsString(b, parentGroupIdTag); err != nil {
221 return err
222 }
223 *securityGroupRule = SecurityGroupRule(jsgr)
224 return nil
225}
226
227func (securityGroupRule SecurityGroupRule) MarshalJSON() ([]byte, error) {
228 var jsgr jsonSecurityGroupRule = jsonSecurityGroupRule(securityGroupRule)
229 data, err := json.Marshal(&jsgr)
230 if err != nil {
231 return nil, err
232 }
233 id := convertId(securityGroupRule.Id)
234 data, err = appendJSON(data, idTag, id)
235 if err != nil {
236 return nil, err
237 }
238 if securityGroupRule.ParentGroupId == "" {
239 return data, nil
240 }
241 id = convertId(securityGroupRule.ParentGroupId)
242 return appendJSON(data, parentGroupIdTag, id)
243}
244
245type jsonRuleInfo RuleInfo
246
247func (ruleInfo *RuleInfo) UnmarshalJSON(b []byte) error {
248 var jri jsonRuleInfo = jsonRuleInfo(*ruleInfo)
249 var err error
250 if err = json.Unmarshal(b, &jri); err != nil {
251 return err
252 }
253 if jri.ParentGroupId, err = getIdAsString(b, parentGroupIdTag); err != nil {
254 return err
255 }
256 if groupId, err := getIdAsString(b, groupIdTag); err != nil {
257 return err
258 } else if groupId != "" {
259 strId := groupId
260 jri.GroupId = &strId
261 }
262 *ruleInfo = RuleInfo(jri)
263 return nil
264}
265
266func (ruleInfo RuleInfo) MarshalJSON() ([]byte, error) {
267 var jri jsonRuleInfo = jsonRuleInfo(ruleInfo)
268 data, err := json.Marshal(&jri)
269 if err != nil {
270 return nil, err
271 }
272 id := convertId(ruleInfo.ParentGroupId)
273 data, err = appendJSON(data, parentGroupIdTag, id)
274 if err != nil {
275 return nil, err
276 }
277 if ruleInfo.GroupId == nil {
278 return data, nil
279 }
280 id = convertId(*ruleInfo.GroupId)
281 return appendJSON(data, groupIdTag, id)
181}282}
182283
=== modified file 'nova/json_test.go'
--- nova/json_test.go 2013-03-21 11:43:56 +0000
+++ nova/json_test.go 2013-07-01 07:24:26 +0000
@@ -52,7 +52,7 @@
5252
53func (s *JsonSuite) TestMarshallFloatingIPLargeIntId(c *C) {53func (s *JsonSuite) TestMarshallFloatingIPLargeIntId(c *C) {
54 id := "3000000"54 id := "3000000"
55 fip := nova.FloatingIP{Id: 2000000, InstanceId: &id}55 fip := nova.FloatingIP{Id: "2000000", InstanceId: &id}
56 var unmarshalled nova.FloatingIP56 var unmarshalled nova.FloatingIP
57 s.assertMarshallRoundtrip(c, &fip, &unmarshalled)57 s.assertMarshallRoundtrip(c, &fip, &unmarshalled)
58}58}
5959
=== modified file 'nova/local_test.go'
--- nova/local_test.go 2013-03-28 09:06:20 +0000
+++ nova/local_test.go 2013-07-01 07:24:26 +0000
@@ -71,7 +71,7 @@
71 Region: "some region",71 Region: "some region",
72 TenantName: "tenant",72 TenantName: "tenant",
73 }73 }
74 s.openstack = openstackservice.New(s.cred)74 s.openstack = openstackservice.New(s.cred, identity.AuthUserPass)
75 s.openstack.SetupHTTP(s.Mux)75 s.openstack.SetupHTTP(s.Mux)
7676
77 s.testFlavor = "m1.small"77 s.testFlavor = "m1.small"
@@ -172,8 +172,8 @@
172 fips, err := novaClient.ListFloatingIPs()172 fips, err := novaClient.ListFloatingIPs()
173 c.Assert(err, IsNil)173 c.Assert(err, IsNil)
174 c.Assert(fips, HasLen, 0)174 c.Assert(fips, HasLen, 0)
175 s.openstack.Nova.RegisterControlPoint("addFloatingIP", s.addFloatingIPHook(s.openstack.Nova))175 cleanup := s.openstack.Nova.RegisterControlPoint("addFloatingIP", s.addFloatingIPHook(s.openstack.Nova))
176 defer s.openstack.Nova.RegisterControlPoint("addFloatingIP", nil)176 defer cleanup()
177 s.noMoreIPs = true177 s.noMoreIPs = true
178 fip, err := novaClient.AllocateFloatingIP()178 fip, err := novaClient.AllocateFloatingIP()
179 c.Assert(err, ErrorMatches, "(.|\n)*Zero floating ips available.*")179 c.Assert(err, ErrorMatches, "(.|\n)*Zero floating ips available.*")
@@ -203,7 +203,8 @@
203func (s *localLiveSuite) TestReauthenticate(c *C) {203func (s *localLiveSuite) TestReauthenticate(c *C) {
204 novaClient := s.setupClient(c, nil)204 novaClient := s.setupClient(c, nil)
205 up := s.openstack.Identity.(*identityservice.UserPass)205 up := s.openstack.Identity.(*identityservice.UserPass)
206 defer up.RegisterControlPoint("authorisation", s.authHook(up))206 cleanup := up.RegisterControlPoint("authorisation", s.authHook(up))
207 defer cleanup()
207208
208 // An invalid token is returned after the first authentication step, resulting in the ListServers call209 // An invalid token is returned after the first authentication step, resulting in the ListServers call
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.
@@ -215,7 +216,8 @@
215func (s *localLiveSuite) TestReauthenticateFailure(c *C) {216func (s *localLiveSuite) TestReauthenticateFailure(c *C) {
216 novaClient := s.setupClient(c, nil)217 novaClient := s.setupClient(c, nil)
217 up := s.openstack.Identity.(*identityservice.UserPass)218 up := s.openstack.Identity.(*identityservice.UserPass)
218 defer up.RegisterControlPoint("authorisation", s.authHook(up))219 cleanup := up.RegisterControlPoint("authorisation", s.authHook(up))
220 defer cleanup()
219221
220 // If the re-authentication fails, ensure an Unauthorised error is returned.222 // If the re-authentication fails, ensure an Unauthorised error is returned.
221 s.badTokens = 2223 s.badTokens = 2
222224
=== modified file 'nova/nova.go'
--- nova/nova.go 2013-04-23 00:19:57 +0000
+++ nova/nova.go 2013-07-01 07:24:26 +0000
@@ -11,7 +11,6 @@
11 "net/http"11 "net/http"
12 "net/url"12 "net/url"
13 "reflect"13 "reflect"
14 "strconv"
15)14)
1615
17// API URL parts.16// API URL parts.
@@ -327,9 +326,9 @@
327 FromPort *int `json:"from_port"` // Can be nil326 FromPort *int `json:"from_port"` // Can be nil
328 IPProtocol *string `json:"ip_protocol"` // Can be nil327 IPProtocol *string `json:"ip_protocol"` // Can be nil
329 ToPort *int `json:"to_port"` // Can be nil328 ToPort *int `json:"to_port"` // Can be nil
330 ParentGroupId int `json:"parent_group_id"`329 ParentGroupId string `json:"-"`
331 IPRange map[string]string `json:"ip_range"` // Can be empty330 IPRange map[string]string `json:"ip_range"` // Can be empty
332 Id int331 Id string `json:"-"`
333 Group SecurityGroupRef332 Group SecurityGroupRef
334}333}
335334
@@ -337,7 +336,7 @@
337type SecurityGroup struct {336type SecurityGroup struct {
338 Rules []SecurityGroupRule337 Rules []SecurityGroupRule
339 TenantId string `json:"tenant_id"`338 TenantId string `json:"tenant_id"`
340 Id int339 Id string `json:"-"`
341 Name string340 Name string
342 Description string341 Description string
343}342}
@@ -389,12 +388,8 @@
389 if err == nil {388 if err == nil {
390 result := make([]SecurityGroup, len(serverDetails.Groups))389 result := make([]SecurityGroup, len(serverDetails.Groups))
391 for i, e := range serverDetails.Groups {390 for i, e := range serverDetails.Groups {
392 id, err := strconv.Atoi(e.Id)
393 if err != nil {
394 return nil, errors.Newf(err, "failed to parse security group id %s", e.Id)
395 }
396 result[i] = SecurityGroup{391 result[i] = SecurityGroup{
397 Id: id,392 Id: e.Id,
398 Name: e.Name,393 Name: e.Name,
399 }394 }
400 }395 }
@@ -429,8 +424,8 @@
429}424}
430425
431// DeleteSecurityGroup deletes the specified security group.426// DeleteSecurityGroup deletes the specified security group.
432func (c *Client) DeleteSecurityGroup(groupId int) error {427func (c *Client) DeleteSecurityGroup(groupId string) error {
433 url := fmt.Sprintf("%s/%d", apiSecurityGroups, groupId)428 url := fmt.Sprintf("%s/%s", apiSecurityGroups, groupId)
434 requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}}429 requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}}
435 err := c.client.SendRequest(client.DELETE, "compute", url, &requestData)430 err := c.client.SendRequest(client.DELETE, "compute", url, &requestData)
436 if err != nil {431 if err != nil {
@@ -473,14 +468,14 @@
473 // Cidr cannot be specified with GroupId. Ingress rules need a valid468 // Cidr cannot be specified with GroupId. Ingress rules need a valid
474 // subnet mast in CIDR format here, while if GroupID is specifed, it469 // subnet mast in CIDR format here, while if GroupID is specifed, it
475 // means you're adding a group rule, specifying source group ID, which470 // means you're adding a group rule, specifying source group ID, which
476 // must exists already and can be equal to ParentGroupId).471 // must exist already and can be equal to ParentGroupId).
477 // need Cidr, while472 // need Cidr, while
478 Cidr string `json:"cidr"`473 Cidr string `json:"cidr"`
479 GroupId *int `json:"group_id"`474 GroupId *string `json:"-"`
480475
481 // ParentGroupId is always required and specifies the group to which476 // ParentGroupId is always required and specifies the group to which
482 // the rule is added.477 // the rule is added.
483 ParentGroupId int `json:"parent_group_id"`478 ParentGroupId string `json:"-"`
484}479}
485480
486// CreateSecurityGroupRule creates a security group rule.481// CreateSecurityGroupRule creates a security group rule.
@@ -505,8 +500,8 @@
505}500}
506501
507// DeleteSecurityGroupRule deletes the specified security group rule.502// DeleteSecurityGroupRule deletes the specified security group rule.
508func (c *Client) DeleteSecurityGroupRule(ruleId int) error {503func (c *Client) DeleteSecurityGroupRule(ruleId string) error {
509 url := fmt.Sprintf("%s/%d", apiSecurityGroupRules, ruleId)504 url := fmt.Sprintf("%s/%s", apiSecurityGroupRules, ruleId)
510 requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}}505 requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}}
511 err := c.client.SendRequest(client.DELETE, "compute", url, &requestData)506 err := c.client.SendRequest(client.DELETE, "compute", url, &requestData)
512 if err != nil {507 if err != nil {
@@ -556,7 +551,7 @@
556type FloatingIP struct {551type FloatingIP struct {
557 // FixedIP holds the private IP address of the machine (when assigned)552 // FixedIP holds the private IP address of the machine (when assigned)
558 FixedIP *string `json:"fixed_ip"`553 FixedIP *string `json:"fixed_ip"`
559 Id int `json:"id"`554 Id string `json:"-"`
560 // InstanceId holds the instance id of the machine, if this FIP is assigned to one555 // InstanceId holds the instance id of the machine, if this FIP is assigned to one
561 InstanceId *string `json:"-"`556 InstanceId *string `json:"-"`
562 IP string `json:"ip"`557 IP string `json:"ip"`
@@ -578,16 +573,16 @@
578}573}
579574
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.
581func (c *Client) GetFloatingIP(ipId int) (*FloatingIP, error) {576func (c *Client) GetFloatingIP(ipId string) (*FloatingIP, error) {
582 var resp struct {577 var resp struct {
583 FloatingIP FloatingIP `json:"floating_ip"`578 FloatingIP FloatingIP `json:"floating_ip"`
584 }579 }
585580
586 url := fmt.Sprintf("%s/%d", apiFloatingIPs, ipId)581 url := fmt.Sprintf("%s/%s", apiFloatingIPs, ipId)
587 requestData := goosehttp.RequestData{RespValue: &resp}582 requestData := goosehttp.RequestData{RespValue: &resp}
588 err := c.client.SendRequest(client.GET, "compute", url, &requestData)583 err := c.client.SendRequest(client.GET, "compute", url, &requestData)
589 if err != nil {584 if err != nil {
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)
591 }586 }
592 return &resp.FloatingIP, nil587 return &resp.FloatingIP, nil
593}588}
@@ -607,12 +602,12 @@
607}602}
608603
609// DeleteFloatingIP deallocates the floating IP address associated with the specified id.604// DeleteFloatingIP deallocates the floating IP address associated with the specified id.
610func (c *Client) DeleteFloatingIP(ipId int) error {605func (c *Client) DeleteFloatingIP(ipId string) error {
611 url := fmt.Sprintf("%s/%d", apiFloatingIPs, ipId)606 url := fmt.Sprintf("%s/%s", apiFloatingIPs, ipId)
612 requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}}607 requestData := goosehttp.RequestData{ExpectedStatus: []int{http.StatusAccepted}}
613 err := c.client.SendRequest(client.DELETE, "compute", url, &requestData)608 err := c.client.SendRequest(client.DELETE, "compute", url, &requestData)
614 if err != nil {609 if err != nil {
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)
616 }611 }
617 return err612 return err
618}613}
619614
=== modified file 'nova/nova_test.go'
--- nova/nova_test.go 2013-02-06 06:15:09 +0000
+++ nova/nova_test.go 2013-07-01 07:24:26 +0000
@@ -18,9 +18,9 @@
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.
19var testConstraints = map[string]imageDetails{19var testConstraints = map[string]imageDetails{
20 "canonistack": imageDetails{20 "canonistack": imageDetails{
21 flavor: "m1.tiny", imageId: "c876e5fe-abb0-41f0-8f29-f0b47481f523"},21 flavor: "m1.tiny", imageId: "f2ca48ce-30d5-4f1f-9075-12e64510368d"},
22 "hpcloud": imageDetails{22 "hpcloud": imageDetails{
23 flavor: "standard.xsmall", imageId: "75845"},23 flavor: "standard.xsmall", imageId: "81078"},
24}24}
2525
26var live = flag.Bool("live", false, "Include live OpenStack tests")26var live = flag.Bool("live", false, "Include live OpenStack tests")
2727
=== modified file 'swift/local_test.go'
--- swift/local_test.go 2013-01-29 00:45:31 +0000
+++ swift/local_test.go 2013-07-01 07:24:26 +0000
@@ -33,7 +33,8 @@
33 TenantName: "tenant",33 TenantName: "tenant",
34 }34 }
35 s.LiveTestsPublicContainer.cred = s.LiveTests.cred35 s.LiveTestsPublicContainer.cred = s.LiveTests.cred
36 s.openstack = openstackservice.New(s.LiveTests.cred)36 s.openstack = openstackservice.New(s.LiveTests.cred,
37 identity.AuthUserPass)
3738
38 s.LiveTests.SetUpSuite(c)39 s.LiveTests.SetUpSuite(c)
39 s.LiveTestsPublicContainer.SetUpSuite(c)40 s.LiveTestsPublicContainer.SetUpSuite(c)
4041
=== modified file 'testservices/identityservice/identityservice.go'
--- testservices/identityservice/identityservice.go 2013-01-24 03:15:19 +0000
+++ testservices/identityservice/identityservice.go 2013-07-01 07:24:26 +0000
@@ -7,6 +7,7 @@
7 AddUser(user, secret, tenant string) *UserInfo7 AddUser(user, secret, tenant string) *UserInfo
8 FindUser(token string) (*UserInfo, error)8 FindUser(token string) (*UserInfo, error)
9 RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider)9 RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider)
10 AddService(service Service)
10 SetupHTTP(mux *http.ServeMux)11 SetupHTTP(mux *http.ServeMux)
11}12}
1213
1314
=== added file 'testservices/identityservice/keypair.go'
--- testservices/identityservice/keypair.go 1970-01-01 00:00:00 +0000
+++ testservices/identityservice/keypair.go 2013-07-01 07:24:26 +0000
@@ -0,0 +1,123 @@
1package identityservice
2
3import (
4 "encoding/json"
5 "fmt"
6 "io/ioutil"
7 "launchpad.net/goose/testservices/hook"
8 "net/http"
9)
10
11// Implement the v2 Key Pair form of identity based on Keystone
12
13type KeyPairRequest struct {
14 Auth struct {
15 ApiAccessKeyCredentials struct {
16 AccessKey string `json:"accessKey"`
17 SecretKey string `json:"secretKey"`
18 } `json:"apiAccessKeyCredentials"`
19 TenantName string `json:"tenantName"`
20 } `json:"auth"`
21}
22
23type KeyPair struct {
24 hook.TestService
25 Users
26 services []Service
27}
28
29func NewKeyPair() *KeyPair {
30 return &KeyPair{
31 Users: Users{
32 users: make(map[string]UserInfo),
33 tenants: make(map[string]string),
34 },
35 }
36}
37
38func (u *KeyPair) RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider) {
39 service := Service{name, serviceType, serviceProvider.Endpoints()}
40 u.AddService(service)
41}
42
43func (u *KeyPair) AddService(service Service) {
44 u.services = append(u.services, service)
45}
46
47func (u *KeyPair) ReturnFailure(w http.ResponseWriter, status int, message string) {
48 e := ErrorWrapper{
49 Error: ErrorResponse{
50 Message: message,
51 Code: status,
52 Title: http.StatusText(status),
53 },
54 }
55 if content, err := json.Marshal(e); err != nil {
56 w.Header().Set("Content-Length", fmt.Sprintf("%d", len(internalError)))
57 w.WriteHeader(http.StatusInternalServerError)
58 w.Write(internalError)
59 } else {
60 w.Header().Set("Content-Length", fmt.Sprintf("%d", len(content)))
61 w.WriteHeader(status)
62 w.Write(content)
63 }
64}
65
66func (u *KeyPair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
67 var req KeyPairRequest
68 // Testing against Canonistack, all responses are application/json, even failures
69 w.Header().Set("Content-Type", "application/json")
70 if r.Header.Get("Content-Type") != "application/json" {
71 u.ReturnFailure(w, http.StatusBadRequest, notJSON)
72 return
73 }
74 if content, err := ioutil.ReadAll(r.Body); err != nil {
75 w.WriteHeader(http.StatusBadRequest)
76 return
77 } else {
78 if err := json.Unmarshal(content, &req); err != nil {
79 u.ReturnFailure(w, http.StatusBadRequest, notJSON)
80 return
81 }
82 }
83 userInfo, errmsg := u.authenticate(req.Auth.ApiAccessKeyCredentials.AccessKey, req.Auth.ApiAccessKeyCredentials.SecretKey)
84 if errmsg != "" {
85 u.ReturnFailure(w, http.StatusUnauthorized, errmsg)
86 return
87 }
88 res, err := u.generateAccessResponse(userInfo)
89 if err != nil {
90 u.ReturnFailure(w, http.StatusInternalServerError, err.Error())
91 return
92 }
93 if content, err := json.Marshal(res); err != nil {
94 u.ReturnFailure(w, http.StatusInternalServerError, err.Error())
95 return
96 } else {
97 w.WriteHeader(http.StatusOK)
98 w.Write(content)
99 return
100 }
101 panic("unreachable")
102}
103
104func (u *KeyPair) generateAccessResponse(userInfo *UserInfo) (*AccessResponse, error) {
105 res := AccessResponse{}
106 // We pre-populate the response with genuine entries so that it looks sane.
107 if err := json.Unmarshal([]byte(exampleResponse), &res); err != nil {
108 return nil, err
109 }
110 res.Access.ServiceCatalog = u.services
111 res.Access.Token.Id = userInfo.Token
112 res.Access.Token.Tenant.Id = userInfo.TenantId
113 res.Access.User.Id = userInfo.Id
114 if err := u.ProcessControlHook("authorisation", u, &res, userInfo); err != nil {
115 return nil, err
116 }
117 return &res, nil
118}
119
120// setupHTTP attaches all the needed handlers to provide the HTTP API.
121func (u *KeyPair) SetupHTTP(mux *http.ServeMux) {
122 mux.Handle("/tokens", u)
123}
0124
=== added file 'testservices/identityservice/keypair_test.go'
--- testservices/identityservice/keypair_test.go 1970-01-01 00:00:00 +0000
+++ testservices/identityservice/keypair_test.go 2013-07-01 07:24:26 +0000
@@ -0,0 +1,130 @@
1package identityservice
2
3import (
4 "encoding/json"
5 "fmt"
6 "io/ioutil"
7 . "launchpad.net/gocheck"
8 "launchpad.net/goose/testing/httpsuite"
9 "net/http"
10 "strings"
11)
12
13type KeyPairSuite struct {
14 httpsuite.HTTPSuite
15}
16
17var _ = Suite(&KeyPairSuite{})
18
19func makeKeyPair(user, secret string) (identity *KeyPair) {
20 identity = NewKeyPair()
21 // Ensure that it conforms to the interface
22 var _ IdentityService = identity
23 if user != "" {
24 identity.AddUser(user, secret, "tenant")
25 }
26 return
27}
28
29func (s *KeyPairSuite) setupKeyPair(user, secret string) {
30 var identity *KeyPair
31 identity = makeKeyPair(user, secret)
32 identity.SetupHTTP(s.Mux)
33 return
34}
35
36func (s *KeyPairSuite) setupKeyPairWithServices(user, secret string, services []Service) {
37 var identity *KeyPair
38 identity = makeKeyPair(user, secret)
39 for _, service := range services {
40 identity.AddService(service)
41 }
42 identity.SetupHTTP(s.Mux)
43 return
44}
45
46const authKeyPairTemplate = `{
47 "auth": {
48 "tenantName": "tenant-something",
49 "apiAccessKeyCredentials": {
50 "accessKey": "%s",
51 "secretKey": "%s"
52 }
53 }
54}`
55
56func keyPairAuthRequest(URL, access, secret string) (*http.Response, error) {
57 client := &http.DefaultClient
58 body := strings.NewReader(fmt.Sprintf(authKeyPairTemplate, access, secret))
59 request, err := http.NewRequest("POST", URL+"/tokens", body)
60 request.Header.Set("Content-Type", "application/json")
61 if err != nil {
62 return nil, err
63 }
64 return client.Do(request)
65}
66
67func (s *KeyPairSuite) TestNotJSON(c *C) {
68 // We do everything in keyPairAuthRequest, except set the Content-Type
69 s.setupKeyPair("user", "secret")
70 client := &http.DefaultClient
71 body := strings.NewReader(fmt.Sprintf(authTemplate, "user", "secret"))
72 request, err := http.NewRequest("POST", s.Server.URL+"/tokens", body)
73 c.Assert(err, IsNil)
74 res, err := client.Do(request)
75 defer res.Body.Close()
76 c.Assert(err, IsNil)
77 CheckErrorResponse(c, res, http.StatusBadRequest, notJSON)
78}
79
80func (s *KeyPairSuite) TestBadJSON(c *C) {
81 // We do everything in keyPairAuthRequest, except set the Content-Type
82 s.setupKeyPair("user", "secret")
83 res, err := keyPairAuthRequest(s.Server.URL, `garbage"in`, "secret")
84 defer res.Body.Close()
85 c.Assert(err, IsNil)
86 CheckErrorResponse(c, res, http.StatusBadRequest, notJSON)
87}
88
89func (s *KeyPairSuite) TestNoSuchUser(c *C) {
90 s.setupKeyPair("user", "secret")
91 res, err := keyPairAuthRequest(s.Server.URL, "not-user", "secret")
92 defer res.Body.Close()
93 c.Assert(err, IsNil)
94 CheckErrorResponse(c, res, http.StatusUnauthorized, notAuthorized)
95}
96
97func (s *KeyPairSuite) TestBadPassword(c *C) {
98 s.setupKeyPair("user", "secret")
99 res, err := keyPairAuthRequest(s.Server.URL, "user", "not-secret")
100 defer res.Body.Close()
101 c.Assert(err, IsNil)
102 CheckErrorResponse(c, res, http.StatusUnauthorized, invalidUser)
103}
104
105func (s *KeyPairSuite) TestValidAuthorization(c *C) {
106 compute_url := "http://testing.invalid/compute"
107 s.setupKeyPairWithServices("user", "secret", []Service{
108 {"nova", "compute", []Endpoint{
109 {PublicURL: compute_url},
110 }}})
111 res, err := keyPairAuthRequest(s.Server.URL, "user", "secret")
112 defer res.Body.Close()
113 c.Assert(err, IsNil)
114 c.Check(res.StatusCode, Equals, http.StatusOK)
115 c.Check(res.Header.Get("Content-Type"), Equals, "application/json")
116 content, err := ioutil.ReadAll(res.Body)
117 c.Assert(err, IsNil)
118 var response AccessResponse
119 err = json.Unmarshal(content, &response)
120 c.Assert(err, IsNil)
121 c.Check(response.Access.Token.Id, NotNil)
122 novaURL := ""
123 for _, service := range response.Access.ServiceCatalog {
124 if service.Type == "compute" {
125 novaURL = service.Endpoints[0].PublicURL
126 break
127 }
128 }
129 c.Assert(novaURL, Equals, compute_url)
130}
0131
=== modified file 'testservices/identityservice/legacy.go'
--- testservices/identityservice/legacy.go 2013-01-24 01:01:35 +0000
+++ testservices/identityservice/legacy.go 2013-07-01 07:24:26 +0000
@@ -20,6 +20,10 @@
20 // NOOP for legacy identity service.20 // NOOP for legacy identity service.
21}21}
2222
23func (lis *Legacy) AddService(service Service) {
24 // NOOP for legacy identity service.
25}
26
23func (lis *Legacy) SetManagementURL(URL string) {27func (lis *Legacy) SetManagementURL(URL string) {
24 lis.managementURL = URL28 lis.managementURL = URL
25}29}
2630
=== modified file 'testservices/identityservice/userpass.go'
--- testservices/identityservice/userpass.go 2013-02-20 06:00:49 +0000
+++ testservices/identityservice/userpass.go 2013-07-01 07:24:26 +0000
@@ -47,8 +47,9 @@
47 Expires string `json:"expires"` // should this be a date object?47 Expires string `json:"expires"` // should this be a date object?
48 Id string `json:"id"` // Actual token string48 Id string `json:"id"` // Actual token string
49 Tenant struct {49 Tenant struct {
50 Id string `json:"id"`50 Id string `json:"id"`
51 Name string `json:"name"`51 Name string `json:"name"`
52 Description *string `json:"description"`
52 } `json:"tenant"`53 } `json:"tenant"`
53}54}
5455
@@ -118,7 +119,8 @@
118 "id": "5df9d45d-d198-4222-9b4c-7a280aa35666", 119 "id": "5df9d45d-d198-4222-9b4c-7a280aa35666",
119 "tenant": {120 "tenant": {
120 "id": "1", 121 "id": "1",
121 "name": "admin"122 "name": "admin",
123 "description": null
122 }124 }
123 }, 125 },
124 "user": {126 "user": {
125127
=== modified file 'testservices/novaservice/service.go'
--- testservices/novaservice/service.go 2013-04-22 23:20:03 +0000
+++ testservices/novaservice/service.go 2013-07-01 07:24:26 +0000
@@ -21,11 +21,11 @@
21 testservices.ServiceInstance21 testservices.ServiceInstance
22 flavors map[string]nova.FlavorDetail22 flavors map[string]nova.FlavorDetail
23 servers map[string]nova.ServerDetail23 servers map[string]nova.ServerDetail
24 groups map[int]nova.SecurityGroup24 groups map[string]nova.SecurityGroup
25 rules map[int]nova.SecurityGroupRule25 rules map[string]nova.SecurityGroupRule
26 floatingIPs map[int]nova.FloatingIP26 floatingIPs map[string]nova.FloatingIP
27 serverGroups map[string][]int27 serverGroups map[string][]string
28 serverIPs map[string][]int28 serverIPs map[string][]string
29 nextServerId int29 nextServerId int
30 nextGroupId int30 nextGroupId int
31 nextRuleId int31 nextRuleId int
@@ -74,16 +74,16 @@
74 }74 }
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.
76 defaultSecurityGroups := []nova.SecurityGroup{76 defaultSecurityGroups := []nova.SecurityGroup{
77 {Id: 999, Name: "default", Description: "default group"},77 {Id: "999", Name: "default", Description: "default group"},
78 }78 }
79 novaService := &Nova{79 novaService := &Nova{
80 flavors: make(map[string]nova.FlavorDetail),80 flavors: make(map[string]nova.FlavorDetail),
81 servers: make(map[string]nova.ServerDetail),81 servers: make(map[string]nova.ServerDetail),
82 groups: make(map[int]nova.SecurityGroup),82 groups: make(map[string]nova.SecurityGroup),
83 rules: make(map[int]nova.SecurityGroupRule),83 rules: make(map[string]nova.SecurityGroupRule),
84 floatingIPs: make(map[int]nova.FloatingIP),84 floatingIPs: make(map[string]nova.FloatingIP),
85 serverGroups: make(map[string][]int),85 serverGroups: make(map[string][]string),
86 serverIPs: make(map[string][]int),86 serverIPs: make(map[string][]string),
87 ServiceInstance: testservices.ServiceInstance{87 ServiceInstance: testservices.ServiceInstance{
88 IdentityService: identityService,88 IdentityService: identityService,
89 Hostname: hostname,89 Hostname: hostname,
@@ -368,7 +368,7 @@
368 return err368 return err
369 }369 }
370 if _, err := n.securityGroup(group.Id); err == nil {370 if _, err := n.securityGroup(group.Id); err == nil {
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)
372 }372 }
373 group.TenantId = n.TenantId373 group.TenantId = n.TenantId
374 if group.Rules == nil {374 if group.Rules == nil {
@@ -379,13 +379,13 @@
379}379}
380380
381// securityGroup retrieves an existing group by ID.381// securityGroup retrieves an existing group by ID.
382func (n *Nova) securityGroup(groupId int) (*nova.SecurityGroup, error) {382func (n *Nova) securityGroup(groupId string) (*nova.SecurityGroup, error) {
383 if err := n.ProcessFunctionHook(n, groupId); err != nil {383 if err := n.ProcessFunctionHook(n, groupId); err != nil {
384 return nil, err384 return nil, err
385 }385 }
386 group, ok := n.groups[groupId]386 group, ok := n.groups[groupId]
387 if !ok {387 if !ok {
388 return nil, fmt.Errorf("no such security group %d", groupId)388 return nil, fmt.Errorf("no such security group %s", groupId)
389 }389 }
390 return &group, nil390 return &group, nil
391}391}
@@ -413,7 +413,7 @@
413}413}
414414
415// removeSecurityGroup deletes an existing group.415// removeSecurityGroup deletes an existing group.
416func (n *Nova) removeSecurityGroup(groupId int) error {416func (n *Nova) removeSecurityGroup(groupId string) error {
417 if err := n.ProcessFunctionHook(n, groupId); err != nil {417 if err := n.ProcessFunctionHook(n, groupId); err != nil {
418 return err418 return err
419 }419 }
@@ -427,12 +427,12 @@
427// addSecurityGroupRule creates a new rule in an existing group.427// addSecurityGroupRule creates a new rule in an existing group.
428// This can be either an ingress or a group rule (see the notes428// This can be either an ingress or a group rule (see the notes
429// about nova.RuleInfo).429// about nova.RuleInfo).
430func (n *Nova) addSecurityGroupRule(ruleId int, rule nova.RuleInfo) error {430func (n *Nova) addSecurityGroupRule(ruleId string, rule nova.RuleInfo) error {
431 if err := n.ProcessFunctionHook(n, ruleId, rule); err != nil {431 if err := n.ProcessFunctionHook(n, ruleId, rule); err != nil {
432 return err432 return err
433 }433 }
434 if _, err := n.securityGroupRule(ruleId); err == nil {434 if _, err := n.securityGroupRule(ruleId); err == nil {
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)
436 }436 }
437 group, err := n.securityGroup(rule.ParentGroupId)437 group, err := n.securityGroup(rule.ParentGroupId)
438 if err != nil {438 if err != nil {
@@ -440,7 +440,7 @@
440 }440 }
441 for _, ru := range group.Rules {441 for _, ru := range group.Rules {
442 if ru.Id == ruleId {442 if ru.Id == ruleId {
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)
444 }444 }
445 }445 }
446 var zeroSecurityGroupRef nova.SecurityGroupRef446 var zeroSecurityGroupRef nova.SecurityGroupRef
@@ -452,7 +452,7 @@
452 if rule.GroupId != nil {452 if rule.GroupId != nil {
453 sourceGroup, err := n.securityGroup(*rule.GroupId)453 sourceGroup, err := n.securityGroup(*rule.GroupId)
454 if err != nil {454 if err != nil {
455 return fmt.Errorf("unknown source security group %d", *rule.GroupId)455 return fmt.Errorf("unknown source security group %s", *rule.GroupId)
456 }456 }
457 newrule.Group = nova.SecurityGroupRef{457 newrule.Group = nova.SecurityGroupRef{
458 TenantId: sourceGroup.TenantId,458 TenantId: sourceGroup.TenantId,
@@ -480,27 +480,27 @@
480}480}
481481
482// hasSecurityGroupRule returns whether the given group contains the given rule,482// hasSecurityGroupRule returns whether the given group contains the given rule,
483// or (when groupId=-1) whether the given rule exists.483// or (when groupId="-1") whether the given rule exists.
484func (n *Nova) hasSecurityGroupRule(groupId, ruleId int) bool {484func (n *Nova) hasSecurityGroupRule(groupId, ruleId string) bool {
485 rule, ok := n.rules[ruleId]485 rule, ok := n.rules[ruleId]
486 _, err := n.securityGroup(groupId)486 _, err := n.securityGroup(groupId)
487 return ok && (groupId == -1 || (err == nil && rule.ParentGroupId == groupId))487 return ok && (groupId == "-1" || (err == nil && rule.ParentGroupId == groupId))
488}488}
489489
490// securityGroupRule retrieves an existing rule by ID.490// securityGroupRule retrieves an existing rule by ID.
491func (n *Nova) securityGroupRule(ruleId int) (*nova.SecurityGroupRule, error) {491func (n *Nova) securityGroupRule(ruleId string) (*nova.SecurityGroupRule, error) {
492 if err := n.ProcessFunctionHook(n, ruleId); err != nil {492 if err := n.ProcessFunctionHook(n, ruleId); err != nil {
493 return nil, err493 return nil, err
494 }494 }
495 rule, ok := n.rules[ruleId]495 rule, ok := n.rules[ruleId]
496 if !ok {496 if !ok {
497 return nil, fmt.Errorf("no such security group rule %d", ruleId)497 return nil, fmt.Errorf("no such security group rule %s", ruleId)
498 }498 }
499 return &rule, nil499 return &rule, nil
500}500}
501501
502// removeSecurityGroupRule deletes an existing rule from its group.502// removeSecurityGroupRule deletes an existing rule from its group.
503func (n *Nova) removeSecurityGroupRule(ruleId int) error {503func (n *Nova) removeSecurityGroupRule(ruleId string) error {
504 if err := n.ProcessFunctionHook(n, ruleId); err != nil {504 if err := n.ProcessFunctionHook(n, ruleId); err != nil {
505 return err505 return err
506 }506 }
@@ -528,7 +528,7 @@
528}528}
529529
530// addServerSecurityGroup attaches an existing server to a group.530// addServerSecurityGroup attaches an existing server to a group.
531func (n *Nova) addServerSecurityGroup(serverId string, groupId int) error {531func (n *Nova) addServerSecurityGroup(serverId string, groupId string) error {
532 if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil {532 if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil {
533 return err533 return err
534 }534 }
@@ -542,7 +542,7 @@
542 if ok {542 if ok {
543 for _, gid := range groups {543 for _, gid := range groups {
544 if gid == groupId {544 if gid == groupId {
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)
546 }546 }
547 }547 }
548 }548 }
@@ -552,7 +552,7 @@
552}552}
553553
554// hasServerSecurityGroup returns whether the given server belongs to the group.554// hasServerSecurityGroup returns whether the given server belongs to the group.
555func (n *Nova) hasServerSecurityGroup(serverId string, groupId int) bool {555func (n *Nova) hasServerSecurityGroup(serverId string, groupId string) bool {
556 if _, err := n.server(serverId); err != nil {556 if _, err := n.server(serverId); err != nil {
557 return false557 return false
558 }558 }
@@ -586,7 +586,7 @@
586}586}
587587
588// removeServerSecurityGroup detaches an existing server from a group.588// removeServerSecurityGroup detaches an existing server from a group.
589func (n *Nova) removeServerSecurityGroup(serverId string, groupId int) error {589func (n *Nova) removeServerSecurityGroup(serverId string, groupId string) error {
590 if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil {590 if err := n.ProcessFunctionHook(n, serverId, groupId); err != nil {
591 return err591 return err
592 }592 }
@@ -608,7 +608,7 @@
608 }608 }
609 }609 }
610 if idx == -1 {610 if idx == -1 {
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)
612 }612 }
613 groups = append(groups[:idx], groups[idx+1:]...)613 groups = append(groups[:idx], groups[idx+1:]...)
614 n.serverGroups[serverId] = groups614 n.serverGroups[serverId] = groups
@@ -621,7 +621,7 @@
621 return err621 return err
622 }622 }
623 if _, err := n.floatingIP(ip.Id); err == nil {623 if _, err := n.floatingIP(ip.Id); err == nil {
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)
625 }625 }
626 n.floatingIPs[ip.Id] = ip626 n.floatingIPs[ip.Id] = ip
627 return nil627 return nil
@@ -641,13 +641,13 @@
641}641}
642642
643// floatingIP retrieves the floating IP by ID.643// floatingIP retrieves the floating IP by ID.
644func (n *Nova) floatingIP(ipId int) (*nova.FloatingIP, error) {644func (n *Nova) floatingIP(ipId string) (*nova.FloatingIP, error) {
645 if err := n.ProcessFunctionHook(n, ipId); err != nil {645 if err := n.ProcessFunctionHook(n, ipId); err != nil {
646 return nil, err646 return nil, err
647 }647 }
648 ip, ok := n.floatingIPs[ipId]648 ip, ok := n.floatingIPs[ipId]
649 if !ok {649 if !ok {
650 return nil, fmt.Errorf("no such floating IP %d", ipId)650 return nil, fmt.Errorf("no such floating IP %s", ipId)
651 }651 }
652 return &ip, nil652 return &ip, nil
653}653}
@@ -675,7 +675,7 @@
675}675}
676676
677// removeFloatingIP deletes an existing floating IP by ID.677// removeFloatingIP deletes an existing floating IP by ID.
678func (n *Nova) removeFloatingIP(ipId int) error {678func (n *Nova) removeFloatingIP(ipId string) error {
679 if err := n.ProcessFunctionHook(n, ipId); err != nil {679 if err := n.ProcessFunctionHook(n, ipId); err != nil {
680 return err680 return err
681 }681 }
@@ -687,7 +687,7 @@
687}687}
688688
689// addServerFloatingIP attaches an existing floating IP to a server.689// addServerFloatingIP attaches an existing floating IP to a server.
690func (n *Nova) addServerFloatingIP(serverId string, ipId int) error {690func (n *Nova) addServerFloatingIP(serverId string, ipId string) error {
691 if err := n.ProcessFunctionHook(n, serverId, ipId); err != nil {691 if err := n.ProcessFunctionHook(n, serverId, ipId); err != nil {
692 return err692 return err
693 }693 }
@@ -706,7 +706,7 @@
706 if ok {706 if ok {
707 for _, fipId := range fips {707 for _, fipId := range fips {
708 if fipId == ipId {708 if fipId == ipId {
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)
710 }710 }
711 }711 }
712 }712 }
@@ -734,7 +734,7 @@
734}734}
735735
736// removeServerFloatingIP deletes an attached floating IP from a server.736// removeServerFloatingIP deletes an attached floating IP from a server.
737func (n *Nova) removeServerFloatingIP(serverId string, ipId int) error {737func (n *Nova) removeServerFloatingIP(serverId string, ipId string) error {
738 if err := n.ProcessFunctionHook(n, serverId); err != nil {738 if err := n.ProcessFunctionHook(n, serverId); err != nil {
739 return err739 return err
740 }740 }
@@ -760,7 +760,7 @@
760 }760 }
761 }761 }
762 if idx == -1 {762 if idx == -1 {
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)
764 }764 }
765 fips = append(fips[:idx], fips[idx+1:]...)765 fips = append(fips[:idx], fips[idx+1:]...)
766 n.serverIPs[serverId] = fips766 n.serverIPs[serverId] = fips
767767
=== modified file 'testservices/novaservice/service_http.go'
--- testservices/novaservice/service_http.go 2013-02-25 07:16:32 +0000
+++ testservices/novaservice/service_http.go 2013-07-01 07:24:26 +0000
@@ -114,14 +114,6 @@
114 nil,114 nil,
115 nil,115 nil,
116 }116 }
117 errBadRequestSG = &errorResponse{
118 http.StatusBadRequest,
119 `{"badRequest": {"message": "Security group id should be integer", "code": 400}}`,
120 "application/json; charset=UTF-8",
121 "bad security group id type",
122 nil,
123 nil,
124 }
125 errNotFound = &errorResponse{117 errNotFound = &errorResponse{
126 http.StatusNotFound,118 http.StatusNotFound,
127 `404 Not Found119 `404 Not Found
@@ -567,7 +559,7 @@
567 if err != nil {559 if err != nil {
568 return err560 return err
569 }561 }
570 var groups []int562 var groups []string
571 if len(req.Server.SecurityGroups) > 0 {563 if len(req.Server.SecurityGroups) > 0 {
572 for _, group := range req.Server.SecurityGroups {564 for _, group := range req.Server.SecurityGroups {
573 groupName := group["name"]565 groupName := group["name"]
@@ -772,11 +764,7 @@
772// If there was no group id specified in the path, it returns errNoGroupId764// If there was no group id specified in the path, it returns errNoGroupId
773func (n *Nova) processGroupId(w http.ResponseWriter, r *http.Request) (*nova.SecurityGroup, error) {765func (n *Nova) processGroupId(w http.ResponseWriter, r *http.Request) (*nova.SecurityGroup, error) {
774 if groupId := path.Base(r.URL.Path); groupId != "os-security-groups" {766 if groupId := path.Base(r.URL.Path); groupId != "os-security-groups" {
775 id, err := strconv.Atoi(groupId)767 group, err := n.securityGroup(groupId)
776 if err != nil {
777 return nil, errBadRequestSG
778 }
779 group, err := n.securityGroup(id)
780 if err != nil {768 if err != nil {
781 return nil, errNotFoundJSONSG769 return nil, errNotFoundJSONSG
782 }770 }
@@ -829,7 +817,7 @@
829 return errBadRequestDuplicateValue817 return errBadRequestDuplicateValue
830 }818 }
831 n.nextGroupId++819 n.nextGroupId++
832 nextId := n.nextGroupId820 nextId := strconv.Itoa(n.nextGroupId)
833 err = n.addSecurityGroup(nova.SecurityGroup{821 err = n.addSecurityGroup(nova.SecurityGroup{
834 Id: nextId,822 Id: nextId,
835 Name: req.Group.Name,823 Name: req.Group.Name,
@@ -912,7 +900,7 @@
912 }900 }
913 }901 }
914 n.nextRuleId++902 n.nextRuleId++
915 nextId := n.nextRuleId903 nextId := strconv.Itoa(n.nextRuleId)
916 err = n.addSecurityGroupRule(nextId, req.Rule)904 err = n.addSecurityGroupRule(nextId, req.Rule)
917 if err != nil {905 if err != nil {
918 return err906 return err
@@ -933,15 +921,10 @@
933 return errNotFound921 return errNotFound
934 case "DELETE":922 case "DELETE":
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" {
936 id, err := strconv.Atoi(ruleId)924 if _, err := n.securityGroupRule(ruleId); err != nil {
937 if err != nil {
938 // weird, but this is how nova responds
939 return errBadRequestSG
940 }
941 if _, err = n.securityGroupRule(id); err != nil {
942 return errNotFoundJSONSGR925 return errNotFoundJSONSGR
943 }926 }
944 if err = n.removeSecurityGroupRule(id); err != nil {927 if err := n.removeSecurityGroupRule(ruleId); err != nil {
945 return err928 return err
946 }929 }
947 writeResponse(w, http.StatusAccepted, nil)930 writeResponse(w, http.StatusAccepted, nil)
@@ -957,11 +940,7 @@
957 switch r.Method {940 switch r.Method {
958 case "GET":941 case "GET":
959 if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" {942 if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" {
960 nId, err := strconv.Atoi(ipId)943 fip, err := n.floatingIP(ipId)
961 if err != nil {
962 return errNotFoundJSON
963 }
964 fip, err := n.floatingIP(nId)
965 if err != nil {944 if err != nil {
966 return errNotFoundJSON945 return errNotFoundJSON
967 }946 }
@@ -983,8 +962,8 @@
983 return errNotFound962 return errNotFound
984 }963 }
985 n.nextIPId++964 n.nextIPId++
986 nextId := n.nextIPId965 addr := fmt.Sprintf("10.0.0.%d", n.nextIPId)
987 addr := fmt.Sprintf("10.0.0.%d", nextId)966 nextId := strconv.Itoa(n.nextIPId)
988 fip := nova.FloatingIP{Id: nextId, IP: addr, Pool: "nova"}967 fip := nova.FloatingIP{Id: nextId, IP: addr, Pool: "nova"}
989 err := n.addFloatingIP(fip)968 err := n.addFloatingIP(fip)
990 if err != nil {969 if err != nil {
@@ -1001,11 +980,9 @@
1001 return errNotFound980 return errNotFound
1002 case "DELETE":981 case "DELETE":
1003 if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" {982 if ipId := path.Base(r.URL.Path); ipId != "os-floating-ips" {
1004 if nId, err := strconv.Atoi(ipId); err == nil {983 if err := n.removeFloatingIP(ipId); err == nil {
1005 if err := n.removeFloatingIP(nId); err == nil {984 writeResponse(w, http.StatusAccepted, nil)
1006 writeResponse(w, http.StatusAccepted, nil)985 return nil
1007 return nil
1008 }
1009 }986 }
1010 return errNotFoundJSON987 return errNotFoundJSON
1011 }988 }
1012989
=== modified file 'testservices/novaservice/service_http_test.go'
--- testservices/novaservice/service_http_test.go 2013-04-23 00:19:57 +0000
+++ testservices/novaservice/service_http_test.go 2013-07-01 07:24:26 +0000
@@ -322,11 +322,6 @@
322 },322 },
323 {323 {
324 method: "GET",324 method: "GET",
325 url: "/os-security-groups/invalid",
326 expect: errBadRequestSG,
327 },
328 {
329 method: "GET",
330 url: "/os-security-groups/42",325 url: "/os-security-groups/42",
331 expect: errNotFoundJSONSG,326 expect: errNotFoundJSONSG,
332 },327 },
@@ -357,11 +352,6 @@
357 },352 },
358 {353 {
359 method: "DELETE",354 method: "DELETE",
360 url: "/os-security-groups/invalid",
361 expect: errBadRequestSG,
362 },
363 {
364 method: "DELETE",
365 url: "/os-security-groups/42",355 url: "/os-security-groups/42",
366 expect: errNotFoundJSONSG,356 expect: errNotFoundJSONSG,
367 },357 },
@@ -404,11 +394,6 @@
404 method: "DELETE",394 method: "DELETE",
405 url: "/os-security-group-rules",395 url: "/os-security-group-rules",
406 expect: errNotFound,396 expect: errNotFound,
407 },
408 {
409 method: "DELETE",
410 url: "/os-security-group-rules/invalid",
411 expect: errBadRequestSG, // sic; should've been rule-specific
412 },397 },
413 {398 {
414 method: "DELETE",399 method: "DELETE",
@@ -676,12 +661,12 @@
676 {"name": "group1"},661 {"name": "group1"},
677 {"name": "group2"},662 {"name": "group2"},
678 }663 }
679 err = s.service.addSecurityGroup(nova.SecurityGroup{Id: 1, Name: "group1"})664 err = s.service.addSecurityGroup(nova.SecurityGroup{Id: "1", Name: "group1"})
680 c.Assert(err, IsNil)665 c.Assert(err, IsNil)
681 defer s.service.removeSecurityGroup(1)666 defer s.service.removeSecurityGroup("1")
682 err = s.service.addSecurityGroup(nova.SecurityGroup{Id: 2, Name: "group2"})667 err = s.service.addSecurityGroup(nova.SecurityGroup{Id: "2", Name: "group2"})
683 c.Assert(err, IsNil)668 c.Assert(err, IsNil)
684 defer s.service.removeSecurityGroup(2)669 defer s.service.removeSecurityGroup("2")
685 resp, err = s.jsonRequest("POST", "/servers", req, nil)670 resp, err = s.jsonRequest("POST", "/servers", req, nil)
686 c.Assert(err, IsNil)671 c.Assert(err, IsNil)
687 c.Assert(resp.StatusCode, Equals, http.StatusAccepted)672 c.Assert(resp.StatusCode, Equals, http.StatusAccepted)
@@ -689,12 +674,12 @@
689 c.Assert(expected.Server.SecurityGroups, DeepEquals, req.Server.SecurityGroups)674 c.Assert(expected.Server.SecurityGroups, DeepEquals, req.Server.SecurityGroups)
690 srv, err = s.service.server(expected.Server.Id)675 srv, err = s.service.server(expected.Server.Id)
691 c.Assert(err, IsNil)676 c.Assert(err, IsNil)
692 ok := s.service.hasServerSecurityGroup(srv.Id, 1)677 ok := s.service.hasServerSecurityGroup(srv.Id, "1")
693 c.Assert(ok, Equals, true)678 c.Assert(ok, Equals, true)
694 ok = s.service.hasServerSecurityGroup(srv.Id, 2)679 ok = s.service.hasServerSecurityGroup(srv.Id, "2")
695 c.Assert(ok, Equals, true)680 c.Assert(ok, Equals, true)
696 s.service.removeServerSecurityGroup(srv.Id, 1)681 s.service.removeServerSecurityGroup(srv.Id, "1")
697 s.service.removeServerSecurityGroup(srv.Id, 2)682 s.service.removeServerSecurityGroup(srv.Id, "2")
698 s.service.removeServer(srv.Id)683 s.service.removeServer(srv.Id)
699}684}
700685
@@ -794,13 +779,13 @@
794 c.Assert(expected.Groups, HasLen, 1)779 c.Assert(expected.Groups, HasLen, 1)
795 groups = []nova.SecurityGroup{780 groups = []nova.SecurityGroup{
796 {781 {
797 Id: 1,782 Id: "1",
798 Name: "group 1",783 Name: "group 1",
799 TenantId: s.service.TenantId,784 TenantId: s.service.TenantId,
800 Rules: []nova.SecurityGroupRule{},785 Rules: []nova.SecurityGroupRule{},
801 },786 },
802 {787 {
803 Id: 2,788 Id: "2",
804 Name: "group 2",789 Name: "group 2",
805 TenantId: s.service.TenantId,790 TenantId: s.service.TenantId,
806 Rules: []nova.SecurityGroupRule{},791 Rules: []nova.SecurityGroupRule{},
@@ -829,7 +814,7 @@
829814
830func (s *NovaHTTPSuite) TestAddSecurityGroup(c *C) {815func (s *NovaHTTPSuite) TestAddSecurityGroup(c *C) {
831 group := nova.SecurityGroup{816 group := nova.SecurityGroup{
832 Id: 1,817 Id: "1",
833 Name: "group 1",818 Name: "group 1",
834 Description: "desc",819 Description: "desc",
835 TenantId: s.service.TenantId,820 TenantId: s.service.TenantId,
@@ -858,7 +843,7 @@
858}843}
859844
860func (s *NovaHTTPSuite) TestDeleteSecurityGroup(c *C) {845func (s *NovaHTTPSuite) TestDeleteSecurityGroup(c *C) {
861 group := nova.SecurityGroup{Id: 1, Name: "group 1"}846 group := nova.SecurityGroup{Id: "1", Name: "group 1"}
862 _, err := s.service.securityGroup(group.Id)847 _, err := s.service.securityGroup(group.Id)
863 c.Assert(err, NotNil)848 c.Assert(err, NotNil)
864 err = s.service.addSecurityGroup(group)849 err = s.service.addSecurityGroup(group)
@@ -872,8 +857,8 @@
872}857}
873858
874func (s *NovaHTTPSuite) TestAddSecurityGroupRule(c *C) {859func (s *NovaHTTPSuite) TestAddSecurityGroupRule(c *C) {
875 group1 := nova.SecurityGroup{Id: 1, Name: "src"}860 group1 := nova.SecurityGroup{Id: "1", Name: "src"}
876 group2 := nova.SecurityGroup{Id: 2, Name: "tgt"}861 group2 := nova.SecurityGroup{Id: "2", Name: "tgt"}
877 err := s.service.addSecurityGroup(group1)862 err := s.service.addSecurityGroup(group1)
878 c.Assert(err, IsNil)863 c.Assert(err, IsNil)
879 defer s.service.removeSecurityGroup(group1.Id)864 defer s.service.removeSecurityGroup(group1.Id)
@@ -881,7 +866,7 @@
881 c.Assert(err, IsNil)866 c.Assert(err, IsNil)
882 defer s.service.removeSecurityGroup(group2.Id)867 defer s.service.removeSecurityGroup(group2.Id)
883 riIngress := nova.RuleInfo{868 riIngress := nova.RuleInfo{
884 ParentGroupId: 1,869 ParentGroupId: "1",
885 FromPort: 1234,870 FromPort: 1234,
886 ToPort: 4321,871 ToPort: 4321,
887 IPProtocol: "tcp",872 IPProtocol: "tcp",
@@ -894,7 +879,7 @@
894 iprange := make(map[string]string)879 iprange := make(map[string]string)
895 iprange["cidr"] = riIngress.Cidr880 iprange["cidr"] = riIngress.Cidr
896 rule1 := nova.SecurityGroupRule{881 rule1 := nova.SecurityGroupRule{
897 Id: 1,882 Id: "1",
898 ParentGroupId: group1.Id,883 ParentGroupId: group1.Id,
899 FromPort: &riIngress.FromPort,884 FromPort: &riIngress.FromPort,
900 ToPort: &riIngress.ToPort,885 ToPort: &riIngress.ToPort,
@@ -902,7 +887,7 @@
902 IPRange: iprange,887 IPRange: iprange,
903 }888 }
904 rule2 := nova.SecurityGroupRule{889 rule2 := nova.SecurityGroupRule{
905 Id: 2,890 Id: "2",
906 ParentGroupId: group2.Id,891 ParentGroupId: group2.Id,
907 Group: nova.SecurityGroupRef{892 Group: nova.SecurityGroupRef{
908 Name: group1.Name,893 Name: group1.Name,
@@ -945,8 +930,8 @@
945}930}
946931
947func (s *NovaHTTPSuite) TestDeleteSecurityGroupRule(c *C) {932func (s *NovaHTTPSuite) TestDeleteSecurityGroupRule(c *C) {
948 group1 := nova.SecurityGroup{Id: 1, Name: "src"}933 group1 := nova.SecurityGroup{Id: "1", Name: "src"}
949 group2 := nova.SecurityGroup{Id: 2, Name: "tgt"}934 group2 := nova.SecurityGroup{Id: "2", Name: "tgt"}
950 err := s.service.addSecurityGroup(group1)935 err := s.service.addSecurityGroup(group1)
951 c.Assert(err, IsNil)936 c.Assert(err, IsNil)
952 defer s.service.removeSecurityGroup(group1.Id)937 defer s.service.removeSecurityGroup(group1.Id)
@@ -958,7 +943,7 @@
958 GroupId: &group1.Id,943 GroupId: &group1.Id,
959 }944 }
960 rule := nova.SecurityGroupRule{945 rule := nova.SecurityGroupRule{
961 Id: 1,946 Id: "1",
962 ParentGroupId: group2.Id,947 ParentGroupId: group2.Id,
963 Group: nova.SecurityGroupRef{948 Group: nova.SecurityGroupRef{
964 Name: group1.Name,949 Name: group1.Name,
@@ -975,7 +960,7 @@
975}960}
976961
977func (s *NovaHTTPSuite) TestAddServerSecurityGroup(c *C) {962func (s *NovaHTTPSuite) TestAddServerSecurityGroup(c *C) {
978 group := nova.SecurityGroup{Id: 1, Name: "group"}963 group := nova.SecurityGroup{Id: "1", Name: "group"}
979 err := s.service.addSecurityGroup(group)964 err := s.service.addSecurityGroup(group)
980 c.Assert(err, IsNil)965 c.Assert(err, IsNil)
981 defer s.service.removeSecurityGroup(group.Id)966 defer s.service.removeSecurityGroup(group.Id)
@@ -1004,13 +989,13 @@
1004 server := nova.ServerDetail{Id: "sr1"}989 server := nova.ServerDetail{Id: "sr1"}
1005 groups := []nova.SecurityGroup{990 groups := []nova.SecurityGroup{
1006 {991 {
1007 Id: 1,992 Id: "1",
1008 Name: "group1",993 Name: "group1",
1009 TenantId: s.service.TenantId,994 TenantId: s.service.TenantId,
1010 Rules: []nova.SecurityGroupRule{},995 Rules: []nova.SecurityGroupRule{},
1011 },996 },
1012 {997 {
1013 Id: 2,998 Id: "2",
1014 Name: "group2",999 Name: "group2",
1015 TenantId: s.service.TenantId,1000 TenantId: s.service.TenantId,
1016 Rules: []nova.SecurityGroupRule{},1001 Rules: []nova.SecurityGroupRule{},
@@ -1040,7 +1025,7 @@
1040}1025}
10411026
1042func (s *NovaHTTPSuite) TestDeleteServerSecurityGroup(c *C) {1027func (s *NovaHTTPSuite) TestDeleteServerSecurityGroup(c *C) {
1043 group := nova.SecurityGroup{Id: 1, Name: "group"}1028 group := nova.SecurityGroup{Id: "1", Name: "group"}
1044 err := s.service.addSecurityGroup(group)1029 err := s.service.addSecurityGroup(group)
1045 c.Assert(err, IsNil)1030 c.Assert(err, IsNil)
1046 defer s.service.removeSecurityGroup(group.Id)1031 defer s.service.removeSecurityGroup(group.Id)
@@ -1066,7 +1051,7 @@
1066}1051}
10671052
1068func (s *NovaHTTPSuite) TestPostFloatingIP(c *C) {1053func (s *NovaHTTPSuite) TestPostFloatingIP(c *C) {
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"}
1070 c.Assert(s.service.allFloatingIPs(), HasLen, 0)1055 c.Assert(s.service.allFloatingIPs(), HasLen, 0)
1071 var expected struct {1056 var expected struct {
1072 IP nova.FloatingIP `json:"floating_ip"`1057 IP nova.FloatingIP `json:"floating_ip"`
@@ -1091,8 +1076,8 @@
1091 assertJSON(c, resp, &expected)1076 assertJSON(c, resp, &expected)
1092 c.Assert(expected.IPs, HasLen, 0)1077 c.Assert(expected.IPs, HasLen, 0)
1093 fips := []nova.FloatingIP{1078 fips := []nova.FloatingIP{
1094 {Id: 1, IP: "1.2.3.4", Pool: "nova"},1079 {Id: "1", IP: "1.2.3.4", Pool: "nova"},
1095 {Id: 2, IP: "4.3.2.1", Pool: "nova"},1080 {Id: "2", IP: "4.3.2.1", Pool: "nova"},
1096 }1081 }
1097 for _, fip := range fips {1082 for _, fip := range fips {
1098 err := s.service.addFloatingIP(fip)1083 err := s.service.addFloatingIP(fip)
@@ -1118,7 +1103,7 @@
1118}1103}
11191104
1120func (s *NovaHTTPSuite) TestDeleteFloatingIP(c *C) {1105func (s *NovaHTTPSuite) TestDeleteFloatingIP(c *C) {
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"}
1122 err := s.service.addFloatingIP(fip)1107 err := s.service.addFloatingIP(fip)
1123 c.Assert(err, IsNil)1108 c.Assert(err, IsNil)
1124 defer s.service.removeFloatingIP(fip.Id)1109 defer s.service.removeFloatingIP(fip.Id)
@@ -1130,7 +1115,7 @@
1130}1115}
11311116
1132func (s *NovaHTTPSuite) TestAddServerFloatingIP(c *C) {1117func (s *NovaHTTPSuite) TestAddServerFloatingIP(c *C) {
1133 fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"}1118 fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
1134 server := nova.ServerDetail{Id: "sr1"}1119 server := nova.ServerDetail{Id: "sr1"}
1135 err := s.service.addFloatingIP(fip)1120 err := s.service.addFloatingIP(fip)
1136 c.Assert(err, IsNil)1121 c.Assert(err, IsNil)
@@ -1154,7 +1139,7 @@
1154}1139}
11551140
1156func (s *NovaHTTPSuite) TestRemoveServerFloatingIP(c *C) {1141func (s *NovaHTTPSuite) TestRemoveServerFloatingIP(c *C) {
1157 fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"}1142 fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
1158 server := nova.ServerDetail{Id: "sr1"}1143 server := nova.ServerDetail{Id: "sr1"}
1159 err := s.service.addFloatingIP(fip)1144 err := s.service.addFloatingIP(fip)
1160 c.Assert(err, IsNil)1145 c.Assert(err, IsNil)
11611146
=== modified file 'testservices/novaservice/service_test.go'
--- testservices/novaservice/service_test.go 2013-04-23 00:19:57 +0000
+++ testservices/novaservice/service_test.go 2013-07-01 07:24:26 +0000
@@ -36,17 +36,17 @@
3636
37func (s *NovaSuite) ensureNoGroup(c *C, group nova.SecurityGroup) {37func (s *NovaSuite) ensureNoGroup(c *C, group nova.SecurityGroup) {
38 _, err := s.service.securityGroup(group.Id)38 _, err := s.service.securityGroup(group.Id)
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))
40}40}
4141
42func (s *NovaSuite) ensureNoRule(c *C, rule nova.SecurityGroupRule) {42func (s *NovaSuite) ensureNoRule(c *C, rule nova.SecurityGroupRule) {
43 _, err := s.service.securityGroupRule(rule.Id)43 _, err := s.service.securityGroupRule(rule.Id)
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))
45}45}
4646
47func (s *NovaSuite) ensureNoIP(c *C, ip nova.FloatingIP) {47func (s *NovaSuite) ensureNoIP(c *C, ip nova.FloatingIP) {
48 _, err := s.service.floatingIP(ip.Id)48 _, err := s.service.floatingIP(ip.Id)
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))
50}50}
5151
52func (s *NovaSuite) createFlavor(c *C, flavor nova.FlavorDetail) {52func (s *NovaSuite) createFlavor(c *C, flavor nova.FlavorDetail) {
@@ -520,19 +520,19 @@
520}520}
521521
522func (s *NovaSuite) TestAddRemoveSecurityGroup(c *C) {522func (s *NovaSuite) TestAddRemoveSecurityGroup(c *C) {
523 group := nova.SecurityGroup{Id: 1}523 group := nova.SecurityGroup{Id: "1"}
524 s.createGroup(c, group)524 s.createGroup(c, group)
525 s.deleteGroup(c, group)525 s.deleteGroup(c, group)
526}526}
527527
528func (s *NovaSuite) TestAddSecurityGroupWithRules(c *C) {528func (s *NovaSuite) TestAddSecurityGroupWithRules(c *C) {
529 group := nova.SecurityGroup{529 group := nova.SecurityGroup{
530 Id: 1,530 Id: "1",
531 Name: "test",531 Name: "test",
532 TenantId: s.service.TenantId,532 TenantId: s.service.TenantId,
533 Rules: []nova.SecurityGroupRule{533 Rules: []nova.SecurityGroupRule{
534 {Id: 10, ParentGroupId: 1},534 {Id: "10", ParentGroupId: "1"},
535 {Id: 20, ParentGroupId: 1},535 {Id: "20", ParentGroupId: "1"},
536 },536 },
537 }537 }
538 s.createGroup(c, group)538 s.createGroup(c, group)
@@ -542,7 +542,7 @@
542}542}
543543
544func (s *NovaSuite) TestAddSecurityGroupTwiceFails(c *C) {544func (s *NovaSuite) TestAddSecurityGroupTwiceFails(c *C) {
545 group := nova.SecurityGroup{Id: 1, Name: "test"}545 group := nova.SecurityGroup{Id: "1", Name: "test"}
546 s.createGroup(c, group)546 s.createGroup(c, group)
547 defer s.deleteGroup(c, group)547 defer s.deleteGroup(c, group)
548 err := s.service.addSecurityGroup(group)548 err := s.service.addSecurityGroup(group)
@@ -550,7 +550,7 @@
550}550}
551551
552func (s *NovaSuite) TestRemoveSecurityGroupTwiceFails(c *C) {552func (s *NovaSuite) TestRemoveSecurityGroupTwiceFails(c *C) {
553 group := nova.SecurityGroup{Id: 1, Name: "test"}553 group := nova.SecurityGroup{Id: "1", Name: "test"}
554 s.createGroup(c, group)554 s.createGroup(c, group)
555 s.deleteGroup(c, group)555 s.deleteGroup(c, group)
556 err := s.service.removeSecurityGroup(group.Id)556 err := s.service.removeSecurityGroup(group.Id)
@@ -563,13 +563,13 @@
563 c.Assert(groups, HasLen, 1)563 c.Assert(groups, HasLen, 1)
564 groups = []nova.SecurityGroup{564 groups = []nova.SecurityGroup{
565 {565 {
566 Id: 1,566 Id: "1",
567 Name: "one",567 Name: "one",
568 TenantId: s.service.TenantId,568 TenantId: s.service.TenantId,
569 Rules: []nova.SecurityGroupRule{},569 Rules: []nova.SecurityGroupRule{},
570 },570 },
571 {571 {
572 Id: 2,572 Id: "2",
573 Name: "two",573 Name: "two",
574 TenantId: s.service.TenantId,574 TenantId: s.service.TenantId,
575 Rules: []nova.SecurityGroupRule{},575 Rules: []nova.SecurityGroupRule{},
@@ -586,7 +586,7 @@
586586
587func (s *NovaSuite) TestGetSecurityGroup(c *C) {587func (s *NovaSuite) TestGetSecurityGroup(c *C) {
588 group := nova.SecurityGroup{588 group := nova.SecurityGroup{
589 Id: 42,589 Id: "42",
590 TenantId: s.service.TenantId,590 TenantId: s.service.TenantId,
591 Name: "group",591 Name: "group",
592 Description: "desc",592 Description: "desc",
@@ -600,7 +600,7 @@
600600
601func (s *NovaSuite) TestGetSecurityGroupByName(c *C) {601func (s *NovaSuite) TestGetSecurityGroupByName(c *C) {
602 group := nova.SecurityGroup{602 group := nova.SecurityGroup{
603 Id: 1,603 Id: "1",
604 Name: "test",604 Name: "test",
605 TenantId: s.service.TenantId,605 TenantId: s.service.TenantId,
606 Rules: []nova.SecurityGroupRule{},606 Rules: []nova.SecurityGroupRule{},
@@ -616,9 +616,9 @@
616}616}
617617
618func (s *NovaSuite) TestAddHasRemoveSecurityGroupRule(c *C) {618func (s *NovaSuite) TestAddHasRemoveSecurityGroupRule(c *C) {
619 group := nova.SecurityGroup{Id: 1}619 group := nova.SecurityGroup{Id: "1"}
620 ri := nova.RuleInfo{ParentGroupId: group.Id}620 ri := nova.RuleInfo{ParentGroupId: group.Id}
621 rule := nova.SecurityGroupRule{Id: 10, ParentGroupId: group.Id}621 rule := nova.SecurityGroupRule{Id: "10", ParentGroupId: group.Id}
622 s.ensureNoGroup(c, group)622 s.ensureNoGroup(c, group)
623 s.ensureNoRule(c, rule)623 s.ensureNoRule(c, rule)
624 ok := s.service.hasSecurityGroupRule(group.Id, rule.Id)624 ok := s.service.hasSecurityGroupRule(group.Id, rule.Id)
@@ -629,17 +629,17 @@
629 ok = s.service.hasSecurityGroupRule(group.Id, rule.Id)629 ok = s.service.hasSecurityGroupRule(group.Id, rule.Id)
630 c.Assert(ok, Equals, true)630 c.Assert(ok, Equals, true)
631 s.deleteGroup(c, group)631 s.deleteGroup(c, group)
632 ok = s.service.hasSecurityGroupRule(-1, rule.Id)632 ok = s.service.hasSecurityGroupRule("-1", rule.Id)
633 c.Assert(ok, Equals, true)633 c.Assert(ok, Equals, true)
634 ok = s.service.hasSecurityGroupRule(group.Id, rule.Id)634 ok = s.service.hasSecurityGroupRule(group.Id, rule.Id)
635 c.Assert(ok, Equals, false)635 c.Assert(ok, Equals, false)
636 s.deleteRule(c, rule)636 s.deleteRule(c, rule)
637 ok = s.service.hasSecurityGroupRule(-1, rule.Id)637 ok = s.service.hasSecurityGroupRule("-1", rule.Id)
638 c.Assert(ok, Equals, false)638 c.Assert(ok, Equals, false)
639}639}
640640
641func (s *NovaSuite) TestAddGetIngressSecurityGroupRule(c *C) {641func (s *NovaSuite) TestAddGetIngressSecurityGroupRule(c *C) {
642 group := nova.SecurityGroup{Id: 1}642 group := nova.SecurityGroup{Id: "1"}
643 s.createGroup(c, group)643 s.createGroup(c, group)
644 defer s.deleteGroup(c, group)644 defer s.deleteGroup(c, group)
645 ri := nova.RuleInfo{645 ri := nova.RuleInfo{
@@ -650,7 +650,7 @@
650 ParentGroupId: group.Id,650 ParentGroupId: group.Id,
651 }651 }
652 rule := nova.SecurityGroupRule{652 rule := nova.SecurityGroupRule{
653 Id: 10,653 Id: "10",
654 ParentGroupId: group.Id,654 ParentGroupId: group.Id,
655 FromPort: &ri.FromPort,655 FromPort: &ri.FromPort,
656 ToPort: &ri.ToPort,656 ToPort: &ri.ToPort,
@@ -673,8 +673,8 @@
673}673}
674674
675func (s *NovaSuite) TestAddGetGroupSecurityGroupRule(c *C) {675func (s *NovaSuite) TestAddGetGroupSecurityGroupRule(c *C) {
676 srcGroup := nova.SecurityGroup{Id: 1, Name: "source", TenantId: s.service.TenantId}676 srcGroup := nova.SecurityGroup{Id: "1", Name: "source", TenantId: s.service.TenantId}
677 tgtGroup := nova.SecurityGroup{Id: 2, Name: "target"}677 tgtGroup := nova.SecurityGroup{Id: "2", Name: "target"}
678 s.createGroup(c, srcGroup)678 s.createGroup(c, srcGroup)
679 defer s.deleteGroup(c, srcGroup)679 defer s.deleteGroup(c, srcGroup)
680 s.createGroup(c, tgtGroup)680 s.createGroup(c, tgtGroup)
@@ -687,7 +687,7 @@
687 ParentGroupId: tgtGroup.Id,687 ParentGroupId: tgtGroup.Id,
688 }688 }
689 rule := nova.SecurityGroupRule{689 rule := nova.SecurityGroupRule{
690 Id: 10,690 Id: "10",
691 ParentGroupId: tgtGroup.Id,691 ParentGroupId: tgtGroup.Id,
692 FromPort: &ri.FromPort,692 FromPort: &ri.FromPort,
693 ToPort: &ri.ToPort,693 ToPort: &ri.ToPort,
@@ -712,11 +712,11 @@
712}712}
713713
714func (s *NovaSuite) TestAddSecurityGroupRuleTwiceFails(c *C) {714func (s *NovaSuite) TestAddSecurityGroupRuleTwiceFails(c *C) {
715 group := nova.SecurityGroup{Id: 1}715 group := nova.SecurityGroup{Id: "1"}
716 s.createGroup(c, group)716 s.createGroup(c, group)
717 defer s.deleteGroup(c, group)717 defer s.deleteGroup(c, group)
718 ri := nova.RuleInfo{ParentGroupId: group.Id}718 ri := nova.RuleInfo{ParentGroupId: group.Id}
719 rule := nova.SecurityGroupRule{Id: 10}719 rule := nova.SecurityGroupRule{Id: "10"}
720 s.ensureNoRule(c, rule)720 s.ensureNoRule(c, rule)
721 err := s.service.addSecurityGroupRule(rule.Id, ri)721 err := s.service.addSecurityGroupRule(rule.Id, ri)
722 c.Assert(err, IsNil)722 c.Assert(err, IsNil)
@@ -727,39 +727,39 @@
727727
728func (s *NovaSuite) TestAddSecurityGroupRuleToParentTwiceFails(c *C) {728func (s *NovaSuite) TestAddSecurityGroupRuleToParentTwiceFails(c *C) {
729 group := nova.SecurityGroup{729 group := nova.SecurityGroup{
730 Id: 1,730 Id: "1",
731 Rules: []nova.SecurityGroupRule{731 Rules: []nova.SecurityGroupRule{
732 {Id: 10},732 {Id: "10"},
733 },733 },
734 }734 }
735 s.createGroup(c, group)735 s.createGroup(c, group)
736 defer s.deleteGroup(c, group)736 defer s.deleteGroup(c, group)
737 ri := nova.RuleInfo{ParentGroupId: group.Id}737 ri := nova.RuleInfo{ParentGroupId: group.Id}
738 rule := nova.SecurityGroupRule{Id: 10}738 rule := nova.SecurityGroupRule{Id: "10"}
739 err := s.service.addSecurityGroupRule(rule.Id, ri)739 err := s.service.addSecurityGroupRule(rule.Id, ri)
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")
741}741}
742742
743func (s *NovaSuite) TestAddSecurityGroupRuleWithInvalidParentFails(c *C) {743func (s *NovaSuite) TestAddSecurityGroupRuleWithInvalidParentFails(c *C) {
744 invalidGroup := nova.SecurityGroup{Id: 1}744 invalidGroup := nova.SecurityGroup{Id: "1"}
745 s.ensureNoGroup(c, invalidGroup)745 s.ensureNoGroup(c, invalidGroup)
746 ri := nova.RuleInfo{ParentGroupId: invalidGroup.Id}746 ri := nova.RuleInfo{ParentGroupId: invalidGroup.Id}
747 rule := nova.SecurityGroupRule{Id: 10}747 rule := nova.SecurityGroupRule{Id: "10"}
748 s.ensureNoRule(c, rule)748 s.ensureNoRule(c, rule)
749 err := s.service.addSecurityGroupRule(rule.Id, ri)749 err := s.service.addSecurityGroupRule(rule.Id, ri)
750 c.Assert(err, ErrorMatches, "no such security group 1")750 c.Assert(err, ErrorMatches, "no such security group 1")
751}751}
752752
753func (s *NovaSuite) TestAddGroupSecurityGroupRuleWithInvalidSourceFails(c *C) {753func (s *NovaSuite) TestAddGroupSecurityGroupRuleWithInvalidSourceFails(c *C) {
754 group := nova.SecurityGroup{Id: 1}754 group := nova.SecurityGroup{Id: "1"}
755 s.createGroup(c, group)755 s.createGroup(c, group)
756 defer s.deleteGroup(c, group)756 defer s.deleteGroup(c, group)
757 invalidGroupId := 42757 invalidGroupId := "42"
758 ri := nova.RuleInfo{758 ri := nova.RuleInfo{
759 ParentGroupId: group.Id,759 ParentGroupId: group.Id,
760 GroupId: &invalidGroupId,760 GroupId: &invalidGroupId,
761 }761 }
762 rule := nova.SecurityGroupRule{Id: 10}762 rule := nova.SecurityGroupRule{Id: "10"}
763 s.ensureNoRule(c, rule)763 s.ensureNoRule(c, rule)
764 err := s.service.addSecurityGroupRule(rule.Id, ri)764 err := s.service.addSecurityGroupRule(rule.Id, ri)
765 c.Assert(err, ErrorMatches, "unknown source security group 42")765 c.Assert(err, ErrorMatches, "unknown source security group 42")
@@ -767,7 +767,7 @@
767767
768func (s *NovaSuite) TestAddSecurityGroupRuleUpdatesParent(c *C) {768func (s *NovaSuite) TestAddSecurityGroupRuleUpdatesParent(c *C) {
769 group := nova.SecurityGroup{769 group := nova.SecurityGroup{
770 Id: 1,770 Id: "1",
771 Name: "test",771 Name: "test",
772 TenantId: s.service.TenantId,772 TenantId: s.service.TenantId,
773 }773 }
@@ -775,7 +775,7 @@
775 defer s.deleteGroup(c, group)775 defer s.deleteGroup(c, group)
776 ri := nova.RuleInfo{ParentGroupId: group.Id}776 ri := nova.RuleInfo{ParentGroupId: group.Id}
777 rule := nova.SecurityGroupRule{777 rule := nova.SecurityGroupRule{
778 Id: 10,778 Id: "10",
779 ParentGroupId: group.Id,779 ParentGroupId: group.Id,
780 Group: nova.SecurityGroupRef{},780 Group: nova.SecurityGroupRef{},
781 }781 }
@@ -791,7 +791,7 @@
791791
792func (s *NovaSuite) TestAddSecurityGroupRuleKeepsNegativePort(c *C) {792func (s *NovaSuite) TestAddSecurityGroupRuleKeepsNegativePort(c *C) {
793 group := nova.SecurityGroup{793 group := nova.SecurityGroup{
794 Id: 1,794 Id: "1",
795 Name: "test",795 Name: "test",
796 TenantId: s.service.TenantId,796 TenantId: s.service.TenantId,
797 }797 }
@@ -805,7 +805,7 @@
805 ParentGroupId: group.Id,805 ParentGroupId: group.Id,
806 }806 }
807 rule := nova.SecurityGroupRule{807 rule := nova.SecurityGroupRule{
808 Id: 10,808 Id: "10",
809 ParentGroupId: group.Id,809 ParentGroupId: group.Id,
810 FromPort: &ri.FromPort,810 FromPort: &ri.FromPort,
811 ToPort: &ri.ToPort,811 ToPort: &ri.ToPort,
@@ -822,11 +822,11 @@
822}822}
823823
824func (s *NovaSuite) TestRemoveSecurityGroupRuleTwiceFails(c *C) {824func (s *NovaSuite) TestRemoveSecurityGroupRuleTwiceFails(c *C) {
825 group := nova.SecurityGroup{Id: 1}825 group := nova.SecurityGroup{Id: "1"}
826 s.createGroup(c, group)826 s.createGroup(c, group)
827 defer s.deleteGroup(c, group)827 defer s.deleteGroup(c, group)
828 ri := nova.RuleInfo{ParentGroupId: group.Id}828 ri := nova.RuleInfo{ParentGroupId: group.Id}
829 rule := nova.SecurityGroupRule{Id: 10}829 rule := nova.SecurityGroupRule{Id: "10"}
830 s.ensureNoRule(c, rule)830 s.ensureNoRule(c, rule)
831 err := s.service.addSecurityGroupRule(rule.Id, ri)831 err := s.service.addSecurityGroupRule(rule.Id, ri)
832 c.Assert(err, IsNil)832 c.Assert(err, IsNil)
@@ -837,7 +837,7 @@
837837
838func (s *NovaSuite) TestAddHasRemoveServerSecurityGroup(c *C) {838func (s *NovaSuite) TestAddHasRemoveServerSecurityGroup(c *C) {
839 server := nova.ServerDetail{Id: "sr1"}839 server := nova.ServerDetail{Id: "sr1"}
840 group := nova.SecurityGroup{Id: 1}840 group := nova.SecurityGroup{Id: "1"}
841 s.ensureNoServer(c, server)841 s.ensureNoServer(c, server)
842 s.ensureNoGroup(c, group)842 s.ensureNoGroup(c, group)
843 ok := s.service.hasServerSecurityGroup(server.Id, group.Id)843 ok := s.service.hasServerSecurityGroup(server.Id, group.Id)
@@ -862,7 +862,7 @@
862862
863func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidServerFails(c *C) {863func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidServerFails(c *C) {
864 server := nova.ServerDetail{Id: "sr1"}864 server := nova.ServerDetail{Id: "sr1"}
865 group := nova.SecurityGroup{Id: 1}865 group := nova.SecurityGroup{Id: "1"}
866 s.ensureNoServer(c, server)866 s.ensureNoServer(c, server)
867 s.createGroup(c, group)867 s.createGroup(c, group)
868 defer s.deleteGroup(c, group)868 defer s.deleteGroup(c, group)
@@ -871,7 +871,7 @@
871}871}
872872
873func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidGroupFails(c *C) {873func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidGroupFails(c *C) {
874 group := nova.SecurityGroup{Id: 1}874 group := nova.SecurityGroup{Id: "1"}
875 server := nova.ServerDetail{Id: "sr1"}875 server := nova.ServerDetail{Id: "sr1"}
876 s.ensureNoGroup(c, group)876 s.ensureNoGroup(c, group)
877 s.createServer(c, server)877 s.createServer(c, server)
@@ -882,7 +882,7 @@
882882
883func (s *NovaSuite) TestAddServerSecurityGroupTwiceFails(c *C) {883func (s *NovaSuite) TestAddServerSecurityGroupTwiceFails(c *C) {
884 server := nova.ServerDetail{Id: "sr1"}884 server := nova.ServerDetail{Id: "sr1"}
885 group := nova.SecurityGroup{Id: 1}885 group := nova.SecurityGroup{Id: "1"}
886 s.createServer(c, server)886 s.createServer(c, server)
887 defer s.deleteServer(c, server)887 defer s.deleteServer(c, server)
888 s.createGroup(c, group)888 s.createGroup(c, group)
@@ -903,13 +903,13 @@
903 defer s.deleteServer(c, server)903 defer s.deleteServer(c, server)
904 groups := []nova.SecurityGroup{904 groups := []nova.SecurityGroup{
905 {905 {
906 Id: 1,906 Id: "1",
907 Name: "gr1",907 Name: "gr1",
908 TenantId: s.service.TenantId,908 TenantId: s.service.TenantId,
909 Rules: []nova.SecurityGroupRule{},909 Rules: []nova.SecurityGroupRule{},
910 },910 },
911 {911 {
912 Id: 2,912 Id: "2",
913 Name: "gr2",913 Name: "gr2",
914 TenantId: s.service.TenantId,914 TenantId: s.service.TenantId,
915 Rules: []nova.SecurityGroupRule{},915 Rules: []nova.SecurityGroupRule{},
@@ -932,7 +932,7 @@
932932
933func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidServerFails(c *C) {933func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidServerFails(c *C) {
934 server := nova.ServerDetail{Id: "sr1"}934 server := nova.ServerDetail{Id: "sr1"}
935 group := nova.SecurityGroup{Id: 1}935 group := nova.SecurityGroup{Id: "1"}
936 s.createServer(c, server)936 s.createServer(c, server)
937 s.createGroup(c, group)937 s.createGroup(c, group)
938 defer s.deleteGroup(c, group)938 defer s.deleteGroup(c, group)
@@ -948,7 +948,7 @@
948}948}
949949
950func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidGroupFails(c *C) {950func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidGroupFails(c *C) {
951 group := nova.SecurityGroup{Id: 1}951 group := nova.SecurityGroup{Id: "1"}
952 server := nova.ServerDetail{Id: "sr1"}952 server := nova.ServerDetail{Id: "sr1"}
953 s.createGroup(c, group)953 s.createGroup(c, group)
954 s.createServer(c, server)954 s.createServer(c, server)
@@ -966,7 +966,7 @@
966966
967func (s *NovaSuite) TestRemoveServerSecurityGroupTwiceFails(c *C) {967func (s *NovaSuite) TestRemoveServerSecurityGroupTwiceFails(c *C) {
968 server := nova.ServerDetail{Id: "sr1"}968 server := nova.ServerDetail{Id: "sr1"}
969 group := nova.SecurityGroup{Id: 1}969 group := nova.SecurityGroup{Id: "1"}
970 s.createServer(c, server)970 s.createServer(c, server)
971 defer s.deleteServer(c, server)971 defer s.deleteServer(c, server)
972 s.createGroup(c, group)972 s.createGroup(c, group)
@@ -980,7 +980,7 @@
980}980}
981981
982func (s *NovaSuite) TestAddHasRemoveFloatingIP(c *C) {982func (s *NovaSuite) TestAddHasRemoveFloatingIP(c *C) {
983 ip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"}983 ip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
984 s.ensureNoIP(c, ip)984 s.ensureNoIP(c, ip)
985 ok := s.service.hasFloatingIP(ip.IP)985 ok := s.service.hasFloatingIP(ip.IP)
986 c.Assert(ok, Equals, false)986 c.Assert(ok, Equals, false)
@@ -995,7 +995,7 @@
995}995}
996996
997func (s *NovaSuite) TestAddFloatingIPTwiceFails(c *C) {997func (s *NovaSuite) TestAddFloatingIPTwiceFails(c *C) {
998 ip := nova.FloatingIP{Id: 1}998 ip := nova.FloatingIP{Id: "1"}
999 s.createIP(c, ip)999 s.createIP(c, ip)
1000 defer s.deleteIP(c, ip)1000 defer s.deleteIP(c, ip)
1001 err := s.service.addFloatingIP(ip)1001 err := s.service.addFloatingIP(ip)
@@ -1003,7 +1003,7 @@
1003}1003}
10041004
1005func (s *NovaSuite) TestRemoveFloatingIPTwiceFails(c *C) {1005func (s *NovaSuite) TestRemoveFloatingIPTwiceFails(c *C) {
1006 ip := nova.FloatingIP{Id: 1}1006 ip := nova.FloatingIP{Id: "1"}
1007 s.createIP(c, ip)1007 s.createIP(c, ip)
1008 s.deleteIP(c, ip)1008 s.deleteIP(c, ip)
1009 err := s.service.removeFloatingIP(ip.Id)1009 err := s.service.removeFloatingIP(ip.Id)
@@ -1014,8 +1014,8 @@
1014 fips := s.service.allFloatingIPs()1014 fips := s.service.allFloatingIPs()
1015 c.Assert(fips, HasLen, 0)1015 c.Assert(fips, HasLen, 0)
1016 fips = []nova.FloatingIP{1016 fips = []nova.FloatingIP{
1017 {Id: 1},1017 {Id: "1"},
1018 {Id: 2},1018 {Id: "2"},
1019 }1019 }
1020 s.createIP(c, fips[0])1020 s.createIP(c, fips[0])
1021 defer s.deleteIP(c, fips[0])1021 defer s.deleteIP(c, fips[0])
@@ -1033,7 +1033,7 @@
1033 inst := "sr1"1033 inst := "sr1"
1034 fixedIP := "4.3.2.1"1034 fixedIP := "4.3.2.1"
1035 fip := nova.FloatingIP{1035 fip := nova.FloatingIP{
1036 Id: 1,1036 Id: "1",
1037 IP: "1.2.3.4",1037 IP: "1.2.3.4",
1038 Pool: "pool",1038 Pool: "pool",
1039 InstanceId: &inst,1039 InstanceId: &inst,
@@ -1046,7 +1046,7 @@
1046}1046}
10471047
1048func (s *NovaSuite) TestGetFloatingIPByAddr(c *C) {1048func (s *NovaSuite) TestGetFloatingIPByAddr(c *C) {
1049 fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"}1049 fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
1050 s.ensureNoIP(c, fip)1050 s.ensureNoIP(c, fip)
1051 ip, err := s.service.floatingIPByAddr(fip.IP)1051 ip, err := s.service.floatingIPByAddr(fip.IP)
1052 c.Assert(err, NotNil)1052 c.Assert(err, NotNil)
@@ -1061,7 +1061,7 @@
10611061
1062func (s *NovaSuite) TestAddHasRemoveServerFloatingIP(c *C) {1062func (s *NovaSuite) TestAddHasRemoveServerFloatingIP(c *C) {
1063 server := nova.ServerDetail{Id: "sr1"}1063 server := nova.ServerDetail{Id: "sr1"}
1064 fip := nova.FloatingIP{Id: 1, IP: "1.2.3.4"}1064 fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
1065 s.ensureNoServer(c, server)1065 s.ensureNoServer(c, server)
1066 s.ensureNoIP(c, fip)1066 s.ensureNoIP(c, fip)
1067 ok := s.service.hasServerFloatingIP(server.Id, fip.IP)1067 ok := s.service.hasServerFloatingIP(server.Id, fip.IP)
@@ -1086,7 +1086,7 @@
10861086
1087func (s *NovaSuite) TestAddServerFloatingIPWithInvalidServerFails(c *C) {1087func (s *NovaSuite) TestAddServerFloatingIPWithInvalidServerFails(c *C) {
1088 server := nova.ServerDetail{Id: "sr1"}1088 server := nova.ServerDetail{Id: "sr1"}
1089 fip := nova.FloatingIP{Id: 1}1089 fip := nova.FloatingIP{Id: "1"}
1090 s.ensureNoServer(c, server)1090 s.ensureNoServer(c, server)
1091 s.createIP(c, fip)1091 s.createIP(c, fip)
1092 defer s.deleteIP(c, fip)1092 defer s.deleteIP(c, fip)
@@ -1095,7 +1095,7 @@
1095}1095}
10961096
1097func (s *NovaSuite) TestAddServerFloatingIPWithInvalidIPFails(c *C) {1097func (s *NovaSuite) TestAddServerFloatingIPWithInvalidIPFails(c *C) {
1098 fip := nova.FloatingIP{Id: 1}1098 fip := nova.FloatingIP{Id: "1"}
1099 server := nova.ServerDetail{Id: "sr1"}1099 server := nova.ServerDetail{Id: "sr1"}
1100 s.ensureNoIP(c, fip)1100 s.ensureNoIP(c, fip)
1101 s.createServer(c, server)1101 s.createServer(c, server)
@@ -1106,7 +1106,7 @@
11061106
1107func (s *NovaSuite) TestAddServerFloatingIPTwiceFails(c *C) {1107func (s *NovaSuite) TestAddServerFloatingIPTwiceFails(c *C) {
1108 server := nova.ServerDetail{Id: "sr1"}1108 server := nova.ServerDetail{Id: "sr1"}
1109 fip := nova.FloatingIP{Id: 1}1109 fip := nova.FloatingIP{Id: "1"}
1110 s.createServer(c, server)1110 s.createServer(c, server)
1111 defer s.deleteServer(c, server)1111 defer s.deleteServer(c, server)
1112 s.createIP(c, fip)1112 s.createIP(c, fip)
@@ -1121,7 +1121,7 @@
11211121
1122func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidServerFails(c *C) {1122func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidServerFails(c *C) {
1123 server := nova.ServerDetail{Id: "sr1"}1123 server := nova.ServerDetail{Id: "sr1"}
1124 fip := nova.FloatingIP{Id: 1}1124 fip := nova.FloatingIP{Id: "1"}
1125 s.createServer(c, server)1125 s.createServer(c, server)
1126 s.createIP(c, fip)1126 s.createIP(c, fip)
1127 defer s.deleteIP(c, fip)1127 defer s.deleteIP(c, fip)
@@ -1137,7 +1137,7 @@
1137}1137}
11381138
1139func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidIPFails(c *C) {1139func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidIPFails(c *C) {
1140 fip := nova.FloatingIP{Id: 1}1140 fip := nova.FloatingIP{Id: "1"}
1141 server := nova.ServerDetail{Id: "sr1"}1141 server := nova.ServerDetail{Id: "sr1"}
1142 s.createIP(c, fip)1142 s.createIP(c, fip)
1143 s.createServer(c, server)1143 s.createServer(c, server)
@@ -1155,7 +1155,7 @@
11551155
1156func (s *NovaSuite) TestRemoveServerFloatingIPTwiceFails(c *C) {1156func (s *NovaSuite) TestRemoveServerFloatingIPTwiceFails(c *C) {
1157 server := nova.ServerDetail{Id: "sr1"}1157 server := nova.ServerDetail{Id: "sr1"}
1158 fip := nova.FloatingIP{Id: 1}1158 fip := nova.FloatingIP{Id: "1"}
1159 s.createServer(c, server)1159 s.createServer(c, server)
1160 defer s.deleteServer(c, server)1160 defer s.deleteServer(c, server)
1161 s.createIP(c, fip)1161 s.createIP(c, fip)
11621162
=== modified file 'testservices/openstackservice/openstack.go'
--- testservices/openstackservice/openstack.go 2013-02-08 02:23:27 +0000
+++ testservices/openstackservice/openstack.go 2013-07-01 07:24:26 +0000
@@ -1,6 +1,7 @@
1package openstackservice1package openstackservice
22
3import (3import (
4 "fmt"
4 "launchpad.net/goose/identity"5 "launchpad.net/goose/identity"
5 "launchpad.net/goose/testservices/identityservice"6 "launchpad.net/goose/testservices/identityservice"
6 "launchpad.net/goose/testservices/novaservice"7 "launchpad.net/goose/testservices/novaservice"
@@ -18,9 +19,16 @@
1819
19// New creates an instance of a full Openstack service double.20// New creates an instance of a full Openstack service double.
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.
21func New(cred *identity.Credentials) *Openstack {22func New(cred *identity.Credentials, authMode identity.AuthMode) *Openstack {
22 openstack := Openstack{23 var openstack Openstack
23 Identity: identityservice.NewUserPass(),24 if authMode == identity.AuthKeyPair {
25 openstack = Openstack{
26 Identity: identityservice.NewKeyPair(),
27 }
28 } else {
29 openstack = Openstack{
30 Identity: identityservice.NewUserPass(),
31 }
24 }32 }
25 userInfo := openstack.Identity.AddUser(cred.User, cred.Secrets, cred.TenantName)33 userInfo := openstack.Identity.AddUser(cred.User, cred.Secrets, cred.TenantName)
26 if cred.TenantName == "" {34 if cred.TenantName == "" {
@@ -31,6 +39,22 @@
31 regionParts := strings.Split(cred.Region, ".")39 regionParts := strings.Split(cred.Region, ".")
32 baseRegion := regionParts[len(regionParts)-1]40 baseRegion := regionParts[len(regionParts)-1]
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)
42 // Create container and add image metadata endpoint so that product-streams URLs are included
43 // in the keystone catalog.
44 err := openstack.Swift.AddContainer("imagemetadata")
45 if err != nil {
46 panic(fmt.Errorf("setting up image metadata container: %v", err))
47 }
48 url := openstack.Swift.Endpoints()[0].PublicURL
49 serviceDef := identityservice.Service{"simplestreams", "product-streams", []identityservice.Endpoint{
50 identityservice.Endpoint{PublicURL: url + "/imagemetadata", Region: cred.Region},
51 }}
52 openstack.Identity.AddService(serviceDef)
53 // Add public bucket endpoint so that juju-tools URLs are included in the keystone catalog.
54 serviceDef = identityservice.Service{"juju", "juju-tools", []identityservice.Endpoint{
55 identityservice.Endpoint{PublicURL: url, Region: cred.Region},
56 }}
57 openstack.Identity.AddService(serviceDef)
34 return &openstack58 return &openstack
35}59}
3660
3761
=== modified file 'tools/secgroup-delete-all/main_test.go'
--- tools/secgroup-delete-all/main_test.go 2013-02-20 06:00:49 +0000
+++ tools/secgroup-delete-all/main_test.go 2013-07-01 07:24:26 +0000
@@ -46,7 +46,7 @@
46 Region: region,46 Region: region,
47 TenantName: tenant,47 TenantName: tenant,
48 }48 }
49 openstack := openstackservice.New(creds)49 openstack := openstackservice.New(creds, identity.AuthUserPass)
50 openstack.SetupHTTP(s.Mux)50 openstack.SetupHTTP(s.Mux)
51 return openstack, createNovaClient(creds)51 return openstack, createNovaClient(creds)
52}52}
@@ -74,7 +74,7 @@
7474
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.
76func deleteGroupError(s hook.ServiceControl, args ...interface{}) error {76func deleteGroupError(s hook.ServiceControl, args ...interface{}) error {
77 groupId := args[0].(int)77 groupId := args[0].(string)
78 if groupId == doNotDelete.Id {78 if groupId == doNotDelete.Id {
79 return fmt.Errorf("cannot delete group %d", groupId)79 return fmt.Errorf("cannot delete group %d", groupId)
80 }80 }
8181
=== modified file 'version.go'
--- version.go 2013-02-05 13:22:51 +0000
+++ version.go 2013-07-01 07:24:26 +0000
@@ -1,3 +1,6 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the LGPLv3, see COPYING and COPYING.LESSER file for details.
3
1package goose4package goose
25
3import (6import (
47
=== modified file 'version_test.go'
--- version_test.go 2013-02-05 13:37:45 +0000
+++ version_test.go 2013-07-01 07:24:26 +0000
@@ -1,3 +1,6 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the LGPLv3, see COPYING and COPYING.LESSER file for details.
3
1package goose4package goose
25
3import (6import (

Subscribers

People subscribed via source and target branches