Skip to content

Commit 83e1156

Browse files
committed
fix: make vlan tag ids configurable
Resolves: #1236
1 parent 6ce0009 commit 83e1156

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

internal/codegen/docs/domain.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6360,7 +6360,7 @@ entries:
63606360
description: Sets an opaque interface identifier for the virtual port profile, typically used by SDN or virtual switch controllers; value is user-provided (often a UUID or similar).
63616361
reference: https://libvirt.org/formatdomain.html#virtual-network
63626362
- path: domain.devices.interfaces.vlan.tags.id
6363-
description: Reports the VLAN ID associated with this tag; this is computed from the underlying XML and must be a valid VLAN tag (typically in the range 1–4094).
6363+
description: Sets the VLAN ID associated with this tag; value is user-provided and must be a valid VLAN tag for the interface configuration.
63646364
reference: https://libvirt.org/formatdomain.html#setting-vlan-tag-on-supported-network-types-only
63656365
- path: domain.devices.interfaces.virtual_port.params.mido_net.interface_id
63666366
description: Sets the Midonet virtual interface identifier associated with this NIC; the value is user-provided and must match the interface ID configured in Midonet.

internal/codegen/docs/network.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ entries:
363363
description: Sets the Open vSwitch profile identifier (profileid) for ports in this portgroup; value is user-provided and used by OVS or higher-level controllers to apply a specific port profile.
364364
reference: https://libvirt.org/formatdomain.html#virtual-network
365365
- path: network.port_groups.vlan.tags.id
366-
description: Reports the VLAN ID associated with this tag; when managed by libvirt it is computed from the backing XML and corresponds to the 802.1Q VLAN identifier (1–4094).
366+
description: Sets the VLAN ID associated with this tag; value is user-provided and corresponds to the 802.1Q VLAN identifier used for this network or portgroup.
367367
reference: https://libvirt.org/formatnetwork.html#setting-vlan-tag-on-supported-network-types-only
368368
- path: network.routes.address
369369
description: Sets the destination network address (in IPv4 or IPv6 form) for this static route; value is user-provided and should match the route’s prefix (e.g. "192.168.2.0/24" or "2001:db8::/64").
@@ -492,7 +492,7 @@ entries:
492492
description: Sets the VEPA 802.1Qbg VSI type ID, indicating the profile or type assigned to this virtual interface; value is user-provided, typically a numeric profile identifier from the network policy.
493493
reference: https://libvirt.org/formatnetwork.html#connectivity
494494
- path: network.vlan.tags.id
495-
description: Reports the VLAN ID for this tag entry; this is computed from libvirt and corresponds to a numeric VLAN identifier between 1 and 4094.
495+
description: Sets the VLAN ID for this tag entry; value is user-provided and corresponds to the numeric VLAN identifier applied to this network.
496496
reference: https://libvirt.org/formatnetwork.html#setting-vlan-tag-on-supported-network-types-only
497497
- path: network.virtual_port.params.vepa8021qbg.manager_id
498498
description: Sets the VEPA 802.1Qbg manager ID that identifies the VSI manager (e.g., a switch or controller) responsible for this interface; value is user-provided according to the physical network’s configuration.

internal/codegen/parser/libvirtxml.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,14 @@ func (r *LibvirtXMLReflector) applyFieldPatterns(structName string, fields []*ge
183183
// Universal patterns (apply to ALL resources)
184184
switch field.TFName {
185185
case "uuid", "id", "key":
186+
if field.TFName == "id" && isUserManagedVLANTagIDStruct(structName) {
187+
field.IsComputed = false
188+
field.IsOptional = false
189+
field.IsRequired = true
190+
field.PlanModifier = "RequiresReplace"
191+
continue
192+
}
193+
186194
field.IsComputed = true
187195
field.IsOptional = false
188196
field.IsRequired = false
@@ -257,6 +265,15 @@ func (r *LibvirtXMLReflector) applyFieldPatterns(structName string, fields []*ge
257265
}
258266
}
259267

268+
func isUserManagedVLANTagIDStruct(structName string) bool {
269+
switch structName {
270+
case "NetworkVLANTag", "DomainInterfaceVLanTag", "NetworkPortVLANTag":
271+
return true
272+
default:
273+
return false
274+
}
275+
}
276+
260277
func (r *LibvirtXMLReflector) analyzeField(structName string, field reflect.StructField) (*generator.FieldIR, error) {
261278
// Skip XMLName fields (used by encoding/xml)
262279
if field.Name == "XMLName" {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package regression
2+
3+
import (
4+
"testing"
5+
6+
"github.com/dmacvicar/terraform-provider-libvirt/v2/internal/generated"
7+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
8+
)
9+
10+
func TestNetworkVLANTagIDIsRequired(t *testing.T) {
11+
attr := generated.NetworkVLANTagSchemaAttribute()
12+
nested, ok := attr.(schema.SingleNestedAttribute)
13+
if !ok {
14+
t.Fatalf("expected SingleNestedAttribute, got %T", attr)
15+
}
16+
17+
idAttr, ok := nested.Attributes["id"].(schema.Int64Attribute)
18+
if !ok {
19+
t.Fatalf("expected Int64Attribute for network VLAN tag id, got %T", nested.Attributes["id"])
20+
}
21+
22+
if !idAttr.Required {
23+
t.Fatal("expected network VLAN tag id to be required")
24+
}
25+
if idAttr.Computed {
26+
t.Fatal("expected network VLAN tag id to not be computed")
27+
}
28+
}
29+
30+
func TestDomainInterfaceVLanTagIDIsRequired(t *testing.T) {
31+
attr := generated.DomainInterfaceVLanTagSchemaAttribute()
32+
nested, ok := attr.(schema.SingleNestedAttribute)
33+
if !ok {
34+
t.Fatalf("expected SingleNestedAttribute, got %T", attr)
35+
}
36+
37+
idAttr, ok := nested.Attributes["id"].(schema.Int64Attribute)
38+
if !ok {
39+
t.Fatalf("expected Int64Attribute for domain interface VLAN tag id, got %T", nested.Attributes["id"])
40+
}
41+
42+
if !idAttr.Required {
43+
t.Fatal("expected domain interface VLAN tag id to be required")
44+
}
45+
if idAttr.Computed {
46+
t.Fatal("expected domain interface VLAN tag id to not be computed")
47+
}
48+
}

0 commit comments

Comments
 (0)