Skip to content

Commit

Permalink
Add rules field to google_compute_router_nat
Browse files Browse the repository at this point in the history
  • Loading branch information
zli82016 committed Oct 4, 2022
1 parent 5e28298 commit 39ef1b5
Show file tree
Hide file tree
Showing 4 changed files with 334 additions and 3 deletions.
62 changes: 62 additions & 0 deletions mmv1/products/compute/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13605,6 +13605,68 @@ objects:
- :ERRORS_ONLY
- :TRANSLATIONS_ONLY
- :ALL
- !ruby/object:Api::Type::Array
name: rules
description: 'A list of rules associated with this NAT.'
send_empty_value: true
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::Integer
name: 'ruleNumber'
description: |
An integer uniquely identifying a rule in the list.
The rule number must be a positive value between 0 and 65000, and must be unique among rules within a NAT.
required: true
send_empty_value: true
- !ruby/object:Api::Type::String
name: 'description'
description: 'An optional description of this rule.'
- !ruby/object:Api::Type::String
name: 'match'
description: |
CEL expression that specifies the match condition that egress traffic from a VM is evaluated against.
If it evaluates to true, the corresponding action is enforced.

The following examples are valid match expressions for public NAT:

"inIpRange(destination.ip, '1.1.0.0/16') || inIpRange(destination.ip, '2.2.0.0/16')"

"destination.ip == '1.1.0.1' || destination.ip == '8.8.8.8'"

The following example is a valid match expression for private NAT:

"nexthop.hub == 'https://networkconnectivity.googleapis.com/v1alpha1/projects/my-project/global/hub/hub-1'"
required: true
- !ruby/object:Api::Type::NestedObject
name: 'action'
description: 'The action to be enforced for traffic that matches this rule.'
send_empty_value: true
properties:
- !ruby/object:Api::Type::Array
name: 'sourceNatActiveIps'
description: |
A list of URLs of the IP resources used for this NAT rule.
These IP addresses must be valid static external IP addresses assigned to the project.
This field is used for public NAT.
send_empty_value: true
item_type: !ruby/object:Api::Type::ResourceRef
name: 'address'
resource: 'Address'
imports: 'selfLink'
description: 'A reference to an address associated with this NAT'
- !ruby/object:Api::Type::Array
name: 'sourceNatDrainIps'
description: |
A list of URLs of the IP resources to be drained.
These IPs must be valid static external IPs that have been assigned to the NAT.
These IPs should be used for updating/patching a NAT rule only.
This field is used for public NAT.
send_empty_value: true
item_type: !ruby/object:Api::Type::ResourceRef
name: 'address'
resource: 'Address'
imports: 'selfLink'
description: 'A reference to an address associated with this NAT'
- !ruby/object:Api::Type::Boolean
name: enableEndpointIndependentMapping
description: |
Expand Down
23 changes: 23 additions & 0 deletions mmv1/products/compute/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,18 @@ overrides: !ruby/object:Overrides::ResourceOverrides
network_name: "my-network"
subnet_name: "my-subnetwork"
address_name: "nat-manual-ip"
- !ruby/object:Provider::Terraform::Examples
name: "router_nat_rules"
primary_resource_id: "nat_rules"
skip_test: true
vars:
router_name: "my-router"
nat_name: "my-router-nat"
network_name: "my-network"
subnet_name: "my-subnetwork"
address_name1: "nat-address1"
address_name2: "nat-address2"
address_name3: "nat-address3"
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
Expand Down Expand Up @@ -2590,6 +2602,17 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_flatten: 'templates/terraform/custom_flatten/default_if_empty.erb'
enableDynamicPortAllocation: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
rules.ruleNumber: !ruby/object:Overrides::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: validation.IntBetween(0, 65000)
rules.action: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
rules.action.sourceNatActiveIps: !ruby/object:Overrides::Terraform::PropertyOverride
is_set: true
set_hash_func: computeRouterNatIPsHash
rules.action.sourceNatDrainIps: !ruby/object:Overrides::Terraform::PropertyOverride
is_set: true
set_hash_func: computeRouterNatIPsHash
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: 'templates/terraform/constants/router_nat.go.erb'
resource_definition: 'templates/terraform/resource_definition/router_nat.go.erb'
Expand Down
58 changes: 58 additions & 0 deletions mmv1/templates/terraform/examples/router_nat_rules.tf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
resource "google_compute_network" "net" {
name = "<%= ctx[:vars]['network_name'] %>"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "subnet" {
name = "<%= ctx[:vars]['subnet_name'] %>"
network = google_compute_network.net.id
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
}

resource "google_compute_router" "router" {
name = "<%= ctx[:vars]['router_name'] %>"
region = google_compute_subnetwork.subnet.region
network = google_compute_network.net.id
}

resource "google_compute_address" "addr1" {
name = "<%= ctx[:vars]['address_name1'] %>"
region = google_compute_subnetwork.subnet.region
}

resource "google_compute_address" "addr2" {
name = "<%= ctx[:vars]['address_name2'] %>"
region = google_compute_subnetwork.subnet.region
}

resource "google_compute_address" "addr3" {
name = "<%= ctx[:vars]['address_name3'] %>"
region = google_compute_subnetwork.subnet.region
}

resource "google_compute_router_nat" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['nat_name'] %>"
router = google_compute_router.router.name
region = google_compute_router.router.region

nat_ip_allocate_option = "MANUAL_ONLY"
nat_ips = [google_compute_address.addr1.self_link]

source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
name = google_compute_subnetwork.subnet.id
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}

