Skip to content

Commit b40ca48

Browse files
compute: support maxPortsPerVm field related to Cloud NAT's enableDynamicPortAllocation (#6155) (#4400)
Support for the Dynamic Port Allocation feature (tracked in terraform-google-modules/terraform-google-cloud-nat#64 and hashicorp/terraform-provider-google#11052) was initially implemented in #6022, but it lacked support for the maxPortsPerVm field. This field is crucial to allow the full configuration to work. Signed-off-by: Modular Magician <[email protected]>
1 parent 4dacefd commit b40ca48

File tree

4 files changed

+111
-2
lines changed

4 files changed

+111
-2
lines changed

.changelog/6155.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
compute: add maxPortsPerVm field to `google_compute_router_nat` resource
3+
```

google-beta/resource_compute_router_nat.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,10 @@ valid static external IPs that have been assigned to the NAT.`,
185185
Computed: true,
186186
Optional: true,
187187
Description: `Enable Dynamic Port Allocation.
188-
If minPorts is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
188+
If minPortsPerVm is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
189189
If minPortsPerVm is not set, a minimum of 32 ports will be allocated to a VM from this NAT config.
190+
If maxPortsPerVm is set, maxPortsPerVm must be set to a power of two greater than minPortsPerVm.
191+
If maxPortsPerVm is not set, a maximum of 65536 ports will be allocated to a VM from this NAT config.
190192
191193
Mutually exclusive with enableEndpointIndependentMapping.`,
192194
},
@@ -224,6 +226,12 @@ see the [official documentation](https://cloud.google.com/nat/docs/overview#spec
224226
},
225227
},
226228
},
229+
"max_ports_per_vm": {
230+
Type: schema.TypeInt,
231+
Optional: true,
232+
Description: `Maximum number of ports allocated to a VM from this NAT.
233+
This field can only be set when enableDynamicPortAllocation is enabled.`,
234+
},
227235
"min_ports_per_vm": {
228236
Type: schema.TypeInt,
229237
Optional: true,
@@ -375,6 +383,12 @@ func resourceComputeRouterNatCreate(d *schema.ResourceData, meta interface{}) er
375383
} else if v, ok := d.GetOkExists("min_ports_per_vm"); !isEmptyValue(reflect.ValueOf(minPortsPerVmProp)) && (ok || !reflect.DeepEqual(v, minPortsPerVmProp)) {
376384
obj["minPortsPerVm"] = minPortsPerVmProp
377385
}
386+
maxPortsPerVmProp, err := expandNestedComputeRouterNatMaxPortsPerVm(d.Get("max_ports_per_vm"), d, config)
387+
if err != nil {
388+
return err
389+
} else if v, ok := d.GetOkExists("max_ports_per_vm"); !isEmptyValue(reflect.ValueOf(maxPortsPerVmProp)) && (ok || !reflect.DeepEqual(v, maxPortsPerVmProp)) {
390+
obj["maxPortsPerVm"] = maxPortsPerVmProp
391+
}
378392
enableDynamicPortAllocationProp, err := expandNestedComputeRouterNatEnableDynamicPortAllocation(d.Get("enable_dynamic_port_allocation"), d, config)
379393
if err != nil {
380394
return err
@@ -543,6 +557,9 @@ func resourceComputeRouterNatRead(d *schema.ResourceData, meta interface{}) erro
543557
if err := d.Set("min_ports_per_vm", flattenNestedComputeRouterNatMinPortsPerVm(res["minPortsPerVm"], d, config)); err != nil {
544558
return fmt.Errorf("Error reading RouterNat: %s", err)
545559
}
560+
if err := d.Set("max_ports_per_vm", flattenNestedComputeRouterNatMaxPortsPerVm(res["maxPortsPerVm"], d, config)); err != nil {
561+
return fmt.Errorf("Error reading RouterNat: %s", err)
562+
}
546563
if err := d.Set("enable_dynamic_port_allocation", flattenNestedComputeRouterNatEnableDynamicPortAllocation(res["enableDynamicPortAllocation"], d, config)); err != nil {
547564
return fmt.Errorf("Error reading RouterNat: %s", err)
548565
}
@@ -620,6 +637,12 @@ func resourceComputeRouterNatUpdate(d *schema.ResourceData, meta interface{}) er
620637
} else if v, ok := d.GetOkExists("min_ports_per_vm"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, minPortsPerVmProp)) {
621638
obj["minPortsPerVm"] = minPortsPerVmProp
622639
}
640+
maxPortsPerVmProp, err := expandNestedComputeRouterNatMaxPortsPerVm(d.Get("max_ports_per_vm"), d, config)
641+
if err != nil {
642+
return err
643+
} else if v, ok := d.GetOkExists("max_ports_per_vm"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, maxPortsPerVmProp)) {
644+
obj["maxPortsPerVm"] = maxPortsPerVmProp
645+
}
623646
enableDynamicPortAllocationProp, err := expandNestedComputeRouterNatEnableDynamicPortAllocation(d.Get("enable_dynamic_port_allocation"), d, config)
624647
if err != nil {
625648
return err
@@ -868,6 +891,23 @@ func flattenNestedComputeRouterNatMinPortsPerVm(v interface{}, d *schema.Resourc
868891
return v // let terraform core handle it otherwise
869892
}
870893

894+
func flattenNestedComputeRouterNatMaxPortsPerVm(v interface{}, d *schema.ResourceData, config *Config) interface{} {
895+
// Handles the string fixed64 format
896+
if strVal, ok := v.(string); ok {
897+
if intVal, err := stringToFixed64(strVal); err == nil {
898+
return intVal
899+
}
900+
}
901+
902+
// number values are represented as float64
903+
if floatVal, ok := v.(float64); ok {
904+
intVal := int(floatVal)
905+
return intVal
906+
}
907+
908+
return v // let terraform core handle it otherwise
909+
}
910+
871911
func flattenNestedComputeRouterNatEnableDynamicPortAllocation(v interface{}, d *schema.ResourceData, config *Config) interface{} {
872912
return v
873913
}
@@ -1060,6 +1100,10 @@ func expandNestedComputeRouterNatMinPortsPerVm(v interface{}, d TerraformResourc
10601100
return v, nil
10611101
}
10621102

1103+
func expandNestedComputeRouterNatMaxPortsPerVm(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
1104+
return v, nil
1105+
}
1106+
10631107
func expandNestedComputeRouterNatEnableDynamicPortAllocation(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
10641108
return v, nil
10651109
}

google-beta/resource_compute_router_nat_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ func TestAccComputeRouterNat_withPortAllocationMethods(t *testing.T) {
211211
ImportState: true,
212212
ImportStateVerify: true,
213213
},
214+
{
215+
Config: testAccComputeRouterNatWithAllocationMethodWithParameters(routerName, false, true, 256, 8192),
216+
},
217+
{
218+
ResourceName: "google_compute_router_nat.foobar",
219+
ImportState: true,
220+
ImportStateVerify: true,
221+
},
214222
},
215223
})
216224
}
@@ -654,6 +662,53 @@ resource "google_compute_router_nat" "foobar" {
654662
`, routerName, routerName, routerName, routerName, routerName, enableEndpointIndependentMapping, enableDynamicPortAllocation)
655663
}
656664

665+
func testAccComputeRouterNatWithAllocationMethodWithParameters(routerName string, enableEndpointIndependentMapping, enableDynamicPortAllocation bool, minPortsPerVm, maxPortsPerVm uint32) string {
666+
return fmt.Sprintf(`
667+
resource "google_compute_network" "foobar" {
668+
name = "%s-net"
669+
auto_create_subnetworks = "false"
670+
}
671+
672+
resource "google_compute_subnetwork" "foobar" {
673+
name = "%s-subnet"
674+
network = google_compute_network.foobar.self_link
675+
ip_cidr_range = "10.0.0.0/16"
676+
region = "us-central1"
677+
}
678+
679+
resource "google_compute_address" "foobar" {
680+
name = "router-nat-%s-addr"
681+
region = google_compute_subnetwork.foobar.region
682+
}
683+
684+
resource "google_compute_router" "foobar" {
685+
name = "%s"
686+
region = google_compute_subnetwork.foobar.region
687+
network = google_compute_network.foobar.self_link
688+
bgp {
689+
asn = 64514
690+
}
691+
}
692+
693+
resource "google_compute_router_nat" "foobar" {
694+
name = "%s"
695+
router = google_compute_router.foobar.name
696+
region = google_compute_router.foobar.region
697+
nat_ip_allocate_option = "MANUAL_ONLY"
698+
nat_ips = [google_compute_address.foobar.self_link]
699+
source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
700+
subnetwork {
701+
name = google_compute_subnetwork.foobar.name
702+
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
703+
}
704+
enable_endpoint_independent_mapping = %t
705+
enable_dynamic_port_allocation = %t
706+
min_ports_per_vm = %d
707+
max_ports_per_vm = %d
708+
}
709+
`, routerName, routerName, routerName, routerName, routerName, enableEndpointIndependentMapping, enableDynamicPortAllocation, minPortsPerVm, maxPortsPerVm)
710+
}
711+
657712
func testAccComputeRouterNatBaseResourcesWithNatIps(routerName string) string {
658713
return fmt.Sprintf(`
659714
resource "google_compute_network" "foobar" {

website/docs/r/compute_router_nat.html.markdown

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,18 @@ The following arguments are supported:
171171
(Optional)
172172
Minimum number of ports allocated to a VM from this NAT.
173173

174+
* `max_ports_per_vm` -
175+
(Optional)
176+
Maximum number of ports allocated to a VM from this NAT.
177+
This field can only be set when enableDynamicPortAllocation is enabled.
178+
174179
* `enable_dynamic_port_allocation` -
175180
(Optional)
176181
Enable Dynamic Port Allocation.
177-
If minPorts is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
182+
If minPortsPerVm is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
178183
If minPortsPerVm is not set, a minimum of 32 ports will be allocated to a VM from this NAT config.
184+
If maxPortsPerVm is set, maxPortsPerVm must be set to a power of two greater than minPortsPerVm.
185+
If maxPortsPerVm is not set, a maximum of 65536 ports will be allocated to a VM from this NAT config.
179186
Mutually exclusive with enableEndpointIndependentMapping.
180187

181188
* `udp_idle_timeout_sec` -

0 commit comments

Comments
 (0)