github.com/gophercloud/gophercloud@v1.11.0/openstack/compute/v2/extensions/hypervisors/results.go (about)

     1  package hypervisors
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strconv"
     7  
     8  	"github.com/gophercloud/gophercloud"
     9  	"github.com/gophercloud/gophercloud/pagination"
    10  )
    11  
    12  // Topology represents a CPU Topology.
    13  type Topology struct {
    14  	Sockets int `json:"sockets"`
    15  	Cores   int `json:"cores"`
    16  	Threads int `json:"threads"`
    17  }
    18  
    19  // CPUInfo represents CPU information of the hypervisor.
    20  type CPUInfo struct {
    21  	Vendor   string   `json:"vendor"`
    22  	Arch     string   `json:"arch"`
    23  	Model    string   `json:"model"`
    24  	Features []string `json:"features"`
    25  	Topology Topology `json:"topology"`
    26  }
    27  
    28  // Service represents a Compute service running on the hypervisor.
    29  type Service struct {
    30  	Host           string `json:"host"`
    31  	ID             string `json:"-"`
    32  	DisabledReason string `json:"disabled_reason"`
    33  }
    34  
    35  func (r *Service) UnmarshalJSON(b []byte) error {
    36  	type tmp Service
    37  	var s struct {
    38  		tmp
    39  		ID interface{} `json:"id"`
    40  	}
    41  
    42  	err := json.Unmarshal(b, &s)
    43  	if err != nil {
    44  		return err
    45  	}
    46  
    47  	*r = Service(s.tmp)
    48  
    49  	// OpenStack Compute service returns ID in string representation since
    50  	// 2.53 microversion API (Pike release).
    51  	switch t := s.ID.(type) {
    52  	case int:
    53  		r.ID = strconv.Itoa(t)
    54  	case float64:
    55  		r.ID = strconv.Itoa(int(t))
    56  	case string:
    57  		r.ID = t
    58  	default:
    59  		return fmt.Errorf("ID has unexpected type: %T", t)
    60  	}
    61  
    62  	return nil
    63  }
    64  
    65  // Server represents an instance running on the hypervisor
    66  type Server struct {
    67  	Name string `json:"name"`
    68  	UUID string `json:"uuid"`
    69  }
    70  
    71  // Hypervisor represents a hypervisor in the OpenStack cloud.
    72  type Hypervisor struct {
    73  	// A structure that contains cpu information like arch, model, vendor,
    74  	// features and topology.
    75  	CPUInfo CPUInfo `json:"-"`
    76  
    77  	// The current_workload is the number of tasks the hypervisor is responsible
    78  	// for. This will be equal or greater than the number of active VMs on the
    79  	// system (it can be greater when VMs are being deleted and the hypervisor is
    80  	// still cleaning up).
    81  	CurrentWorkload int `json:"current_workload"`
    82  
    83  	// Status of the hypervisor, either "enabled" or "disabled".
    84  	Status string `json:"status"`
    85  
    86  	// State of the hypervisor, either "up" or "down".
    87  	State string `json:"state"`
    88  
    89  	// DiskAvailableLeast is the actual free disk on this hypervisor,
    90  	// measured in GB.
    91  	DiskAvailableLeast int `json:"disk_available_least"`
    92  
    93  	// HostIP is the hypervisor's IP address.
    94  	HostIP string `json:"host_ip"`
    95  
    96  	// FreeDiskGB is the free disk remaining on the hypervisor, measured in GB.
    97  	FreeDiskGB int `json:"-"`
    98  
    99  	// FreeRAMMB is the free RAM in the hypervisor, measured in MB.
   100  	FreeRamMB int `json:"free_ram_mb"`
   101  
   102  	// HypervisorHostname is the hostname of the hypervisor.
   103  	HypervisorHostname string `json:"hypervisor_hostname"`
   104  
   105  	// HypervisorType is the type of hypervisor.
   106  	HypervisorType string `json:"hypervisor_type"`
   107  
   108  	// HypervisorVersion is the version of the hypervisor.
   109  	HypervisorVersion int `json:"-"`
   110  
   111  	// ID is the unique ID of the hypervisor.
   112  	ID string `json:"-"`
   113  
   114  	// LocalGB is the disk space in the hypervisor, measured in GB.
   115  	LocalGB int `json:"-"`
   116  
   117  	// LocalGBUsed is the used disk space of the  hypervisor, measured in GB.
   118  	LocalGBUsed int `json:"local_gb_used"`
   119  
   120  	// MemoryMB is the total memory of the hypervisor, measured in MB.
   121  	MemoryMB int `json:"memory_mb"`
   122  
   123  	// MemoryMBUsed is the used memory of the hypervisor, measured in MB.
   124  	MemoryMBUsed int `json:"memory_mb_used"`
   125  
   126  	// RunningVMs is the The number of running vms on the hypervisor.
   127  	RunningVMs int `json:"running_vms"`
   128  
   129  	// Service is the service this hypervisor represents.
   130  	Service Service `json:"service"`
   131  
   132  	// Servers is a list of Server object.
   133  	// The requires microversion 2.53 or later.
   134  	Servers *[]Server `json:"servers"`
   135  
   136  	// VCPUs is the total number of vcpus on the hypervisor.
   137  	VCPUs int `json:"vcpus"`
   138  
   139  	// VCPUsUsed is the number of used vcpus on the hypervisor.
   140  	VCPUsUsed int `json:"vcpus_used"`
   141  }
   142  
   143  func (r *Hypervisor) UnmarshalJSON(b []byte) error {
   144  	type tmp Hypervisor
   145  	var s struct {
   146  		tmp
   147  		ID                interface{} `json:"id"`
   148  		CPUInfo           interface{} `json:"cpu_info"`
   149  		HypervisorVersion interface{} `json:"hypervisor_version"`
   150  		FreeDiskGB        interface{} `json:"free_disk_gb"`
   151  		LocalGB           interface{} `json:"local_gb"`
   152  	}
   153  
   154  	err := json.Unmarshal(b, &s)
   155  	if err != nil {
   156  		return err
   157  	}
   158  
   159  	*r = Hypervisor(s.tmp)
   160  
   161  	// Newer versions return the CPU info as the correct type.
   162  	// Older versions return the CPU info as a string and need to be
   163  	// unmarshalled by the json parser.
   164  	var tmpb []byte
   165  
   166  	switch t := s.CPUInfo.(type) {
   167  	case string:
   168  		tmpb = []byte(t)
   169  	case map[string]interface{}:
   170  		tmpb, err = json.Marshal(t)
   171  		if err != nil {
   172  			return err
   173  		}
   174  	default:
   175  		return fmt.Errorf("CPUInfo has unexpected type: %T", t)
   176  	}
   177  
   178  	if len(tmpb) != 0 {
   179  		err = json.Unmarshal(tmpb, &r.CPUInfo)
   180  		if err != nil {
   181  			return err
   182  		}
   183  	}
   184  
   185  	// These fields may be returned as a scientific notation, so they need
   186  	// converted to int.
   187  	switch t := s.HypervisorVersion.(type) {
   188  	case int:
   189  		r.HypervisorVersion = t
   190  	case float64:
   191  		r.HypervisorVersion = int(t)
   192  	default:
   193  		return fmt.Errorf("Hypervisor version has unexpected type: %T", t)
   194  	}
   195  
   196  	switch t := s.FreeDiskGB.(type) {
   197  	case int:
   198  		r.FreeDiskGB = t
   199  	case float64:
   200  		r.FreeDiskGB = int(t)
   201  	default:
   202  		return fmt.Errorf("Free disk GB has unexpected type: %T", t)
   203  	}
   204  
   205  	switch t := s.LocalGB.(type) {
   206  	case int:
   207  		r.LocalGB = t
   208  	case float64:
   209  		r.LocalGB = int(t)
   210  	default:
   211  		return fmt.Errorf("Local GB has unexpected type: %T", t)
   212  	}
   213  
   214  	// OpenStack Compute service returns ID in string representation since
   215  	// 2.53 microversion API (Pike release).
   216  	switch t := s.ID.(type) {
   217  	case int:
   218  		r.ID = strconv.Itoa(t)
   219  	case float64:
   220  		r.ID = strconv.Itoa(int(t))
   221  	case string:
   222  		r.ID = t
   223  	default:
   224  		return fmt.Errorf("ID has unexpected type: %T", t)
   225  	}
   226  
   227  	return nil
   228  }
   229  
   230  // HypervisorPage represents a single page of all Hypervisors from a List
   231  // request.
   232  type HypervisorPage struct {
   233  	pagination.SinglePageBase
   234  }
   235  
   236  // IsEmpty determines whether or not a HypervisorPage is empty.
   237  func (page HypervisorPage) IsEmpty() (bool, error) {
   238  	if page.StatusCode == 204 {
   239  		return true, nil
   240  	}
   241  
   242  	va, err := ExtractHypervisors(page)
   243  	return len(va) == 0, err
   244  }
   245  
   246  // ExtractHypervisors interprets a page of results as a slice of Hypervisors.
   247  func ExtractHypervisors(p pagination.Page) ([]Hypervisor, error) {
   248  	var h struct {
   249  		Hypervisors []Hypervisor `json:"hypervisors"`
   250  	}
   251  	err := (p.(HypervisorPage)).ExtractInto(&h)
   252  	return h.Hypervisors, err
   253  }
   254  
   255  type HypervisorResult struct {
   256  	gophercloud.Result
   257  }
   258  
   259  // Extract interprets any HypervisorResult as a Hypervisor, if possible.
   260  func (r HypervisorResult) Extract() (*Hypervisor, error) {
   261  	var s struct {
   262  		Hypervisor Hypervisor `json:"hypervisor"`
   263  	}
   264  	err := r.ExtractInto(&s)
   265  	return &s.Hypervisor, err
   266  }
   267  
   268  // Statistics represents a summary statistics for all enabled
   269  // hypervisors over all compute nodes in the OpenStack cloud.
   270  type Statistics struct {
   271  	// The number of hypervisors.
   272  	Count int `json:"count"`
   273  
   274  	// The current_workload is the number of tasks the hypervisor is responsible for
   275  	CurrentWorkload int `json:"current_workload"`
   276  
   277  	// The actual free disk on this hypervisor(in GB).
   278  	DiskAvailableLeast int `json:"disk_available_least"`
   279  
   280  	// The free disk remaining on this hypervisor(in GB).
   281  	FreeDiskGB int `json:"free_disk_gb"`
   282  
   283  	// The free RAM in this hypervisor(in MB).
   284  	FreeRamMB int `json:"free_ram_mb"`
   285  
   286  	// The disk in this hypervisor(in GB).
   287  	LocalGB int `json:"local_gb"`
   288  
   289  	// The disk used in this hypervisor(in GB).
   290  	LocalGBUsed int `json:"local_gb_used"`
   291  
   292  	// The memory of this hypervisor(in MB).
   293  	MemoryMB int `json:"memory_mb"`
   294  
   295  	// The memory used in this hypervisor(in MB).
   296  	MemoryMBUsed int `json:"memory_mb_used"`
   297  
   298  	// The total number of running vms on all hypervisors.
   299  	RunningVMs int `json:"running_vms"`
   300  
   301  	// The number of vcpu in this hypervisor.
   302  	VCPUs int `json:"vcpus"`
   303  
   304  	// The number of vcpu used in this hypervisor.
   305  	VCPUsUsed int `json:"vcpus_used"`
   306  }
   307  
   308  type StatisticsResult struct {
   309  	gophercloud.Result
   310  }
   311  
   312  // Extract interprets any StatisticsResult as a Statistics, if possible.
   313  func (r StatisticsResult) Extract() (*Statistics, error) {
   314  	var s struct {
   315  		Stats Statistics `json:"hypervisor_statistics"`
   316  	}
   317  	err := r.ExtractInto(&s)
   318  	return &s.Stats, err
   319  }
   320  
   321  // Uptime represents uptime and additional info for a specific hypervisor.
   322  type Uptime struct {
   323  	// The hypervisor host name provided by the Nova virt driver.
   324  	// For the Ironic driver, it is the Ironic node uuid.
   325  	HypervisorHostname string `json:"hypervisor_hostname"`
   326  
   327  	// The id of the hypervisor.
   328  	ID string `json:"-"`
   329  
   330  	// The state of the hypervisor. One of up or down.
   331  	State string `json:"state"`
   332  
   333  	// The status of the hypervisor. One of enabled or disabled.
   334  	Status string `json:"status"`
   335  
   336  	// The total uptime of the hypervisor and information about average load.
   337  	Uptime string `json:"uptime"`
   338  }
   339  
   340  func (r *Uptime) UnmarshalJSON(b []byte) error {
   341  	type tmp Uptime
   342  	var s struct {
   343  		tmp
   344  		ID interface{} `json:"id"`
   345  	}
   346  
   347  	err := json.Unmarshal(b, &s)
   348  	if err != nil {
   349  		return err
   350  	}
   351  
   352  	*r = Uptime(s.tmp)
   353  
   354  	// OpenStack Compute service returns ID in string representation since
   355  	// 2.53 microversion API (Pike release).
   356  	switch t := s.ID.(type) {
   357  	case int:
   358  		r.ID = strconv.Itoa(t)
   359  	case float64:
   360  		r.ID = strconv.Itoa(int(t))
   361  	case string:
   362  		r.ID = t
   363  	default:
   364  		return fmt.Errorf("ID has unexpected type: %T", t)
   365  	}
   366  
   367  	return nil
   368  }
   369  
   370  type UptimeResult struct {
   371  	gophercloud.Result
   372  }
   373  
   374  // Extract interprets any UptimeResult as a Uptime, if possible.
   375  func (r UptimeResult) Extract() (*Uptime, error) {
   376  	var s struct {
   377  		Uptime Uptime `json:"hypervisor"`
   378  	}
   379  	err := r.ExtractInto(&s)
   380  	return &s.Uptime, err
   381  }