Skip to content

Commit

Permalink
Compute availability zones info support (#704)
Browse files Browse the repository at this point in the history
* Availability zones info support (#320)

Add ability to get list and detailed AZs info

* Style fixes

* Change test fixture to proper

* Delete useless method of `ServerAvailabilityZoneExt`

* Code improvements

* Change `AvailabilityZoneInfo` type from `struct` to `slice`
* Add custom `UnmarshalJSON` to `AvailabilityZoneInfo`
* Get rid of 'OS' prefixes in variable's names

* Update doc.go

* Code refactoring

* Rename `ServiceOfState` to `ServiceState`
* Change type `Services` from `struct` to `map[string]ServiceState`
* Delete useless type `AvailabilityZoneInfo`
* Update doc.go

* Acceptance tests for #704

* Change struct tag `updated_at` to `-`
  • Loading branch information
dstdfx authored and jtopjian committed Jan 8, 2018
1 parent fe4853e commit b2bf8a6
Show file tree
Hide file tree
Showing 8 changed files with 425 additions and 8 deletions.
53 changes: 53 additions & 0 deletions acceptance/openstack/compute/v2/availabilityzones_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// +build acceptance compute availabilityzones

package v2

import (
"testing"

"github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/acceptance/tools"
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones"
)

func TestAvailabilityZonesList(t *testing.T) {
client, err := clients.NewComputeV2Client()
if err != nil {
t.Fatalf("Unable to create a compute client: %v", err)
}

allPages, err := availabilityzones.List(client).AllPages()
if err != nil {
t.Fatalf("Unable to list availability zones info: %v", err)
}

availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages)
if err != nil {
t.Fatalf("Unable to extract availability zones info: %v", err)
}

for _, zoneInfo := range availabilityZoneInfo {
tools.PrintResource(t, zoneInfo)
}
}

func TestAvailabilityZonesListDetail(t *testing.T) {
client, err := clients.NewComputeV2Client()
if err != nil {
t.Fatalf("Unable to create a compute client: %v", err)
}

allPages, err := availabilityzones.ListDetail(client).AllPages()
if err != nil {
t.Fatalf("Unable to list availability zones detailed info: %v", err)
}

availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages)
if err != nil {
t.Fatalf("Unable to extract availability zones detailed info: %v", err)
}

for _, zoneInfo := range availabilityZoneInfo {
tools.PrintResource(t, zoneInfo)
}
}
43 changes: 37 additions & 6 deletions openstack/compute/v2/extensions/availabilityzones/doc.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,57 @@
/*
Package availabilityzones provides the ability to extend a server result with
availability zone information. Example:
Package availabilityzones provides the ability to get lists and detailed
availability zone information and to extend a server result with
availability zone information.
Example of Extend server result with Availability Zone Information:
type ServerWithAZ struct {
servers.Server
availabilityzones.ServerAvailabilityZoneExt
}
var allServers []ServerWithAZ
allPages, err := servers.List(client, nil).AllPages()
if err != nil {
panic("Unable to retrieve servers: %s", err)
}
err = servers.ExtractServersInto(allPages, &allServers)
if err != nil {
panic("Unable to extract servers: %s", err)
}
for _, server := range allServers {
fmt.Println(server.AvailabilityZone)
}
Example of Get Availability Zone Information
allPages, err := availabilityzones.List(computeClient).AllPages()
if err != nil {
panic(err)
}
availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages)
if err != nil {
panic(err)
}
for _, zoneInfo := range availabilityZoneInfo {
fmt.Printf("%+v\n", zoneInfo)
}
Example of Get Detailed Availability Zone Information
allPages, err := availabilityzones.ListDetail(computeClient).AllPages()
if err != nil {
panic(err)
}
availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages)
if err != nil {
panic(err)
}
for _, zoneInfo := range availabilityZoneInfo {
fmt.Printf("%+v\n", zoneInfo)
}
*/
package availabilityzones
20 changes: 20 additions & 0 deletions openstack/compute/v2/extensions/availabilityzones/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package availabilityzones

import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)

// List will return the existing availability zones.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
return AvailabilityZonePage{pagination.SinglePageBase(r)}
})
}

// ListDetail will return the existing availability zones with detailed information.
func ListDetail(client *gophercloud.ServiceClient) pagination.Pager {
return pagination.NewPager(client, listDetailURL(client), func(r pagination.PageResult) pagination.Page {
return AvailabilityZonePage{pagination.SinglePageBase(r)}
})
}
66 changes: 64 additions & 2 deletions openstack/compute/v2/extensions/availabilityzones/results.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,70 @@
package availabilityzones

// ServerAvailabilityZoneExt is an extension to the base Server result which
// includes the Availability Zone information.
import (
"encoding/json"
"time"

"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)

// ServerExt is an extension to the base Server object
type ServerAvailabilityZoneExt struct {
// AvailabilityZone is the availabilty zone the server is in.
AvailabilityZone string `json:"OS-EXT-AZ:availability_zone"`
}

type ServiceState struct {
Active bool `json:"active"`
Available bool `json:"available"`
UpdatedAt time.Time `json:"-"`
}

// UnmarshalJSON to override default
func (r *ServiceState) UnmarshalJSON(b []byte) error {
type tmp ServiceState
var s struct {
tmp
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
}
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*r = ServiceState(s.tmp)

r.UpdatedAt = time.Time(s.UpdatedAt)

return nil
}

type Services map[string]ServiceState

type Hosts map[string]Services

// The current state of the availability zone
type ZoneState struct {
// Returns true if the availability zone is available
Available bool `json:"available"`
}

// AvailabilityZone contains all the information associated with an OpenStack
// AvailabilityZone.
type AvailabilityZone struct {
Hosts Hosts `json:"hosts"`
// The availability zone name
ZoneName string `json:"zoneName"`
ZoneState ZoneState `json:"zoneState"`
}

type AvailabilityZonePage struct {
pagination.SinglePageBase
}

func ExtractAvailabilityZones(r pagination.Page) ([]AvailabilityZone, error) {
var s struct {
AvailabilityZoneInfo []AvailabilityZone `json:"availabilityZoneInfo"`
}
err := (r.(AvailabilityZonePage)).ExtractInto(&s)
return s.AvailabilityZoneInfo, err
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// availabilityzones unittests
package testing

0 comments on commit b2bf8a6

Please sign in to comment.