From 11b6bfd95ef8e441859b34e75b68cc1c93dc5eb8 Mon Sep 17 00:00:00 2001 From: Anna Khmelnitsky Date: Tue, 10 Dec 2024 11:05:42 -0800 Subject: [PATCH] Add nat type to nat rule resource Before this change, only NAT64 and USER nat types were supported, and the value was calculated based on action. With this change, we need to keep in mind refresh of existing nat rule resources, hence the new type will be calculated. Signed-off-by: Anna Khmelnitsky --- nsxt/resource_nsxt_policy_nat_rule.go | 83 ++++++++++++----- nsxt/resource_nsxt_policy_nat_rule_test.go | 94 ++++++++++++++++---- website/docs/r/policy_nat_rule.html.markdown | 1 + 3 files changed, 139 insertions(+), 39 deletions(-) diff --git a/nsxt/resource_nsxt_policy_nat_rule.go b/nsxt/resource_nsxt_policy_nat_rule.go index bef2fe138..e7d1b6f11 100644 --- a/nsxt/resource_nsxt_policy_nat_rule.go +++ b/nsxt/resource_nsxt_policy_nat_rule.go @@ -40,6 +40,13 @@ var policyNATRulePolicyBasedVpnModeTypeValues = []string{ model.PolicyNatRule_POLICY_BASED_VPN_MODE_MATCH, } +var policyNATRuleTypeValues = []string{ + model.PolicyNat_NAT_TYPE_INTERNAL, + model.PolicyNat_NAT_TYPE_USER, + model.PolicyNat_NAT_TYPE_DEFAULT, + model.PolicyNat_NAT_TYPE_NAT64, +} + func resourceNsxtPolicyNATRule() *schema.Resource { return &schema.Resource{ Create: resourceNsxtPolicyNATRuleCreate, @@ -144,6 +151,14 @@ func resourceNsxtPolicyNATRule() *schema.Resource { Computed: true, ValidateFunc: validation.StringInSlice(policyNATRulePolicyBasedVpnModeTypeValues, false), }, + "type": { + Type: schema.TypeString, + Description: "NAT Type", + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice(policyNATRuleTypeValues, false), + Computed: true, + }, }, } } @@ -180,7 +195,8 @@ func resourceNsxtPolicyNATRuleDelete(d *schema.ResourceData, m interface{}) erro } action := d.Get("action").(string) - natType := getNatTypeByAction(action) + natType := d.Get("type").(string) + natType = getNatTypeByAction(natType, action) err := deleteNsxtPolicyNATRule(context, getPolicyConnector(m), gwID, isT0, natType, id) if err != nil { return handleDeleteError("NAT Rule", id, err) @@ -204,8 +220,7 @@ func getNsxtPolicyNATRuleByID(sessionContext utl.SessionContext, connector clien return client.Get(gwID, natType, ruleID) } -func patchNsxtPolicyNATRule(sessionContext utl.SessionContext, connector client.Connector, gwID string, rule model.PolicyNatRule, isT0 bool) error { - natType := getNatTypeByAction(*rule.Action) +func patchNsxtPolicyNATRule(sessionContext utl.SessionContext, connector client.Connector, gwID string, rule model.PolicyNatRule, isT0 bool, natType string) error { _, err := getTranslatedNetworks(rule) if err != nil { return err @@ -231,12 +246,15 @@ func patchNsxtPolicyNATRule(sessionContext utl.SessionContext, connector client. return client.Patch(gwID, natType, *rule.Id, rule) } -func getNatTypeByAction(action string) string { +func getNatTypeByAction(natType string, action string) string { if action == model.PolicyNatRule_ACTION_NAT64 { return model.PolicyNat_NAT_TYPE_NAT64 } + if natType == "" { + return model.PolicyNat_NAT_TYPE_USER + } - return model.PolicyNat_NAT_TYPE_USER + return natType } func translatedNetworksNeeded(action string) bool { @@ -284,8 +302,14 @@ func resourceNsxtPolicyNATRuleRead(d *schema.ResourceData, m interface{}) error return handleMultitenancyTier0Error() } - action := d.Get("action").(string) - natType := getNatTypeByAction(action) + natType := d.Get("type").(string) + if natType == "" { + // This can happen when provider was upgraded and we're refreshing an existing resource + // This is not an import case, so action should be set + action := d.Get("action").(string) + natType = getNatTypeByAction(natType, action) + d.Set("type", natType) + } obj, err := getNsxtPolicyNATRuleByID(context, connector, gwID, isT0, natType, id) if err != nil { return handleReadError(d, "NAT Rule", id, err) @@ -322,12 +346,30 @@ func resourceNsxtPolicyNATRuleRead(d *schema.ResourceData, m interface{}) error return nil } +func validateNatTypeAction(action string, natType string) error { + if action == model.PolicyNatRule_ACTION_NAT64 && (natType != "" && natType != model.PolicyNat_NAT_TYPE_NAT64) { + return fmt.Errorf("Rules with NAT64 action must have NAT64 nat type") + } + + if natType == model.PolicyNat_NAT_TYPE_NAT64 && action != model.PolicyNatRule_ACTION_NAT64 { + return fmt.Errorf("Rules with type NAT64 action must have NAT64 action") + } + return nil +} + func resourceNsxtPolicyNATRuleCreate(d *schema.ResourceData, m interface{}) error { connector := getPolicyConnector(m) gwPolicyPath := d.Get("gateway_path").(string) action := d.Get("action").(string) - natType := getNatTypeByAction(action) + natType := d.Get("type").(string) + if err := validateNatTypeAction(action, natType); err != nil { + return err + } + // nat type attribute was introduced as explicit attribute when existing deployments + // were calculating it based on action + // for backward compatibility, we allow the type to be overridden by NAT64 action + natType = getNatTypeByAction(natType, action) isT0, gwID := parseGatewayPolicyPath(gwPolicyPath) if gwID == "" { return fmt.Errorf("gateway_path is not valid") @@ -394,13 +436,15 @@ func resourceNsxtPolicyNATRuleCreate(d *schema.ResourceData, m interface{}) erro log.Printf("[INFO] Creating NAT Rule with ID %s", id) - err := patchNsxtPolicyNATRule(getSessionContext(d, m), connector, gwID, ruleStruct, isT0) + err := patchNsxtPolicyNATRule(getSessionContext(d, m), connector, gwID, ruleStruct, isT0, natType) if err != nil { return handleCreateError("NAT Rule", id, err) } d.SetId(id) d.Set("nsx_id", id) + // In case nat type was not specified or got overridden by action + d.Set("type", natType) return resourceNsxtPolicyNATRuleRead(d, m) } @@ -426,6 +470,11 @@ func resourceNsxtPolicyNATRuleUpdate(d *schema.ResourceData, m interface{}) erro displayName := d.Get("display_name").(string) description := d.Get("description").(string) action := d.Get("action").(string) + natType := d.Get("type").(string) + if err := validateNatTypeAction(action, natType); err != nil { + return err + } + natType = getNatTypeByAction(natType, action) enabled := d.Get("enabled").(bool) logging := d.Get("logging").(bool) priority := int64(d.Get("rule_priority").(int)) @@ -467,7 +516,7 @@ func resourceNsxtPolicyNATRuleUpdate(d *schema.ResourceData, m interface{}) erro } log.Printf("[INFO] Updating NAT Rule with ID %s", id) - err := patchNsxtPolicyNATRule(context, connector, gwID, ruleStruct, isT0) + err := patchNsxtPolicyNATRule(context, connector, gwID, ruleStruct, isT0, natType) if err != nil { return handleUpdateError("NAT Rule", id, err) } @@ -492,12 +541,7 @@ func resourceNsxtPolicyNATRuleImport(d *schema.ResourceData, m interface{}) ([]* if err != nil { return nil, err } - if natType == model.PolicyNat_NAT_TYPE_USER { - // Value will be overwritten by resourceNsxtPolicyNATRuleRead() - d.Set("action", model.PolicyNatRule_ACTION_DNAT) - } else { - d.Set("action", model.PolicyNatRule_ACTION_NAT64) - } + d.Set("type", natType) return rd, nil } else if !errors.Is(err, ErrNotAPolicyPath) { return rd, err @@ -505,11 +549,8 @@ func resourceNsxtPolicyNATRuleImport(d *schema.ResourceData, m interface{}) ([]* if len(s) < 2 || len(s) > 3 { return nil, fmt.Errorf("Please provide //[nat-type] as an input") } - if len(s) == 3 { - // take care of NAT64 nat-type via action - if s[2] == model.PolicyNat_NAT_TYPE_NAT64 { - d.Set("action", model.PolicyNatRule_ACTION_NAT64) - } + if len(s) < 3 { + d.Set("type", model.PolicyNat_NAT_TYPE_USER) } gwID := s[0] diff --git a/nsxt/resource_nsxt_policy_nat_rule_test.go b/nsxt/resource_nsxt_policy_nat_rule_test.go index a2ef6e5e7..bf492529c 100644 --- a/nsxt/resource_nsxt_policy_nat_rule_test.go +++ b/nsxt/resource_nsxt_policy_nat_rule_test.go @@ -31,7 +31,7 @@ func TestAccResourceNsxtPolicyNATRule_minimalT0(t *testing.T) { { Config: testAccNsxtPolicyNATRuleTier0MinimalCreateTemplate(name, testAccResourcePolicyNATRuleSourceNet, testAccResourcePolicyNATRuleTransNet), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "source_networks.#", "1"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "translated_networks.#", "1"), @@ -48,7 +48,7 @@ func TestAccResourceNsxtPolicyNATRule_minimalT0(t *testing.T) { }) } -func TestAccResourceNsxtPolicyNATRule_basicT1(t *testing.T) { +func TestAccResourceNsxtPolicyNATRule_basic_T1(t *testing.T) { testAccResourceNsxtPolicyNATRuleBasicT1(t, false, func() { testAccPreCheck(t) }) @@ -79,7 +79,7 @@ func testAccResourceNsxtPolicyNATRuleBasicT1(t *testing.T, withContext bool, pre { Config: testAccNsxtPolicyNATRuleTier1CreateTemplate(name, action, testAccResourcePolicyNATRuleSourceNet, testAccResourcePolicyNATRuleDestNet, testAccResourcePolicyNATRuleTransNet, withContext), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -99,7 +99,7 @@ func testAccResourceNsxtPolicyNATRuleBasicT1(t *testing.T, withContext bool, pre { Config: testAccNsxtPolicyNATRuleTier1CreateTemplate(updateName, action, snet, dnet, tnet, withContext), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", updateName), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -119,7 +119,7 @@ func testAccResourceNsxtPolicyNATRuleBasicT1(t *testing.T, withContext bool, pre { Config: testAccNsxtPolicyNATRuleTier1UpdateMultipleSourceNetworksTemplate(name, action, testAccResourcePolicyNATRuleSourceNet, snet, dnet, tnet, withContext), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -139,6 +139,47 @@ func testAccResourceNsxtPolicyNATRuleBasicT1(t *testing.T, withContext bool, pre }) } +func TestAccResourceNsxtPolicyNATRuleT1_natType(t *testing.T) { + name := getAccTestResourceName() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: func(state *terraform.State) error { + return testAccNsxtPolicyNATRuleCheckDestroy(state, name, false) + }, + Steps: []resource.TestStep{ + { + Config: testAccNsxtPolicyNATRuleNatTypeTemplate(name, "DEFAULT", model.PolicyNatRule_ACTION_DNAT, "22.1.1.14", "33.1.1.14"), + Check: resource.ComposeTestCheckFunc( + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "DEFAULT"), + resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), + resource.TestCheckResourceAttrSet(testAccResourcePolicyNATRuleName, "path"), + resource.TestCheckResourceAttrSet(testAccResourcePolicyNATRuleName, "revision"), + ), + }, + { + Config: testAccNsxtPolicyNATRuleNatTypeTemplate(name, "USER", model.PolicyNatRule_ACTION_DNAT, "22.1.1.14", "33.1.1.14"), + Check: resource.ComposeTestCheckFunc( + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), + resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), + resource.TestCheckResourceAttrSet(testAccResourcePolicyNATRuleName, "path"), + resource.TestCheckResourceAttrSet(testAccResourcePolicyNATRuleName, "revision"), + ), + }, + { + Config: testAccNsxtPolicyNATRuleNatTypeTemplate(name, "NAT64", model.PolicyNatRule_ACTION_NAT64, "2201::0014", "3301:1122::1280:0014"), + Check: resource.ComposeTestCheckFunc( + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "NAT64"), + resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), + resource.TestCheckResourceAttrSet(testAccResourcePolicyNATRuleName, "path"), + resource.TestCheckResourceAttrSet(testAccResourcePolicyNATRuleName, "revision"), + ), + }, + }, + }) +} + func TestAccResourceNsxtPolicyNATRule_withPolicyBasedVpnMode(t *testing.T) { name := getAccTestResourceName() updateName := getAccTestResourceName() @@ -157,7 +198,7 @@ func TestAccResourceNsxtPolicyNATRule_withPolicyBasedVpnMode(t *testing.T) { { Config: testAccNsxtPolicyNATRuleTier1CreateTemplateWithPolicyBasedVpnMode(name, action, testAccResourcePolicyNATRuleSourceNet, testAccResourcePolicyNATRuleDestNet, testAccResourcePolicyNATRuleTransNet, model.PolicyNatRule_POLICY_BASED_VPN_MODE_BYPASS, false), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -178,7 +219,7 @@ func TestAccResourceNsxtPolicyNATRule_withPolicyBasedVpnMode(t *testing.T) { { Config: testAccNsxtPolicyNATRuleTier1CreateTemplateWithPolicyBasedVpnMode(updateName, action, snet, dnet, tnet, model.PolicyNatRule_POLICY_BASED_VPN_MODE_MATCH, false), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", updateName), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -219,7 +260,7 @@ func TestAccResourceNsxtPolicyNATRule_basicT0(t *testing.T) { { Config: testAccNsxtPolicyNATRuleTier0CreateTemplate(name, action, testAccResourcePolicyNATRuleSourceNet, testAccResourcePolicyNATRuleTransNet), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "source_networks.#", "1"), @@ -238,7 +279,7 @@ func TestAccResourceNsxtPolicyNATRule_basicT0(t *testing.T) { { Config: testAccNsxtPolicyNATRuleTier0CreateTemplate(updateName, action, snet, tnet), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", updateName), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "source_networks.#", "1"), @@ -325,7 +366,7 @@ func TestAccResourceNsxtPolicyNATRule_nat64T1(t *testing.T) { { Config: testAccNsxtPolicyNATRuleTier1CreateTemplate(name, action, snet, dnet, tnet, false), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, true), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "NAT64"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -345,7 +386,7 @@ func TestAccResourceNsxtPolicyNATRule_nat64T1(t *testing.T) { { Config: testAccNsxtPolicyNATRuleTier1CreateTemplate(updateName, action, snet, dnet, tnet1, false), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, true), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "NAT64"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", updateName), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -384,7 +425,7 @@ func TestAccResourceNsxtPolicyNATRuleNoSnatWithoutTNet(t *testing.T) { { Config: testAccNsxPolicyNatRuleNoTranslatedNetworkTemplate(name, action, testAccResourcePolicyNATRuleSourceNet, testAccResourcePolicyNATRuleDestNet), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", name), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -402,7 +443,7 @@ func TestAccResourceNsxtPolicyNATRuleNoSnatWithoutTNet(t *testing.T) { { Config: testAccNsxPolicyNatRuleNoTranslatedNetworkTemplate(updateName, action, snet, dnet), Check: resource.ComposeTestCheckFunc( - testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, false), + testAccNsxtPolicyNATRuleExists(testAccResourcePolicyNATRuleName, "USER"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "display_name", updateName), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "description", "Acceptance Test"), resource.TestCheckResourceAttr(testAccResourcePolicyNATRuleName, "destination_networks.#", "1"), @@ -438,7 +479,7 @@ func testAccNSXPolicyNATRuleImporterGetID(s *terraform.State) (string, error) { return fmt.Sprintf("%s/%s", gwID, resourceID), nil } -func testAccNsxtPolicyNATRuleExists(resourceName string, isNat bool) resource.TestCheckFunc { +func testAccNsxtPolicyNATRuleExists(resourceName string, natType string) resource.TestCheckFunc { return func(state *terraform.State) error { connector := getPolicyConnector(testAccProvider.Meta().(nsxtClients)) @@ -453,10 +494,6 @@ func testAccNsxtPolicyNATRuleExists(resourceName string, isNat bool) resource.Te } gwPath := rs.Primary.Attributes["gateway_path"] - natType := model.PolicyNat_NAT_TYPE_USER - if isNat { - natType = model.PolicyNat_NAT_TYPE_NAT64 - } isT0, gwID := parseGatewayPolicyPath(gwPath) _, err := getNsxtPolicyNATRuleByID(testAccGetSessionContext(), connector, gwID, isT0, natType, resourceID) if err != nil { @@ -503,6 +540,27 @@ resource "nsxt_policy_nat_rule" "test" { `, name, model.PolicyNatRule_ACTION_REFLEXIVE, sourceNet, translatedNet) } +func testAccNsxtPolicyNATRuleNatTypeTemplate(name string, natType string, action string, srcIP string, dstIP string) string { + return testAccNsxtPolicyEdgeClusterReadTemplate(getEdgeClusterName()) + + testAccNsxtPolicyTier1WithEdgeClusterTemplate("test", false, false) + fmt.Sprintf(` +data "nsxt_policy_service" "test" { + display_name = "DNS-UDP" +} + +resource "nsxt_policy_nat_rule" "test" { + display_name = "%s" + type = "%s" + description = "Acceptance Test" + gateway_path = nsxt_policy_tier1_gateway.test.path + action = "%s" + source_networks = ["%s"] + destination_networks = ["%s"] + translated_networks = ["44.11.11.2"] + service = data.nsxt_policy_service.test.path +} +`, name, natType, action, srcIP, dstIP) +} + func testAccNsxtPolicyNATRuleTier1CreateTemplate(name string, action string, sourceNet string, destNet string, translatedNet string, withContext bool) string { context := "" if withContext { diff --git a/website/docs/r/policy_nat_rule.html.markdown b/website/docs/r/policy_nat_rule.html.markdown index 3ca3703c7..920691898 100644 --- a/website/docs/r/policy_nat_rule.html.markdown +++ b/website/docs/r/policy_nat_rule.html.markdown @@ -72,6 +72,7 @@ The following arguments are supported: * `project_id` - (Required) The ID of the project which the object belongs to * `gateway_path` - (Required) The NSX Policy path to the Tier0 or Tier1 Gateway for this NAT Rule. * `action` - (Required) The action for the NAT Rule. One of `SNAT`, `DNAT`, `REFLEXIVE`, `NO_SNAT`, `NO_DNAT`, `NAT64`. +* `section` - (Optional) Nat type, one of `USER`, `DEFAULT`, `NAT64` and `SYSTEM`. If not provided, `USER` type will be assumed, unless action is `NAT64`, in which case type is also `NAT64`. * `destination_networks` - (Optional) A list of destination network IP addresses or CIDR. If unspecified, the value will be `ANY`. * `enabled` - (Optional) Enable/disable the Rule. Defaults to `true`. * `firewall_match` - (Optional) Firewall match flag. One of `MATCH_EXTERNAL_ADDRESS`, `MATCH_INTERNAL_ADDRESS`, `BYPASS`.