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 14, 2022
1 parent 5e28298 commit 6af4d42
Show file tree
Hide file tree
Showing 6 changed files with 610 additions and 4 deletions.
59 changes: 59 additions & 0 deletions mmv1/products/compute/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13605,6 +13605,65 @@ 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.'
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.
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.
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
28 changes: 28 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,22 @@ 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: !ruby/object:Overrides::Terraform::PropertyOverride
is_set: true
set_hash_func: computeRouterNatRulesHash
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
custom_flatten: 'templates/terraform/custom_flatten/nat_rules_ip_set.erb'
rules.action.sourceNatDrainIps: !ruby/object:Overrides::Terraform::PropertyOverride
is_set: true
set_hash_func: computeRouterNatIPsHash
custom_flatten: 'templates/terraform/custom_flatten/nat_rules_ip_set.erb'
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
42 changes: 42 additions & 0 deletions mmv1/templates/terraform/constants/router_nat.go.erb
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,46 @@ func computeRouterNatIPsHash(v interface{}) int {
return schema.HashString(newParts[0])
}
return schema.HashString(GetResourceNameFromSelfLink(val))
}

func computeRouterNatRulesHash(v interface{}) int {
obj := v.(map[string]interface{})
ruleNumber := obj["rule_number"].(int)

description := obj["description"]
descriptionHash := 0
if description != nil {
descriptionHash = schema.HashString(description.(string))
}

match := obj["match"].(string)

sourceNatActiveIpHash := 0
sourceNatDrainIpHash := 0
if obj["action"] != nil {
actions := obj["action"].([]interface{})
if len(actions) != 0 && actions[0] != nil {
action := actions[0].(map[string]interface{})

sourceNatActiveIps := action["source_nat_active_ips"]
if sourceNatActiveIps != nil {
sourceNatActiveIpSet := sourceNatActiveIps.(*schema.Set)
for _, sourceNatActiveIp := range sourceNatActiveIpSet.List() {
sourceNatActiveIpStr := fmt.Sprintf("source_nat_active_ips-%d", computeRouterNatIPsHash(sourceNatActiveIp.(string)))
sourceNatActiveIpHash += schema.HashString(sourceNatActiveIpStr)
}
}

soureNatDrainIps := action["source_nat_drain_ips"]
if soureNatDrainIps != nil {
soureNatDrainIpSet := soureNatDrainIps.(*schema.Set)
for _, soureNatDrainIp := range soureNatDrainIpSet.List() {
sourceNatDrainIpStr := fmt.Sprintf("source_nat_drain_ips-%d", computeRouterNatIPsHash(soureNatDrainIp.(string)))
sourceNatDrainIpHash += schema.HashString(sourceNatDrainIpStr)
}
}
}
}

return ruleNumber + descriptionHash + schema.HashString(match) + sourceNatActiveIpHash + sourceNatDrainIpHash
}
6 changes: 6 additions & 0 deletions mmv1/templates/terraform/custom_flatten/nat_rules_ip_set.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return v
}
return schema.NewSet(computeRouterNatIPsHash, convertStringArrToInterface(convertAndMapStringArr(v.([]interface{}), ConvertSelfLinkToV1)))
}
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
}

0 comments on commit 6af4d42

Please sign in to comment.