From 445189d1de76337f3e76a38e430c18303134a161 Mon Sep 17 00:00:00 2001 From: Kobi Samoray Date: Tue, 21 Mar 2023 11:19:39 +0100 Subject: [PATCH] Add group_type attribue to policy group Fixes: #855 Signed-off-by: Kobi Samoray --- nsxt/resource_nsxt_policy_group.go | 30 +++++++ nsxt/resource_nsxt_policy_group_test.go | 101 ++++++++++++++++++++++ website/docs/r/policy_group.html.markdown | 1 + 3 files changed, 132 insertions(+) diff --git a/nsxt/resource_nsxt_policy_group.go b/nsxt/resource_nsxt_policy_group.go index ec635a9cf..f87607fa0 100644 --- a/nsxt/resource_nsxt_policy_group.go +++ b/nsxt/resource_nsxt_policy_group.go @@ -51,6 +51,11 @@ var externalMemberTypeValues = []string{ model.ExternalIDExpression_MEMBER_TYPE_PHYSICALSERVER, } +var groupTypeValues = []string{ + model.Group_GROUP_TYPE_IPADDRESS, + model.Group_GROUP_TYPE_ANTREA, +} + func resourceNsxtPolicyGroup() *schema.Resource { return &schema.Resource{ Create: resourceNsxtPolicyGroupCreate, @@ -69,6 +74,12 @@ func resourceNsxtPolicyGroup() *schema.Resource { "revision": getRevisionSchema(), "tag": getTagsSchema(), "domain": getDomainNameSchema(), + "group_type": { + Type: schema.TypeString, + Description: "Indicates the group type", + ValidateFunc: validation.StringInSlice(groupTypeValues, false), + Optional: true, + }, "criteria": { Type: schema.TypeList, Description: "Criteria to determine Group membership", @@ -833,6 +844,9 @@ func resourceNsxtPolicyGroupCreate(d *schema.ResourceData, m interface{}) error description := d.Get("description").(string) tags := getPolicyTagsFromSchema(d) + var groupTypes []string + groupType := d.Get("group_type").(string) + groupTypes = append(groupTypes, groupType) obj := model.Group{ DisplayName: &displayName, Description: &description, @@ -841,6 +855,10 @@ func resourceNsxtPolicyGroupCreate(d *schema.ResourceData, m interface{}) error ExtendedExpression: extendedExpressionList, } + if groupType != "" && nsxVersionHigherOrEqual("3.2.0") { + obj.GroupType = groupTypes + } + if isPolicyGlobalManager(m) { gmObj, err1 := convertModelBindingType(obj, model.GroupBindingType(), gm_model.GroupBindingType()) if err1 != nil { @@ -898,6 +916,11 @@ func resourceNsxtPolicyGroupRead(d *schema.ResourceData, m interface{}) error { d.Set("path", obj.Path) d.Set("domain", getDomainFromResourcePath(*obj.Path)) d.Set("revision", obj.Revision) + groupType := "" + if len(obj.GroupType) > 0 && nsxVersionHigherOrEqual("3.2.0") { + groupType = obj.GroupType[0] + d.Set("group_type", groupType) + } criteria, conditions, err := fromGroupExpressionData(obj.Expression) log.Printf("[INFO] Found %d criteria, %d conjunctions for group %s", len(criteria), len(conditions), id) if err != nil { @@ -958,6 +981,9 @@ func resourceNsxtPolicyGroupUpdate(d *schema.ResourceData, m interface{}) error displayName := d.Get("display_name").(string) tags := getPolicyTagsFromSchema(d) + var groupTypes []string + groupType := d.Get("group_type").(string) + groupTypes = append(groupTypes, groupType) obj := model.Group{ DisplayName: &displayName, Description: &description, @@ -966,6 +992,10 @@ func resourceNsxtPolicyGroupUpdate(d *schema.ResourceData, m interface{}) error ExtendedExpression: extendedExpressionList, } + if groupType != "" && nsxVersionHigherOrEqual("3.2.0") { + obj.GroupType = groupTypes + } + if isPolicyGlobalManager(m) { gmObj, err1 := convertModelBindingType(obj, model.GroupBindingType(), gm_model.GroupBindingType()) if err1 != nil { diff --git a/nsxt/resource_nsxt_policy_group_test.go b/nsxt/resource_nsxt_policy_group_test.go index fadfe1b06..241428721 100644 --- a/nsxt/resource_nsxt_policy_group_test.go +++ b/nsxt/resource_nsxt_policy_group_test.go @@ -83,6 +83,55 @@ func TestAccResourceNsxtPolicyGroup_AddressCriteria(t *testing.T) { }) } +func TestAccResourceNsxtPolicyGroup_GroupTypeIPAddressCriteria(t *testing.T) { + name := getAccTestResourceName() + testResourceName := "nsxt_policy_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccNSXVersion(t, "3.2.0") + }, + Providers: testAccProviders, + CheckDestroy: func(state *terraform.State) error { + return testAccNsxtPolicyGroupCheckDestroy(state, name, defaultDomain) + }, + Steps: []resource.TestStep{ + { + Config: testAccNsxtPolicyGroupIPAddressCreateTemplate(name), + Check: resource.ComposeTestCheckFunc( + testAccNsxtPolicyGroupExists(testResourceName, defaultDomain), + resource.TestCheckResourceAttr(testResourceName, "display_name", name), + resource.TestCheckResourceAttr(testResourceName, "description", "Acceptance Test"), + resource.TestCheckResourceAttr(testResourceName, "domain", defaultDomain), + resource.TestCheckResourceAttrSet(testResourceName, "path"), + resource.TestCheckResourceAttrSet(testResourceName, "revision"), + resource.TestCheckResourceAttr(testResourceName, "tag.#", "2"), + resource.TestCheckResourceAttr(testResourceName, "criteria.#", "1"), + resource.TestCheckResourceAttr(testResourceName, "criteria.0.ipaddress_expression.#", "1"), + resource.TestCheckResourceAttr(testResourceName, "criteria.0.ipaddress_expression.0.ip_addresses.#", "2"), + ), + }, + { + Config: testAccNsxtPolicyGroupIPAddressUpdateTemplate(name), + Check: resource.ComposeTestCheckFunc( + testAccNsxtPolicyGroupExists(testResourceName, defaultDomain), + resource.TestCheckResourceAttr(testResourceName, "display_name", name), + resource.TestCheckResourceAttr(testResourceName, "description", "Acceptance Test"), + resource.TestCheckResourceAttr(testResourceName, "domain", defaultDomain), + resource.TestCheckResourceAttrSet(testResourceName, "path"), + resource.TestCheckResourceAttrSet(testResourceName, "revision"), + resource.TestCheckResourceAttr(testResourceName, "conjunction.#", "1"), + resource.TestCheckResourceAttr(testResourceName, "tag.#", "0"), + resource.TestCheckResourceAttr(testResourceName, "criteria.#", "2"), + resource.TestCheckResourceAttr(testResourceName, "criteria.0.ipaddress_expression.#", "1"), + resource.TestCheckResourceAttr(testResourceName, "criteria.0.ipaddress_expression.0.ip_addresses.#", "2"), + ), + }, + }, + }) +} + func TestAccResourceNsxtGlobalPolicyGroup_singleIPAddressCriteria(t *testing.T) { name := getAccTestResourceName() updatedName := getAccTestResourceName() @@ -1348,3 +1397,55 @@ resource "nsxt_policy_group" "test" { } `, name) } + +func testAccNsxtPolicyGroupIPAddressCreateTemplate(name string) string { + return fmt.Sprintf(` +resource "nsxt_policy_group" "test" { + display_name = "%s" + description = "Acceptance Test" + group_type = "IPAddress" + + criteria { + ipaddress_expression { + ip_addresses = ["111.1.1.1", "222.2.2.2"] + } + } + + tag { + scope = "scope1" + tag = "tag1" + } + + tag { + scope = "scope2" + tag = "tag2" + } +} +`, name) +} + +func testAccNsxtPolicyGroupIPAddressUpdateTemplate(name string) string { + return fmt.Sprintf(` +resource "nsxt_policy_group" "test" { + display_name = "%s" + description = "Acceptance Test" + group_type = "IPAddress" + + criteria { + ipaddress_expression { + ip_addresses = ["111.2.1.1", "232.2.2.2"] + } + } + + conjunction { + operator = "OR" + } + + criteria { + ipaddress_expression { + ip_addresses = ["111.1.1.3", "222.2.2.4"] + } + } +} +`, name) +} diff --git a/website/docs/r/policy_group.html.markdown b/website/docs/r/policy_group.html.markdown index 60a766141..9b1a0b658 100644 --- a/website/docs/r/policy_group.html.markdown +++ b/website/docs/r/policy_group.html.markdown @@ -184,6 +184,7 @@ The following arguments are supported: * `distinguished_name` (Required for an `identity_group`) LDAP distinguished name (DN). A valid fully qualified distinguished name should be provided here. This value is valid only if it matches to exactly 1 LDAP object on the LDAP server. * `domain_base_distinguished_name` (Required for an `identity_group`) Identity (Directory) domain base distinguished name. This is the base distinguished name for the domain where this identity group resides. (e.g. dc=example,dc=com) * `sid` (Optional) Identity (Directory) Group SID (security identifier). A security identifier (SID) is a unique value of variable length used to identify a trustee. This field is only populated for Microsoft Active Directory identity store. +* `group_type` - (Optional) Group type can be specified during create and update of a group. Empty group type indicates a 'generic' group, ie group can be one of IPAddress, ANTREA. Attribute is supported with NSX version 3.2.0 and above. ## Attributes Reference