mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
chore(vm): refactoring: extract network device code from vm.go (#1127)
chore(vm): refactoring: extract network code Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
279b41a0e4
commit
29b5438faf
@ -28,7 +28,7 @@ func TestDatastoresInstantiation(t *testing.T) {
|
||||
func TestDatastoresSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Datastores()
|
||||
s := Datastores().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentDatastoresNodeName,
|
||||
|
@ -28,7 +28,7 @@ func TestDNSInstantiation(t *testing.T) {
|
||||
func TestDNSSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := DNS()
|
||||
s := DNS().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentDNSNodeName,
|
||||
|
@ -25,18 +25,18 @@ func TestAliasSchemaInstantiation(t *testing.T) {
|
||||
func TestAliasSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := schema.Resource{Schema: AliasSchema()}
|
||||
s := AliasSchema()
|
||||
|
||||
test.AssertRequiredArguments(t, &r, []string{
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkAliasName,
|
||||
})
|
||||
|
||||
test.AssertComputedAttributes(t, &r, []string{
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkAliasCIDR,
|
||||
mkAliasComment,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, &r, map[string]schema.ValueType{
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkAliasName: schema.TypeString,
|
||||
mkAliasCIDR: schema.TypeString,
|
||||
mkAliasComment: schema.TypeString,
|
||||
|
@ -25,13 +25,13 @@ func TestAliasesSchemaInstantiation(t *testing.T) {
|
||||
func TestAliasesSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := schema.Resource{Schema: AliasesSchema()}
|
||||
s := AliasesSchema()
|
||||
|
||||
test.AssertComputedAttributes(t, &r, []string{
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkAliasesAliasNames,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, &r, map[string]schema.ValueType{
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkAliasesAliasNames: schema.TypeList,
|
||||
})
|
||||
}
|
||||
|
@ -25,24 +25,24 @@ func TestIPSetSchemaInstantiation(t *testing.T) {
|
||||
func TestIPSetSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := schema.Resource{Schema: IPSetSchema()}
|
||||
s := IPSetSchema()
|
||||
|
||||
test.AssertRequiredArguments(t, &r, []string{
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkIPSetName,
|
||||
})
|
||||
|
||||
test.AssertComputedAttributes(t, &r, []string{
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkIPSetCIDR,
|
||||
mkIPSetCIDRComment,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, &r, map[string]schema.ValueType{
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkIPSetName: schema.TypeString,
|
||||
mkIPSetCIDR: schema.TypeList,
|
||||
mkIPSetCIDRComment: schema.TypeString,
|
||||
})
|
||||
|
||||
cird := test.AssertNestedSchemaExistence(t, &r, mkIPSetCIDR)
|
||||
cird := test.AssertNestedSchemaExistence(t, s, mkIPSetCIDR)
|
||||
|
||||
test.AssertComputedAttributes(t, cird, []string{
|
||||
mkIPSetCIDRName,
|
||||
|
@ -25,13 +25,13 @@ func TestIPSetsSchemaInstantiation(t *testing.T) {
|
||||
func TestIPSetsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := schema.Resource{Schema: IPSetsSchema()}
|
||||
s := IPSetsSchema()
|
||||
|
||||
test.AssertComputedAttributes(t, &r, []string{
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkIPSetsIPSetNames,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, &r, map[string]schema.ValueType{
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkIPSetsIPSetNames: schema.TypeList,
|
||||
})
|
||||
}
|
||||
|
@ -25,14 +25,14 @@ func TestRuleSchemaInstantiation(t *testing.T) {
|
||||
func TestRuleSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := schema.Resource{Schema: RuleSchema()}
|
||||
s := RuleSchema()
|
||||
|
||||
test.AssertRequiredArguments(t, &r, []string{
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkRuleAction,
|
||||
mkRuleType,
|
||||
})
|
||||
|
||||
test.AssertComputedAttributes(t, &r, []string{
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkRuleComment,
|
||||
mkRuleDest,
|
||||
mkRuleDPort,
|
||||
@ -45,7 +45,7 @@ func TestRuleSchema(t *testing.T) {
|
||||
mkRuleSPort,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, &r, map[string]schema.ValueType{
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkRulePos: schema.TypeInt,
|
||||
mkRuleAction: schema.TypeString,
|
||||
mkRuleType: schema.TypeString,
|
||||
|
@ -25,18 +25,18 @@ func TestSecurityGroupSchemaInstantiation(t *testing.T) {
|
||||
func TestSecurityGroupSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := schema.Resource{Schema: SecurityGroupSchema()}
|
||||
s := SecurityGroupSchema()
|
||||
|
||||
test.AssertRequiredArguments(t, &r, []string{
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkSecurityGroupName,
|
||||
})
|
||||
|
||||
test.AssertComputedAttributes(t, &r, []string{
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkSecurityGroupComment,
|
||||
mkRules,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, &r, map[string]schema.ValueType{
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkSecurityGroupName: schema.TypeString,
|
||||
mkSecurityGroupComment: schema.TypeString,
|
||||
mkRules: schema.TypeList,
|
||||
|
@ -25,13 +25,13 @@ func TestSecurityGroupsSchemaInstantiation(t *testing.T) {
|
||||
func TestSecurityGroupsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := schema.Resource{Schema: SecurityGroupsSchema()}
|
||||
s := SecurityGroupsSchema()
|
||||
|
||||
test.AssertComputedAttributes(t, &r, []string{
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkSecurityGroupsSecurityGroupNames,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, &r, map[string]schema.ValueType{
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkSecurityGroupsSecurityGroupNames: schema.TypeList,
|
||||
})
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func TestGroupInstantiation(t *testing.T) {
|
||||
func TestGroupSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Group()
|
||||
s := Group().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentGroupID,
|
||||
|
@ -28,7 +28,7 @@ func TestGroupsInstantiation(t *testing.T) {
|
||||
func TestGroupsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Groups()
|
||||
s := Groups().Schema
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentGroupsComments,
|
||||
|
@ -28,7 +28,7 @@ func TestHostsInstantiation(t *testing.T) {
|
||||
func TestHostsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Hosts()
|
||||
s := Hosts().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentHostsNodeName,
|
||||
|
@ -28,7 +28,7 @@ func TestNodesInstantiation(t *testing.T) {
|
||||
func TestNodesSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Nodes()
|
||||
s := Nodes().Schema
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentNodesCPUCount,
|
||||
|
@ -28,7 +28,7 @@ func TestPoolInstantiation(t *testing.T) {
|
||||
func TestPoolSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Pool()
|
||||
s := Pool().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentPoolPoolID,
|
||||
|
@ -28,7 +28,7 @@ func TestPoolsInstantiation(t *testing.T) {
|
||||
func TestPoolsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Pools()
|
||||
s := Pools().Schema
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentPoolsPoolIDs,
|
||||
|
@ -28,7 +28,7 @@ func TestRoleInstantiation(t *testing.T) {
|
||||
func TestRoleSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Role()
|
||||
s := Role().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentRoleID,
|
||||
|
@ -28,7 +28,7 @@ func TestRolesInstantiation(t *testing.T) {
|
||||
func TestRolesSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Roles()
|
||||
s := Roles().Schema
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentRolesPrivileges,
|
||||
|
@ -28,7 +28,7 @@ func TestTimeInstantiation(t *testing.T) {
|
||||
func TestTimeSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Time()
|
||||
s := Time().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentTimeNodeName,
|
||||
|
@ -28,7 +28,7 @@ func TestUserInstantiation(t *testing.T) {
|
||||
func TestUserSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := User()
|
||||
s := User().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentUserUserID,
|
||||
|
@ -28,7 +28,7 @@ func TestUsersInstantiation(t *testing.T) {
|
||||
func TestUsersSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Users()
|
||||
s := Users().Schema
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentUsersComments,
|
||||
|
@ -29,7 +29,7 @@ func TestVMInstantiation(t *testing.T) {
|
||||
func TestVMSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := VM()
|
||||
s := VM().Schema
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentVMName,
|
||||
|
@ -29,7 +29,7 @@ func TestVMsInstantiation(t *testing.T) {
|
||||
func TestVMsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := VMs()
|
||||
s := VMs().Schema
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkDataSourceVirtualEnvironmentVMs,
|
||||
|
@ -28,9 +28,7 @@ func TestProviderInstantiation(t *testing.T) {
|
||||
func TestProviderSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := &schema.Resource{
|
||||
Schema: ProxmoxVirtualEnvironment().Schema,
|
||||
}
|
||||
s := ProxmoxVirtualEnvironment().Schema
|
||||
|
||||
test.AssertOptionalArguments(t, s, []string{
|
||||
mkProviderUsername,
|
||||
|
@ -28,7 +28,7 @@ func TestCertificateInstantiation(t *testing.T) {
|
||||
func TestCertificateSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Certificate()
|
||||
s := Certificate().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentCertificateCertificate,
|
||||
|
@ -26,7 +26,7 @@ func TestSecurityGroupInstantiation(t *testing.T) {
|
||||
func TestSecurityGroupSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := SecurityGroup()
|
||||
s := SecurityGroup().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkSecurityGroupName,
|
||||
|
@ -28,7 +28,7 @@ func TestContainerInstantiation(t *testing.T) {
|
||||
func TestContainerSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Container()
|
||||
s := Container().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkNodeName,
|
||||
|
@ -28,7 +28,7 @@ func TestDNSInstantiation(t *testing.T) {
|
||||
func TestDNSSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := DNS()
|
||||
s := DNS().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentDNSDomain,
|
||||
|
@ -29,7 +29,7 @@ func TestFileInstantiation(t *testing.T) {
|
||||
func TestFileSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := File()
|
||||
s := File().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentFileDatastoreID,
|
||||
|
@ -25,7 +25,7 @@ func TestAliasInstantiation(t *testing.T) {
|
||||
func TestAliasSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Alias()
|
||||
s := Alias().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkAliasName,
|
||||
|
@ -26,7 +26,7 @@ func TestIPSetInstantiation(t *testing.T) {
|
||||
func TestIPSetSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := IPSet()
|
||||
s := IPSet().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkIPSetName,
|
||||
|
@ -25,7 +25,7 @@ func TestOptionsInstantiation(t *testing.T) {
|
||||
func TestOptionsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Options()
|
||||
s := Options().Schema
|
||||
|
||||
test.AssertOptionalArguments(t, s, []string{
|
||||
mkDHCP,
|
||||
|
@ -25,7 +25,7 @@ func TestRuleInstantiation(t *testing.T) {
|
||||
func TestRuleSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rules := Rules()
|
||||
rules := Rules().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, rules, []string{
|
||||
MkRule,
|
||||
|
@ -28,7 +28,7 @@ func TestGroupInstantiation(t *testing.T) {
|
||||
func TestGroupSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Group()
|
||||
s := Group().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentGroupID,
|
||||
|
@ -28,7 +28,7 @@ func TestHostsInstantiation(t *testing.T) {
|
||||
func TestHostsSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Hosts()
|
||||
s := Hosts().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentHostsEntry,
|
||||
|
@ -28,7 +28,7 @@ func TestPoolInstantiation(t *testing.T) {
|
||||
func TestPoolSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Pool()
|
||||
s := Pool().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentPoolPoolID,
|
||||
|
@ -28,7 +28,7 @@ func TestRoleInstantiation(t *testing.T) {
|
||||
func TestRoleSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Role()
|
||||
s := Role().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentRolePrivileges,
|
||||
|
@ -28,7 +28,7 @@ func TestTimeInstantiation(t *testing.T) {
|
||||
func TestTimeSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Time()
|
||||
s := Time().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentTimeNodeName,
|
||||
|
@ -28,7 +28,7 @@ func TestUserInstantiation(t *testing.T) {
|
||||
func TestUserSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := User()
|
||||
s := User().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkResourceVirtualEnvironmentUserUserID,
|
||||
|
53
proxmoxtf/resource/vm/disk/schema_test.go
Normal file
53
proxmoxtf/resource/vm/disk/schema_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/test"
|
||||
)
|
||||
|
||||
func TestVMSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Schema()
|
||||
|
||||
diskSchema := test.AssertNestedSchemaExistence(t, s, MkDisk)
|
||||
|
||||
test.AssertOptionalArguments(t, diskSchema, []string{
|
||||
mkDiskDatastoreID,
|
||||
mkDiskPathInDatastore,
|
||||
mkDiskFileFormat,
|
||||
mkDiskFileID,
|
||||
mkDiskSize,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, diskSchema, map[string]schema.ValueType{
|
||||
mkDiskDatastoreID: schema.TypeString,
|
||||
mkDiskPathInDatastore: schema.TypeString,
|
||||
mkDiskFileFormat: schema.TypeString,
|
||||
mkDiskFileID: schema.TypeString,
|
||||
mkDiskSize: schema.TypeInt,
|
||||
})
|
||||
|
||||
diskSpeedSchema := test.AssertNestedSchemaExistence(
|
||||
t,
|
||||
diskSchema,
|
||||
mkDiskSpeed,
|
||||
)
|
||||
|
||||
test.AssertOptionalArguments(t, diskSpeedSchema, []string{
|
||||
mkDiskSpeedRead,
|
||||
mkDiskSpeedReadBurstable,
|
||||
mkDiskSpeedWrite,
|
||||
mkDiskSpeedWriteBurstable,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, diskSpeedSchema, map[string]schema.ValueType{
|
||||
mkDiskSpeedRead: schema.TypeInt,
|
||||
mkDiskSpeedReadBurstable: schema.TypeInt,
|
||||
mkDiskSpeedWrite: schema.TypeInt,
|
||||
mkDiskSpeedWriteBurstable: schema.TypeInt,
|
||||
})
|
||||
}
|
276
proxmoxtf/resource/vm/network/network.go
Normal file
276
proxmoxtf/resource/vm/network/network.go
Normal file
@ -0,0 +1,276 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||
)
|
||||
|
||||
// GetNetworkDeviceObjects returns a list of network devices from the resource data.
|
||||
func GetNetworkDeviceObjects(d *schema.ResourceData) (vms.CustomNetworkDevices, error) {
|
||||
networkDevice := d.Get(MkNetworkDevice).([]interface{})
|
||||
networkDeviceObjects := make(vms.CustomNetworkDevices, len(networkDevice))
|
||||
|
||||
for i, networkDeviceEntry := range networkDevice {
|
||||
block := networkDeviceEntry.(map[string]interface{})
|
||||
|
||||
bridge := block[mkNetworkDeviceBridge].(string)
|
||||
enabled := block[mkNetworkDeviceEnabled].(bool)
|
||||
firewall := types.CustomBool(block[mkNetworkDeviceFirewall].(bool))
|
||||
macAddress := block[mkNetworkDeviceMACAddress].(string)
|
||||
model := block[mkNetworkDeviceModel].(string)
|
||||
queues := block[mkNetworkDeviceQueues].(int)
|
||||
rateLimit := block[mkNetworkDeviceRateLimit].(float64)
|
||||
vlanID := block[mkNetworkDeviceVLANID].(int)
|
||||
trunks := block[mkNetworkDeviceTrunks].(string)
|
||||
mtu := block[mkNetworkDeviceMTU].(int)
|
||||
|
||||
device := vms.CustomNetworkDevice{
|
||||
Enabled: enabled,
|
||||
Firewall: &firewall,
|
||||
Model: model,
|
||||
}
|
||||
|
||||
if bridge != "" {
|
||||
device.Bridge = &bridge
|
||||
}
|
||||
|
||||
if macAddress != "" {
|
||||
device.MACAddress = &macAddress
|
||||
}
|
||||
|
||||
if queues != 0 {
|
||||
device.Queues = &queues
|
||||
}
|
||||
|
||||
if rateLimit != 0 {
|
||||
device.RateLimit = &rateLimit
|
||||
}
|
||||
|
||||
if vlanID != 0 {
|
||||
device.Tag = &vlanID
|
||||
}
|
||||
|
||||
if trunks != "" {
|
||||
splitTrunks := strings.Split(trunks, ";")
|
||||
|
||||
var trunksAsInt []int
|
||||
|
||||
for _, numStr := range splitTrunks {
|
||||
num, err := strconv.Atoi(numStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing trunks: %w", err)
|
||||
}
|
||||
|
||||
trunksAsInt = append(trunksAsInt, num)
|
||||
}
|
||||
|
||||
device.Trunks = trunksAsInt
|
||||
}
|
||||
|
||||
if mtu != 0 {
|
||||
device.MTU = &mtu
|
||||
}
|
||||
|
||||
networkDeviceObjects[i] = device
|
||||
}
|
||||
|
||||
return networkDeviceObjects, nil
|
||||
}
|
||||
|
||||
// ReadNetworkDeviceObjects reads the network device objects from the resource data.
|
||||
func ReadNetworkDeviceObjects(d *schema.ResourceData, vmConfig *vms.GetResponseData) diag.Diagnostics {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
// Compare the network devices to those stored in the state.
|
||||
currentNetworkDeviceList := d.Get(MkNetworkDevice).([]interface{})
|
||||
|
||||
macAddresses := make([]interface{}, MaxNetworkDevices)
|
||||
networkDeviceLast := -1
|
||||
networkDeviceList := make([]interface{}, MaxNetworkDevices)
|
||||
networkDeviceObjects := []*vms.CustomNetworkDevice{
|
||||
vmConfig.NetworkDevice0,
|
||||
vmConfig.NetworkDevice1,
|
||||
vmConfig.NetworkDevice2,
|
||||
vmConfig.NetworkDevice3,
|
||||
vmConfig.NetworkDevice4,
|
||||
vmConfig.NetworkDevice5,
|
||||
vmConfig.NetworkDevice6,
|
||||
vmConfig.NetworkDevice7,
|
||||
vmConfig.NetworkDevice8,
|
||||
vmConfig.NetworkDevice9,
|
||||
vmConfig.NetworkDevice10,
|
||||
vmConfig.NetworkDevice11,
|
||||
vmConfig.NetworkDevice12,
|
||||
vmConfig.NetworkDevice13,
|
||||
vmConfig.NetworkDevice14,
|
||||
vmConfig.NetworkDevice15,
|
||||
vmConfig.NetworkDevice16,
|
||||
vmConfig.NetworkDevice17,
|
||||
vmConfig.NetworkDevice18,
|
||||
vmConfig.NetworkDevice19,
|
||||
vmConfig.NetworkDevice20,
|
||||
vmConfig.NetworkDevice21,
|
||||
vmConfig.NetworkDevice22,
|
||||
vmConfig.NetworkDevice23,
|
||||
vmConfig.NetworkDevice24,
|
||||
vmConfig.NetworkDevice25,
|
||||
vmConfig.NetworkDevice26,
|
||||
vmConfig.NetworkDevice27,
|
||||
vmConfig.NetworkDevice28,
|
||||
vmConfig.NetworkDevice29,
|
||||
vmConfig.NetworkDevice30,
|
||||
vmConfig.NetworkDevice31,
|
||||
}
|
||||
|
||||
for ni, nd := range networkDeviceObjects {
|
||||
networkDevice := map[string]interface{}{}
|
||||
|
||||
if nd != nil {
|
||||
networkDeviceLast = ni
|
||||
|
||||
if nd.Bridge != nil {
|
||||
networkDevice[mkNetworkDeviceBridge] = *nd.Bridge
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceBridge] = ""
|
||||
}
|
||||
|
||||
networkDevice[mkNetworkDeviceEnabled] = nd.Enabled
|
||||
|
||||
if nd.Firewall != nil {
|
||||
networkDevice[mkNetworkDeviceFirewall] = *nd.Firewall
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceFirewall] = false
|
||||
}
|
||||
|
||||
if nd.MACAddress != nil {
|
||||
macAddresses[ni] = *nd.MACAddress
|
||||
} else {
|
||||
macAddresses[ni] = ""
|
||||
}
|
||||
|
||||
networkDevice[mkNetworkDeviceMACAddress] = macAddresses[ni]
|
||||
networkDevice[mkNetworkDeviceModel] = nd.Model
|
||||
|
||||
if nd.Queues != nil {
|
||||
networkDevice[mkNetworkDeviceQueues] = *nd.Queues
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceQueues] = 0
|
||||
}
|
||||
|
||||
if nd.RateLimit != nil {
|
||||
networkDevice[mkNetworkDeviceRateLimit] = *nd.RateLimit
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceRateLimit] = 0
|
||||
}
|
||||
|
||||
if nd.Tag != nil {
|
||||
networkDevice[mkNetworkDeviceVLANID] = nd.Tag
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceVLANID] = 0
|
||||
}
|
||||
|
||||
if nd.Trunks != nil {
|
||||
networkDevice[mkNetworkDeviceTrunks] = strings.Trim(
|
||||
strings.Join(strings.Fields(fmt.Sprint(nd.Trunks)), ";"), "[]")
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceTrunks] = ""
|
||||
}
|
||||
|
||||
if nd.MTU != nil {
|
||||
networkDevice[mkNetworkDeviceMTU] = nd.MTU
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceMTU] = 0
|
||||
}
|
||||
} else {
|
||||
macAddresses[ni] = ""
|
||||
networkDevice[mkNetworkDeviceEnabled] = false
|
||||
}
|
||||
|
||||
networkDeviceList[ni] = networkDevice
|
||||
}
|
||||
|
||||
if len(currentNetworkDeviceList) > 0 || networkDeviceLast > -1 {
|
||||
err := d.Set(MkNetworkDevice, networkDeviceList[:networkDeviceLast+1])
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
err := d.Set(mkMACAddresses, macAddresses[0:len(currentNetworkDeviceList)])
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// ReadNetworkValues reads the network values from the resource data.
|
||||
func ReadNetworkValues(
|
||||
ctx context.Context,
|
||||
d *schema.ResourceData,
|
||||
vmAPI *vms.Client,
|
||||
started bool,
|
||||
vmConfig *vms.GetResponseData,
|
||||
agentTimeout time.Duration,
|
||||
) diag.Diagnostics {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
var ipv4Addresses []interface{}
|
||||
|
||||
var ipv6Addresses []interface{}
|
||||
|
||||
var networkInterfaceNames []interface{}
|
||||
|
||||
if started {
|
||||
if vmConfig.Agent != nil && vmConfig.Agent.Enabled != nil && *vmConfig.Agent.Enabled {
|
||||
var macAddresses []interface{}
|
||||
|
||||
networkInterfaces, err := vmAPI.WaitForNetworkInterfacesFromVMAgent(ctx, int(agentTimeout.Seconds()), 5, true)
|
||||
if err == nil && networkInterfaces.Result != nil {
|
||||
ipv4Addresses = make([]interface{}, len(*networkInterfaces.Result))
|
||||
ipv6Addresses = make([]interface{}, len(*networkInterfaces.Result))
|
||||
macAddresses = make([]interface{}, len(*networkInterfaces.Result))
|
||||
networkInterfaceNames = make([]interface{}, len(*networkInterfaces.Result))
|
||||
|
||||
for ri, rv := range *networkInterfaces.Result {
|
||||
var rvIPv4Addresses []interface{}
|
||||
|
||||
var rvIPv6Addresses []interface{}
|
||||
|
||||
if rv.IPAddresses != nil {
|
||||
for _, ip := range *rv.IPAddresses {
|
||||
switch ip.Type {
|
||||
case "ipv4":
|
||||
rvIPv4Addresses = append(rvIPv4Addresses, ip.Address)
|
||||
case "ipv6":
|
||||
rvIPv6Addresses = append(rvIPv6Addresses, ip.Address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipv4Addresses[ri] = rvIPv4Addresses
|
||||
ipv6Addresses[ri] = rvIPv6Addresses
|
||||
macAddresses[ri] = strings.ToUpper(rv.MACAddress)
|
||||
networkInterfaceNames[ri] = rv.Name
|
||||
}
|
||||
}
|
||||
|
||||
err = d.Set(mkMACAddresses, macAddresses)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
}
|
||||
|
||||
e := d.Set(mkIPv4Addresses, ipv4Addresses)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
e = d.Set(mkIPv6Addresses, ipv6Addresses)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
e = d.Set(mkNetworkInterfaceNames, networkInterfaceNames)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
|
||||
return diags
|
||||
}
|
189
proxmoxtf/resource/vm/network/schema.go
Normal file
189
proxmoxtf/resource/vm/network/schema.go
Normal file
@ -0,0 +1,189 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validators"
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxNetworkDevices is the maximum number of network devices supported by the resource.
|
||||
MaxNetworkDevices = 32
|
||||
|
||||
dvNetworkDeviceBridge = "vmbr0"
|
||||
dvNetworkDeviceEnabled = true
|
||||
dvNetworkDeviceFirewall = false
|
||||
dvNetworkDeviceModel = "virtio"
|
||||
dvNetworkDeviceQueues = 0
|
||||
dvNetworkDeviceRateLimit = 0
|
||||
dvNetworkDeviceVLANID = 0
|
||||
dvNetworkDeviceTrunks = ""
|
||||
dvNetworkDeviceMTU = 0
|
||||
|
||||
mkIPv4Addresses = "ipv4_addresses"
|
||||
mkIPv6Addresses = "ipv6_addresses"
|
||||
mkMACAddresses = "mac_addresses"
|
||||
|
||||
// MkNetworkDevice is the name of the network device.
|
||||
MkNetworkDevice = "network_device"
|
||||
mkNetworkDeviceBridge = "bridge"
|
||||
mkNetworkDeviceEnabled = "enabled"
|
||||
mkNetworkDeviceFirewall = "firewall"
|
||||
mkNetworkDeviceMACAddress = "mac_address"
|
||||
mkNetworkDeviceModel = "model"
|
||||
mkNetworkDeviceQueues = "queues"
|
||||
mkNetworkDeviceRateLimit = "rate_limit"
|
||||
mkNetworkDeviceVLANID = "vlan_id"
|
||||
mkNetworkDeviceTrunks = "trunks"
|
||||
mkNetworkDeviceMTU = "mtu"
|
||||
mkNetworkInterfaceNames = "network_interface_names"
|
||||
)
|
||||
|
||||
// Schema returns the schema for the network resource.
|
||||
func Schema() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
mkIPv4Addresses: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The IPv4 addresses published by the QEMU agent",
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
},
|
||||
mkIPv6Addresses: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The IPv6 addresses published by the QEMU agent",
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
},
|
||||
mkMACAddresses: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The MAC addresses for the network interfaces",
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
MkNetworkDevice: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The network devices",
|
||||
Optional: true,
|
||||
DefaultFunc: func() (interface{}, error) {
|
||||
return make([]interface{}, 1), nil
|
||||
},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
mkNetworkDeviceBridge: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The bridge",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceBridge,
|
||||
},
|
||||
mkNetworkDeviceEnabled: {
|
||||
Type: schema.TypeBool,
|
||||
Description: "Whether to enable the network device",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceEnabled,
|
||||
},
|
||||
mkNetworkDeviceFirewall: {
|
||||
Type: schema.TypeBool,
|
||||
Description: "Whether this interface's firewall rules should be used",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceFirewall,
|
||||
},
|
||||
mkNetworkDeviceMACAddress: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The MAC address",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ValidateDiagFunc: validators.MACAddress(),
|
||||
},
|
||||
mkNetworkDeviceModel: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The model",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceModel,
|
||||
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{
|
||||
"e1000",
|
||||
"rtl8139",
|
||||
"virtio",
|
||||
"vmxnet3",
|
||||
}, false)),
|
||||
},
|
||||
mkNetworkDeviceQueues: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "Number of packet queues to be used on the device",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceQueues,
|
||||
ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(0, 64)),
|
||||
},
|
||||
mkNetworkDeviceRateLimit: {
|
||||
Type: schema.TypeFloat,
|
||||
Description: "The rate limit in megabytes per second",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceRateLimit,
|
||||
},
|
||||
mkNetworkDeviceVLANID: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "The VLAN identifier",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceVLANID,
|
||||
},
|
||||
mkNetworkDeviceTrunks: {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "List of VLAN trunks for the network interface",
|
||||
},
|
||||
mkNetworkDeviceMTU: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "Maximum transmission unit (MTU)",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceMTU,
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxItems: MaxNetworkDevices,
|
||||
MinItems: 0,
|
||||
},
|
||||
mkNetworkInterfaceNames: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The network interface names published by the QEMU agent",
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CustomizeDiff returns the custom diff functions for the network resource.
|
||||
func CustomizeDiff() []schema.CustomizeDiffFunc {
|
||||
return []schema.CustomizeDiffFunc{
|
||||
customdiff.ComputedIf(
|
||||
mkIPv4Addresses,
|
||||
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) bool {
|
||||
return d.HasChange("started") ||
|
||||
d.HasChange(MkNetworkDevice)
|
||||
},
|
||||
),
|
||||
customdiff.ComputedIf(
|
||||
mkIPv6Addresses,
|
||||
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) bool {
|
||||
return d.HasChange("started") ||
|
||||
d.HasChange(MkNetworkDevice)
|
||||
},
|
||||
),
|
||||
customdiff.ComputedIf(
|
||||
mkNetworkInterfaceNames,
|
||||
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) bool {
|
||||
return d.HasChange("started") ||
|
||||
d.HasChange(MkNetworkDevice)
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
55
proxmoxtf/resource/vm/network/schema_test.go
Normal file
55
proxmoxtf/resource/vm/network/schema_test.go
Normal file
@ -0,0 +1,55 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/test"
|
||||
)
|
||||
|
||||
func TestNetworkSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := Schema()
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkIPv4Addresses,
|
||||
mkIPv6Addresses,
|
||||
mkMACAddresses,
|
||||
mkNetworkInterfaceNames,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkIPv4Addresses: schema.TypeList,
|
||||
mkIPv6Addresses: schema.TypeList,
|
||||
mkMACAddresses: schema.TypeList,
|
||||
mkNetworkInterfaceNames: schema.TypeList,
|
||||
})
|
||||
|
||||
deviceSchema := test.AssertNestedSchemaExistence(
|
||||
t,
|
||||
s,
|
||||
MkNetworkDevice,
|
||||
)
|
||||
|
||||
test.AssertOptionalArguments(t, deviceSchema, []string{
|
||||
mkNetworkDeviceBridge,
|
||||
mkNetworkDeviceEnabled,
|
||||
mkNetworkDeviceMACAddress,
|
||||
mkNetworkDeviceModel,
|
||||
mkNetworkDeviceRateLimit,
|
||||
mkNetworkDeviceVLANID,
|
||||
mkNetworkDeviceMTU,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, deviceSchema, map[string]schema.ValueType{
|
||||
mkNetworkDeviceBridge: schema.TypeString,
|
||||
mkNetworkDeviceEnabled: schema.TypeBool,
|
||||
mkNetworkDeviceMACAddress: schema.TypeString,
|
||||
mkNetworkDeviceModel: schema.TypeString,
|
||||
mkNetworkDeviceRateLimit: schema.TypeFloat,
|
||||
mkNetworkDeviceVLANID: schema.TypeInt,
|
||||
mkNetworkDeviceMTU: schema.TypeInt,
|
||||
})
|
||||
}
|
@ -144,11 +144,6 @@ func CPUTypeValidator() schema.SchemaValidateDiagFunc {
|
||||
))
|
||||
}
|
||||
|
||||
// NetworkDeviceModelValidator is a schema validation function for network device models.
|
||||
func NetworkDeviceModelValidator() schema.SchemaValidateDiagFunc {
|
||||
return validation.ToDiagFunc(validation.StringInSlice([]string{"e1000", "rtl8139", "virtio", "vmxnet3"}, false))
|
||||
}
|
||||
|
||||
// QEMUAgentTypeValidator is a schema validation function for QEMU agent types.
|
||||
func QEMUAgentTypeValidator() schema.SchemaValidateDiagFunc {
|
||||
return validation.ToDiagFunc(validation.StringInSlice([]string{"isa", "virtio"}, false))
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/disk"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/network"
|
||||
"github.com/bpg/terraform-provider-proxmox/utils"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
@ -93,48 +94,39 @@ const (
|
||||
dvMemoryShared = 0
|
||||
dvMigrate = false
|
||||
dvName = ""
|
||||
dvNetworkDeviceBridge = "vmbr0"
|
||||
dvNetworkDeviceEnabled = true
|
||||
dvNetworkDeviceFirewall = false
|
||||
dvNetworkDeviceModel = "virtio"
|
||||
dvNetworkDeviceQueues = 0
|
||||
dvNetworkDeviceRateLimit = 0
|
||||
dvNetworkDeviceVLANID = 0
|
||||
dvNetworkDeviceTrunks = ""
|
||||
dvNetworkDeviceMTU = 0
|
||||
dvOperatingSystemType = "other"
|
||||
dvPoolID = ""
|
||||
dvProtection = false
|
||||
dvSerialDeviceDevice = "socket"
|
||||
dvSMBIOSFamily = ""
|
||||
dvSMBIOSManufacturer = ""
|
||||
dvSMBIOSProduct = ""
|
||||
dvSMBIOSSKU = ""
|
||||
dvSMBIOSSerial = ""
|
||||
dvSMBIOSVersion = ""
|
||||
dvStarted = true
|
||||
dvStartupOrder = -1
|
||||
dvStartupUpDelay = -1
|
||||
dvStartupDownDelay = -1
|
||||
dvTabletDevice = true
|
||||
dvTemplate = false
|
||||
dvTimeoutClone = 1800
|
||||
dvTimeoutCreate = 1800
|
||||
dvTimeoutMoveDisk = 1800
|
||||
dvTimeoutMigrate = 1800
|
||||
dvTimeoutReboot = 1800
|
||||
dvTimeoutShutdownVM = 1800
|
||||
dvTimeoutStartVM = 1800
|
||||
dvTimeoutStopVM = 300
|
||||
dvVGAEnabled = true
|
||||
dvVGAMemory = 16
|
||||
dvVGAType = "std"
|
||||
dvSCSIHardware = "virtio-scsi-pci"
|
||||
dvStopOnDestroy = false
|
||||
dvHookScript = ""
|
||||
|
||||
dvOperatingSystemType = "other"
|
||||
dvPoolID = ""
|
||||
dvProtection = false
|
||||
dvSerialDeviceDevice = "socket"
|
||||
dvSMBIOSFamily = ""
|
||||
dvSMBIOSManufacturer = ""
|
||||
dvSMBIOSProduct = ""
|
||||
dvSMBIOSSKU = ""
|
||||
dvSMBIOSSerial = ""
|
||||
dvSMBIOSVersion = ""
|
||||
dvStarted = true
|
||||
dvStartupOrder = -1
|
||||
dvStartupUpDelay = -1
|
||||
dvStartupDownDelay = -1
|
||||
dvTabletDevice = true
|
||||
dvTemplate = false
|
||||
dvTimeoutClone = 1800
|
||||
dvTimeoutCreate = 1800
|
||||
dvTimeoutMoveDisk = 1800
|
||||
dvTimeoutMigrate = 1800
|
||||
dvTimeoutReboot = 1800
|
||||
dvTimeoutShutdownVM = 1800
|
||||
dvTimeoutStartVM = 1800
|
||||
dvTimeoutStopVM = 300
|
||||
dvVGAEnabled = true
|
||||
dvVGAMemory = 16
|
||||
dvVGAType = "std"
|
||||
dvSCSIHardware = "virtio-scsi-pci"
|
||||
dvStopOnDestroy = false
|
||||
dvHookScript = ""
|
||||
|
||||
maxResourceVirtualEnvironmentVMAudioDevices = 1
|
||||
maxResourceVirtualEnvironmentVMNetworkDevices = 32
|
||||
maxResourceVirtualEnvironmentVMSerialDevices = 4
|
||||
maxResourceVirtualEnvironmentVMHostPCIDevices = 8
|
||||
maxResourceVirtualEnvironmentVMHostUSBDevices = 4
|
||||
@ -215,72 +207,59 @@ const (
|
||||
mkInitializationVendorDataFileID = "vendor_data_file_id"
|
||||
mkInitializationNetworkDataFileID = "network_data_file_id"
|
||||
mkInitializationMetaDataFileID = "meta_data_file_id"
|
||||
mkIPv4Addresses = "ipv4_addresses"
|
||||
mkIPv6Addresses = "ipv6_addresses"
|
||||
mkKeyboardLayout = "keyboard_layout"
|
||||
mkKVMArguments = "kvm_arguments"
|
||||
mkMachine = "machine"
|
||||
mkMACAddresses = "mac_addresses"
|
||||
mkMemory = "memory"
|
||||
mkMemoryDedicated = "dedicated"
|
||||
mkMemoryFloating = "floating"
|
||||
mkMemoryShared = "shared"
|
||||
mkMigrate = "migrate"
|
||||
mkName = "name"
|
||||
mkNetworkDevice = "network_device"
|
||||
mkNetworkDeviceBridge = "bridge"
|
||||
mkNetworkDeviceEnabled = "enabled"
|
||||
mkNetworkDeviceFirewall = "firewall"
|
||||
mkNetworkDeviceMACAddress = "mac_address"
|
||||
mkNetworkDeviceModel = "model"
|
||||
mkNetworkDeviceQueues = "queues"
|
||||
mkNetworkDeviceRateLimit = "rate_limit"
|
||||
mkNetworkDeviceVLANID = "vlan_id"
|
||||
mkNetworkDeviceTrunks = "trunks"
|
||||
mkNetworkDeviceMTU = "mtu"
|
||||
mkNetworkInterfaceNames = "network_interface_names"
|
||||
mkNodeName = "node_name"
|
||||
mkOperatingSystem = "operating_system"
|
||||
mkOperatingSystemType = "type"
|
||||
mkPoolID = "pool_id"
|
||||
mkProtection = "protection"
|
||||
mkSerialDevice = "serial_device"
|
||||
mkSerialDeviceDevice = "device"
|
||||
mkSMBIOS = "smbios"
|
||||
mkSMBIOSFamily = "family"
|
||||
mkSMBIOSManufacturer = "manufacturer"
|
||||
mkSMBIOSProduct = "product"
|
||||
mkSMBIOSSKU = "sku"
|
||||
mkSMBIOSSerial = "serial"
|
||||
mkSMBIOSUUID = "uuid"
|
||||
mkSMBIOSVersion = "version"
|
||||
mkStarted = "started"
|
||||
mkStartup = "startup"
|
||||
mkStartupOrder = "order"
|
||||
mkStartupUpDelay = "up_delay"
|
||||
mkStartupDownDelay = "down_delay"
|
||||
mkTabletDevice = "tablet_device"
|
||||
mkTags = "tags"
|
||||
mkTemplate = "template"
|
||||
mkTimeoutClone = "timeout_clone"
|
||||
mkTimeoutCreate = "timeout_create"
|
||||
mkTimeoutMigrate = "timeout_migrate"
|
||||
mkTimeoutReboot = "timeout_reboot"
|
||||
mkTimeoutShutdownVM = "timeout_shutdown_vm"
|
||||
mkTimeoutStartVM = "timeout_start_vm"
|
||||
mkTimeoutStopVM = "timeout_stop_vm"
|
||||
mkHostUSB = "usb"
|
||||
mkHostUSBDevice = "host"
|
||||
mkHostUSBDeviceMapping = "mapping"
|
||||
mkHostUSBDeviceUSB3 = "usb3"
|
||||
mkVGA = "vga"
|
||||
mkVGAEnabled = "enabled"
|
||||
mkVGAMemory = "memory"
|
||||
mkVGAType = "type"
|
||||
mkVMID = "vm_id"
|
||||
mkSCSIHardware = "scsi_hardware"
|
||||
mkHookScriptFileID = "hook_script_file_id"
|
||||
mkStopOnDestroy = "stop_on_destroy"
|
||||
|
||||
mkKeyboardLayout = "keyboard_layout"
|
||||
mkKVMArguments = "kvm_arguments"
|
||||
mkMachine = "machine"
|
||||
mkMemory = "memory"
|
||||
mkMemoryDedicated = "dedicated"
|
||||
mkMemoryFloating = "floating"
|
||||
mkMemoryShared = "shared"
|
||||
mkMigrate = "migrate"
|
||||
mkName = "name"
|
||||
|
||||
mkNodeName = "node_name"
|
||||
mkOperatingSystem = "operating_system"
|
||||
mkOperatingSystemType = "type"
|
||||
mkPoolID = "pool_id"
|
||||
mkProtection = "protection"
|
||||
mkSerialDevice = "serial_device"
|
||||
mkSerialDeviceDevice = "device"
|
||||
mkSMBIOS = "smbios"
|
||||
mkSMBIOSFamily = "family"
|
||||
mkSMBIOSManufacturer = "manufacturer"
|
||||
mkSMBIOSProduct = "product"
|
||||
mkSMBIOSSKU = "sku"
|
||||
mkSMBIOSSerial = "serial"
|
||||
mkSMBIOSUUID = "uuid"
|
||||
mkSMBIOSVersion = "version"
|
||||
mkStarted = "started"
|
||||
mkStartup = "startup"
|
||||
mkStartupOrder = "order"
|
||||
mkStartupUpDelay = "up_delay"
|
||||
mkStartupDownDelay = "down_delay"
|
||||
mkTabletDevice = "tablet_device"
|
||||
mkTags = "tags"
|
||||
mkTemplate = "template"
|
||||
mkTimeoutClone = "timeout_clone"
|
||||
mkTimeoutCreate = "timeout_create"
|
||||
mkTimeoutMigrate = "timeout_migrate"
|
||||
mkTimeoutReboot = "timeout_reboot"
|
||||
mkTimeoutShutdownVM = "timeout_shutdown_vm"
|
||||
mkTimeoutStartVM = "timeout_start_vm"
|
||||
mkTimeoutStopVM = "timeout_stop_vm"
|
||||
mkHostUSB = "usb"
|
||||
mkHostUSBDevice = "host"
|
||||
mkHostUSBDeviceMapping = "mapping"
|
||||
mkHostUSBDeviceUSB3 = "usb3"
|
||||
mkVGA = "vga"
|
||||
mkVGAEnabled = "enabled"
|
||||
mkVGAMemory = "memory"
|
||||
mkVGAType = "type"
|
||||
mkVMID = "vm_id"
|
||||
mkSCSIHardware = "scsi_hardware"
|
||||
mkHookScriptFileID = "hook_script_file_id"
|
||||
mkStopOnDestroy = "stop_on_destroy"
|
||||
)
|
||||
|
||||
// VM returns a resource that manages VMs.
|
||||
@ -897,24 +876,6 @@ func VM() *schema.Resource {
|
||||
MaxItems: 1,
|
||||
MinItems: 0,
|
||||
},
|
||||
mkIPv4Addresses: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The IPv4 addresses published by the QEMU agent",
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
},
|
||||
mkIPv6Addresses: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The IPv6 addresses published by the QEMU agent",
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
},
|
||||
mkHostPCI: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The Host PCI devices mapped to the VM",
|
||||
@ -1013,13 +974,6 @@ func VM() *schema.Resource {
|
||||
Default: dvMachineType,
|
||||
ValidateDiagFunc: MachineTypeValidator(),
|
||||
},
|
||||
mkMACAddresses: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The MAC addresses for the network interfaces",
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
mkMemory: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The memory allocation",
|
||||
@ -1073,88 +1027,6 @@ func VM() *schema.Resource {
|
||||
Optional: true,
|
||||
Default: dvName,
|
||||
},
|
||||
mkNetworkDevice: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The network devices",
|
||||
Optional: true,
|
||||
DefaultFunc: func() (interface{}, error) {
|
||||
return make([]interface{}, 1), nil
|
||||
},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
mkNetworkDeviceBridge: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The bridge",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceBridge,
|
||||
},
|
||||
mkNetworkDeviceEnabled: {
|
||||
Type: schema.TypeBool,
|
||||
Description: "Whether to enable the network device",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceEnabled,
|
||||
},
|
||||
mkNetworkDeviceFirewall: {
|
||||
Type: schema.TypeBool,
|
||||
Description: "Whether this interface's firewall rules should be used",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceFirewall,
|
||||
},
|
||||
mkNetworkDeviceMACAddress: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The MAC address",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ValidateDiagFunc: validators.MACAddress(),
|
||||
},
|
||||
mkNetworkDeviceModel: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The model",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceModel,
|
||||
ValidateDiagFunc: NetworkDeviceModelValidator(),
|
||||
},
|
||||
mkNetworkDeviceQueues: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "Number of packet queues to be used on the device",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceQueues,
|
||||
ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(0, 64)),
|
||||
},
|
||||
mkNetworkDeviceRateLimit: {
|
||||
Type: schema.TypeFloat,
|
||||
Description: "The rate limit in megabytes per second",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceRateLimit,
|
||||
},
|
||||
mkNetworkDeviceVLANID: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "The VLAN identifier",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceVLANID,
|
||||
},
|
||||
mkNetworkDeviceTrunks: {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "List of VLAN trunks for the network interface",
|
||||
},
|
||||
mkNetworkDeviceMTU: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "Maximum transmission unit (MTU)",
|
||||
Optional: true,
|
||||
Default: dvNetworkDeviceMTU,
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxItems: maxResourceVirtualEnvironmentVMNetworkDevices,
|
||||
MinItems: 0,
|
||||
},
|
||||
mkNetworkInterfaceNames: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The network interface names published by the QEMU agent",
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
mkNodeName: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The node name",
|
||||
@ -1462,6 +1334,7 @@ func VM() *schema.Resource {
|
||||
}
|
||||
|
||||
structure.MergeSchema(s, disk.Schema())
|
||||
structure.MergeSchema(s, network.Schema())
|
||||
|
||||
return &schema.Resource{
|
||||
Schema: s,
|
||||
@ -1470,27 +1343,7 @@ func VM() *schema.Resource {
|
||||
UpdateContext: vmUpdate,
|
||||
DeleteContext: vmDelete,
|
||||
CustomizeDiff: customdiff.All(
|
||||
customdiff.ComputedIf(
|
||||
mkIPv4Addresses,
|
||||
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) bool {
|
||||
return d.HasChange(mkStarted) ||
|
||||
d.HasChange(mkNetworkDevice)
|
||||
},
|
||||
),
|
||||
customdiff.ComputedIf(
|
||||
mkIPv6Addresses,
|
||||
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) bool {
|
||||
return d.HasChange(mkStarted) ||
|
||||
d.HasChange(mkNetworkDevice)
|
||||
},
|
||||
),
|
||||
customdiff.ComputedIf(
|
||||
mkNetworkInterfaceNames,
|
||||
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) bool {
|
||||
return d.HasChange(mkStarted) ||
|
||||
d.HasChange(mkNetworkDevice)
|
||||
},
|
||||
),
|
||||
customdiff.All(network.CustomizeDiff()...),
|
||||
customdiff.ForceNewIf(
|
||||
mkVMID,
|
||||
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) bool {
|
||||
@ -1825,7 +1678,6 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
||||
hostUSB := d.Get(mkHostUSB).([]interface{})
|
||||
keyboardLayout := d.Get(mkKeyboardLayout).(string)
|
||||
memory := d.Get(mkMemory).([]interface{})
|
||||
networkDevice := d.Get(mkNetworkDevice).([]interface{})
|
||||
operatingSystem := d.Get(mkOperatingSystem).([]interface{})
|
||||
serialDevice := d.Get(mkSerialDevice).([]interface{})
|
||||
onBoot := types.CustomBool(d.Get(mkOnBoot).(bool))
|
||||
@ -2027,8 +1879,9 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
||||
}
|
||||
}
|
||||
|
||||
networkDevice := d.Get(network.MkNetworkDevice).([]interface{})
|
||||
if len(networkDevice) > 0 {
|
||||
updateBody.NetworkDevices, err = vmGetNetworkDeviceObjects(d)
|
||||
updateBody.NetworkDevices, err = network.GetNetworkDeviceObjects(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@ -2039,7 +1892,7 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
||||
}
|
||||
}
|
||||
|
||||
for i := len(updateBody.NetworkDevices); i < maxResourceVirtualEnvironmentVMNetworkDevices; i++ {
|
||||
for i := len(updateBody.NetworkDevices); i < network.MaxNetworkDevices; i++ {
|
||||
del = append(del, fmt.Sprintf("net%d", i))
|
||||
}
|
||||
}
|
||||
@ -2426,7 +2279,7 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
name := d.Get(mkName).(string)
|
||||
tags := d.Get(mkTags).([]interface{})
|
||||
|
||||
networkDeviceObjects, err := vmGetNetworkDeviceObjects(d)
|
||||
networkDeviceObjects, err := network.GetNetworkDeviceObjects(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@ -3054,77 +2907,6 @@ func vmGetHostUSBDeviceObjects(d *schema.ResourceData) vms.CustomUSBDevices {
|
||||
return usbDeviceObjects
|
||||
}
|
||||
|
||||
func vmGetNetworkDeviceObjects(d *schema.ResourceData) (vms.CustomNetworkDevices, error) {
|
||||
networkDevice := d.Get(mkNetworkDevice).([]interface{})
|
||||
networkDeviceObjects := make(vms.CustomNetworkDevices, len(networkDevice))
|
||||
|
||||
for i, networkDeviceEntry := range networkDevice {
|
||||
block := networkDeviceEntry.(map[string]interface{})
|
||||
|
||||
bridge := block[mkNetworkDeviceBridge].(string)
|
||||
enabled := block[mkNetworkDeviceEnabled].(bool)
|
||||
firewall := types.CustomBool(block[mkNetworkDeviceFirewall].(bool))
|
||||
macAddress := block[mkNetworkDeviceMACAddress].(string)
|
||||
model := block[mkNetworkDeviceModel].(string)
|
||||
queues := block[mkNetworkDeviceQueues].(int)
|
||||
rateLimit := block[mkNetworkDeviceRateLimit].(float64)
|
||||
vlanID := block[mkNetworkDeviceVLANID].(int)
|
||||
trunks := block[mkNetworkDeviceTrunks].(string)
|
||||
mtu := block[mkNetworkDeviceMTU].(int)
|
||||
|
||||
device := vms.CustomNetworkDevice{
|
||||
Enabled: enabled,
|
||||
Firewall: &firewall,
|
||||
Model: model,
|
||||
}
|
||||
|
||||
if bridge != "" {
|
||||
device.Bridge = &bridge
|
||||
}
|
||||
|
||||
if macAddress != "" {
|
||||
device.MACAddress = &macAddress
|
||||
}
|
||||
|
||||
if queues != 0 {
|
||||
device.Queues = &queues
|
||||
}
|
||||
|
||||
if rateLimit != 0 {
|
||||
device.RateLimit = &rateLimit
|
||||
}
|
||||
|
||||
if vlanID != 0 {
|
||||
device.Tag = &vlanID
|
||||
}
|
||||
|
||||
if trunks != "" {
|
||||
splitTrunks := strings.Split(trunks, ";")
|
||||
|
||||
var trunksAsInt []int
|
||||
|
||||
for _, numStr := range splitTrunks {
|
||||
num, err := strconv.Atoi(numStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing trunks: %w", err)
|
||||
}
|
||||
|
||||
trunksAsInt = append(trunksAsInt, num)
|
||||
}
|
||||
|
||||
device.Trunks = trunksAsInt
|
||||
}
|
||||
|
||||
if mtu != 0 {
|
||||
device.MTU = &mtu
|
||||
}
|
||||
|
||||
networkDeviceObjects[i] = device
|
||||
}
|
||||
|
||||
return networkDeviceObjects, nil
|
||||
}
|
||||
|
||||
func vmGetSerialDeviceList(d *schema.ResourceData) vms.CustomSerialDevices {
|
||||
device := d.Get(mkSerialDevice).([]interface{})
|
||||
list := make(vms.CustomSerialDevices, len(device))
|
||||
@ -3350,9 +3132,9 @@ func vmReadCustom(
|
||||
) diag.Diagnostics {
|
||||
config := m.(proxmoxtf.ProviderConfiguration)
|
||||
|
||||
api, err := config.GetClient()
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
api, e := config.GetClient()
|
||||
if e != nil {
|
||||
return diag.FromErr(e)
|
||||
}
|
||||
|
||||
diags := vmReadPrimitiveValues(d, vmConfig, vmStatus)
|
||||
@ -3368,7 +3150,7 @@ func vmReadCustom(
|
||||
d.Id(), storedVMID, vmID),
|
||||
})
|
||||
|
||||
err = d.Set(mkVMID, vmID)
|
||||
err := d.Set(mkVMID, vmID)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
@ -3418,7 +3200,7 @@ func vmReadCustom(
|
||||
|
||||
if len(clone) > 0 {
|
||||
if len(currentAgent) > 0 {
|
||||
err = d.Set(mkAgent, []interface{}{agent})
|
||||
err := d.Set(mkAgent, []interface{}{agent})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else if len(currentAgent) > 0 ||
|
||||
@ -3426,16 +3208,16 @@ func vmReadCustom(
|
||||
agent[mkAgentTimeout] != dvAgentTimeout ||
|
||||
agent[mkAgentTrim] != dvAgentTrim ||
|
||||
agent[mkAgentType] != dvAgentType {
|
||||
err = d.Set(mkAgent, []interface{}{agent})
|
||||
err := d.Set(mkAgent, []interface{}{agent})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else if len(clone) > 0 {
|
||||
if len(currentAgent) > 0 {
|
||||
err = d.Set(mkAgent, []interface{}{})
|
||||
err := d.Set(mkAgent, []interface{}{})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else {
|
||||
err = d.Set(mkAgent, []interface{}{})
|
||||
err := d.Set(mkAgent, []interface{}{})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
}
|
||||
@ -3474,7 +3256,7 @@ func vmReadCustom(
|
||||
}
|
||||
|
||||
if len(clone) == 0 || len(currentAudioDevice) > 0 {
|
||||
err = d.Set(mkAudioDevice, audioDevices[:audioDevicesCount])
|
||||
err := d.Set(mkAudioDevice, audioDevices[:audioDevicesCount])
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
@ -3512,11 +3294,11 @@ func vmReadCustom(
|
||||
|
||||
cdrom[0] = cdromBlock
|
||||
|
||||
err = d.Set(mkCDROM, cdrom)
|
||||
err := d.Set(mkCDROM, cdrom)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else {
|
||||
err = d.Set(mkCDROM, []interface{}{})
|
||||
err := d.Set(mkCDROM, []interface{}{})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
@ -3601,7 +3383,7 @@ func vmReadCustom(
|
||||
|
||||
if len(clone) > 0 {
|
||||
if len(currentCPU) > 0 {
|
||||
err = d.Set(mkCPU, []interface{}{cpu})
|
||||
err := d.Set(mkCPU, []interface{}{cpu})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else if len(currentCPU) > 0 ||
|
||||
@ -3613,7 +3395,7 @@ func vmReadCustom(
|
||||
cpu[mkCPUSockets] != dvCPUSockets ||
|
||||
cpu[mkCPUType] != dvCPUType ||
|
||||
cpu[mkCPUUnits] != dvCPUUnits {
|
||||
err = d.Set(mkCPU, []interface{}{cpu})
|
||||
err := d.Set(mkCPU, []interface{}{cpu})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
@ -3636,8 +3418,8 @@ func vmReadCustom(
|
||||
} else {
|
||||
// disk format may not be returned by config API if it is default for the storage, and that may be different
|
||||
// from the default qcow2, so we need to read it from the storage API to make sure we have the correct value
|
||||
volume, e := api.Node(nodeName).Storage(fileIDParts[0]).GetDatastoreFile(ctx, vmConfig.EFIDisk.FileVolume)
|
||||
if e != nil {
|
||||
volume, err := api.Node(nodeName).Storage(fileIDParts[0]).GetDatastoreFile(ctx, vmConfig.EFIDisk.FileVolume)
|
||||
if err != nil {
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
} else {
|
||||
efiDisk[mkEFIDiskFileFormat] = volume.FileFormat
|
||||
@ -3660,7 +3442,7 @@ func vmReadCustom(
|
||||
|
||||
if len(clone) > 0 {
|
||||
if len(currentEfiDisk) > 0 {
|
||||
err = d.Set(mkEFIDisk, []interface{}{efiDisk})
|
||||
err := d.Set(mkEFIDisk, []interface{}{efiDisk})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else if len(currentEfiDisk) > 0 ||
|
||||
@ -3668,7 +3450,7 @@ func vmReadCustom(
|
||||
efiDisk[mkEFIDiskType] != dvEFIDiskType ||
|
||||
efiDisk[mkEFIDiskPreEnrolledKeys] != dvEFIDiskPreEnrolledKeys ||
|
||||
efiDisk[mkEFIDiskFileFormat] != dvEFIDiskFileFormat {
|
||||
err = d.Set(mkEFIDisk, []interface{}{efiDisk})
|
||||
err := d.Set(mkEFIDisk, []interface{}{efiDisk})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
}
|
||||
@ -3685,13 +3467,13 @@ func vmReadCustom(
|
||||
|
||||
if len(clone) > 0 {
|
||||
if len(currentTPMState) > 0 {
|
||||
err = d.Set(mkTPMState, []interface{}{tpmState})
|
||||
err := d.Set(mkTPMState, []interface{}{tpmState})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else if len(currentTPMState) > 0 ||
|
||||
tpmState[mkTPMStateDatastoreID] != dvTPMStateDatastoreID ||
|
||||
tpmState[mkTPMStateVersion] != dvTPMStateVersion {
|
||||
err = d.Set(mkTPMState, []interface{}{tpmState})
|
||||
err := d.Set(mkTPMState, []interface{}{tpmState})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
}
|
||||
@ -3755,7 +3537,7 @@ func vmReadCustom(
|
||||
|
||||
if len(clone) == 0 || len(currentPCIList) > 0 {
|
||||
orderedPCIList := utils.OrderedListFromMap(pciMap)
|
||||
err = d.Set(mkHostPCI, orderedPCIList)
|
||||
err := d.Set(mkHostPCI, orderedPCIList)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
@ -3794,7 +3576,7 @@ func vmReadCustom(
|
||||
if len(clone) == 0 || len(currentUSBList) > 0 {
|
||||
// NOTE: reordering of devices by PVE may cause an issue here
|
||||
orderedUSBList := utils.OrderedListFromMap(usbMap)
|
||||
err = d.Set(mkHostUSB, orderedUSBList)
|
||||
err := d.Set(mkHostUSB, orderedUSBList)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
@ -4022,18 +3804,18 @@ func vmReadCustom(
|
||||
if len(clone) > 0 {
|
||||
if len(currentInitialization) > 0 {
|
||||
if len(initialization) > 0 {
|
||||
err = d.Set(mkInitialization, []interface{}{initialization})
|
||||
err := d.Set(mkInitialization, []interface{}{initialization})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
} else {
|
||||
err = d.Set(mkInitialization, []interface{}{})
|
||||
err := d.Set(mkInitialization, []interface{}{})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
}
|
||||
} else if len(initialization) > 0 {
|
||||
err = d.Set(mkInitialization, []interface{}{initialization})
|
||||
err := d.Set(mkInitialization, []interface{}{initialization})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
} else {
|
||||
err = d.Set(mkInitialization, []interface{}{})
|
||||
err := d.Set(mkInitialization, []interface{}{})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
@ -4071,132 +3853,18 @@ func vmReadCustom(
|
||||
|
||||
if len(clone) > 0 {
|
||||
if len(currentMemory) > 0 {
|
||||
err = d.Set(mkMemory, []interface{}{memory})
|
||||
err := d.Set(mkMemory, []interface{}{memory})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else if len(currentMemory) > 0 ||
|
||||
memory[mkMemoryDedicated] != dvMemoryDedicated ||
|
||||
memory[mkMemoryFloating] != dvMemoryFloating ||
|
||||
memory[mkMemoryShared] != dvMemoryShared {
|
||||
err = d.Set(mkMemory, []interface{}{memory})
|
||||
err := d.Set(mkMemory, []interface{}{memory})
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
// Compare the network devices to those stored in the state.
|
||||
currentNetworkDeviceList := d.Get(mkNetworkDevice).([]interface{})
|
||||
|
||||
macAddresses := make([]interface{}, maxResourceVirtualEnvironmentVMNetworkDevices)
|
||||
networkDeviceLast := -1
|
||||
networkDeviceList := make([]interface{}, maxResourceVirtualEnvironmentVMNetworkDevices)
|
||||
networkDeviceObjects := []*vms.CustomNetworkDevice{
|
||||
vmConfig.NetworkDevice0,
|
||||
vmConfig.NetworkDevice1,
|
||||
vmConfig.NetworkDevice2,
|
||||
vmConfig.NetworkDevice3,
|
||||
vmConfig.NetworkDevice4,
|
||||
vmConfig.NetworkDevice5,
|
||||
vmConfig.NetworkDevice6,
|
||||
vmConfig.NetworkDevice7,
|
||||
vmConfig.NetworkDevice8,
|
||||
vmConfig.NetworkDevice9,
|
||||
vmConfig.NetworkDevice10,
|
||||
vmConfig.NetworkDevice11,
|
||||
vmConfig.NetworkDevice12,
|
||||
vmConfig.NetworkDevice13,
|
||||
vmConfig.NetworkDevice14,
|
||||
vmConfig.NetworkDevice15,
|
||||
vmConfig.NetworkDevice16,
|
||||
vmConfig.NetworkDevice17,
|
||||
vmConfig.NetworkDevice18,
|
||||
vmConfig.NetworkDevice19,
|
||||
vmConfig.NetworkDevice20,
|
||||
vmConfig.NetworkDevice21,
|
||||
vmConfig.NetworkDevice22,
|
||||
vmConfig.NetworkDevice23,
|
||||
vmConfig.NetworkDevice24,
|
||||
vmConfig.NetworkDevice25,
|
||||
vmConfig.NetworkDevice26,
|
||||
vmConfig.NetworkDevice27,
|
||||
vmConfig.NetworkDevice28,
|
||||
vmConfig.NetworkDevice29,
|
||||
vmConfig.NetworkDevice30,
|
||||
vmConfig.NetworkDevice31,
|
||||
}
|
||||
|
||||
for ni, nd := range networkDeviceObjects {
|
||||
networkDevice := map[string]interface{}{}
|
||||
|
||||
if nd != nil {
|
||||
networkDeviceLast = ni
|
||||
|
||||
if nd.Bridge != nil {
|
||||
networkDevice[mkNetworkDeviceBridge] = *nd.Bridge
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceBridge] = ""
|
||||
}
|
||||
|
||||
networkDevice[mkNetworkDeviceEnabled] = nd.Enabled
|
||||
|
||||
if nd.Firewall != nil {
|
||||
networkDevice[mkNetworkDeviceFirewall] = *nd.Firewall
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceFirewall] = false
|
||||
}
|
||||
|
||||
if nd.MACAddress != nil {
|
||||
macAddresses[ni] = *nd.MACAddress
|
||||
} else {
|
||||
macAddresses[ni] = ""
|
||||
}
|
||||
|
||||
networkDevice[mkNetworkDeviceMACAddress] = macAddresses[ni]
|
||||
networkDevice[mkNetworkDeviceModel] = nd.Model
|
||||
|
||||
if nd.Queues != nil {
|
||||
networkDevice[mkNetworkDeviceQueues] = *nd.Queues
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceQueues] = 0
|
||||
}
|
||||
|
||||
if nd.RateLimit != nil {
|
||||
networkDevice[mkNetworkDeviceRateLimit] = *nd.RateLimit
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceRateLimit] = 0
|
||||
}
|
||||
|
||||
if nd.Tag != nil {
|
||||
networkDevice[mkNetworkDeviceVLANID] = nd.Tag
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceVLANID] = 0
|
||||
}
|
||||
|
||||
if nd.Trunks != nil {
|
||||
networkDevice[mkNetworkDeviceTrunks] = strings.Trim(
|
||||
strings.Join(strings.Fields(fmt.Sprint(nd.Trunks)), ";"), "[]")
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceTrunks] = ""
|
||||
}
|
||||
|
||||
if nd.MTU != nil {
|
||||
networkDevice[mkNetworkDeviceMTU] = nd.MTU
|
||||
} else {
|
||||
networkDevice[mkNetworkDeviceMTU] = 0
|
||||
}
|
||||
} else {
|
||||
macAddresses[ni] = ""
|
||||
networkDevice[mkNetworkDeviceEnabled] = false
|
||||
}
|
||||
|
||||
networkDeviceList[ni] = networkDevice
|
||||
}
|
||||
|
||||
err = d.Set(mkMACAddresses, macAddresses[0:len(currentNetworkDeviceList)])
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
|
||||
if len(currentNetworkDeviceList) > 0 || networkDeviceLast > -1 {
|
||||
err := d.Set(mkNetworkDevice, networkDeviceList[:networkDeviceLast+1])
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
diags = append(diags, network.ReadNetworkDeviceObjects(d, vmConfig)...)
|
||||
|
||||
// Compare the operating system configuration to the one stored in the state.
|
||||
operatingSystem := map[string]interface{}{}
|
||||
@ -4455,112 +4123,23 @@ func vmReadCustom(
|
||||
}
|
||||
}
|
||||
|
||||
diags = append(
|
||||
diags,
|
||||
vmReadNetworkValues(ctx, d, m, vmID, vmConfig)...)
|
||||
vmAPI := api.Node(nodeName).VM(vmID)
|
||||
started := d.Get(mkStarted).(bool)
|
||||
|
||||
// during import these core attributes might not be set, so set them explicitly here
|
||||
d.SetId(strconv.Itoa(vmID))
|
||||
e := d.Set(mkVMID, vmID)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
e = d.Set(mkNodeName, nodeName)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
func vmReadNetworkValues(
|
||||
ctx context.Context,
|
||||
d *schema.ResourceData,
|
||||
m interface{},
|
||||
vmID int,
|
||||
vmConfig *vms.GetResponseData,
|
||||
) diag.Diagnostics {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
config := m.(proxmoxtf.ProviderConfiguration)
|
||||
|
||||
api, e := config.GetClient()
|
||||
agentTimeout, e := getAgentTimeout(d)
|
||||
if e != nil {
|
||||
return diag.FromErr(e)
|
||||
}
|
||||
|
||||
nodeName := d.Get(mkNodeName).(string)
|
||||
diags = append(
|
||||
diags,
|
||||
network.ReadNetworkValues(ctx, d, vmAPI, started, vmConfig, agentTimeout)...)
|
||||
|
||||
vmAPI := api.Node(nodeName).VM(vmID)
|
||||
|
||||
started := d.Get(mkStarted).(bool)
|
||||
|
||||
var ipv4Addresses []interface{}
|
||||
|
||||
var ipv6Addresses []interface{}
|
||||
|
||||
var networkInterfaceNames []interface{}
|
||||
|
||||
if started {
|
||||
if vmConfig.Agent != nil && vmConfig.Agent.Enabled != nil && *vmConfig.Agent.Enabled {
|
||||
resource := VM()
|
||||
|
||||
agentBlock, err := structure.GetSchemaBlock(
|
||||
resource,
|
||||
d,
|
||||
[]string{mkAgent},
|
||||
0,
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
agentTimeout, err := time.ParseDuration(
|
||||
agentBlock[mkAgentTimeout].(string),
|
||||
)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
var macAddresses []interface{}
|
||||
|
||||
networkInterfaces, err := vmAPI.WaitForNetworkInterfacesFromVMAgent(ctx, int(agentTimeout.Seconds()), 5, true)
|
||||
if err == nil && networkInterfaces.Result != nil {
|
||||
ipv4Addresses = make([]interface{}, len(*networkInterfaces.Result))
|
||||
ipv6Addresses = make([]interface{}, len(*networkInterfaces.Result))
|
||||
macAddresses = make([]interface{}, len(*networkInterfaces.Result))
|
||||
networkInterfaceNames = make([]interface{}, len(*networkInterfaces.Result))
|
||||
|
||||
for ri, rv := range *networkInterfaces.Result {
|
||||
var rvIPv4Addresses []interface{}
|
||||
|
||||
var rvIPv6Addresses []interface{}
|
||||
|
||||
if rv.IPAddresses != nil {
|
||||
for _, ip := range *rv.IPAddresses {
|
||||
switch ip.Type {
|
||||
case "ipv4":
|
||||
rvIPv4Addresses = append(rvIPv4Addresses, ip.Address)
|
||||
case "ipv6":
|
||||
rvIPv6Addresses = append(rvIPv6Addresses, ip.Address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipv4Addresses[ri] = rvIPv4Addresses
|
||||
ipv6Addresses[ri] = rvIPv6Addresses
|
||||
macAddresses[ri] = strings.ToUpper(rv.MACAddress)
|
||||
networkInterfaceNames[ri] = rv.Name
|
||||
}
|
||||
}
|
||||
|
||||
err = d.Set(mkMACAddresses, macAddresses)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
}
|
||||
|
||||
e = d.Set(mkIPv4Addresses, ipv4Addresses)
|
||||
// during import these core attributes might not be set, so set them explicitly here
|
||||
d.SetId(strconv.Itoa(vmID))
|
||||
e = d.Set(mkVMID, vmID)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
e = d.Set(mkIPv6Addresses, ipv6Addresses)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
e = d.Set(mkNetworkInterfaceNames, networkInterfaceNames)
|
||||
e = d.Set(mkNodeName, nodeName)
|
||||
diags = append(diags, diag.FromErr(e)...)
|
||||
|
||||
return diags
|
||||
@ -5257,8 +4836,9 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
||||
}
|
||||
|
||||
// Prepare the new network device configuration.
|
||||
if d.HasChange(mkNetworkDevice) {
|
||||
updateBody.NetworkDevices, err = vmGetNetworkDeviceObjects(d)
|
||||
|
||||
if d.HasChange(network.MkNetworkDevice) {
|
||||
updateBody.NetworkDevices, err = network.GetNetworkDeviceObjects(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@ -5269,7 +4849,7 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
||||
}
|
||||
}
|
||||
|
||||
for i := len(updateBody.NetworkDevices); i < maxResourceVirtualEnvironmentVMNetworkDevices; i++ {
|
||||
for i := len(updateBody.NetworkDevices); i < network.MaxNetworkDevices; i++ {
|
||||
del = append(del, fmt.Sprintf("net%d", i))
|
||||
}
|
||||
|
||||
@ -5731,3 +5311,27 @@ func parseImportIDWithNodeName(id string) (string, string, error) {
|
||||
|
||||
return nodeName, id, nil
|
||||
}
|
||||
|
||||
func getAgentTimeout(d *schema.ResourceData) (time.Duration, error) {
|
||||
resource := VM()
|
||||
|
||||
agentBlock, err := structure.GetSchemaBlock(
|
||||
resource,
|
||||
d,
|
||||
[]string{mkAgent},
|
||||
0,
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get agent block: %w", err)
|
||||
}
|
||||
|
||||
agentTimeout, err := time.ParseDuration(
|
||||
agentBlock[mkAgentTimeout].(string),
|
||||
)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to parse agent timeout: %w", err)
|
||||
}
|
||||
|
||||
return agentTimeout, nil
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/disk"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/network"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/test"
|
||||
)
|
||||
|
||||
@ -20,8 +21,8 @@ import (
|
||||
func TestVMInstantiation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := VM()
|
||||
if s == nil {
|
||||
r := VM()
|
||||
if r == nil {
|
||||
t.Fatalf("Cannot instantiate VM")
|
||||
}
|
||||
}
|
||||
@ -30,7 +31,7 @@ func TestVMInstantiation(t *testing.T) {
|
||||
func TestVMSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := VM()
|
||||
s := VM().Schema
|
||||
|
||||
test.AssertRequiredArguments(t, s, []string{
|
||||
mkNodeName,
|
||||
@ -56,7 +57,7 @@ func TestVMSchema(t *testing.T) {
|
||||
mkMachine,
|
||||
mkMemory,
|
||||
mkName,
|
||||
mkNetworkDevice,
|
||||
network.MkNetworkDevice,
|
||||
mkOperatingSystem,
|
||||
mkPoolID,
|
||||
mkSerialDevice,
|
||||
@ -67,45 +68,33 @@ func TestVMSchema(t *testing.T) {
|
||||
mkSCSIHardware,
|
||||
})
|
||||
|
||||
test.AssertComputedAttributes(t, s, []string{
|
||||
mkIPv4Addresses,
|
||||
mkIPv6Addresses,
|
||||
mkMACAddresses,
|
||||
mkNetworkInterfaceNames,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||
mkACPI: schema.TypeBool,
|
||||
mkAgent: schema.TypeList,
|
||||
mkAudioDevice: schema.TypeList,
|
||||
mkBIOS: schema.TypeString,
|
||||
mkBootOrder: schema.TypeList,
|
||||
mkCDROM: schema.TypeList,
|
||||
mkCPU: schema.TypeList,
|
||||
mkDescription: schema.TypeString,
|
||||
disk.MkDisk: schema.TypeList,
|
||||
mkEFIDisk: schema.TypeList,
|
||||
mkHostPCI: schema.TypeList,
|
||||
mkHostUSB: schema.TypeList,
|
||||
mkInitialization: schema.TypeList,
|
||||
mkIPv4Addresses: schema.TypeList,
|
||||
mkIPv6Addresses: schema.TypeList,
|
||||
mkKeyboardLayout: schema.TypeString,
|
||||
mkKVMArguments: schema.TypeString,
|
||||
mkMachine: schema.TypeString,
|
||||
mkMemory: schema.TypeList,
|
||||
mkName: schema.TypeString,
|
||||
mkNetworkDevice: schema.TypeList,
|
||||
mkMACAddresses: schema.TypeList,
|
||||
mkNetworkInterfaceNames: schema.TypeList,
|
||||
mkOperatingSystem: schema.TypeList,
|
||||
mkPoolID: schema.TypeString,
|
||||
mkSerialDevice: schema.TypeList,
|
||||
mkStarted: schema.TypeBool,
|
||||
mkTabletDevice: schema.TypeBool,
|
||||
mkTemplate: schema.TypeBool,
|
||||
mkVMID: schema.TypeInt,
|
||||
mkSCSIHardware: schema.TypeString,
|
||||
mkACPI: schema.TypeBool,
|
||||
mkAgent: schema.TypeList,
|
||||
mkAudioDevice: schema.TypeList,
|
||||
mkBIOS: schema.TypeString,
|
||||
mkBootOrder: schema.TypeList,
|
||||
mkCDROM: schema.TypeList,
|
||||
mkCPU: schema.TypeList,
|
||||
mkDescription: schema.TypeString,
|
||||
disk.MkDisk: schema.TypeList,
|
||||
mkEFIDisk: schema.TypeList,
|
||||
mkHostPCI: schema.TypeList,
|
||||
mkHostUSB: schema.TypeList,
|
||||
mkInitialization: schema.TypeList,
|
||||
mkKeyboardLayout: schema.TypeString,
|
||||
mkKVMArguments: schema.TypeString,
|
||||
mkMachine: schema.TypeString,
|
||||
mkMemory: schema.TypeList,
|
||||
mkName: schema.TypeString,
|
||||
mkOperatingSystem: schema.TypeList,
|
||||
mkPoolID: schema.TypeString,
|
||||
mkSerialDevice: schema.TypeList,
|
||||
mkStarted: schema.TypeBool,
|
||||
mkTabletDevice: schema.TypeBool,
|
||||
mkTemplate: schema.TypeBool,
|
||||
mkVMID: schema.TypeInt,
|
||||
mkSCSIHardware: schema.TypeString,
|
||||
})
|
||||
|
||||
agentSchema := test.AssertNestedSchemaExistence(t, s, mkAgent)
|
||||
@ -188,44 +177,6 @@ func TestVMSchema(t *testing.T) {
|
||||
mkCPUUnits: schema.TypeInt,
|
||||
})
|
||||
|
||||
// diskSchema := test.AssertNestedSchemaExistence(t, s, mkDisk)
|
||||
//
|
||||
// test.AssertOptionalArguments(t, diskSchema, []string{
|
||||
// mkDiskDatastoreID,
|
||||
// mkDiskPathInDatastore,
|
||||
// mkDiskFileFormat,
|
||||
// mkDiskFileID,
|
||||
// mkDiskSize,
|
||||
// })
|
||||
//
|
||||
// test.AssertValueTypes(t, diskSchema, map[string]schema.ValueType{
|
||||
// mkDiskDatastoreID: schema.TypeString,
|
||||
// mkDiskPathInDatastore: schema.TypeString,
|
||||
// mkDiskFileFormat: schema.TypeString,
|
||||
// mkDiskFileID: schema.TypeString,
|
||||
// mkDiskSize: schema.TypeInt,
|
||||
// })
|
||||
//
|
||||
// diskSpeedSchema := test.AssertNestedSchemaExistence(
|
||||
// t,
|
||||
// diskSchema,
|
||||
// mkDiskSpeed,
|
||||
//)
|
||||
//
|
||||
// test.AssertOptionalArguments(t, diskSpeedSchema, []string{
|
||||
// mkDiskSpeedRead,
|
||||
// mkDiskSpeedReadBurstable,
|
||||
// mkDiskSpeedWrite,
|
||||
// mkDiskSpeedWriteBurstable,
|
||||
// })
|
||||
//
|
||||
// test.AssertValueTypes(t, diskSpeedSchema, map[string]schema.ValueType{
|
||||
// mkDiskSpeedRead: schema.TypeInt,
|
||||
// mkDiskSpeedReadBurstable: schema.TypeInt,
|
||||
// mkDiskSpeedWrite: schema.TypeInt,
|
||||
// mkDiskSpeedWriteBurstable: schema.TypeInt,
|
||||
// })
|
||||
|
||||
efiDiskSchema := test.AssertNestedSchemaExistence(t, s, mkEFIDisk)
|
||||
|
||||
test.AssertOptionalArguments(t, efiDiskSchema, []string{
|
||||
@ -390,32 +341,6 @@ func TestVMSchema(t *testing.T) {
|
||||
mkMemoryShared: schema.TypeInt,
|
||||
})
|
||||
|
||||
networkDeviceSchema := test.AssertNestedSchemaExistence(
|
||||
t,
|
||||
s,
|
||||
mkNetworkDevice,
|
||||
)
|
||||
|
||||
test.AssertOptionalArguments(t, networkDeviceSchema, []string{
|
||||
mkNetworkDeviceBridge,
|
||||
mkNetworkDeviceEnabled,
|
||||
mkNetworkDeviceMACAddress,
|
||||
mkNetworkDeviceModel,
|
||||
mkNetworkDeviceRateLimit,
|
||||
mkNetworkDeviceVLANID,
|
||||
mkNetworkDeviceMTU,
|
||||
})
|
||||
|
||||
test.AssertValueTypes(t, networkDeviceSchema, map[string]schema.ValueType{
|
||||
mkNetworkDeviceBridge: schema.TypeString,
|
||||
mkNetworkDeviceEnabled: schema.TypeBool,
|
||||
mkNetworkDeviceMACAddress: schema.TypeString,
|
||||
mkNetworkDeviceModel: schema.TypeString,
|
||||
mkNetworkDeviceRateLimit: schema.TypeFloat,
|
||||
mkNetworkDeviceVLANID: schema.TypeInt,
|
||||
mkNetworkDeviceMTU: schema.TypeInt,
|
||||
})
|
||||
|
||||
operatingSystemSchema := test.AssertNestedSchemaExistence(
|
||||
t,
|
||||
s,
|
||||
|
@ -15,20 +15,20 @@ import (
|
||||
)
|
||||
|
||||
// AssertComputedAttributes checks that the given schema has the given computed attributes.
|
||||
func AssertComputedAttributes(t *testing.T, s *schema.Resource, keys []string) {
|
||||
func AssertComputedAttributes(t *testing.T, s map[string]*schema.Schema, keys []string) {
|
||||
t.Helper()
|
||||
|
||||
for _, v := range keys {
|
||||
require.NotNil(t, s.Schema[v], "Error in Schema: Missing definition for \"%s\"", v)
|
||||
assert.True(t, s.Schema[v].Computed, "Error in Schema: Attribute \"%s\" is not computed", v)
|
||||
require.NotNil(t, s[v], "Error in Schema: Missing definition for \"%s\"", v)
|
||||
assert.True(t, s[v].Computed, "Error in Schema: Attribute \"%s\" is not computed", v)
|
||||
}
|
||||
}
|
||||
|
||||
// AssertNestedSchemaExistence checks that the given schema has a nested schema for the given key.
|
||||
func AssertNestedSchemaExistence(t *testing.T, s *schema.Resource, key string) *schema.Resource {
|
||||
func AssertNestedSchemaExistence(t *testing.T, s map[string]*schema.Schema, key string) map[string]*schema.Schema {
|
||||
t.Helper()
|
||||
|
||||
sh, ok := s.Schema[key].Elem.(*schema.Resource)
|
||||
r, ok := s[key].Elem.(*schema.Resource)
|
||||
|
||||
if !ok {
|
||||
t.Fatalf("Error in Schema: Missing nested schema for \"%s\"", key)
|
||||
@ -36,45 +36,45 @@ func AssertNestedSchemaExistence(t *testing.T, s *schema.Resource, key string) *
|
||||
return nil
|
||||
}
|
||||
|
||||
return sh
|
||||
return r.Schema
|
||||
}
|
||||
|
||||
// AssertListMaxItems checks that the given schema attribute has given expected MaxItems value.
|
||||
func AssertListMaxItems(t *testing.T, s *schema.Resource, key string, expectedMaxItems int) {
|
||||
func AssertListMaxItems(t *testing.T, s map[string]*schema.Schema, key string, expectedMaxItems int) {
|
||||
t.Helper()
|
||||
|
||||
require.NotNil(t, s.Schema[key], "Error in Schema: Missing definition for \"%s\"", key)
|
||||
assert.Equal(t, expectedMaxItems, s.Schema[key].MaxItems,
|
||||
require.NotNil(t, s[key], "Error in Schema: Missing definition for \"%s\"", key)
|
||||
assert.Equal(t, expectedMaxItems, s[key].MaxItems,
|
||||
"Error in Schema: Argument \"%s\" has \"MaxItems: %#v\", but value %#v is expected!",
|
||||
key, s.Schema[key].MaxItems, expectedMaxItems)
|
||||
key, s[key].MaxItems, expectedMaxItems)
|
||||
}
|
||||
|
||||
// AssertOptionalArguments checks that the given schema has the given optional arguments.
|
||||
func AssertOptionalArguments(t *testing.T, s *schema.Resource, keys []string) {
|
||||
func AssertOptionalArguments(t *testing.T, s map[string]*schema.Schema, keys []string) {
|
||||
t.Helper()
|
||||
|
||||
for _, v := range keys {
|
||||
require.NotNil(t, s.Schema[v], "Error in Schema: Missing definition for \"%s\"", v)
|
||||
assert.True(t, s.Schema[v].Optional, "Error in Schema: Argument \"%s\" is not optional", v)
|
||||
require.NotNil(t, s[v], "Error in Schema: Missing definition for \"%s\"", v)
|
||||
assert.True(t, s[v].Optional, "Error in Schema: Argument \"%s\" is not optional", v)
|
||||
}
|
||||
}
|
||||
|
||||
// AssertRequiredArguments checks that the given schema has the given required arguments.
|
||||
func AssertRequiredArguments(t *testing.T, s *schema.Resource, keys []string) {
|
||||
func AssertRequiredArguments(t *testing.T, s map[string]*schema.Schema, keys []string) {
|
||||
t.Helper()
|
||||
|
||||
for _, v := range keys {
|
||||
require.NotNil(t, s.Schema[v], "Error in Schema: Missing definition for \"%s\"", v)
|
||||
assert.True(t, s.Schema[v].Required, "Error in Schema: Argument \"%s\" is not required", v)
|
||||
require.NotNil(t, s[v], "Error in Schema: Missing definition for \"%s\"", v)
|
||||
assert.True(t, s[v].Required, "Error in Schema: Argument \"%s\" is not required", v)
|
||||
}
|
||||
}
|
||||
|
||||
// AssertValueTypes checks that the given schema has the given value types for the given fields.
|
||||
func AssertValueTypes(t *testing.T, s *schema.Resource, f map[string]schema.ValueType) {
|
||||
func AssertValueTypes(t *testing.T, s map[string]*schema.Schema, f map[string]schema.ValueType) {
|
||||
t.Helper()
|
||||
|
||||
for fn, ft := range f {
|
||||
require.NotNil(t, s.Schema[fn], "Error in Schema: Missing definition for \"%s\"", fn)
|
||||
assert.Equal(t, ft, s.Schema[fn].Type, "Error in Schema: Argument or attribute \"%s\" is not of type \"%v\"", fn, ft)
|
||||
require.NotNil(t, s[fn], "Error in Schema: Missing definition for \"%s\"", fn)
|
||||
assert.Equal(t, ft, s[fn].Type, "Error in Schema: Argument or attribute \"%s\" is not of type \"%v\"", fn, ft)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user