From dabb51961c174ed8e882d821fa42b407e2aedb77 Mon Sep 17 00:00:00 2001 From: Starttoaster Date: Thu, 19 Sep 2024 23:37:50 +0000 Subject: [PATCH 1/7] Set RPM to IntOrString type --- nodes.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/nodes.go b/nodes.go index ddd4b1f..707dd55 100644 --- a/nodes.go +++ b/nodes.go @@ -214,20 +214,20 @@ type GetNodeDisksListResponse struct { // GetNodeDisksListData contains data of disks from a GetNodeDisksList response type GetNodeDisksListData struct { - ByIDLink string `json:"by_id_link"` - DevPath string `json:"devpath"` - GPT int `json:"gpt"` - Health string `json:"health"` - Model string `json:"model"` - RPM int `json:"rpm"` - Serial string `json:"serial"` - Size int `json:"size"` - Type string `json:"type"` - Used string `json:"used"` - Vendor string `json:"vendor"` - WWN string `json:"wwn"` - Bluestore int `json:"bluestore,omitempty"` - OSDEncrypted int `json:"osdencrypted,omitempty"` + ByIDLink string `json:"by_id_link"` + DevPath string `json:"devpath"` + GPT int `json:"gpt"` + Health string `json:"health"` + Model string `json:"model"` + RPM IntOrString `json:"rpm"` + Serial string `json:"serial"` + Size int `json:"size"` + Type string `json:"type"` + Used string `json:"used"` + Vendor string `json:"vendor"` + WWN string `json:"wwn"` + Bluestore int `json:"bluestore,omitempty"` + OSDEncrypted int `json:"osdencrypted,omitempty"` } // GetNodeDisksList makes a GET request to the /nodes/{node}/disks/list endpoint From 12b843b9048fc4560e0d6bceffaf5c8e1c95a59e Mon Sep 17 00:00:00 2001 From: Starttoaster Date: Thu, 19 Sep 2024 23:52:34 +0000 Subject: [PATCH 2/7] Don't close the response body for the user --- request.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/request.go b/request.go index 2b84ccb..2bc6362 100644 --- a/request.go +++ b/request.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "io" - "log" "net/http" "net/url" @@ -61,16 +60,6 @@ func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) { if err != nil { return nil, err } - defer func() { - if err := resp.Body.Close(); err != nil { - log.Printf("proxmox client couldn't close the response body: %v", err) - } - }() - defer func() { - if _, err := io.Copy(io.Discard, resp.Body); err != nil { - log.Printf("proxmox client couldn't discard the response body: %v", err) - } - }() // Check for error API response and capture it as an error // 3xx codes get treated as errors, unclear if there's a valid reason for redirection here From 6c84c8dd527db6565b010369baf095a7ae9be06d Mon Sep 17 00:00:00 2001 From: Starttoaster Date: Fri, 20 Sep 2024 00:03:13 +0000 Subject: [PATCH 3/7] Switch back to int --- nodes.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/nodes.go b/nodes.go index 707dd55..ddd4b1f 100644 --- a/nodes.go +++ b/nodes.go @@ -214,20 +214,20 @@ type GetNodeDisksListResponse struct { // GetNodeDisksListData contains data of disks from a GetNodeDisksList response type GetNodeDisksListData struct { - ByIDLink string `json:"by_id_link"` - DevPath string `json:"devpath"` - GPT int `json:"gpt"` - Health string `json:"health"` - Model string `json:"model"` - RPM IntOrString `json:"rpm"` - Serial string `json:"serial"` - Size int `json:"size"` - Type string `json:"type"` - Used string `json:"used"` - Vendor string `json:"vendor"` - WWN string `json:"wwn"` - Bluestore int `json:"bluestore,omitempty"` - OSDEncrypted int `json:"osdencrypted,omitempty"` + ByIDLink string `json:"by_id_link"` + DevPath string `json:"devpath"` + GPT int `json:"gpt"` + Health string `json:"health"` + Model string `json:"model"` + RPM int `json:"rpm"` + Serial string `json:"serial"` + Size int `json:"size"` + Type string `json:"type"` + Used string `json:"used"` + Vendor string `json:"vendor"` + WWN string `json:"wwn"` + Bluestore int `json:"bluestore,omitempty"` + OSDEncrypted int `json:"osdencrypted,omitempty"` } // GetNodeDisksList makes a GET request to the /nodes/{node}/disks/list endpoint From 1f1c4595406a61e255c6c3e5f6b81506b2a23b91 Mon Sep 17 00:00:00 2001 From: Starttoaster Date: Sat, 21 Sep 2024 00:37:37 +0000 Subject: [PATCH 4/7] Fix IntOrString unmarshaler to allow zero values --- types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types.go b/types.go index 585a8e5..fa20f9e 100644 --- a/types.go +++ b/types.go @@ -69,7 +69,7 @@ func (is *IntOrString) UnmarshalJSON(data []byte) error { // attempt to unmarshal into an integer var i int var intErr error - if intErr = json.Unmarshal(data, &i); intErr == nil && i != 0 { + if intErr = json.Unmarshal(data, &i); intErr == nil { *is = IntOrString(strconv.Itoa(i)) return nil } @@ -77,7 +77,7 @@ func (is *IntOrString) UnmarshalJSON(data []byte) error { // attempt to unmarshal into a string var str string var strErr error - if strErr = json.Unmarshal(data, &str); strErr == nil && str != "" { + if strErr = json.Unmarshal(data, &str); strErr == nil { *is = IntOrString(str) return nil } From 407008ab7bfc5e1e1921fab3ecab3e24a26489ae Mon Sep 17 00:00:00 2001 From: Starttoaster Date: Sat, 21 Sep 2024 00:38:17 +0000 Subject: [PATCH 5/7] Fix list disk function type for Int and String RPM representations --- nodes.go | 29 +++---- nodes_test.go | 101 ++++++++++++++++++++++++ testdata/nodes/get_node_disks_list.json | 93 ++++++++++++++++++++++ 3 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 testdata/nodes/get_node_disks_list.json diff --git a/nodes.go b/nodes.go index ddd4b1f..15621ee 100644 --- a/nodes.go +++ b/nodes.go @@ -214,20 +214,21 @@ type GetNodeDisksListResponse struct { // GetNodeDisksListData contains data of disks from a GetNodeDisksList response type GetNodeDisksListData struct { - ByIDLink string `json:"by_id_link"` - DevPath string `json:"devpath"` - GPT int `json:"gpt"` - Health string `json:"health"` - Model string `json:"model"` - RPM int `json:"rpm"` - Serial string `json:"serial"` - Size int `json:"size"` - Type string `json:"type"` - Used string `json:"used"` - Vendor string `json:"vendor"` - WWN string `json:"wwn"` - Bluestore int `json:"bluestore,omitempty"` - OSDEncrypted int `json:"osdencrypted,omitempty"` + ByIDLink string `json:"by_id_link"` + DevPath string `json:"devpath"` + GPT int `json:"gpt"` + Health string `json:"health"` + Model string `json:"model"` + RPM IntOrString `json:"rpm"` + Serial string `json:"serial"` + Size int `json:"size"` + Type string `json:"type"` + Used string `json:"used"` + Vendor string `json:"vendor"` + WWN string `json:"wwn"` + Wearout IntOrString `json:"wearout"` + Bluestore int `json:"bluestore,omitempty"` + OSDEncrypted int `json:"osdencrypted,omitempty"` } // GetNodeDisksList makes a GET request to the /nodes/{node}/disks/list endpoint diff --git a/nodes_test.go b/nodes_test.go index bb0c897..04b0103 100644 --- a/nodes_test.go +++ b/nodes_test.go @@ -155,3 +155,104 @@ func TestGetNodeQemu(t *testing.T) { require.NotNil(t, resp) require.Equal(t, want, *r) } + +func TestGetNodeDisksList(t *testing.T) { + mux, server, client := setup(t) + defer teardown(server) + + mux.HandleFunc("/api2/json/nodes/srv1/disks/list", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, err := fmt.Fprint(w, fixture("nodes/get_node_disks_list.json")) + if err != nil { + return + } + }) + + want := GetNodeDisksListResponse{ + Data: []GetNodeDisksListData{ + { + DevPath: "/dev/nvme0n1", + WWN: "testwwn", + Serial: "testser", + ByIDLink: "/dev/disk/by-id/nvme-drive", + Size: 512110190592, + Used: "BIOS boot", + RPM: IntOrString("0"), + Wearout: IntOrString("99"), + GPT: 1, + Health: "PASSED", + Model: "Test Model", + Vendor: "unknown", + Type: "nvme", + }, + { + Serial: "testser", + ByIDLink: "/dev/disk/by-id/ata-TOSHIBA_THNS", + Bluestore: 1, + DevPath: "/dev/sda", + OSDEncrypted: 0, + Type: "ssd", + Health: "PASSED", + RPM: IntOrString("0"), + Wearout: IntOrString("N/A"), + GPT: 0, + Vendor: "unknown", + Size: 1920383410176, + Model: "Test Model", + WWN: "testwwn", + Used: "LVM", + }, + { + DevPath: "/dev/sda", + WWN: "testwwn", + Serial: "testser", + ByIDLink: "/dev/disk/by-id/ata-ST2000", + Size: 2000398934016, + Used: "LVM", + RPM: IntOrString("5400"), + Wearout: IntOrString("N/A"), + GPT: 0, + Health: "PASSED", + Model: "Test Model", + Vendor: "unknown", + Type: "hdd", + }, + { + DevPath: "/dev/sdc", + WWN: "testwwn", + Serial: "testser", + ByIDLink: "/dev/disk/by-id/ata-WDC_DRIVE2", + Size: 5000947302400, + Used: "ext4", + RPM: IntOrString("4800"), + Wearout: IntOrString("N/A"), + GPT: 0, + Health: "PASSED", + Model: "Test Model", + Vendor: "unknown", + Type: "hdd", + }, + { + DevPath: "/dev/sde", + WWN: "testwwn", + Serial: "testser", + ByIDLink: "/dev/disk/by-id/ata-WDC_DRIVE1", + Size: 5000947302400, + Used: "ZFS", + RPM: IntOrString("4800"), + Wearout: IntOrString("N/A"), + GPT: 0, + Health: "PASSED", + Model: "Test Model", + Vendor: "unknown", + Type: "hdd", + }, + }, + } + + r, resp, err := client.Nodes.GetNodeDisksList("srv1") + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, want, *r) +} diff --git a/testdata/nodes/get_node_disks_list.json b/testdata/nodes/get_node_disks_list.json new file mode 100644 index 0000000..995782b --- /dev/null +++ b/testdata/nodes/get_node_disks_list.json @@ -0,0 +1,93 @@ +{ + "data": [ + { + "devpath": "/dev/nvme0n1", + "wwn": "testwwn", + "serial": "testser", + "by_id_link": "/dev/disk/by-id/nvme-drive", + "size": 512110190592, + "used": "BIOS boot", + "osdid": -1, + "rpm": 0, + "wearout": 99, + "gpt": 1, + "osdid-list": null, + "health": "PASSED", + "model": "Test Model", + "vendor": "unknown", + "type": "nvme" + }, + { + "serial": "testser", + "by_id_link": "/dev/disk/by-id/ata-TOSHIBA_THNS", + "bluestore": 1, + "devpath": "/dev/sda", + "osdencrypted": 0, + "type": "ssd", + "osdid-list":[ + "1" + ], + "osdid": "1", + "health": "PASSED", + "rpm": 0, + "wearout": "N/A", + "gpt": 0, + "vendor": "unknown", + "size": 1920383410176, + "model": "Test Model", + "wwn": "testwwn", + "used": "LVM" + }, + { + "osdid": -1, + "rpm": "5400", + "serial": "testser", + "by_id_link": "/dev/disk/by-id/ata-ST2000", + "size": 2000398934016, + "used": "LVM", + "devpath": "/dev/sda", + "wwn": "testwwn", + "type": "hdd", + "vendor": "unknown", + "health": "PASSED", + "model": "Test Model", + "gpt": 0, + "osdid-list": null, + "wearout": "N/A" + }, + { + "rpm": "4800", + "osdid": -1, + "by_id_link": "/dev/disk/by-id/ata-WDC_DRIVE2", + "size": 5000947302400, + "used": "ext4", + "serial": "testser", + "wwn": "testwwn", + "devpath": "/dev/sdc", + "type": "hdd", + "vendor": "unknown", + "model": "Test Model", + "health": "PASSED", + "osdid-list": null, + "gpt": 0, + "wearout": "N/A" + }, + { + "size": 5000947302400, + "used": "ZFS", + "by_id_link": "/dev/disk/by-id/ata-WDC_DRIVE1", + "serial": "testser", + "rpm": "4800", + "osdid": -1, + "wwn": "testwwn", + "devpath": "/dev/sde", + "model": "Test Model", + "health": "PASSED", + "type": "hdd", + "vendor": "unknown", + "wearout": "N/A", + "osdid-list": null, + "gpt": 0 + } + ] +} From d858ad777c5fd01fe887071601424ea794c9642e Mon Sep 17 00:00:00 2001 From: Starttoaster Date: Sat, 21 Sep 2024 00:39:27 +0000 Subject: [PATCH 6/7] Add a test case to get node lxc for string VM ID --- nodes_test.go | 18 ++++++++++++++++++ testdata/nodes/get_node_lxc.json | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/nodes_test.go b/nodes_test.go index 04b0103..105a92f 100644 --- a/nodes_test.go +++ b/nodes_test.go @@ -106,6 +106,24 @@ func TestGetNodeLxc(t *testing.T) { Uptime: 0, VMID: IntOrString("103"), }, + { + CPU: 0, + CPUs: 1, + Disk: 0, + DiskRead: 0, + DiskWrite: 0, + MaxDisk: 8589934592, + MaxMem: 536870912, + MaxSwap: 536870912, + Mem: 0, + Name: "CT104", + NetIn: 0, + NetOut: 0, + Status: "stopped", + Type: "lxc", + Uptime: 0, + VMID: IntOrString("104"), + }, }, } diff --git a/testdata/nodes/get_node_lxc.json b/testdata/nodes/get_node_lxc.json index 91f92cd..97e50fa 100644 --- a/testdata/nodes/get_node_lxc.json +++ b/testdata/nodes/get_node_lxc.json @@ -18,6 +18,25 @@ "diskread":0, "netout":0, "mem":0 + }, + { + "status":"stopped", + "maxdisk":8589934592, + "maxswap":536870912, + "swap":0, + "netin":0, + "cpu":0, + "cpus":1, + "type":"lxc", + "maxmem":536870912, + "name":"CT104", + "disk":0, + "diskwrite":0, + "vmid":"104", + "uptime":0, + "diskread":0, + "netout":0, + "mem":0 } ] } From a1c6cad75bf8bca99fdc6bddca7425f47313cce2 Mon Sep 17 00:00:00 2001 From: Starttoaster Date: Sat, 21 Sep 2024 00:40:30 +0000 Subject: [PATCH 7/7] Fix staticcheck lint --- request.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/request.go b/request.go index 2bc6362..feab83b 100644 --- a/request.go +++ b/request.go @@ -2,6 +2,7 @@ package proxmox import ( "encoding/json" + "errors" "fmt" "io" "net/http" @@ -69,7 +70,7 @@ func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) { return nil, fmt.Errorf("error reading Proxmox response body: %v", err) } - return resp, fmt.Errorf(string(body)) + return resp, errors.New(string(body)) } // Copy body into v