Skip to content

Commit

Permalink
compute: support maxPortsPerVm field related to Cloud NAT's enableDyn…
Browse files Browse the repository at this point in the history
…amicPortAllocation (hashicorp#6155)

Support for the Dynamic Port Allocation feature (tracked in
terraform-google-modules/terraform-google-cloud-nat#64 and
hashicorp#11052) was initially implemented
in hashicorp#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]>
  • Loading branch information
modular-magician committed Jun 22, 2022
1 parent 6e28de4 commit 5b0f81b
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .changelog/6155.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: add maxPortsPerVm field to `google_compute_router_nat` resource
```
46 changes: 45 additions & 1 deletion google/resource_compute_router_nat.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,10 @@ valid static external IPs that have been assigned to the NAT.`,
Computed: true,
Optional: true,
Description: `Enable Dynamic Port Allocation.
If minPorts is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
If minPortsPerVm is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
If minPortsPerVm is not set, a minimum of 32 ports will be allocated to a VM from this NAT config.
If maxPortsPerVm is set, maxPortsPerVm must be set to a power of two greater than minPortsPerVm.
If maxPortsPerVm is not set, a maximum of 65536 ports will be allocated to a VM from this NAT config.
Mutually exclusive with enableEndpointIndependentMapping.`,
},
Expand Down Expand Up @@ -224,6 +226,12 @@ see the [official documentation](https://cloud.google.com/nat/docs/overview#spec
},
},
},
"max_ports_per_vm": {
Type: schema.TypeInt,
Optional: true,
Description: `Maximum number of ports allocated to a VM from this NAT.
This field can only be set when enableDynamicPortAllocation is enabled.`,
},
"min_ports_per_vm": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -375,6 +383,12 @@ func resourceComputeRouterNatCreate(d *schema.ResourceData, meta interface{}) er
} else if v, ok := d.GetOkExists("min_ports_per_vm"); !isEmptyValue(reflect.ValueOf(minPortsPerVmProp)) && (ok || !reflect.DeepEqual(v, minPortsPerVmProp)) {
obj["minPortsPerVm"] = minPortsPerVmProp
}
maxPortsPerVmProp, err := expandNestedComputeRouterNatMaxPortsPerVm(d.Get("max_ports_per_vm"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("max_ports_per_vm"); !isEmptyValue(reflect.ValueOf(maxPortsPerVmProp)) && (ok || !reflect.DeepEqual(v, maxPortsPerVmProp)) {
obj["maxPortsPerVm"] = maxPortsPerVmProp
}
enableDynamicPortAllocationProp, err := expandNestedComputeRouterNatEnableDynamicPortAllocation(d.Get("enable_dynamic_port_allocation"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -543,6 +557,9 @@ func resourceComputeRouterNatRead(d *schema.ResourceData, meta interface{}) erro
if err := d.Set("min_ports_per_vm", flattenNestedComputeRouterNatMinPortsPerVm(res["minPortsPerVm"], d, config)); err != nil {
return fmt.Errorf("Error reading RouterNat: %s", err)
}
if err := d.Set("max_ports_per_vm", flattenNestedComputeRouterNatMaxPortsPerVm(res["maxPortsPerVm"], d, config)); err != nil {
return fmt.Errorf("Error reading RouterNat: %s", err)
}
if err := d.Set("enable_dynamic_port_allocation", flattenNestedComputeRouterNatEnableDynamicPortAllocation(res["enableDynamicPortAllocation"], d, config)); err != nil {
return fmt.Errorf("Error reading RouterNat: %s", err)
}
Expand Down Expand Up @@ -620,6 +637,12 @@ func resourceComputeRouterNatUpdate(d *schema.ResourceData, meta interface{}) er
} else if v, ok := d.GetOkExists("min_ports_per_vm"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, minPortsPerVmProp)) {
obj["minPortsPerVm"] = minPortsPerVmProp
}
maxPortsPerVmProp, err := expandNestedComputeRouterNatMaxPortsPerVm(d.Get("max_ports_per_vm"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("max_ports_per_vm"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, maxPortsPerVmProp)) {
obj["maxPortsPerVm"] = maxPortsPerVmProp
}
enableDynamicPortAllocationProp, err := expandNestedComputeRouterNatEnableDynamicPortAllocation(d.Get("enable_dynamic_port_allocation"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -868,6 +891,23 @@ func flattenNestedComputeRouterNatMinPortsPerVm(v interface{}, d *schema.Resourc
return v // let terraform core handle it otherwise
}

func flattenNestedComputeRouterNatMaxPortsPerVm(v interface{}, d *schema.ResourceData, config *Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := stringToFixed64(strVal); err == nil {
return intVal
}
}

// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}

return v // let terraform core handle it otherwise
}

func flattenNestedComputeRouterNatEnableDynamicPortAllocation(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}
Expand Down Expand Up @@ -1060,6 +1100,10 @@ func expandNestedComputeRouterNatMinPortsPerVm(v interface{}, d TerraformResourc
return v, nil
}

func expandNestedComputeRouterNatMaxPortsPerVm(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandNestedComputeRouterNatEnableDynamicPortAllocation(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
Expand Down
55 changes: 55 additions & 0 deletions google/resource_compute_router_nat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ func TestAccComputeRouterNat_withPortAllocationMethods(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeRouterNatWithAllocationMethodWithParameters(routerName, false, true, 256, 8192),
},
{
ResourceName: "google_compute_router_nat.foobar",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
Expand Down Expand Up @@ -605,6 +613,53 @@ resource "google_compute_router_nat" "foobar" {
`, routerName, routerName, routerName, routerName, routerName, enableEndpointIndependentMapping, enableDynamicPortAllocation)
}

func testAccComputeRouterNatWithAllocationMethodWithParameters(routerName string, enableEndpointIndependentMapping, enableDynamicPortAllocation bool, minPortsPerVm, maxPortsPerVm uint32) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
name = "%s-net"
auto_create_subnetworks = "false"
}
resource "google_compute_subnetwork" "foobar" {
name = "%s-subnet"
network = google_compute_network.foobar.self_link
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
}
resource "google_compute_address" "foobar" {
name = "router-nat-%s-addr"
region = google_compute_subnetwork.foobar.region
}
resource "google_compute_router" "foobar" {
name = "%s"
region = google_compute_subnetwork.foobar.region
network = google_compute_network.foobar.self_link
bgp {
asn = 64514
}
}
resource "google_compute_router_nat" "foobar" {
name = "%s"
router = google_compute_router.foobar.name
region = google_compute_router.foobar.region
nat_ip_allocate_option = "MANUAL_ONLY"
nat_ips = [google_compute_address.foobar.self_link]
source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
name = google_compute_subnetwork.foobar.name
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}
enable_endpoint_independent_mapping = %t
enable_dynamic_port_allocation = %t
min_ports_per_vm = %d
max_ports_per_vm = %d
}
`, routerName, routerName, routerName, routerName, routerName, enableEndpointIndependentMapping, enableDynamicPortAllocation, minPortsPerVm, maxPortsPerVm)
}

func testAccComputeRouterNatKeepRouter(routerName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
Expand Down
9 changes: 8 additions & 1 deletion website/docs/r/compute_router_nat.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,18 @@ The following arguments are supported:
(Optional)
Minimum number of ports allocated to a VM from this NAT.

* `max_ports_per_vm` -
(Optional)
Maximum number of ports allocated to a VM from this NAT.
This field can only be set when enableDynamicPortAllocation is enabled.

* `enable_dynamic_port_allocation` -
(Optional)
Enable Dynamic Port Allocation.
If minPorts is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
If minPortsPerVm is set, minPortsPerVm must be set to a power of two greater than or equal to 32.
If minPortsPerVm is not set, a minimum of 32 ports will be allocated to a VM from this NAT config.
If maxPortsPerVm is set, maxPortsPerVm must be set to a power of two greater than minPortsPerVm.
If maxPortsPerVm is not set, a maximum of 65536 ports will be allocated to a VM from this NAT config.
Mutually exclusive with enableEndpointIndependentMapping.

* `udp_idle_timeout_sec` -
Expand Down

0 comments on commit 5b0f81b

Please sign in to comment.