diff --git a/cinder/autogenerated_client.go b/cinder/autogenerated_client.go index 2169f15..0f73f3c 100644 --- a/cinder/autogenerated_client.go +++ b/cinder/autogenerated_client.go @@ -17,6 +17,7 @@ import ( "net/url" "gopkg.in/goose.v2/client" + gooseerrors "gopkg.in/goose.v2/errors" goosehttp "gopkg.in/goose.v2/http" ) @@ -1667,3 +1668,58 @@ func updateVolumeMetadata(client *Client, volumeId string, args *UpdateVolumeMet return &results, nil } + +// GetAvailabilityZonesResults holds the result of getting availability zones. +type GetAvailabilityZonesResults struct { + AvailabilityZoneInfo []AvailabilityZone +} + +// AvailabilityZone identifies an availability zone, and describes its state. +type AvailabilityZone struct { + Name string `json:"zoneName"` + State AvailabilityZoneState `json:"zoneState"` +} + +// AvailabilityZoneState describes an availability zone's state. +type AvailabilityZoneState struct { + Available bool +} + +// +// Lists volume availability zones. +func listAvailabilityZones(client *Client) (*GetAvailabilityZonesResults, error) { + + urlPath := url.URL{Path: "os-availability-zone"} + url := client.endpoint.ResolveReference(&urlPath).String() + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + + resp, err := client.handleRequest(req) + if err != nil { + return nil, err + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + switch resp.StatusCode { + default: + return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) + case 400, 404: + return nil, gooseerrors.NewNotImplementedf( + err, nil, "the server does not support availability zones for volumes", + ) + case 200: + break + } + + var results GetAvailabilityZonesResults + json.Unmarshal(body, &results) + + return &results, nil +} diff --git a/cinder/client.go b/cinder/client.go index 7bd5636..33a2936 100644 --- a/cinder/client.go +++ b/cinder/client.go @@ -10,6 +10,7 @@ import ( "net/url" "time" + "gopkg.in/goose.v2/errors" goosehttp "gopkg.in/goose.v2/http" ) @@ -341,3 +342,12 @@ func (c *Client) SetVolumeMetadata(volumeId string, metadata map[string]string) } return response.Metadata, nil } + +// ListVolumeAvailabilityZones lists any volume availability zones. +func (c *Client) ListVolumeAvailabilityZones() ([]AvailabilityZone, error) { + resp, err := listAvailabilityZones(c) + if err != nil { + return nil, errors.Newf(err, "failed to get list of availability zones") + } + return resp.AvailabilityZoneInfo, nil +} diff --git a/cinder/client_test.go b/cinder/client_test.go index 6cd65a5..f2d59e1 100644 --- a/cinder/client_test.go +++ b/cinder/client_test.go @@ -802,12 +802,42 @@ func (s *CinderTestSuite) TestGetVolumeTypes(c *gc.C) { c.Check(volumeType.ID, gc.Equals, testId) } +func (s *CinderTestSuite) TestGetAvailabilityZones(c *gc.C) { + + numCalls := 0 + s.HandleFunc("/v2/"+testId+"/os-availability-zone", func(w http.ResponseWriter, req *http.Request) { + numCalls++ + + resp := []AvailabilityZone{{ + Name: "zone-1", + State: AvailabilityZoneState{ + Available: true, + }, + }} + + respBody, err := json.Marshal(&GetAvailabilityZonesResults{AvailabilityZoneInfo: resp}) + c.Assert(err, gc.IsNil) + + w.(*responseWriter).StatusCode = 200 + w.(*responseWriter).Body = ioutil.NopCloser(bytes.NewBuffer(respBody)) + }) + + zones, err := s.client.ListVolumeAvailabilityZones() + c.Assert(numCalls, gc.Equals, 1) + c.Assert(err, gc.IsNil) + c.Assert(zones, gc.HasLen, 1) + + zone := zones[0] + + c.Check(zone.Name, gc.Equals, "zone-1") + c.Check(zone.State.Available, gc.Equals, true) +} + func (s *CinderTestSuite) localDo(req *http.Request) (*http.Response, error) { handler, matchedPattern := s.Handler(req) if matchedPattern == "" { return nil, fmt.Errorf("no test handler registered for %s", req.URL.Path) } - fmt.Println(matchedPattern) var response http.Response handler.ServeHTTP(&responseWriter{&response}, req) diff --git a/cinder/package_test.go b/cinder/package_test.go index 8d8f8a2..c3dd65d 100644 --- a/cinder/package_test.go +++ b/cinder/package_test.go @@ -14,10 +14,6 @@ var ( live = flag.Bool("live", false, "Include live OpenStack tests") ) -func init() { - flag.Parse() -} - func Test(t *testing.T) { gc.TestingT(t) }