0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00
terraform-provider-proxmox/proxmox/nodes/vms/custom_cloud_init.go
Pavel Boldyrev 580381f892
chore(api): refactor nodes/vms/vms_types.go: split into multiple files (#1368)
Split all `Custom*` structs and marshaling code into separate files from `vms_types.go`

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
2024-06-09 04:11:16 +00:00

211 lines
5.5 KiB
Go

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package vms
import (
"encoding/json"
"fmt"
"net/url"
"strings"
)
// CustomCloudInitConfig handles QEMU cloud-init parameters.
type CustomCloudInitConfig struct {
Files *CustomCloudInitFiles `json:"cicustom,omitempty" url:"cicustom,omitempty"`
IPConfig []CustomCloudInitIPConfig `json:"ipconfig,omitempty" url:"ipconfig,omitempty,numbered"`
Nameserver *string `json:"nameserver,omitempty" url:"nameserver,omitempty"`
Password *string `json:"cipassword,omitempty" url:"cipassword,omitempty"`
SearchDomain *string `json:"searchdomain,omitempty" url:"searchdomain,omitempty"`
SSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty" url:"sshkeys,omitempty"`
Type *string `json:"citype,omitempty" url:"citype,omitempty"`
// Can't be reliably set, it is TRUE by default in PVE
// Upgrade *types.CustomBool `json:"ciupgrade,omitempty" url:"ciupgrade,omitempty,int"`
Username *string `json:"ciuser,omitempty" url:"ciuser,omitempty"`
}
// CustomCloudInitFiles handles QEMU cloud-init custom files parameters.
type CustomCloudInitFiles struct {
MetaVolume *string `json:"meta,omitempty" url:"meta,omitempty"`
NetworkVolume *string `json:"network,omitempty" url:"network,omitempty"`
UserVolume *string `json:"user,omitempty" url:"user,omitempty"`
VendorVolume *string `json:"vendor,omitempty" url:"vendor,omitempty"`
}
// CustomCloudInitIPConfig handles QEMU cloud-init IP configuration parameters.
type CustomCloudInitIPConfig struct {
GatewayIPv4 *string `json:"gw,omitempty" url:"gw,omitempty"`
GatewayIPv6 *string `json:"gw6,omitempty" url:"gw6,omitempty"`
IPv4 *string `json:"ip,omitempty" url:"ip,omitempty"`
IPv6 *string `json:"ip6,omitempty" url:"ip6,omitempty"`
}
// CustomCloudInitSSHKeys handles QEMU cloud-init SSH keys parameters.
type CustomCloudInitSSHKeys []string
// EncodeValues converts a CustomCloudInitConfig struct to multiple URL values.
func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
//nolint:nestif
if r.Files != nil {
var volumes []string
if r.Files.MetaVolume != nil {
volumes = append(volumes, fmt.Sprintf("meta=%s", *r.Files.MetaVolume))
}
if r.Files.NetworkVolume != nil {
volumes = append(volumes, fmt.Sprintf("network=%s", *r.Files.NetworkVolume))
}
if r.Files.UserVolume != nil {
volumes = append(volumes, fmt.Sprintf("user=%s", *r.Files.UserVolume))
}
if r.Files.VendorVolume != nil {
volumes = append(volumes, fmt.Sprintf("vendor=%s", *r.Files.VendorVolume))
}
if len(volumes) > 0 {
v.Add("cicustom", strings.Join(volumes, ","))
}
}
for i, c := range r.IPConfig {
var config []string
if c.GatewayIPv4 != nil {
config = append(config, fmt.Sprintf("gw=%s", *c.GatewayIPv4))
}
if c.GatewayIPv6 != nil {
config = append(config, fmt.Sprintf("gw6=%s", *c.GatewayIPv6))
}
if c.IPv4 != nil {
config = append(config, fmt.Sprintf("ip=%s", *c.IPv4))
}
if c.IPv6 != nil {
config = append(config, fmt.Sprintf("ip6=%s", *c.IPv6))
}
if len(config) > 0 {
v.Add(fmt.Sprintf("ipconfig%d", i), strings.Join(config, ","))
}
}
if r.Nameserver != nil {
v.Add("nameserver", *r.Nameserver)
}
if r.Password != nil {
v.Add("cipassword", *r.Password)
}
if r.SearchDomain != nil {
v.Add("searchdomain", *r.SearchDomain)
}
if r.SSHKeys != nil {
v.Add(
"sshkeys",
strings.ReplaceAll(url.QueryEscape(strings.Join(*r.SSHKeys, "\n")), "+", "%20"),
)
}
if r.Type != nil {
v.Add("citype", *r.Type)
}
if r.Username != nil {
v.Add("ciuser", *r.Username)
}
return nil
}
// UnmarshalJSON converts a CustomCloudInitFiles string to an object.
func (r *CustomCloudInitFiles) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return fmt.Errorf("error unmarshalling CustomCloudInitFiles: %w", err)
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 2 {
switch v[0] {
case "meta":
r.MetaVolume = &v[1]
case "network":
r.NetworkVolume = &v[1]
case "user":
r.UserVolume = &v[1]
case "vendor":
r.VendorVolume = &v[1]
}
}
}
return nil
}
// UnmarshalJSON converts a CustomCloudInitIPConfig string to an object.
func (r *CustomCloudInitIPConfig) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return fmt.Errorf("error unmarshalling CustomCloudInitIPConfig: %w", err)
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 2 {
switch v[0] {
case "gw":
r.GatewayIPv4 = &v[1]
case "gw6":
r.GatewayIPv6 = &v[1]
case "ip":
r.IPv4 = &v[1]
case "ip6":
r.IPv6 = &v[1]
}
}
}
return nil
}
// UnmarshalJSON converts a CustomCloudInitFiles string to an object.
func (r *CustomCloudInitSSHKeys) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return fmt.Errorf("error unmarshalling CustomCloudInitSSHKeys: %w", err)
}
s, err := url.QueryUnescape(s)
if err != nil {
return fmt.Errorf("error unescaping CustomCloudInitSSHKeys: %w", err)
}
if s != "" {
*r = strings.Split(strings.TrimSpace(s), "\n")
} else {
*r = []string{}
}
return nil
}