@@ -158,27 +158,31 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error {
158158
159159 * r = Hypervisor (s .tmp )
160160
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 ]any :
170- tmpb , err = json .Marshal (t )
171- if err != nil {
172- return err
161+ // cpu_info doesn't exist after api version 2.87,
162+ // see https://docs.openstack.org/api-ref/compute/#id288
163+ if s .CPUInfo != nil {
164+ // api versions 2.28 to 2.87 return the CPU info as the correct type.
165+ // api versions < 2.28 return the CPU info as a string and need to be
166+ // unmarshalled by the json parser.
167+ var tmpb []byte
168+
169+ switch t := s .CPUInfo .(type ) {
170+ case string :
171+ tmpb = []byte (t )
172+ case map [string ]any :
173+ tmpb , err = json .Marshal (t )
174+ if err != nil {
175+ return err
176+ }
177+ default :
178+ return fmt .Errorf ("CPUInfo has unexpected type: %T" , t )
173179 }
174- default :
175- return fmt .Errorf ("CPUInfo has unexpected type: %T" , t )
176- }
177180
178- if len (tmpb ) != 0 {
179- err = json .Unmarshal (tmpb , & r .CPUInfo )
180- if err != nil {
181- return err
181+ if len (tmpb ) != 0 {
182+ err = json .Unmarshal (tmpb , & r .CPUInfo )
183+ if err != nil {
184+ return err
185+ }
182186 }
183187 }
184188
@@ -193,22 +197,28 @@ func (r *Hypervisor) UnmarshalJSON(b []byte) error {
193197 return fmt .Errorf ("Hypervisor version has unexpected type: %T" , t )
194198 }
195199
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 )
200+ // free_disk_gb doesn't exist after api version 2.87
201+ if s .FreeDiskGB != nil {
202+ switch t := s .FreeDiskGB .(type ) {
203+ case int :
204+ r .FreeDiskGB = t
205+ case float64 :
206+ r .FreeDiskGB = int (t )
207+ default :
208+ return fmt .Errorf ("Free disk GB has unexpected type: %T" , t )
209+ }
203210 }
204211
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+ // local_gb doesn't exist after api version 2.87
213+ if s .LocalGB != nil {
214+ switch t := s .LocalGB .(type ) {
215+ case int :
216+ r .LocalGB = t
217+ case float64 :
218+ r .LocalGB = int (t )
219+ default :
220+ return fmt .Errorf ("Local GB has unexpected type: %T" , t )
221+ }
212222 }
213223
214224 // OpenStack Compute service returns ID in string representation since
0 commit comments