|
Packit |
63bb0d |
package servers
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
import (
|
|
Packit |
63bb0d |
"crypto/rsa"
|
|
Packit |
63bb0d |
"encoding/base64"
|
|
Packit |
63bb0d |
"encoding/json"
|
|
Packit |
63bb0d |
"fmt"
|
|
Packit |
63bb0d |
"net/url"
|
|
Packit |
63bb0d |
"path"
|
|
Packit |
63bb0d |
"time"
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
"github.com/gophercloud/gophercloud"
|
|
Packit |
63bb0d |
"github.com/gophercloud/gophercloud/pagination"
|
|
Packit |
63bb0d |
)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type serverResult struct {
|
|
Packit |
63bb0d |
gophercloud.Result
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Extract interprets any serverResult as a Server, if possible.
|
|
Packit |
63bb0d |
func (r serverResult) Extract() (*Server, error) {
|
|
Packit |
63bb0d |
var s Server
|
|
Packit |
63bb0d |
err := r.ExtractInto(&s)
|
|
Packit |
63bb0d |
return &s, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (r serverResult) ExtractInto(v interface{}) error {
|
|
Packit |
63bb0d |
return r.Result.ExtractIntoStructPtr(v, "server")
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func ExtractServersInto(r pagination.Page, v interface{}) error {
|
|
Packit |
63bb0d |
return r.(ServerPage).Result.ExtractIntoSlicePtr(v, "servers")
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// CreateResult is the response from a Create operation. Call its Extract
|
|
Packit |
63bb0d |
// method to interpret it as a Server.
|
|
Packit |
63bb0d |
type CreateResult struct {
|
|
Packit |
63bb0d |
serverResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// GetResult is the response from a Get operation. Call its Extract
|
|
Packit |
63bb0d |
// method to interpret it as a Server.
|
|
Packit |
63bb0d |
type GetResult struct {
|
|
Packit |
63bb0d |
serverResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// UpdateResult is the response from an Update operation. Call its Extract
|
|
Packit |
63bb0d |
// method to interpret it as a Server.
|
|
Packit |
63bb0d |
type UpdateResult struct {
|
|
Packit |
63bb0d |
serverResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
|
Packit |
63bb0d |
// method to determine if the call succeeded or failed.
|
|
Packit |
63bb0d |
type DeleteResult struct {
|
|
Packit |
63bb0d |
gophercloud.ErrResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// RebuildResult is the response from a Rebuild operation. Call its Extract
|
|
Packit |
63bb0d |
// method to interpret it as a Server.
|
|
Packit |
63bb0d |
type RebuildResult struct {
|
|
Packit |
63bb0d |
serverResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ActionResult represents the result of server action operations, like reboot.
|
|
Packit |
63bb0d |
// Call its ExtractErr method to determine if the action succeeded or failed.
|
|
Packit |
63bb0d |
type ActionResult struct {
|
|
Packit |
63bb0d |
gophercloud.ErrResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// CreateImageResult is the response from a CreateImage operation. Call its
|
|
Packit |
63bb0d |
// ExtractImageID method to retrieve the ID of the newly created image.
|
|
Packit |
63bb0d |
type CreateImageResult struct {
|
|
Packit |
63bb0d |
gophercloud.Result
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ShowConsoleOutputResult represents the result of console output from a server
|
|
Packit |
63bb0d |
type ShowConsoleOutputResult struct {
|
|
Packit |
63bb0d |
gophercloud.Result
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Extract will return the console output from a ShowConsoleOutput request.
|
|
Packit |
63bb0d |
func (r ShowConsoleOutputResult) Extract() (string, error) {
|
|
Packit |
63bb0d |
var s struct {
|
|
Packit |
63bb0d |
Output string `json:"output"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
err := r.ExtractInto(&s)
|
|
Packit |
63bb0d |
return s.Output, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// GetPasswordResult represent the result of a get os-server-password operation.
|
|
Packit |
63bb0d |
// Call its ExtractPassword method to retrieve the password.
|
|
Packit |
63bb0d |
type GetPasswordResult struct {
|
|
Packit |
63bb0d |
gophercloud.Result
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ExtractPassword gets the encrypted password.
|
|
Packit |
63bb0d |
// If privateKey != nil the password is decrypted with the private key.
|
|
Packit |
63bb0d |
// If privateKey == nil the encrypted password is returned and can be decrypted
|
|
Packit |
63bb0d |
// with:
|
|
Packit |
63bb0d |
// echo '<pwd>' | base64 -D | openssl rsautl -decrypt -inkey <private_key>
|
|
Packit |
63bb0d |
func (r GetPasswordResult) ExtractPassword(privateKey *rsa.PrivateKey) (string, error) {
|
|
Packit |
63bb0d |
var s struct {
|
|
Packit |
63bb0d |
Password string `json:"password"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
err := r.ExtractInto(&s)
|
|
Packit |
63bb0d |
if err == nil && privateKey != nil && s.Password != "" {
|
|
Packit |
63bb0d |
return decryptPassword(s.Password, privateKey)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return s.Password, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func decryptPassword(encryptedPassword string, privateKey *rsa.PrivateKey) (string, error) {
|
|
Packit |
63bb0d |
b64EncryptedPassword := make([]byte, base64.StdEncoding.DecodedLen(len(encryptedPassword)))
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
n, err := base64.StdEncoding.Decode(b64EncryptedPassword, []byte(encryptedPassword))
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return "", fmt.Errorf("Failed to base64 decode encrypted password: %s", err)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
password, err := rsa.DecryptPKCS1v15(nil, privateKey, b64EncryptedPassword[0:n])
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return "", fmt.Errorf("Failed to decrypt password: %s", err)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return string(password), nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ExtractImageID gets the ID of the newly created server image from the header.
|
|
Packit |
63bb0d |
func (r CreateImageResult) ExtractImageID() (string, error) {
|
|
Packit |
63bb0d |
if r.Err != nil {
|
|
Packit |
63bb0d |
return "", r.Err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
// Get the image id from the header
|
|
Packit |
63bb0d |
u, err := url.ParseRequestURI(r.Header.Get("Location"))
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return "", err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
imageID := path.Base(u.Path)
|
|
Packit |
63bb0d |
if imageID == "." || imageID == "/" {
|
|
Packit |
63bb0d |
return "", fmt.Errorf("Failed to parse the ID of newly created image: %s", u)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return imageID, nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Server represents a server/instance in the OpenStack cloud.
|
|
Packit |
63bb0d |
type Server struct {
|
|
Packit |
63bb0d |
// ID uniquely identifies this server amongst all other servers,
|
|
Packit |
63bb0d |
// including those not accessible to the current tenant.
|
|
Packit |
63bb0d |
ID string `json:"id"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// TenantID identifies the tenant owning this server resource.
|
|
Packit |
63bb0d |
TenantID string `json:"tenant_id"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// UserID uniquely identifies the user account owning the tenant.
|
|
Packit |
63bb0d |
UserID string `json:"user_id"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Name contains the human-readable name for the server.
|
|
Packit |
63bb0d |
Name string `json:"name"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Updated and Created contain ISO-8601 timestamps of when the state of the
|
|
Packit |
63bb0d |
// server last changed, and when it was created.
|
|
Packit |
63bb0d |
Updated time.Time `json:"updated"`
|
|
Packit |
63bb0d |
Created time.Time `json:"created"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// HostID is the host where the server is located in the cloud.
|
|
Packit |
63bb0d |
HostID string `json:"hostid"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Status contains the current operational status of the server,
|
|
Packit |
63bb0d |
// such as IN_PROGRESS or ACTIVE.
|
|
Packit |
63bb0d |
Status string `json:"status"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Progress ranges from 0..100.
|
|
Packit |
63bb0d |
// A request made against the server completes only once Progress reaches 100.
|
|
Packit |
63bb0d |
Progress int `json:"progress"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// AccessIPv4 and AccessIPv6 contain the IP addresses of the server,
|
|
Packit |
63bb0d |
// suitable for remote access for administration.
|
|
Packit |
63bb0d |
AccessIPv4 string `json:"accessIPv4"`
|
|
Packit |
63bb0d |
AccessIPv6 string `json:"accessIPv6"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Image refers to a JSON object, which itself indicates the OS image used to
|
|
Packit |
63bb0d |
// deploy the server.
|
|
Packit |
63bb0d |
Image map[string]interface{} `json:"-"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Flavor refers to a JSON object, which itself indicates the hardware
|
|
Packit |
63bb0d |
// configuration of the deployed server.
|
|
Packit |
63bb0d |
Flavor map[string]interface{} `json:"flavor"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Addresses includes a list of all IP addresses assigned to the server,
|
|
Packit |
63bb0d |
// keyed by pool.
|
|
Packit |
63bb0d |
Addresses map[string]interface{} `json:"addresses"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Metadata includes a list of all user-specified key-value pairs attached
|
|
Packit |
63bb0d |
// to the server.
|
|
Packit |
63bb0d |
Metadata map[string]string `json:"metadata"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Links includes HTTP references to the itself, useful for passing along to
|
|
Packit |
63bb0d |
// other APIs that might want a server reference.
|
|
Packit |
63bb0d |
Links []interface{} `json:"links"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// KeyName indicates which public key was injected into the server on launch.
|
|
Packit |
63bb0d |
KeyName string `json:"key_name"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// AdminPass will generally be empty (""). However, it will contain the
|
|
Packit |
63bb0d |
// administrative password chosen when provisioning a new server without a
|
|
Packit |
63bb0d |
// set AdminPass setting in the first place.
|
|
Packit |
63bb0d |
// Note that this is the ONLY time this field will be valid.
|
|
Packit |
63bb0d |
AdminPass string `json:"adminPass"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// SecurityGroups includes the security groups that this instance has applied
|
|
Packit |
63bb0d |
// to it.
|
|
Packit |
63bb0d |
SecurityGroups []map[string]interface{} `json:"security_groups"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// AttachedVolumes includes the volume attachments of this instance
|
|
Packit |
63bb0d |
AttachedVolumes []AttachedVolume `json:"os-extended-volumes:volumes_attached"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Fault contains failure information about a server.
|
|
Packit |
63bb0d |
Fault Fault `json:"fault"`
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Tags is a slice/list of string tags in a server.
|
|
Packit |
63bb0d |
// The requires microversion 2.26 or later.
|
|
Packit |
63bb0d |
Tags *[]string `json:"tags"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type AttachedVolume struct {
|
|
Packit |
63bb0d |
ID string `json:"id"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type Fault struct {
|
|
Packit |
63bb0d |
Code int `json:"code"`
|
|
Packit |
63bb0d |
Created time.Time `json:"created"`
|
|
Packit |
63bb0d |
Details string `json:"details"`
|
|
Packit |
63bb0d |
Message string `json:"message"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (r *Server) UnmarshalJSON(b []byte) error {
|
|
Packit |
63bb0d |
type tmp Server
|
|
Packit |
63bb0d |
var s struct {
|
|
Packit |
63bb0d |
tmp
|
|
Packit |
63bb0d |
Image interface{} `json:"image"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
err := json.Unmarshal(b, &s)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
*r = Server(s.tmp)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
switch t := s.Image.(type) {
|
|
Packit |
63bb0d |
case map[string]interface{}:
|
|
Packit |
63bb0d |
r.Image = t
|
|
Packit |
63bb0d |
case string:
|
|
Packit |
63bb0d |
switch t {
|
|
Packit |
63bb0d |
case "":
|
|
Packit |
63bb0d |
r.Image = nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ServerPage abstracts the raw results of making a List() request against
|
|
Packit |
63bb0d |
// the API. As OpenStack extensions may freely alter the response bodies of
|
|
Packit |
63bb0d |
// structures returned to the client, you may only safely access the data
|
|
Packit |
63bb0d |
// provided through the ExtractServers call.
|
|
Packit |
63bb0d |
type ServerPage struct {
|
|
Packit |
63bb0d |
pagination.LinkedPageBase
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// IsEmpty returns true if a page contains no Server results.
|
|
Packit |
63bb0d |
func (r ServerPage) IsEmpty() (bool, error) {
|
|
Packit |
63bb0d |
s, err := ExtractServers(r)
|
|
Packit |
63bb0d |
return len(s) == 0, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// NextPageURL uses the response's embedded link reference to navigate to the
|
|
Packit |
63bb0d |
// next page of results.
|
|
Packit |
63bb0d |
func (r ServerPage) NextPageURL() (string, error) {
|
|
Packit |
63bb0d |
var s struct {
|
|
Packit |
63bb0d |
Links []gophercloud.Link `json:"servers_links"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
err := r.ExtractInto(&s)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return "", err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return gophercloud.ExtractNextURL(s.Links)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ExtractServers interprets the results of a single page from a List() call,
|
|
Packit |
63bb0d |
// producing a slice of Server entities.
|
|
Packit |
63bb0d |
func ExtractServers(r pagination.Page) ([]Server, error) {
|
|
Packit |
63bb0d |
var s []Server
|
|
Packit |
63bb0d |
err := ExtractServersInto(r, &s)
|
|
Packit |
63bb0d |
return s, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// MetadataResult contains the result of a call for (potentially) multiple
|
|
Packit |
63bb0d |
// key-value pairs. Call its Extract method to interpret it as a
|
|
Packit |
63bb0d |
// map[string]interface.
|
|
Packit |
63bb0d |
type MetadataResult struct {
|
|
Packit |
63bb0d |
gophercloud.Result
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// GetMetadataResult contains the result of a Get operation. Call its Extract
|
|
Packit |
63bb0d |
// method to interpret it as a map[string]interface.
|
|
Packit |
63bb0d |
type GetMetadataResult struct {
|
|
Packit |
63bb0d |
MetadataResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ResetMetadataResult contains the result of a Reset operation. Call its
|
|
Packit |
63bb0d |
// Extract method to interpret it as a map[string]interface.
|
|
Packit |
63bb0d |
type ResetMetadataResult struct {
|
|
Packit |
63bb0d |
MetadataResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// UpdateMetadataResult contains the result of an Update operation. Call its
|
|
Packit |
63bb0d |
// Extract method to interpret it as a map[string]interface.
|
|
Packit |
63bb0d |
type UpdateMetadataResult struct {
|
|
Packit |
63bb0d |
MetadataResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// MetadatumResult contains the result of a call for individual a single
|
|
Packit |
63bb0d |
// key-value pair.
|
|
Packit |
63bb0d |
type MetadatumResult struct {
|
|
Packit |
63bb0d |
gophercloud.Result
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// GetMetadatumResult contains the result of a Get operation. Call its Extract
|
|
Packit |
63bb0d |
// method to interpret it as a map[string]interface.
|
|
Packit |
63bb0d |
type GetMetadatumResult struct {
|
|
Packit |
63bb0d |
MetadatumResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// CreateMetadatumResult contains the result of a Create operation. Call its
|
|
Packit |
63bb0d |
// Extract method to interpret it as a map[string]interface.
|
|
Packit |
63bb0d |
type CreateMetadatumResult struct {
|
|
Packit |
63bb0d |
MetadatumResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// DeleteMetadatumResult contains the result of a Delete operation. Call its
|
|
Packit |
63bb0d |
// ExtractErr method to determine if the call succeeded or failed.
|
|
Packit |
63bb0d |
type DeleteMetadatumResult struct {
|
|
Packit |
63bb0d |
gophercloud.ErrResult
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Extract interprets any MetadataResult as a Metadata, if possible.
|
|
Packit |
63bb0d |
func (r MetadataResult) Extract() (map[string]string, error) {
|
|
Packit |
63bb0d |
var s struct {
|
|
Packit |
63bb0d |
Metadata map[string]string `json:"metadata"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
err := r.ExtractInto(&s)
|
|
Packit |
63bb0d |
return s.Metadata, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Extract interprets any MetadatumResult as a Metadatum, if possible.
|
|
Packit |
63bb0d |
func (r MetadatumResult) Extract() (map[string]string, error) {
|
|
Packit |
63bb0d |
var s struct {
|
|
Packit |
63bb0d |
Metadatum map[string]string `json:"meta"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
err := r.ExtractInto(&s)
|
|
Packit |
63bb0d |
return s.Metadatum, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Address represents an IP address.
|
|
Packit |
63bb0d |
type Address struct {
|
|
Packit |
63bb0d |
Version int `json:"version"`
|
|
Packit |
63bb0d |
Address string `json:"addr"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// AddressPage abstracts the raw results of making a ListAddresses() request
|
|
Packit |
63bb0d |
// against the API. As OpenStack extensions may freely alter the response bodies
|
|
Packit |
63bb0d |
// of structures returned to the client, you may only safely access the data
|
|
Packit |
63bb0d |
// provided through the ExtractAddresses call.
|
|
Packit |
63bb0d |
type AddressPage struct {
|
|
Packit |
63bb0d |
pagination.SinglePageBase
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// IsEmpty returns true if an AddressPage contains no networks.
|
|
Packit |
63bb0d |
func (r AddressPage) IsEmpty() (bool, error) {
|
|
Packit |
63bb0d |
addresses, err := ExtractAddresses(r)
|
|
Packit |
63bb0d |
return len(addresses) == 0, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ExtractAddresses interprets the results of a single page from a
|
|
Packit |
63bb0d |
// ListAddresses() call, producing a map of addresses.
|
|
Packit |
63bb0d |
func ExtractAddresses(r pagination.Page) (map[string][]Address, error) {
|
|
Packit |
63bb0d |
var s struct {
|
|
Packit |
63bb0d |
Addresses map[string][]Address `json:"addresses"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
err := (r.(AddressPage)).ExtractInto(&s)
|
|
Packit |
63bb0d |
return s.Addresses, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// NetworkAddressPage abstracts the raw results of making a
|
|
Packit |
63bb0d |
// ListAddressesByNetwork() request against the API.
|
|
Packit |
63bb0d |
// As OpenStack extensions may freely alter the response bodies of structures
|
|
Packit |
63bb0d |
// returned to the client, you may only safely access the data provided through
|
|
Packit |
63bb0d |
// the ExtractAddresses call.
|
|
Packit |
63bb0d |
type NetworkAddressPage struct {
|
|
Packit |
63bb0d |
pagination.SinglePageBase
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// IsEmpty returns true if a NetworkAddressPage contains no addresses.
|
|
Packit |
63bb0d |
func (r NetworkAddressPage) IsEmpty() (bool, error) {
|
|
Packit |
63bb0d |
addresses, err := ExtractNetworkAddresses(r)
|
|
Packit |
63bb0d |
return len(addresses) == 0, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// ExtractNetworkAddresses interprets the results of a single page from a
|
|
Packit |
63bb0d |
// ListAddressesByNetwork() call, producing a slice of addresses.
|
|
Packit |
63bb0d |
func ExtractNetworkAddresses(r pagination.Page) ([]Address, error) {
|
|
Packit |
63bb0d |
var s map[string][]Address
|
|
Packit |
63bb0d |
err := (r.(NetworkAddressPage)).ExtractInto(&s)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return nil, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
var key string
|
|
Packit |
63bb0d |
for k := range s {
|
|
Packit |
63bb0d |
key = k
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return s[key], err
|
|
Packit |
63bb0d |
}
|