rules {
rule_number = 100
description = "nat rules example"
match = "inIpRange(destination.ip, '1.1.0.0/16') || inIpRange(destination.ip, '2.2.0.0/16')"
action {
source_nat_active_ips = [google_compute_address.addr2.self_link, google_compute_address.addr3.self_link]
}
}

enable_endpoint_independent_mapping = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,73 @@ func TestAccComputeRouterNat_withNatIpsAndDrainNatIps(t *testing.T) {

<% end -%>

func TestAccComputeRouterNat_withNatRules(t *testing.T) {
t.Parallel()

testId := randString(t, 10)
routerName := fmt.Sprintf("tf-test-router-nat-%s", testId)
ruleDescription := randString(t, 10)
ruleDescriptionUpdate := randString(t, 10)
match := "inIpRange(destination.ip, '1.1.0.0/16') || inIpRange(destination.ip, '2.2.0.0/16')"
matchUpdate := "destination.ip == '1.1.0.1' || destination.ip == '8.8.8.8'"

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeRouterNatDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComputeRouterNatRulesBasic_omitRules(routerName),
},
{
ResourceName: "google_compute_router_nat.foobar",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeRouterNatRulesBasic(routerName, 0, ruleDescription, match),
},
{
ResourceName: "google_compute_router_nat.foobar",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeRouterNatRulesBasic(routerName, 65000, ruleDescription, match),
},
{
ResourceName: "google_compute_router_nat.foobar",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeRouterNatRulesBasic(routerName, 100, ruleDescriptionUpdate, matchUpdate),
},
{
ResourceName: "google_compute_router_nat.foobar",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeRouterNatRulesWithSourceActiveAndDrainIps(routerName, 100, ruleDescriptionUpdate, matchUpdate),
},
{
ResourceName: "google_compute_router_nat.foobar",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeRouterNatRulesWithDrainIps(routerName, 100, ruleDescriptionUpdate, matchUpdate),
},
{
ResourceName: "google_compute_router_nat.foobar",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckComputeRouterNatDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
config := googleProviderConfig(t)
Expand Down Expand Up @@ -715,7 +782,6 @@ resource "google_compute_router_nat" "foobar" {
`, routerName, routerName, routerName, routerName, routerName, enableEndpointIndependentMapping, enableDynamicPortAllocation, minPortsPerVm, maxPortsPerVm)
}

<% unless version == 'ga' -%>
func testAccComputeRouterNatBaseResourcesWithNatIps(routerName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
Expand Down Expand Up @@ -753,6 +819,7 @@ resource "google_compute_router" "foobar" {
`, routerName, routerName, routerName, routerName, routerName, routerName)
}

<% unless version == 'ga' -%>
func testAccComputeRouterNatWithNatIps(routerName string) string {
return fmt.Sprintf(`
%s
Expand Down Expand Up @@ -861,9 +928,130 @@ resource "google_compute_router_nat" "foobar" {
}
`, testAccComputeRouterNatBaseResourcesWithNatIps(routerName), routerName)
}

<% end -%>

func testAccComputeRouterNatRulesBasic_omitRules(routerName string) string {
return fmt.Sprintf(`
%s

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.addr1.self_link]


source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
name = google_compute_subnetwork.foobar.id
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}

enable_endpoint_independent_mapping = false
}
`, testAccComputeRouterNatBaseResourcesWithNatIps(routerName), routerName)
}

func testAccComputeRouterNatRulesBasic(routerName string, ruleNumber int, ruleDescription string, ruleMatch string) string {
return fmt.Sprintf(`
%s

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.addr1.self_link]


source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
name = google_compute_subnetwork.foobar.id
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}

rules {
rule_number = %d
description = "%s"
match = "%s"
action {
source_nat_active_ips = [google_compute_address.addr2.self_link, google_compute_address.addr3.self_link]
}
}

enable_endpoint_independent_mapping = false
}
`, testAccComputeRouterNatBaseResourcesWithNatIps(routerName), routerName, ruleNumber, ruleDescription, ruleMatch)
}

func testAccComputeRouterNatRulesWithSourceActiveAndDrainIps(routerName string, ruleNumber int, ruleDescription string, ruleMatch string) string {
return fmt.Sprintf(`
%s

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.addr1.self_link]

source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
name = google_compute_subnetwork.foobar.id
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}

rules {
rule_number = %d
description = "%s"
match = "%s"
action {
source_nat_active_ips = [google_compute_address.addr2.self_link]
source_nat_drain_ips = [google_compute_address.addr3.self_link]
}
}

enable_endpoint_independent_mapping = false
}
`, testAccComputeRouterNatBaseResourcesWithNatIps(routerName), routerName, ruleNumber, ruleDescription, ruleMatch)
}

func testAccComputeRouterNatRulesWithDrainIps(routerName string, ruleNumber int, ruleDescription string, ruleMatch string) string {
return fmt.Sprintf(`
%s

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.addr1.self_link]

source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
name = google_compute_subnetwork.foobar.id
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}

rules {
rule_number = %d
description = "%s"
match = "%s"
action {
source_nat_drain_ips = [google_compute_address.addr2.self_link]
}
}

enable_endpoint_independent_mapping = false
}
`, testAccComputeRouterNatBaseResourcesWithNatIps(routerName), routerName, ruleNumber, ruleDescription, ruleMatch)
}

func testAccComputeRouterNatKeepRouter(routerName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
Expand Down Expand Up @@ -946,4 +1134,4 @@ resource "google_compute_router_nat" "foobar" {
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
}
`, routerName, routerName, routerName, routerName)
}
}

0 comments on commit 39ef1b5

Please sign in to comment.