Merge pull request #8241 from carlpett/bump-proxmox-api

Bump proxmox dependency
This commit is contained in:
Adrien Delorme 2019-10-29 14:45:41 +01:00 committed by GitHub
commit 889ab163f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 189 additions and 67 deletions

2
go.mod
View File

@ -10,7 +10,7 @@ require (
github.com/NaverCloudPlatform/ncloud-sdk-go v0.0.0-20180110055012-c2e73f942591
github.com/PuerkitoBio/goquery v1.5.0 // indirect
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/Telmate/proxmox-api-go v0.0.0-20190815172943-ef9222844e60
github.com/Telmate/proxmox-api-go v0.0.0-20191015171801-b0c2796b9fcf
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af // indirect
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190418113227-25233c783f4e
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20170113022742-e6dbea820a9f

2
go.sum
View File

@ -29,6 +29,8 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUW
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/Telmate/proxmox-api-go v0.0.0-20190815172943-ef9222844e60 h1:iEmbIRk4brAP3wevhCr5MGAqxHUbbIDHvE+6D1/7pRA=
github.com/Telmate/proxmox-api-go v0.0.0-20190815172943-ef9222844e60/go.mod h1:OGWyIMJ87/k/GCz8CGiWB2HOXsOVDM6Lpe/nFPkC4IQ=
github.com/Telmate/proxmox-api-go v0.0.0-20191015171801-b0c2796b9fcf h1:rVT2xsBm03Jp0r0yfGm5AMlqp0mZmxTTiNnSrc9S+Hs=
github.com/Telmate/proxmox-api-go v0.0.0-20191015171801-b0c2796b9fcf/go.mod h1:OGWyIMJ87/k/GCz8CGiWB2HOXsOVDM6Lpe/nFPkC4IQ=
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=

View File

@ -3,12 +3,14 @@ package proxmox
// inspired by https://github.com/Telmate/vagrant-proxmox/blob/master/lib/vagrant-proxmox/proxmox/connection.rb
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net"
"net/http"
"regexp"
@ -57,7 +59,7 @@ func (vmr *VmRef) SetVmType(vmType string) {
return
}
func (vmr *VmRef) GetVmType() (string) {
func (vmr *VmRef) GetVmType() string {
return vmr.vmType
}
@ -90,7 +92,7 @@ func NewClient(apiUrl string, hclient *http.Client, tls *tls.Config) (client *Cl
func (c *Client) Login(username string, password string, otp string) (err error) {
c.Username = username
c.Password = password
c.Otp = otp
c.Otp = otp
return c.session.Login(username, password, otp)
}
@ -135,6 +137,10 @@ func (c *Client) GetVmInfo(vmr *VmRef) (vmInfo map[string]interface{}, err error
vmInfo = vm
vmr.node = vmInfo["node"].(string)
vmr.vmType = vmInfo["type"].(string)
vmr.pool = ""
if vmInfo["pool"] != nil {
vmr.pool = vmInfo["pool"].(string)
}
return
}
}
@ -150,6 +156,10 @@ func (c *Client) GetVmRefByName(vmName string) (vmr *VmRef, err error) {
vmr = NewVmRef(int(vm["vmid"].(float64)))
vmr.node = vm["node"].(string)
vmr.vmType = vm["type"].(string)
vmr.pool = ""
if vm["pool"] != nil {
vmr.pool = vm["pool"].(string)
}
return
}
}
@ -667,6 +677,50 @@ func (c *Client) DeleteVMDisks(
return nil
}
func (c *Client) Upload(node string, storage string, contentType string, filename string, file io.Reader) error {
body, mimetype, err := createUploadBody(contentType, filename, file)
if err != nil {
return err
}
url := fmt.Sprintf("%s/nodes/%s/storage/%s/upload", c.session.ApiUrl, node, storage)
req, err := c.session.NewRequest(http.MethodPost, url, nil, body)
if err != nil {
return err
}
req.Header.Add("Content-Type", mimetype)
req.Header.Add("Accept", "application/json")
_, err = c.session.Do(req)
return err
}
func createUploadBody(contentType string, filename string, r io.Reader) (io.Reader, string, error) {
var buf bytes.Buffer
w := multipart.NewWriter(&buf)
err := w.WriteField("content", contentType)
if err != nil {
return nil, "", err
}
fw, err := w.CreateFormFile("filename", filename)
if err != nil {
return nil, "", err
}
_, err = io.Copy(fw, r)
if err != nil {
return nil, "", err
}
err = w.Close()
if err != nil {
return nil, "", err
}
return &buf, w.FormDataContentType(), nil
}
// getStorageAndVolumeName - Extract disk storage and disk volume, since disk name is saved
// in Proxmox with its storage.
func getStorageAndVolumeName(
@ -685,3 +739,51 @@ func getStorageAndVolumeName(
return storageName, volumeName
}
func (c *Client) UpdateVMPool(vmr *VmRef, pool string) (exitStatus interface{}, err error) {
// Same pool
if vmr.pool == pool {
return
}
// Remove from old pool
if vmr.pool != "" {
paramMap := map[string]interface{}{
"vms": vmr.vmId,
"delete": 1,
}
reqbody := ParamsToBody(paramMap)
url := fmt.Sprintf("/pools/%s", vmr.pool)
resp, err := c.session.Put(url, nil, nil, &reqbody)
if err == nil {
taskResponse, err := ResponseJSON(resp)
if err != nil {
return nil, err
}
exitStatus, err = c.WaitForCompletion(taskResponse)
if err != nil {
return nil, err
}
}
}
// Add to the new pool
if pool != "" {
paramMap := map[string]interface{}{
"vms": vmr.vmId,
}
reqbody := ParamsToBody(paramMap)
url := fmt.Sprintf("/pools/%s", pool)
resp, err := c.session.Put(url, nil, nil, &reqbody)
if err == nil {
taskResponse, err := ResponseJSON(resp)
if err != nil {
return nil, err
}
exitStatus, err = c.WaitForCompletion(taskResponse)
} else {
return nil, err
}
}
return
}

View File

@ -5,66 +5,66 @@ import (
"fmt"
"io"
"log"
"strings"
"strconv"
"strings"
)
// LXC options for the Proxmox API
type configLxc struct {
Ostemplate string `json:"ostemplate"`
Arch string `json:"arch"`
BWLimit int `json:"bwlimit,omitempty"`
CMode string `json:"cmode"`
Console bool `json:"console"`
Cores int `json:"cores,omitempty"`
CPULimit int `json:"cpulimit"`
CPUUnits int `json:"cpuunits"`
Description string `json:"description,omitempty"`
Features QemuDevice `json:"features,omitempty"`
Force bool `json:"force,omitempty"`
Hookscript string `json:"hookscript,omitempty"`
Hostname string `json:"hostname,omitempty"`
IgnoreUnpackErrors bool `json:"ignore-unpack-errors,omitempty"`
Lock string `json:"lock,omitempty"`
Memory int `json:"memory"`
Mountpoints QemuDevices `json:"mountpoints,omitempty"`
Nameserver string `json:"nameserver,omitempty"`
Networks QemuDevices `json:"networks,omitempty"`
OnBoot bool `json:"onboot"`
OsType string `json:"ostype,omitempty"`
Password string `json:"password,omitempty"`
Pool string `json:"pool,omitempty"`
Protection bool `json:"protection"`
Restore bool `json:"restore,omitempty"`
RootFs string `json:"rootfs,omitempty"`
SearchDomain string `json:"searchdomain,omitempty"`
SSHPublicKeys string `json:"ssh-public-keys,omitempty"`
Start bool `json:"start"`
Startup string `json:"startup,omitempty"`
Storage string `json:"storage"`
Swap int `json:"swap"`
Template bool `json:"template,omitempty"`
Tty int `json:"tty"`
Unique bool `json:"unique,omitempty"`
Unprivileged bool `json:"unprivileged"`
Unused []string `json:"unused,omitempty"`
Ostemplate string `json:"ostemplate"`
Arch string `json:"arch"`
BWLimit int `json:"bwlimit,omitempty"`
CMode string `json:"cmode"`
Console bool `json:"console"`
Cores int `json:"cores,omitempty"`
CPULimit int `json:"cpulimit"`
CPUUnits int `json:"cpuunits"`
Description string `json:"description,omitempty"`
Features QemuDevice `json:"features,omitempty"`
Force bool `json:"force,omitempty"`
Hookscript string `json:"hookscript,omitempty"`
Hostname string `json:"hostname,omitempty"`
IgnoreUnpackErrors bool `json:"ignore-unpack-errors,omitempty"`
Lock string `json:"lock,omitempty"`
Memory int `json:"memory"`
Mountpoints QemuDevices `json:"mountpoints,omitempty"`
Nameserver string `json:"nameserver,omitempty"`
Networks QemuDevices `json:"networks,omitempty"`
OnBoot bool `json:"onboot"`
OsType string `json:"ostype,omitempty"`
Password string `json:"password,omitempty"`
Pool string `json:"pool,omitempty"`
Protection bool `json:"protection"`
Restore bool `json:"restore,omitempty"`
RootFs string `json:"rootfs,omitempty"`
SearchDomain string `json:"searchdomain,omitempty"`
SSHPublicKeys string `json:"ssh-public-keys,omitempty"`
Start bool `json:"start"`
Startup string `json:"startup,omitempty"`
Storage string `json:"storage"`
Swap int `json:"swap"`
Template bool `json:"template,omitempty"`
Tty int `json:"tty"`
Unique bool `json:"unique,omitempty"`
Unprivileged bool `json:"unprivileged"`
Unused []string `json:"unused,omitempty"`
}
func NewConfigLxc() (configLxc) {
func NewConfigLxc() configLxc {
return configLxc{
Arch: "amd64",
CMode: "tty",
Console: true,
CPULimit: 0,
CPUUnits: 1024,
Memory: 512,
OnBoot: false,
Protection: false,
Start: false,
Storage: "local",
Swap: 512,
Template: false,
Tty: 2,
Arch: "amd64",
CMode: "tty",
Console: true,
CPULimit: 0,
CPUUnits: 1024,
Memory: 512,
OnBoot: false,
Protection: false,
Start: false,
Storage: "local",
Swap: 512,
Template: false,
Tty: 2,
Unprivileged: false,
}
}
@ -162,7 +162,7 @@ func NewConfigLxcFromApi(vmr *VmRef, client *Client) (config *configLxc, err err
mpNames := []string{}
for k, _ := range lxcConfig {
if mpName:= rxMpName.FindStringSubmatch(k); len(mpName) > 0 {
if mpName := rxMpName.FindStringSubmatch(k); len(mpName) > 0 {
mpNames = append(mpNames, mpName[0])
}
}
@ -175,7 +175,7 @@ func NewConfigLxcFromApi(vmr *VmRef, client *Client) (config *configLxc, err err
mpID, _ := strconv.Atoi(id[0])
// add mp id
mpConfMap := QemuDevice{
"id": mpID,
"id": mpID,
}
// add rest of device config
mpConfMap.readDeviceConfig(mpConfList)
@ -211,7 +211,7 @@ func NewConfigLxcFromApi(vmr *VmRef, client *Client) (config *configLxc, err err
nicID, _ := strconv.Atoi(id[0])
// add nic id
nicConfMap := QemuDevice{
"id": nicID,
"id": nicID,
}
// add rest of device config
nicConfMap.readDeviceConfig(nicConfList)

View File

@ -25,6 +25,7 @@ type (
type ConfigQemu struct {
Name string `json:"name"`
Description string `json:"desc"`
Pool string `json:"pool,omitempty"`
Onboot bool `json:"onboot"`
Agent int `json:"agent"`
Memory int `json:"memory"`
@ -63,9 +64,10 @@ type ConfigQemu struct {
Nameserver string `json:"nameserver"`
Sshkeys string `json:"sshkeys"`
// arrays are hard, support 2 interfaces for now
// arrays are hard, support 3 interfaces for now
Ipconfig0 string `json:"ipconfig0"`
Ipconfig1 string `json:"ipconfig1"`
Ipconfig2 string `json:"ipconfig2"`
}
// CreateVm - Tell Proxmox API to make the VM
@ -156,16 +158,19 @@ func (config ConfigQemu) CloneVm(sourceVmr *VmRef, vmr *VmRef, client *Client) (
storage = disk0Storage
}
params := map[string]interface{}{
"newid": vmr.vmId,
"target": vmr.node,
"name": config.Name,
"storage": storage,
"full": fullclone,
"newid": vmr.vmId,
"target": vmr.node,
"name": config.Name,
"full": fullclone,
}
if vmr.pool != "" {
params["pool"] = vmr.pool
}
if fullclone == "1" {
params["storage"] = storage
}
_, err = client.CloneQemuVm(sourceVmr, params)
if err != nil {
return
@ -234,7 +239,17 @@ func (config ConfigQemu) UpdateConfig(vmr *VmRef, client *Client) (err error) {
if config.Ipconfig1 != "" {
configParams["ipconfig1"] = config.Ipconfig1
}
if config.Ipconfig2 != "" {
configParams["ipconfig2"] = config.Ipconfig2
}
_, err = client.SetVmConfig(vmr, configParams)
if err != nil {
log.Fatal(err)
return err
}
_, err = client.UpdateVMPool(vmr, config.Pool)
return err
}
@ -404,6 +419,9 @@ func NewConfigQemuFromApi(vmr *VmRef, client *Client) (config *ConfigQemu, err e
if _, isSet := vmConfig["ipconfig1"]; isSet {
config.Ipconfig1 = vmConfig["ipconfig1"].(string)
}
if _, isSet := vmConfig["ipconfig2"]; isSet {
config.Ipconfig2 = vmConfig["ipconfig2"].(string)
}
// Add disks.
diskNames := []string{}

View File

@ -163,7 +163,7 @@ func (s *Session) Do(req *http.Request) (*http.Response, error) {
if *Debug {
d, _ := httputil.DumpRequestOut(req, true)
log.Printf(">>>>>>>>>> REQUEST:\n", string(d))
log.Printf(">>>>>>>>>> REQUEST:\n%v", string(d))
}
resp, err := s.httpClient.Do(req)
@ -174,7 +174,7 @@ func (s *Session) Do(req *http.Request) (*http.Response, error) {
if *Debug {
dr, _ := httputil.DumpResponse(resp, true)
log.Printf("<<<<<<<<<< RESULT:\n", string(dr))
log.Printf("<<<<<<<<<< RESULT:\n%v", string(dr))
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {

2
vendor/modules.txt vendored
View File

@ -59,7 +59,7 @@ github.com/NaverCloudPlatform/ncloud-sdk-go/sdk
github.com/PuerkitoBio/goquery
# github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d
github.com/StackExchange/wmi
# github.com/Telmate/proxmox-api-go v0.0.0-20190815172943-ef9222844e60
# github.com/Telmate/proxmox-api-go v0.0.0-20191015171801-b0c2796b9fcf
github.com/Telmate/proxmox-api-go/proxmox
# github.com/agext/levenshtein v1.2.1
github.com/agext/levenshtein