diff --git a/nsxt/provider.go b/nsxt/provider.go index 66e28d00d..89a2815fc 100644 --- a/nsxt/provider.go +++ b/nsxt/provider.go @@ -1231,9 +1231,35 @@ func getContextDataFromSchema(d *schema.ResourceData) (string, string) { return "", "" } +func getContextDataFromParentPath(parentPath string) (string, string) { + segments := strings.Split(parentPath, "/") + var projectID, vpcID string + if len(segments) > 4 && segments[1] == "orgs" && segments[3] == "projects" { + projectID = segments[4] + + if len(segments) > 6 && segments[5] == "vpcs" { + vpcID = segments[6] + } + } + return projectID, vpcID +} + func getSessionContext(d *schema.ResourceData, m interface{}) tf_api.SessionContext { + return getSessionContextHelper(d, m, "") +} + +func getParentContext(d *schema.ResourceData, m interface{}, parentPath string) tf_api.SessionContext { + return getSessionContextHelper(d, m, parentPath) +} + +func getSessionContextHelper(d *schema.ResourceData, m interface{}, parentPath string) tf_api.SessionContext { var clientType tf_api.ClientType - projectID, vpcID := getContextDataFromSchema(d) + var projectID, vpcID string + if parentPath == "" { + projectID, vpcID = getContextDataFromSchema(d) + } else { + projectID, vpcID = getContextDataFromParentPath(parentPath) + } if projectID != "" { clientType = tf_api.Multitenancy if vpcID != "" { diff --git a/nsxt/resource_nsxt_policy_security_policy_rule.go b/nsxt/resource_nsxt_policy_security_policy_rule.go index 5fb03b322..083bf55b7 100644 --- a/nsxt/resource_nsxt_policy_security_policy_rule.go +++ b/nsxt/resource_nsxt_policy_security_policy_rule.go @@ -25,7 +25,7 @@ func resourceNsxtPolicySecurityPolicyRule() *schema.Resource { Importer: &schema.ResourceImporter{ State: nsxtSecurityPolicyRuleImporter, }, - Schema: getSecurityPolicyAndGatewayRuleSchema(false, false, true, true), + Schema: getSecurityPolicyAndGatewayRuleSchema(false, false, false, true), } } @@ -38,7 +38,7 @@ func resourceNsxtPolicySecurityPolicyRuleCreate(d *schema.ResourceData, m interf policyID := getPolicyIDFromPath(policyPath) // Initialize resource Id and verify this ID is not yet used - id, err := getOrGenerateID2(d, m, resourceNsxtPolicySecurityPolicyRuleExistsPartial(policyPath)) + id, err := getOrGenerateID2(d, m, resourceNsxtPolicySecurityPolicyRuleExistsPartial(d, m, policyPath)) if err != nil { return err } @@ -124,9 +124,12 @@ func securityPolicyRuleSchemaToModel(d *schema.ResourceData, id string) model.Ru } } -func resourceNsxtPolicySecurityPolicyRuleExistsPartial(policyPath string) func(sessionContext utl.SessionContext, id string, connector client.Connector) (bool, error) { +func resourceNsxtPolicySecurityPolicyRuleExistsPartial(d *schema.ResourceData, m interface{}, policyPath string) func(sessionContext utl.SessionContext, id string, connector client.Connector) (bool, error) { + // we need to take context from the parent rather than from resource context clause, + // which does not exist for policy rule resource + parentContext := getParentContext(d, m, policyPath) return func(sessionContext utl.SessionContext, id string, connector client.Connector) (bool, error) { - return resourceNsxtPolicySecurityPolicyRuleExists(sessionContext, id, policyPath, connector) + return resourceNsxtPolicySecurityPolicyRuleExists(parentContext, id, policyPath, connector) } } diff --git a/nsxt/resource_nsxt_policy_security_policy_rule_test.go b/nsxt/resource_nsxt_policy_security_policy_rule_test.go index 34bfb3ff1..77f4b5d4a 100644 --- a/nsxt/resource_nsxt_policy_security_policy_rule_test.go +++ b/nsxt/resource_nsxt_policy_security_policy_rule_test.go @@ -58,7 +58,7 @@ func testAccResourceNsxtPolicySecurityPolicyRuleBasic(t *testing.T, withContext Steps: []resource.TestStep{ { Config: testAccNsxtPolicySecurityPolicyRuleDeps(withContext, policyName, locked) + - testAccNsxtPolicySecurityPolicyRuleTemplate("test", name, action, direction, proto, seqNum), + testAccNsxtPolicySecurityPolicyRuleTemplate("test", name, action, direction, proto, seqNum, false), Check: resource.ComposeTestCheckFunc( testAccNsxtPolicySecurityPolicyExists(policyResourceName, defaultDomain), resource.TestCheckResourceAttr(policyResourceName, "display_name", policyName), @@ -75,7 +75,7 @@ func testAccResourceNsxtPolicySecurityPolicyRuleBasic(t *testing.T, withContext { // Update Policy and Rule at the same time Config: testAccNsxtPolicySecurityPolicyRuleDeps(withContext, updatedPolicyName, updatedLocked) + - testAccNsxtPolicySecurityPolicyRuleTemplate("test", updatedName, updatedAction, updatedDirection, updatedProto, updatedSeqNum), + testAccNsxtPolicySecurityPolicyRuleTemplate("test", updatedName, updatedAction, updatedDirection, updatedProto, updatedSeqNum, false), Check: resource.ComposeTestCheckFunc( testAccNsxtPolicySecurityPolicyExists(policyResourceName, defaultDomain), resource.TestCheckResourceAttr(policyResourceName, "display_name", updatedPolicyName), @@ -92,8 +92,8 @@ func testAccResourceNsxtPolicySecurityPolicyRuleBasic(t *testing.T, withContext { // Update Policy and append another Rule at the same time Config: testAccNsxtPolicySecurityPolicyRuleDeps(withContext, policyName, locked) + - testAccNsxtPolicySecurityPolicyRuleTemplate("test", updatedName, updatedAction, updatedDirection, updatedProto, updatedSeqNum) + - testAccNsxtPolicySecurityPolicyRuleTemplate("test2", appendRuleName, action, direction, proto, seqNum), + testAccNsxtPolicySecurityPolicyRuleTemplate("test", updatedName, updatedAction, updatedDirection, updatedProto, updatedSeqNum, false) + + testAccNsxtPolicySecurityPolicyRuleTemplate("test2", appendRuleName, action, direction, proto, seqNum, true), Check: resource.ComposeTestCheckFunc( testAccNsxtPolicySecurityPolicyExists(policyResourceName, defaultDomain), resource.TestCheckResourceAttr(policyResourceName, "display_name", policyName), @@ -117,7 +117,7 @@ func testAccResourceNsxtPolicySecurityPolicyRuleBasic(t *testing.T, withContext { // Update Policy and delete one of its Rule at the same time Config: testAccNsxtPolicySecurityPolicyRuleDeps(withContext, updatedPolicyName, updatedLocked) + - testAccNsxtPolicySecurityPolicyRuleTemplate("test", updatedName, updatedAction, updatedDirection, updatedProto, updatedSeqNum), + testAccNsxtPolicySecurityPolicyRuleTemplate("test", updatedName, updatedAction, updatedDirection, updatedProto, updatedSeqNum, false), Check: resource.ComposeTestCheckFunc( testAccNsxtPolicySecurityPolicyExists(policyResourceName, defaultDomain), resource.TestCheckResourceAttr(policyResourceName, "display_name", updatedPolicyName), @@ -152,7 +152,7 @@ func TestAccResourceNsxtPolicySecurityPolicyRule_importBasic(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccNsxtPolicySecurityPolicyRuleDeps(false, "policyName", "true") + - testAccNsxtPolicySecurityPolicyRuleTemplate("test", name, "ALLOW", "IN", "IPV4", "1"), + testAccNsxtPolicySecurityPolicyRuleTemplate("test", name, "ALLOW", "IN", "IPV4", "1", false), }, { ResourceName: testResourceName, @@ -180,7 +180,7 @@ func TestAccResourceNsxtPolicySecurityPolicyRule_importBasic_multitenancy(t *tes Steps: []resource.TestStep{ { Config: testAccNsxtPolicySecurityPolicyRuleDeps(true, "policyName", "true") + - testAccNsxtPolicySecurityPolicyRuleTemplate("test", name, "ALLOW", "IN", "IPV4", "1"), + testAccNsxtPolicySecurityPolicyRuleTemplate("test", name, "ALLOW", "IN", "IPV4", "1", false), }, { ResourceName: testResourceName, @@ -267,9 +267,14 @@ resource "nsxt_policy_parent_security_policy" "policy1" { }`, context, displayName, locked) } -func testAccNsxtPolicySecurityPolicyRuleTemplate(resourceName, displayName, action, direction, ipVersion, seqNum string) string { +func testAccNsxtPolicySecurityPolicyRuleTemplate(resourceName, displayName, action, direction, ipVersion, seqNum string, withID bool) string { + idString := "" + if withID { + idString = fmt.Sprintf(`nsx_id = "%s"`, displayName) + } return fmt.Sprintf(` resource "nsxt_policy_security_policy_rule" "%s" { +%s display_name = "%s" policy_path = nsxt_policy_parent_security_policy.policy1.path action = "%s" @@ -281,5 +286,5 @@ resource "nsxt_policy_security_policy_rule" "%s" { scope = "color" tag = "orange" } -}`, resourceName, displayName, action, direction, ipVersion, seqNum) +}`, resourceName, idString, displayName, action, direction, ipVersion, seqNum) }