Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Handle nova api version > 2.87 for hypervisor #3028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 43 additions & 33 deletions openstack/compute/v2/hypervisors/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,27 +158,31 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error {

*r = Hypervisor(s.tmp)

// Newer versions return the CPU info as the correct type.
// Older versions return the CPU info as a string and need to be
// unmarshalled by the json parser.
var tmpb []byte

switch t := s.CPUInfo.(type) {
case string:
tmpb = []byte(t)
case map[string]any:
tmpb, err = json.Marshal(t)
if err != nil {
return err
// cpu_info doesn't exist after api version 2.87,
// see https://docs.openstack.org/api-ref/compute/#id288
if s.CPUInfo != nil {
// api versions 2.28 to 2.87 return the CPU info as the correct type.
// api versions < 2.28 return the CPU info as a string and need to be
// unmarshalled by the json parser.
var tmpb []byte

switch t := s.CPUInfo.(type) {
case string:
tmpb = []byte(t)
case map[string]any:
tmpb, err = json.Marshal(t)
if err != nil {
return err
}
default:
return fmt.Errorf("CPUInfo has unexpected type: %T", t)
}
default:
return fmt.Errorf("CPUInfo has unexpected type: %T", t)
}

if len(tmpb) != 0 {
err = json.Unmarshal(tmpb, &r.CPUInfo)
if err != nil {
return err
if len(tmpb) != 0 {
err = json.Unmarshal(tmpb, &r.CPUInfo)
if err != nil {
return err
}
}
}

Expand All @@ -193,22 +197,28 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error {
return fmt.Errorf("Hypervisor version has unexpected type: %T", t)
}

switch t := s.FreeDiskGB.(type) {
case int:
r.FreeDiskGB = t
case float64:
r.FreeDiskGB = int(t)
default:
return fmt.Errorf("Free disk GB has unexpected type: %T", t)
// free_disk_gb doesn't exist after api version 2.87
if s.FreeDiskGB != nil {
switch t := s.FreeDiskGB.(type) {
case int:
r.FreeDiskGB = t
case float64:
r.FreeDiskGB = int(t)
default:
return fmt.Errorf("Free disk GB has unexpected type: %T", t)
}
}

switch t := s.LocalGB.(type) {
case int:
r.LocalGB = t
case float64:
r.LocalGB = int(t)
default:
return fmt.Errorf("Local GB has unexpected type: %T", t)
// local_gb doesn't exist after api version 2.87
if s.LocalGB != nil {
switch t := s.LocalGB.(type) {
case int:
r.LocalGB = t
case float64:
r.LocalGB = int(t)
default:
return fmt.Errorf("Local GB has unexpected type: %T", t)
}
}

// OpenStack Compute service returns ID in string representation since
Expand Down
68 changes: 68 additions & 0 deletions openstack/compute/v2/hypervisors/testing/fixtures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,36 @@ const HypervisorGetEmptyCPUInfoBody = `
}
`

// HypervisorAfterV287ResponseBody represents a raw hypervisor GET result with
// missing cpu_info, free_disk_gb, local_gb as seen after v2.87
const HypervisorAfterV287ResponseBody = `
{
"hypervisor":{
"current_workload":0,
"status":"enabled",
"state":"up",
"disk_available_least":0,
"host_ip":"1.1.1.1",
"free_ram_mb":7680,
"hypervisor_hostname":"fake-mini",
"hypervisor_type":"fake",
"hypervisor_version":2002000,
"id":"c48f6247-abe4-4a24-824e-ea39e108874f",
"local_gb_used":0,
"memory_mb":8192,
"memory_mb_used":512,
"running_vms":0,
"service":{
"host":"e6a37ee802d74863ab8b91ade8f12a67",
"id":"9c2566e7-7a54-4777-a1ae-c2662f0c407c",
"disabled_reason":null
},
"vcpus":1,
"vcpus_used":0
}
}
`

// HypervisorUptimeBody represents a raw hypervisor uptime request result with
// Pike+ release.
const HypervisorUptimeBody = `
Expand Down Expand Up @@ -492,6 +522,7 @@ var (
}

HypervisorEmptyCPUInfo = hypervisors.Hypervisor{
CPUInfo: hypervisors.CPUInfo{},
CurrentWorkload: 0,
Status: "enabled",
State: "up",
Expand All @@ -517,6 +548,33 @@ var (
VCPUsUsed: 0,
}

HypervisorAfterV287Response = hypervisors.Hypervisor{
CPUInfo: hypervisors.CPUInfo{},
CurrentWorkload: 0,
Status: "enabled",
State: "up",
DiskAvailableLeast: 0,
HostIP: "1.1.1.1",
FreeDiskGB: 0,
FreeRamMB: 7680,
HypervisorHostname: "fake-mini",
HypervisorType: "fake",
HypervisorVersion: 2002000,
ID: "c48f6247-abe4-4a24-824e-ea39e108874f",
LocalGB: 0,
LocalGBUsed: 0,
MemoryMB: 8192,
MemoryMBUsed: 512,
RunningVMs: 0,
Service: hypervisors.Service{
Host: "e6a37ee802d74863ab8b91ade8f12a67",
ID: "9c2566e7-7a54-4777-a1ae-c2662f0c407c",
DisabledReason: "",
},
VCPUs: 1,
VCPUsUsed: 0,
}

HypervisorsStatisticsExpected = hypervisors.Statistics{
Count: 1,
CurrentWorkload: 0,
Expand Down Expand Up @@ -604,6 +662,16 @@ func HandleHypervisorGetEmptyCPUInfoSuccessfully(t *testing.T) {
})
}

func HandleHypervisorAfterV287ResponseSuccessfully(t *testing.T) {
testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID, func(w http.ResponseWriter, r *http.Request) {
testhelper.TestMethod(t, r, "GET")
testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)

w.Header().Add("Content-Type", "application/json")
fmt.Fprintf(w, HypervisorAfterV287ResponseBody)
})
}

func HandleHypervisorUptimeSuccessfully(t *testing.T) {
testhelper.Mux.HandleFunc("/os-hypervisors/"+HypervisorFake.ID+"/uptime", func(w http.ResponseWriter, r *http.Request) {
testhelper.TestMethod(t, r, "GET")
Expand Down
12 changes: 12 additions & 0 deletions openstack/compute/v2/hypervisors/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ func TestGetHypervisorEmptyCPUInfo(t *testing.T) {
testhelper.CheckDeepEquals(t, &expected, actual)
}

func TestGetHypervisorAfterV287Response(t *testing.T) {
testhelper.SetupHTTP()
defer testhelper.TeardownHTTP()
HandleHypervisorAfterV287ResponseSuccessfully(t)

expected := HypervisorAfterV287Response

actual, err := hypervisors.Get(context.TODO(), client.ServiceClient(), expected.ID).Extract()
testhelper.AssertNoErr(t, err)
testhelper.CheckDeepEquals(t, &expected, actual)
}

func TestHypervisorsUptime(t *testing.T) {
testhelper.SetupHTTP()
defer testhelper.TeardownHTTP()
Expand Down
Loading