Skip to content

Commit 71cd5ea

Browse files
Support 4.x compatibility (#23)
* handle type compatibilty for 4.x baseline * fix CSLong to be more permissive and add unit test * Rename CSLong to UUID Co-authored-by: Xavier MARCELET <xavier.marcelet@orange.com>
1 parent 3d07af9 commit 71cd5ea

5 files changed

Lines changed: 99 additions & 9 deletions

File tree

cloudstack/HostService.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ type AddBaremetalHostResponse struct {
356356
Jobstatus int `json:"jobstatus"`
357357
Lastannotated string `json:"lastannotated"`
358358
Lastpinged string `json:"lastpinged"`
359-
Managementserverid string `json:"managementserverid"`
359+
Managementserverid UUID `json:"managementserverid"`
360360
Memoryallocated int64 `json:"memoryallocated"`
361361
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
362362
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`
@@ -789,7 +789,7 @@ type AddHostResponse struct {
789789
Jobstatus int `json:"jobstatus"`
790790
Lastannotated string `json:"lastannotated"`
791791
Lastpinged string `json:"lastpinged"`
792-
Managementserverid string `json:"managementserverid"`
792+
Managementserverid UUID `json:"managementserverid"`
793793
Memoryallocated int64 `json:"memoryallocated"`
794794
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
795795
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`
@@ -1032,7 +1032,7 @@ type CancelHostMaintenanceResponse struct {
10321032
Jobstatus int `json:"jobstatus"`
10331033
Lastannotated string `json:"lastannotated"`
10341034
Lastpinged string `json:"lastpinged"`
1035-
Managementserverid string `json:"managementserverid"`
1035+
Managementserverid UUID `json:"managementserverid"`
10361036
Memoryallocated int64 `json:"memoryallocated"`
10371037
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
10381038
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`
@@ -1830,7 +1830,7 @@ type FindHostsForMigrationResponse struct {
18301830
JobID string `json:"jobid"`
18311831
Jobstatus int `json:"jobstatus"`
18321832
Lastpinged string `json:"lastpinged"`
1833-
Managementserverid int64 `json:"managementserverid"`
1833+
Managementserverid UUID `json:"managementserverid"`
18341834
Memoryallocated string `json:"memoryallocated"`
18351835
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
18361836
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`
@@ -2645,7 +2645,7 @@ type Host struct {
26452645
Jobstatus int `json:"jobstatus"`
26462646
Lastannotated string `json:"lastannotated"`
26472647
Lastpinged string `json:"lastpinged"`
2648-
Managementserverid string `json:"managementserverid"`
2648+
Managementserverid UUID `json:"managementserverid"`
26492649
Memoryallocated int64 `json:"memoryallocated"`
26502650
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
26512651
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`
@@ -3167,7 +3167,7 @@ type HostsMetric struct {
31673167
Jobstatus int `json:"jobstatus"`
31683168
Lastannotated string `json:"lastannotated"`
31693169
Lastpinged string `json:"lastpinged"`
3170-
Managementserverid string `json:"managementserverid"`
3170+
Managementserverid UUID `json:"managementserverid"`
31713171
Memoryallocated int64 `json:"memoryallocated"`
31723172
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
31733173
Memoryallocateddisablethreshold bool `json:"memoryallocateddisablethreshold"`
@@ -3331,7 +3331,7 @@ type PrepareHostForMaintenanceResponse struct {
33313331
Jobstatus int `json:"jobstatus"`
33323332
Lastannotated string `json:"lastannotated"`
33333333
Lastpinged string `json:"lastpinged"`
3334-
Managementserverid string `json:"managementserverid"`
3334+
Managementserverid UUID `json:"managementserverid"`
33353335
Memoryallocated int64 `json:"memoryallocated"`
33363336
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
33373337
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`
@@ -3485,7 +3485,7 @@ type ReconnectHostResponse struct {
34853485
Jobstatus int `json:"jobstatus"`
34863486
Lastannotated string `json:"lastannotated"`
34873487
Lastpinged string `json:"lastpinged"`
3488-
Managementserverid string `json:"managementserverid"`
3488+
Managementserverid UUID `json:"managementserverid"`
34893489
Memoryallocated int64 `json:"memoryallocated"`
34903490
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
34913491
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`
@@ -3880,7 +3880,7 @@ type UpdateHostResponse struct {
38803880
Jobstatus int `json:"jobstatus"`
38813881
Lastannotated string `json:"lastannotated"`
38823882
Lastpinged string `json:"lastpinged"`
3883-
Managementserverid string `json:"managementserverid"`
3883+
Managementserverid UUID `json:"managementserverid"`
38843884
Memoryallocated int64 `json:"memoryallocated"`
38853885
Memoryallocatedbytes int64 `json:"memoryallocatedbytes"`
38863886
Memoryallocatedpercentage string `json:"memoryallocatedpercentage"`

cloudstack/HostService_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func TestHostService_PrepareHostForMaintenance(t *testing.T) {
8888
resp, err := client.Host.PrepareHostForMaintenance(params)
8989
if err != nil {
9090
t.Errorf("Failed to prepare host for maintenance due to: %v", err)
91+
return
9192
}
9293
if resp.Resourcestate != "PrepareForMaintenance" {
9394
t.Errorf("Failed to prepare host for maintenance")
@@ -109,6 +110,7 @@ func TestHostService_CancelHostForMaintenance(t *testing.T) {
109110
resp, err := client.Host.CancelHostMaintenance(params)
110111
if err != nil {
111112
t.Errorf("Failed to cancel host for maintenance due to: %v", err)
113+
return
112114
}
113115
if resp.Resourcestate != "Enabled" {
114116
t.Errorf("Failed to cancel host for maintenance")

cloudstack/cloudstack.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"net/url"
3636
"regexp"
3737
"sort"
38+
"strconv"
3839
"strings"
3940
"time"
4041

@@ -67,6 +68,26 @@ func (e *CSError) Error() error {
6768
return fmt.Errorf("CloudStack API error %d (CSExceptionErrorCode: %d): %s", e.ErrorCode, e.CSErrorCode, e.ErrorText)
6869
}
6970

71+
type UUID string
72+
73+
func (c UUID) MarshalJSON() ([]byte, error) {
74+
return json.Marshal(string(c))
75+
}
76+
77+
func (c *UUID) UnmarshalJSON(data []byte) error {
78+
value := strings.Trim(string(data), "\"")
79+
if strings.HasPrefix(string(data), "\"") {
80+
*c = UUID(value)
81+
return nil
82+
}
83+
_, err := strconv.ParseInt(value, 10, 64)
84+
if err != nil {
85+
return err
86+
}
87+
*c = UUID(value)
88+
return nil
89+
}
90+
7091
type CloudStackClient struct {
7192
HTTPGETOnly bool // If `true` only use HTTP GET calls
7293

cloudstack/cloudstack_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,35 @@ func TestCreateSyncClient(t *testing.T) {
8787
t.Errorf("Failed to create Cloudstack Client")
8888
}
8989
}
90+
91+
type UUIDStruct struct {
92+
Value UUID `json:"value"`
93+
}
94+
95+
func TestUUID(t *testing.T) {
96+
valLong := `{"value": 4801878}`
97+
valString := `{"value": "994801878"}`
98+
valBool := `{"value": false}`
99+
res := UUIDStruct{}
100+
101+
res.Value = ""
102+
if err := json.Unmarshal([]byte(valLong), &res); err != nil {
103+
t.Errorf("could not unserialize long into UUID: %s", err)
104+
}
105+
if res.Value != "4801878" {
106+
t.Errorf("unepected value '%s', expecting 4801878", res.Value)
107+
}
108+
109+
res.Value = ""
110+
if err := json.Unmarshal([]byte(valString), &res); err != nil {
111+
t.Errorf("could not unserialize string into UUID: %s", err)
112+
}
113+
if res.Value != "994801878" {
114+
t.Errorf("unepected value '%s', expecting 994801878", res.Value)
115+
}
116+
117+
res.Value = ""
118+
if err := json.Unmarshal([]byte(valBool), &res); err == nil {
119+
t.Errorf("missing expected error when serializing bool into UUID")
120+
}
121+
}

generate/generate.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ var nestedResponse = map[string]string{
7171
"getUploadParamsForVolume": "getuploadparams",
7272
}
7373

74+
// longToStringConvertedParams is a prefilled map with the list of
75+
// response fields that migrated from long to string within
76+
// the current major baseline. This fields will be parsed from
77+
// json as string and then fallback on long.
78+
var longToStringConvertedParams = map[string]bool{
79+
"managementserverid": true,
80+
}
81+
7482
// We prefill this one value to make sure it is not
7583
// created twice, as this is also a top level type.
7684
var typeNames = map[string]bool{"Nic": true}
@@ -301,6 +309,27 @@ func (as *allServices) GeneralCode() ([]byte, error) {
301309
pn(" return fmt.Errorf(\"CloudStack API error %%d (CSExceptionErrorCode: %%d): %%s\", e.ErrorCode, e.CSErrorCode, e.ErrorText)")
302310
pn("}")
303311
pn("")
312+
313+
pn("type UUID string")
314+
pn("")
315+
pn("func (c UUID) MarshalJSON() ([]byte, error) {")
316+
pn(" return json.Marshal(string(c))")
317+
pn("}")
318+
pn("")
319+
pn("func (c *UUID) UnmarshalJSON(data []byte) error {")
320+
pn(" value := strings.Trim(string(data), \"\\\"\")")
321+
pn(" if strings.HasPrefix(string(data), \"\\\"\") {")
322+
pn(" *c = UUID(value)")
323+
pn(" return nil")
324+
pn(" }")
325+
pn(" _, err := strconv.ParseInt(value, 10, 64)")
326+
pn(" if err != nil {")
327+
pn(" return err")
328+
pn(" }")
329+
pn(" *c = UUID(value)")
330+
pn(" return nil")
331+
pn("}")
332+
304333
pn("type CloudStackClient struct {")
305334
pn(" HTTPGETOnly bool // If `true` only use HTTP GET calls")
306335
pn("")
@@ -1802,7 +1831,13 @@ func sourceDir() (string, error) {
18021831
}
18031832

18041833
func mapType(aName string, pName string, pType string) string {
1834+
if _, ok := longToStringConvertedParams[pName]; ok {
1835+
pType = "UUID"
1836+
}
1837+
18051838
switch pType {
1839+
case "UUID":
1840+
return "UUID"
18061841
case "boolean":
18071842
return "bool"
18081843
case "short", "int", "integer":

0 commit comments

Comments
 (0)