Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions cloudstack/resource_cloudstack_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func resourceCloudStackNetwork() *schema.Resource {

"cidr": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
},

Expand Down Expand Up @@ -190,23 +190,25 @@ func resourceCloudStackNetworkCreate(d *schema.ResourceData, meta interface{}) e
return err
}

m, err := parseCIDR(d, no.Specifyipranges)
if err != nil {
return err
}
if _, ok := d.GetOk("cidr"); ok {
m, err := parseCIDR(d, no.Specifyipranges)
if err != nil {
Comment on lines +193 to +195
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With cidr optional, GetNetworkOfferingByID is only needed when cidr is present (to read Specifyipranges for parseCIDR). To avoid an extra API call on L2/no-cidr networks, consider moving the network-offering lookup inside the cidr conditional block.

Copilot uses AI. Check for mistakes.
return err
}
Comment on lines +193 to +197
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that cidr is optional, users can set gateway/startip/endip without setting cidr. In that case this block is skipped and those arguments are silently ignored, which can lead to confusing behavior and perpetual diffs (e.g., config sets gateway but API/state stays empty). Consider validating that gateway, startip, and endip may only be set when cidr is also set (e.g., schema RequiredWith/ConflictsWith or an explicit check in Create returning a clear error).

Copilot uses AI. Check for mistakes.

// Set the needed IP config
p.SetGateway(m["gateway"])
p.SetNetmask(m["netmask"])
// Set the needed IP config
p.SetGateway(m["gateway"])
p.SetNetmask(m["netmask"])

// Only set the start IP if we have one
if startip, ok := m["startip"]; ok {
p.SetStartip(startip)
}
// Only set the start IP if we have one
if startip, ok := m["startip"]; ok {
p.SetStartip(startip)
}

// Only set the end IP if we have one
if endip, ok := m["endip"]; ok {
p.SetEndip(endip)
// Only set the end IP if we have one
if endip, ok := m["endip"]; ok {
p.SetEndip(endip)
}
}

// Set the network domain if we have one
Expand Down
27 changes: 27 additions & 0 deletions cloudstack/resource_cloudstack_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,30 @@ resource "cloudstack_network" "foo" {
acl_id = cloudstack_network_acl.bar.id
zone = cloudstack_vpc.foo.zone
}`

func TestAccCloudStackNetwork_l2NoCidr(t *testing.T) {
var network cloudstack.Network

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudStackNetworkDestroy,
Steps: []resource.TestStep{
{
Config: testAccCloudStackNetwork_l2NoCidr,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackNetworkExists(
"cloudstack_network.l2", &network),
),
},
},
})
}

const testAccCloudStackNetwork_l2NoCidr = `
resource "cloudstack_network" "l2" {
name = "terraform-l2-network"
display_text = "terraform-l2-network"
network_offering = "DefaultL2NetworkOffering"
zone = "Sandbox-simulator"
}`
Loading