Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: vm agent interface prefixes #72

Open
wants to merge 9 commits into
base: release/v0.5.0
Choose a base branch
from
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ENHANCEMENTS:
* data-source/virtual_environment_users: Add `tokens` attribute
* provider/configuration: Add `virtual_environment.token` argument for API token support
* resource/virtual_environment_user: Add `tokens` attribute
* resource/virtual_environment_vm: Add `agent.prefixes` argument

BUG FIXES:

Expand Down
1 change: 1 addition & 0 deletions docs/resources/virtual_environment_vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ output "ubuntu_vm_public_key" {
* `acpi` - (Optional) Whether to enable ACPI (defaults to `true`).
* `agent` - (Optional) The QEMU agent configuration.
* `enabled` - (Optional) Whether to enable the QEMU agent (defaults to `false`).
* `prefixes` - (Optional) The prefixes for the network interfaces which need to have an IP assigned before continuing (defaults to `["eno","enp","ens","eth","tun"]`).
* `timeout` - (Optional) The maximum amount of time to wait for data from the QEMU agent to become available (defaults to `15m`).
* `trim` - (Optional) Whether to enable the FSTRIM feature in the QEMU agent (defaults to `false`).
* `type` - (Optional) The QEMU agent interface type (defaults to `virtio`).
Expand Down
16 changes: 8 additions & 8 deletions proxmox/virtual_environment_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ func (c *VirtualEnvironmentClient) UpdateVMAsync(nodeName string, vmID int, d *V
}

// WaitForNetworkInterfacesFromVMAgent waits for a virtual machine's QEMU agent to publish the network interfaces.
func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName string, vmID int, timeout int, delay int, waitForIP bool) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) {
func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName string, vmID int, timeout int, delay int, waitForIP bool, interfacePrefixes []string) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) {
timeDelay := int64(delay)
timeMax := float64(timeout)
timeStart := time.Now()
Expand All @@ -389,13 +389,13 @@ func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName

if waitForIP {
for _, nic := range *data.Result {
if nic.Name == "lo" {
continue
}

if nic.IPAddresses == nil || (nic.IPAddresses != nil && len(*nic.IPAddresses) == 0) {
missingIP = true
break
for _, prefix := range interfacePrefixes {
if strings.HasPrefix(nic.Name, prefix) {
if nic.IPAddresses == nil || (nic.IPAddresses != nil && len(*nic.IPAddresses) == 0) {
missingIP = true
break
}
}
}
}
}
Expand Down
38 changes: 33 additions & 5 deletions proxmoxtf/resource_virtual_environment_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const (
mkResourceVirtualEnvironmentVMACPI = "acpi"
mkResourceVirtualEnvironmentVMAgent = "agent"
mkResourceVirtualEnvironmentVMAgentEnabled = "enabled"
mkResourceVirtualEnvironmentVMAgentPrefixes = "prefixes"
mkResourceVirtualEnvironmentVMAgentTimeout = "timeout"
mkResourceVirtualEnvironmentVMAgentTrim = "trim"
mkResourceVirtualEnvironmentVMAgentType = "type"
Expand Down Expand Up @@ -192,6 +193,16 @@ const (
mkResourceVirtualEnvironmentVMVMID = "vm_id"
)

var (
dvResourceVirtualEnvironmentVMAgentPrefixes = []interface{}{
"eno",
"enp",
"ens",
"eth",
"tun",
}
)

func resourceVirtualEnvironmentVM() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -220,10 +231,11 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
DefaultFunc: func() (interface{}, error) {
return []interface{}{
map[string]interface{}{
mkResourceVirtualEnvironmentVMAgentEnabled: dvResourceVirtualEnvironmentVMAgentEnabled,
mkResourceVirtualEnvironmentVMAgentTimeout: dvResourceVirtualEnvironmentVMAgentTimeout,
mkResourceVirtualEnvironmentVMAgentTrim: dvResourceVirtualEnvironmentVMAgentEnabled,
mkResourceVirtualEnvironmentVMAgentType: dvResourceVirtualEnvironmentVMAgentType,
mkResourceVirtualEnvironmentVMAgentEnabled: dvResourceVirtualEnvironmentVMAgentEnabled,
mkResourceVirtualEnvironmentVMAgentPrefixes: dvResourceVirtualEnvironmentVMAgentPrefixes,
mkResourceVirtualEnvironmentVMAgentTimeout: dvResourceVirtualEnvironmentVMAgentTimeout,
mkResourceVirtualEnvironmentVMAgentTrim: dvResourceVirtualEnvironmentVMAgentEnabled,
mkResourceVirtualEnvironmentVMAgentType: dvResourceVirtualEnvironmentVMAgentType,
},
}, nil
},
Expand All @@ -235,6 +247,15 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
Optional: true,
Default: dvResourceVirtualEnvironmentVMAgentEnabled,
},
mkResourceVirtualEnvironmentVMAgentPrefixes: {
Type: schema.TypeList,
Description: "The prefixes for the network interfaces which need to have an IP assigned before continuing",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return dvResourceVirtualEnvironmentVMAgentPrefixes, nil
},
Elem: &schema.Schema{Type: schema.TypeString},
},
mkResourceVirtualEnvironmentVMAgentTimeout: {
Type: schema.TypeString,
Description: "The maximum amount of time to wait for data from the QEMU agent to become available",
Expand Down Expand Up @@ -3056,14 +3077,21 @@ func resourceVirtualEnvironmentVMReadNetworkValues(d *schema.ResourceData, m int
return err
}

agentPrefixes := agentBlock[mkResourceVirtualEnvironmentVMAgentPrefixes].([]interface{})
agentTimeout, err := time.ParseDuration(agentBlock[mkResourceVirtualEnvironmentVMAgentTimeout].(string))

if err != nil {
return err
}

interfacePrefixes := make([]string, len(agentPrefixes))

for i, v := range agentPrefixes {
interfacePrefixes[i] = v.(string)
}

macAddresses := []interface{}{}
networkInterfaces, err := veClient.WaitForNetworkInterfacesFromVMAgent(nodeName, vmID, int(agentTimeout.Seconds()), 5, true)
networkInterfaces, err := veClient.WaitForNetworkInterfacesFromVMAgent(nodeName, vmID, int(agentTimeout.Seconds()), 5, true, interfacePrefixes)

if err == nil && networkInterfaces.Result != nil {
ipv4Addresses = make([]interface{}, len(*networkInterfaces.Result))
Expand Down
9 changes: 6 additions & 3 deletions proxmoxtf/resource_virtual_environment_vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,18 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {

testOptionalArguments(t, agentSchema, []string{
mkResourceVirtualEnvironmentVMAgentEnabled,
mkResourceVirtualEnvironmentVMAgentPrefixes,
mkResourceVirtualEnvironmentVMAgentTimeout,
mkResourceVirtualEnvironmentVMAgentTrim,
mkResourceVirtualEnvironmentVMAgentType,
})

testValueTypes(t, agentSchema, map[string]schema.ValueType{
mkResourceVirtualEnvironmentVMAgentEnabled: schema.TypeBool,
mkResourceVirtualEnvironmentVMAgentTrim: schema.TypeBool,
mkResourceVirtualEnvironmentVMAgentType: schema.TypeString,
mkResourceVirtualEnvironmentVMAgentEnabled: schema.TypeBool,
mkResourceVirtualEnvironmentVMAgentPrefixes: schema.TypeList,
mkResourceVirtualEnvironmentVMAgentTimeout: schema.TypeString,
mkResourceVirtualEnvironmentVMAgentTrim: schema.TypeBool,
mkResourceVirtualEnvironmentVMAgentType: schema.TypeString,
})

audioDeviceSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMAudioDevice)
Expand Down