From e2e1c9f54de7e50f0b94b04151045414da11f9ed Mon Sep 17 00:00:00 2001 From: Brad House - Nexthop Date: Fri, 6 Mar 2026 18:51:15 +0000 Subject: [PATCH 1/3] Add bypassvlanoverlapcheck parameter to cloudstack_private_gateway resource - Add bypassvlanoverlapcheck optional parameter (defaults to false) - Parameter allows bypassing VLAN overlap checks during gateway creation - Update resource creation logic to pass parameter to CloudStack API - Add comprehensive test coverage: - Test with bypass enabled - Test default value (false) - Update import test to ignore field (not returned by API) - Update documentation with examples and parameter description - All acceptance tests passing (4/4) --- .../resource_cloudstack_private_gateway.go | 11 +++ ...esource_cloudstack_private_gateway_test.go | 74 ++++++++++++++++++- website/docs/r/private_gateway.html.markdown | 19 +++++ 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/cloudstack/resource_cloudstack_private_gateway.go b/cloudstack/resource_cloudstack_private_gateway.go index 6d4e0078..b962207b 100644 --- a/cloudstack/resource_cloudstack_private_gateway.go +++ b/cloudstack/resource_cloudstack_private_gateway.go @@ -85,6 +85,12 @@ func resourceCloudStackPrivateGateway() *schema.Resource { Required: true, ForceNew: true, }, + + "bypassvlanoverlapcheck": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, }, } } @@ -119,6 +125,11 @@ func resourceCloudStackPrivateGatewayCreate(d *schema.ResourceData, meta interfa p.SetAclid(aclid.(string)) } + // Set bypassvlanoverlapcheck if specified + if bypassvlanoverlapcheck, ok := d.GetOk("bypassvlanoverlapcheck"); ok { + p.SetBypassvlanoverlapcheck(bypassvlanoverlapcheck.(bool)) + } + // Create the new private gateway r, err := cs.VPC.CreatePrivateGateway(p) if err != nil { diff --git a/cloudstack/resource_cloudstack_private_gateway_test.go b/cloudstack/resource_cloudstack_private_gateway_test.go index a20a8141..aeedffee 100644 --- a/cloudstack/resource_cloudstack_private_gateway_test.go +++ b/cloudstack/resource_cloudstack_private_gateway_test.go @@ -59,9 +59,52 @@ func TestAccCloudStackPrivateGateway_import(t *testing.T) { }, { - ResourceName: "cloudstack_private_gateway.foo", - ImportState: true, - ImportStateVerify: true, + ResourceName: "cloudstack_private_gateway.foo", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"bypassvlanoverlapcheck"}, + }, + }, + }) +} + +func TestAccCloudStackPrivateGateway_bypassVlanOverlapCheck(t *testing.T) { + var gateway cloudstack.PrivateGateway + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudStackPrivateGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCloudStackPrivateGateway_bypassVlanOverlapCheck, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudStackPrivateGatewayExists( + "cloudstack_private_gateway.bar", &gateway), + resource.TestCheckResourceAttr( + "cloudstack_private_gateway.bar", "bypassvlanoverlapcheck", "true"), + ), + }, + }, + }) +} + +func TestAccCloudStackPrivateGateway_bypassVlanOverlapCheckDefault(t *testing.T) { + var gateway cloudstack.PrivateGateway + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudStackPrivateGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCloudStackPrivateGateway_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudStackPrivateGatewayExists( + "cloudstack_private_gateway.foo", &gateway), + resource.TestCheckResourceAttr( + "cloudstack_private_gateway.foo", "bypassvlanoverlapcheck", "false"), + ), }, }, }) @@ -160,3 +203,28 @@ resource "cloudstack_private_gateway" "foo" { acl_id = cloudstack_network_acl.foo.id depends_on = ["cloudstack_vpc.foo","cloudstack_network_acl.foo"] }` + +const testAccCloudStackPrivateGateway_bypassVlanOverlapCheck = ` +resource "cloudstack_vpc" "bar" { + name = "terraform-vpc-bypass" + cidr = "10.0.0.0/8" + vpc_offering = "Default VPC offering" + zone = "Sandbox-simulator" +} + +resource "cloudstack_network_acl" "bar" { + name = "terraform-acl-bypass" + vpc_id = cloudstack_vpc.bar.id + depends_on = ["cloudstack_vpc.bar"] +} + +resource "cloudstack_private_gateway" "bar" { + gateway = "10.1.1.254" + ip_address = "192.168.0.2" + netmask = "255.255.255.0" + vlan = "2" + vpc_id = cloudstack_vpc.bar.id + acl_id = cloudstack_network_acl.bar.id + bypassvlanoverlapcheck = true + depends_on = ["cloudstack_vpc.bar","cloudstack_network_acl.bar"] +}` diff --git a/website/docs/r/private_gateway.html.markdown b/website/docs/r/private_gateway.html.markdown index b5a32435..2c42a6f8 100644 --- a/website/docs/r/private_gateway.html.markdown +++ b/website/docs/r/private_gateway.html.markdown @@ -25,6 +25,20 @@ resource "cloudstack_private_gateway" "default" { } ``` +Example with VLAN overlap check bypass: + +```hcl +resource "cloudstack_private_gateway" "with_bypass" { + gateway = "10.0.0.1" + ip_address = "10.0.0.2" + netmask = "255.255.255.252" + vlan = "200" + vpc_id = "76f6e8dc-07e3-4971-b2a2-8831b0cc4cb4" + acl_id = "cf4f1dad-aade-4ccd-866c-0a2166e5be3d" + bypassvlanoverlapcheck = true +} +``` + ## Argument Reference The following arguments are supported: @@ -51,6 +65,11 @@ The following arguments are supported: * `vpc_id` - (Required) The VPC ID in which to create this Private gateway. Changing this forces a new resource to be created. +* `bypassvlanoverlapcheck` - (Optional) When set to true, bypasses the VLAN overlap + check during private gateway creation. This allows creating private gateways with + VLANs that may overlap with existing VLANs in the physical network. Defaults to + false. + ## Attributes Reference The following attributes are exported: From 1712cbfb9644a5792d62820804d1a9c34dd38b27 Mon Sep 17 00:00:00 2001 From: Brad House - Nexthop Date: Tue, 10 Mar 2026 15:21:39 +0000 Subject: [PATCH 2/3] Change bypassvlanoverlapcheck to bypass_vlan_overlap_check for naming consistency The parameter name has been changed from camelCase (bypassvlanoverlapcheck) to snake_case (bypass_vlan_overlap_check) to maintain consistency with other resource arguments like ip_address, physical_network_id, and acl_id. This change affects: - Resource schema definition - Resource creation logic - Test cases and assertions - Documentation examples The parameter is now also marked as ForceNew since it can only be set during gateway creation and cannot be modified afterwards. --- .../resource_cloudstack_private_gateway.go | 9 +++++---- ...resource_cloudstack_private_gateway_test.go | 8 ++++---- website/docs/r/private_gateway.html.markdown | 18 +++++++++--------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/cloudstack/resource_cloudstack_private_gateway.go b/cloudstack/resource_cloudstack_private_gateway.go index b962207b..79d075f5 100644 --- a/cloudstack/resource_cloudstack_private_gateway.go +++ b/cloudstack/resource_cloudstack_private_gateway.go @@ -86,10 +86,11 @@ func resourceCloudStackPrivateGateway() *schema.Resource { ForceNew: true, }, - "bypassvlanoverlapcheck": { + "bypass_vlan_overlap_check": { Type: schema.TypeBool, Optional: true, Default: false, + ForceNew: true, }, }, } @@ -125,9 +126,9 @@ func resourceCloudStackPrivateGatewayCreate(d *schema.ResourceData, meta interfa p.SetAclid(aclid.(string)) } - // Set bypassvlanoverlapcheck if specified - if bypassvlanoverlapcheck, ok := d.GetOk("bypassvlanoverlapcheck"); ok { - p.SetBypassvlanoverlapcheck(bypassvlanoverlapcheck.(bool)) + // Set bypass_vlan_overlap_check if specified + if bypassVlanOverlapCheck, ok := d.GetOk("bypass_vlan_overlap_check"); ok { + p.SetBypassvlanoverlapcheck(bypassVlanOverlapCheck.(bool)) } // Create the new private gateway diff --git a/cloudstack/resource_cloudstack_private_gateway_test.go b/cloudstack/resource_cloudstack_private_gateway_test.go index aeedffee..058cce90 100644 --- a/cloudstack/resource_cloudstack_private_gateway_test.go +++ b/cloudstack/resource_cloudstack_private_gateway_test.go @@ -62,7 +62,7 @@ func TestAccCloudStackPrivateGateway_import(t *testing.T) { ResourceName: "cloudstack_private_gateway.foo", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"bypassvlanoverlapcheck"}, + ImportStateVerifyIgnore: []string{"bypass_vlan_overlap_check"}, }, }, }) @@ -82,7 +82,7 @@ func TestAccCloudStackPrivateGateway_bypassVlanOverlapCheck(t *testing.T) { testAccCheckCloudStackPrivateGatewayExists( "cloudstack_private_gateway.bar", &gateway), resource.TestCheckResourceAttr( - "cloudstack_private_gateway.bar", "bypassvlanoverlapcheck", "true"), + "cloudstack_private_gateway.bar", "bypass_vlan_overlap_check", "true"), ), }, }, @@ -103,7 +103,7 @@ func TestAccCloudStackPrivateGateway_bypassVlanOverlapCheckDefault(t *testing.T) testAccCheckCloudStackPrivateGatewayExists( "cloudstack_private_gateway.foo", &gateway), resource.TestCheckResourceAttr( - "cloudstack_private_gateway.foo", "bypassvlanoverlapcheck", "false"), + "cloudstack_private_gateway.foo", "bypass_vlan_overlap_check", "false"), ), }, }, @@ -225,6 +225,6 @@ resource "cloudstack_private_gateway" "bar" { vlan = "2" vpc_id = cloudstack_vpc.bar.id acl_id = cloudstack_network_acl.bar.id - bypassvlanoverlapcheck = true + bypass_vlan_overlap_check = true depends_on = ["cloudstack_vpc.bar","cloudstack_network_acl.bar"] }` diff --git a/website/docs/r/private_gateway.html.markdown b/website/docs/r/private_gateway.html.markdown index 2c42a6f8..a50e149c 100644 --- a/website/docs/r/private_gateway.html.markdown +++ b/website/docs/r/private_gateway.html.markdown @@ -29,13 +29,13 @@ Example with VLAN overlap check bypass: ```hcl resource "cloudstack_private_gateway" "with_bypass" { - gateway = "10.0.0.1" - ip_address = "10.0.0.2" - netmask = "255.255.255.252" - vlan = "200" - vpc_id = "76f6e8dc-07e3-4971-b2a2-8831b0cc4cb4" - acl_id = "cf4f1dad-aade-4ccd-866c-0a2166e5be3d" - bypassvlanoverlapcheck = true + gateway = "10.0.0.1" + ip_address = "10.0.0.2" + netmask = "255.255.255.252" + vlan = "200" + vpc_id = "76f6e8dc-07e3-4971-b2a2-8831b0cc4cb4" + acl_id = "cf4f1dad-aade-4ccd-866c-0a2166e5be3d" + bypass_vlan_overlap_check = true } ``` @@ -65,10 +65,10 @@ The following arguments are supported: * `vpc_id` - (Required) The VPC ID in which to create this Private gateway. Changing this forces a new resource to be created. -* `bypassvlanoverlapcheck` - (Optional) When set to true, bypasses the VLAN overlap +* `bypass_vlan_overlap_check` - (Optional) When set to true, bypasses the VLAN overlap check during private gateway creation. This allows creating private gateways with VLANs that may overlap with existing VLANs in the physical network. Defaults to - false. + false. Changing this forces a new resource to be created. ## Attributes Reference From a5a909cb9cb3d725795823f557863f33864ec82a Mon Sep 17 00:00:00 2001 From: Brad House - Nexthop Date: Wed, 11 Mar 2026 11:30:21 +0000 Subject: [PATCH 3/3] bypass_vlan_overlap_check is not forcenew --- cloudstack/resource_cloudstack_private_gateway.go | 1 - website/docs/r/private_gateway.html.markdown | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cloudstack/resource_cloudstack_private_gateway.go b/cloudstack/resource_cloudstack_private_gateway.go index 79d075f5..db4aa186 100644 --- a/cloudstack/resource_cloudstack_private_gateway.go +++ b/cloudstack/resource_cloudstack_private_gateway.go @@ -90,7 +90,6 @@ func resourceCloudStackPrivateGateway() *schema.Resource { Type: schema.TypeBool, Optional: true, Default: false, - ForceNew: true, }, }, } diff --git a/website/docs/r/private_gateway.html.markdown b/website/docs/r/private_gateway.html.markdown index a50e149c..77db0990 100644 --- a/website/docs/r/private_gateway.html.markdown +++ b/website/docs/r/private_gateway.html.markdown @@ -68,7 +68,7 @@ The following arguments are supported: * `bypass_vlan_overlap_check` - (Optional) When set to true, bypasses the VLAN overlap check during private gateway creation. This allows creating private gateways with VLANs that may overlap with existing VLANs in the physical network. Defaults to - false. Changing this forces a new resource to be created. + false. ## Attributes Reference