0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 10:33:46 +00:00
terraform-provider-proxmox/fwprovider/vm/cloudinit/resource.go
Pavel Boldyrev 9eb497fa95
stopped at clone
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
2024-09-22 21:34:21 -04:00

155 lines
4.0 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 cloudinit
import (
"context"
"fmt"
"reflect"
"strings"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types"
"github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr"
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
)
// NewValue returns a new Value with the given CPU settings from the PVE API.
func NewValue(ctx context.Context, config *vms.GetResponseData, vmID int, diags *diag.Diagnostics) *Model {
ci := Model{}
devices := config.CustomStorageDevices.Filter(func(device *vms.CustomStorageDevice) bool {
return device.IsCloudInitDrive(vmID)
})
if len(devices) != 1 {
return nil
}
for iface, device := range devices {
ci.Interface = types.StringValue(iface)
ci.DatastoreID = types.StringValue(device.GetDatastoreID())
dns := ModelDNS{}
dns.Domain = types.StringPointerValue(config.CloudInitDNSDomain)
if config.CloudInitDNSServer != nil {
dnsServers := strings.Split(*config.CloudInitDNSServer, " ")
servers, d := types.ListValueFrom(ctx, customtypes.IPAddrType{}, dnsServers)
diags.Append(d...)
dns.Servers = servers
} else {
dns.Servers = types.ListNull(customtypes.IPAddrType{})
}
if !reflect.DeepEqual(dns, ModelDNS{}) {
ci.DNS = &dns
}
return &ci
}
return nil
}
// FillCreateBody fills the CreateRequestBody with the Cloud-Init settings from the Value.
func FillCreateBody(ctx context.Context, plan *Model, body *vms.CreateRequestBody) {
if plan == nil {
return
}
ci := vms.CustomCloudInitConfig{}
if plan.DNS != nil {
dns := *plan.DNS
if !dns.Domain.IsUnknown() {
ci.SearchDomain = dns.Domain.ValueStringPointer()
}
if !dns.Servers.IsUnknown() {
var servers []string
dns.Servers.ElementsAs(ctx, &servers, false)
ci.Nameserver = ptr.Ptr(strings.Join(servers, " "))
}
}
body.CloudInitConfig = &ci
device := vms.CustomStorageDevice{
Enabled: true,
FileVolume: fmt.Sprintf("%s:cloudinit", plan.DatastoreID.ValueString()),
Media: ptr.Ptr("cdrom"),
}
body.AddCustomStorageDevice(plan.Interface.ValueString(), device)
}
// FillUpdateBody fills the UpdateRequestBody with the CPU settings from the Value.
func FillUpdateBody(
ctx context.Context,
plan, state *Model,
updateBody *vms.UpdateRequestBody,
isClone bool,
diags *diag.Diagnostics,
) {
if plan == nil || reflect.DeepEqual(plan, state) {
return
}
del := func(field ...string) {
updateBody.Delete = append(updateBody.Delete, field...)
}
// TODO: migrate cloud init to another datastore
if !reflect.DeepEqual(plan.DNS, state.DNS) {
if plan.DNS == nil && state.DNS != nil && !isClone {
del("searchdomain", "nameserver")
} else if plan.DNS != nil {
ci := vms.CustomCloudInitConfig{}
planDNS := plan.DNS
stateDNS := state.DNS
if !planDNS.Domain.Equal(stateDNS.Domain) {
if attribute.ShouldBeRemoved(planDNS.Domain, stateDNS.Domain, isClone) {
del("searchdomain")
} else if attribute.IsDefined(planDNS.Domain) {
ci.SearchDomain = planDNS.Domain.ValueStringPointer()
}
}
if !planDNS.Servers.Equal(stateDNS.Servers) {
if attribute.ShouldBeRemoved(planDNS.Servers, stateDNS.Servers, isClone) {
del("nameserver")
} else if attribute.IsDefined(planDNS.Servers) {
// TODO: duplicates code from FillCreateBody
var servers []string
planDNS.Servers.ElementsAs(ctx, &servers, false)
//// special case for the servers list, if we want to remove them during update
//if len(servers) == 0 {
// del("nameserver")
//} else {
ci.Nameserver = ptr.Ptr(strings.Join(servers, " "))
//}
}
}
updateBody.CloudInitConfig = &ci
}
}
}