fix(pve): 修复PVE API认证和VM状态查询路径
- PVE ticket字段名是'ticket'不是'PVEAuthCookie'
- Cookie header格式应为 PVEAuthCookie=<ticket>
- VM状态API路径改为 /status/current
- VM列表API从cluster级改为node级 /nodes/{node}/qemu
- vmid从int解析再转string
[砚砚/K2.6🐾]
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -81,16 +82,21 @@ func (c *PVEClient) Login() error {
|
||||
var result struct {
|
||||
Data struct {
|
||||
CSRFToken string `json:"CSRFPreventionToken"`
|
||||
Cookie string `json:"PVEAuthCookie"`
|
||||
Ticket string `json:"ticket"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return err
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read login response failed: %v", err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return fmt.Errorf("decode login response failed: %v, body: %s", err, string(body))
|
||||
}
|
||||
|
||||
c.CSRFToken = result.Data.CSRFToken
|
||||
c.Cookie = result.Data.Cookie
|
||||
c.Cookie = "PVEAuthCookie=" + result.Data.Ticket
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -103,7 +109,7 @@ func (c *PVEClient) GetVMStatus(vmid string) (*models.PVEVMStatus, error) {
|
||||
}
|
||||
|
||||
// 获取 node 名称(通常是 pve)
|
||||
statusURL := c.baseURL() + "/api2/json/nodes/" + c.NodeName + "/qemu/" + vmid + "/status"
|
||||
statusURL := c.baseURL() + "/api2/json/nodes/" + c.NodeName + "/qemu/" + vmid + "/status/current"
|
||||
|
||||
req, err := http.NewRequest("GET", statusURL, nil)
|
||||
if err != nil {
|
||||
@@ -246,7 +252,7 @@ func (c *PVEClient) GetVMList() ([]struct {
|
||||
}
|
||||
}
|
||||
|
||||
listURL := c.baseURL() + "/api2/json/cluster/resources?type=vm"
|
||||
listURL := c.baseURL() + "/api2/json/nodes/" + c.NodeName + "/qemu"
|
||||
|
||||
req, err := http.NewRequest("GET", listURL, nil)
|
||||
if err != nil {
|
||||
@@ -262,22 +268,45 @@ func (c *PVEClient) GetVMList() ([]struct {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("get vm list failed, status: %d", resp.StatusCode)
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return nil, fmt.Errorf("get vm list failed, status: %d, body: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read vm list body failed: %v", err)
|
||||
}
|
||||
|
||||
var result struct {
|
||||
Data []struct {
|
||||
VMID string `json:"vmid"`
|
||||
VMID int `json:"vmid"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return nil, err
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("decode vm list failed: %v, body: %s", err, string(body))
|
||||
}
|
||||
|
||||
return result.Data, nil
|
||||
// vmid 是 int,转换为 string
|
||||
vms := make([]struct {
|
||||
VMID string `json:"vmid"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
}, len(result.Data))
|
||||
for i, vm := range result.Data {
|
||||
vms[i] = struct {
|
||||
VMID string `json:"vmid"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
VMID: strconv.Itoa(vm.VMID),
|
||||
Name: vm.Name,
|
||||
Status: vm.Status,
|
||||
}
|
||||
}
|
||||
return vms, nil
|
||||
}
|
||||
|
||||
// PVEHostService PVE 主机服务
|
||||
|
||||
Reference in New Issue
Block a user