Skip to content

Commit

Permalink
Add custom attribute support to context profile
Browse files Browse the repository at this point in the history
Allow usage of custom attributes in context profile objects.

Fixes: #698, #839

Signed-off-by: Kobi Samoray <[email protected]>
  • Loading branch information
ksamoray committed Feb 26, 2023
1 parent 6eba95d commit 687b172
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 30 deletions.
60 changes: 45 additions & 15 deletions nsxt/resource_nsxt_policy_context_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@ import (
"github.com/vmware/vsphere-automation-sdk-go/runtime/protocol/client"
gm_infra "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-gm/global_infra"
gm_cont_prof "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-gm/global_infra/context_profiles"
gm_custom_attr "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-gm/global_infra/context_profiles/custom_attributes"
gm_model "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-gm/model"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra"
cont_prof "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra/context_profiles"
custom_attr "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra/context_profiles/custom_attributes"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
)

var attributeKeyMap = map[string]string{
"app_id": model.PolicyAttributes_KEY_APP_ID,
"custom_url": model.PolicyAttributes_KEY_CUSTOM_URL,
"domain_name": model.PolicyAttributes_KEY_DOMAIN_NAME,
"url_category": model.PolicyAttributes_KEY_URL_CATEGORY,
}

var attributeReverseKeyMap = map[string]string{
model.PolicyAttributes_KEY_APP_ID: "app_id",
model.PolicyAttributes_KEY_CUSTOM_URL: "custom_url",
model.PolicyAttributes_KEY_DOMAIN_NAME: "domain_name",
model.PolicyAttributes_KEY_URL_CATEGORY: "url_category",
}
Expand Down Expand Up @@ -59,6 +63,7 @@ func resourceNsxtPolicyContextProfile() *schema.Resource {
"revision": getRevisionSchema(),
"tag": getTagsSchema(),
"app_id": getContextProfilePolicyAppIDAttributesSchema(),
"custom_url": getContextProfilePolicyOtherAttributesSchema(),
"domain_name": getContextProfilePolicyOtherAttributesSchema(),
"url_category": getContextProfilePolicyOtherAttributesSchema(),
},
Expand Down Expand Up @@ -346,15 +351,7 @@ func checkAttributesValid(attributes []interface{}, m interface{}, key string) e
return err
}
}
var attrClient interface{}
connector := getPolicyConnector(m)
isPolicyGlobalManager := isPolicyGlobalManager(m)
if isPolicyGlobalManager {
attrClient = gm_cont_prof.NewAttributesClient(connector)
} else {
attrClient = cont_prof.NewAttributesClient(connector)
}
attributeValues, err := listAttributesWithKey(attributeKeyMap[key], attrClient, isPolicyGlobalManager)
attributeValues, err := listAttributesWithKey(attributeKeyMap[key], m)
if err != nil {
return err
}
Expand Down Expand Up @@ -382,10 +379,19 @@ func validateSubAttributes(attributes []interface{}) error {
return nil
}

func listAttributesWithKey(attributeKey string, attributeClient interface{}, isPolicyGlobalManager bool) ([]string, error) {
func listAttributesWithKey(attributeKey string, m interface{}) ([]string, error) {
// returns a list of attribute values
policyAttributes := make([]string, 0)
policyContextProfileListResult, err := listContextProfileWithKey(&attributeKey, attributeClient, isPolicyGlobalManager)
policyContextProfileListResult, err := listSystemAttributesWithKey(&attributeKey, m)
if err != nil {
return policyAttributes, err
}
for _, policyContextProfile := range policyContextProfileListResult.Results {
for _, attribute := range policyContextProfile.Attributes {
policyAttributes = append(policyAttributes, attribute.Value...)
}
}
policyContextProfileListResult, err = listCustomAttributesWithKey(&attributeKey, m)
if err != nil {
return policyAttributes, err
}
Expand All @@ -397,11 +403,35 @@ func listAttributesWithKey(attributeKey string, attributeClient interface{}, isP
return policyAttributes, nil
}

func listContextProfileWithKey(attributeKey *string, attributeClient interface{}, isPolicyGlobalManager bool) (model.PolicyContextProfileListResult, error) {
func listSystemAttributesWithKey(attributeKey *string, m interface{}) (model.PolicyContextProfileListResult, error) {
var policyContextProfileListResult model.PolicyContextProfileListResult
includeMarkForDeleteObjectsParam := false
if isPolicyGlobalManager {
client := attributeClient.(gm_cont_prof.AttributesClient)
connector := getPolicyConnector(m)
if isPolicyGlobalManager(m) {
client := gm_cont_prof.NewAttributesClient(connector)
gmPolicyContextProfileListResult, err := client.List(attributeKey, nil, nil, &includeMarkForDeleteObjectsParam, nil, nil, nil, nil)
if err != nil {
return policyContextProfileListResult, err
}
lmPolicyContextProfileListResult, err := convertModelBindingType(gmPolicyContextProfileListResult, gm_model.PolicyContextProfileListResultBindingType(), model.PolicyContextProfileListResultBindingType())
if err != nil {
return policyContextProfileListResult, err
}
policyContextProfileListResult = lmPolicyContextProfileListResult.(model.PolicyContextProfileListResult)
return policyContextProfileListResult, err
}
var err error
client := cont_prof.NewAttributesClient(connector)
policyContextProfileListResult, err = client.List(attributeKey, nil, nil, &includeMarkForDeleteObjectsParam, nil, nil, nil, nil)
return policyContextProfileListResult, err
}

func listCustomAttributesWithKey(attributeKey *string, m interface{}) (model.PolicyContextProfileListResult, error) {
var policyContextProfileListResult model.PolicyContextProfileListResult
includeMarkForDeleteObjectsParam := false
connector := getPolicyConnector(m)
if isPolicyGlobalManager(m) {
client := gm_custom_attr.NewDefaultClient(connector)
gmPolicyContextProfileListResult, err := client.List(attributeKey, nil, nil, &includeMarkForDeleteObjectsParam, nil, nil, nil, nil)
if err != nil {
return policyContextProfileListResult, err
Expand All @@ -414,7 +444,7 @@ func listContextProfileWithKey(attributeKey *string, attributeClient interface{}
return policyContextProfileListResult, err
}
var err error
client := attributeClient.(cont_prof.AttributesClient)
client := custom_attr.NewDefaultClient(connector)
policyContextProfileListResult, err = client.List(attributeKey, nil, nil, &includeMarkForDeleteObjectsParam, nil, nil, nil, nil)
return policyContextProfileListResult, err
}
Expand Down
68 changes: 55 additions & 13 deletions nsxt/resource_nsxt_policy_context_profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ import (
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra"
)

const (
testSystemDomainName = "*-myfiles.sharepoint.com"
)

func TestAccResourceNsxtPolicyContextProfile_basic(t *testing.T) {
name := getAccTestResourceName()
updatedName := getAccTestResourceName()
testResourceName := "nsxt_policy_context_profile.test"
attributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate()
attributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(testSystemDomainName)
updatedAttributes := testAccNsxtPolicyContextProfileAttributeURLCategoryTemplate()

resource.Test(t, resource.TestCase{
Expand All @@ -41,7 +45,7 @@ func TestAccResourceNsxtPolicyContextProfile_basic(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "domain_name.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "url_category.#", "0"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", "*-myfiles.sharepoint.com"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", testSystemDomainName),
),
},
{
Expand All @@ -65,10 +69,43 @@ func TestAccResourceNsxtPolicyContextProfile_basic(t *testing.T) {
})
}

func TestAccResourceNsxtPolicyContextProfile_CustomDomain(t *testing.T) {
name := getAccTestResourceName()
testResourceName := "nsxt_policy_context_profile.test"
attributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(accTestPolicyContextProfileCustomAttributeAttributes["attribute"])
depends_on := testAccNsxtPolicyContextProfileDependsOnTemplate("nsxt_policy_context_profile_custom_attribute.test")
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccNSXVersion(t, "3.0.0") },
Providers: testAccProviders,
CheckDestroy: func(state *terraform.State) error {
return testAccNsxtPolicyContextProfileCheckDestroy(state, testResourceName)
},
Steps: []resource.TestStep{
{
Config: testAccNsxtPolicyContextProfileCustomAttributeTemplate() + testAccNsxtPolicyContextProfileTemplate(name, attributes+depends_on),
Check: resource.ComposeTestCheckFunc(
testAccNsxtPolicyContextProfileExists(testResourceName),
resource.TestCheckResourceAttr(testResourceName, "display_name", name),
resource.TestCheckResourceAttr(testResourceName, "description", "Acceptance Test"),
resource.TestCheckResourceAttrSet(testResourceName, "nsx_id"),
resource.TestCheckResourceAttrSet(testResourceName, "path"),
resource.TestCheckResourceAttrSet(testResourceName, "revision"),
resource.TestCheckResourceAttr(testResourceName, "tag.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "app_id.#", "0"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "url_category.#", "0"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", accTestPolicyContextProfileCustomAttributeAttributes["attribute"]),
),
},
},
})
}

func TestAccResourceNsxtPolicyContextProfile_importBasic(t *testing.T) {
name := getAccTestResourceName()
testResourceName := "nsxt_policy_context_profile.test"
attributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate()
attributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(testSystemDomainName)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccNSXVersion(t, "3.0.0") },
Expand All @@ -93,8 +130,8 @@ func TestAccResourceNsxtPolicyContextProfile_multipleAttributes(t *testing.T) {
name := getAccTestResourceName()
updatedName := getAccTestResourceName()
testResourceName := "nsxt_policy_context_profile.test"
attributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate()
updatedAttributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate() + testAccNsxtPolicyContextProfileAttributeAppIDTemplate()
attributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(testSystemDomainName)
updatedAttributes := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(testSystemDomainName) + testAccNsxtPolicyContextProfileAttributeAppIDTemplate()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccNSXVersion(t, "3.0.0") },
Expand All @@ -117,7 +154,7 @@ func TestAccResourceNsxtPolicyContextProfile_multipleAttributes(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "domain_name.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "url_category.#", "0"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", "*-myfiles.sharepoint.com"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", testSystemDomainName),
),
},
{
Expand All @@ -139,7 +176,7 @@ func TestAccResourceNsxtPolicyContextProfile_multipleAttributes(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "app_id.0.value.1", "SSH"),
resource.TestCheckResourceAttr(testResourceName, "app_id.0.value.2", "SSL"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", "*-myfiles.sharepoint.com"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", testSystemDomainName),
),
},
},
Expand All @@ -153,7 +190,7 @@ func TestAccResourceNsxtPolicyContextProfile_subAttributes(t *testing.T) {
attributes := testAccNsxtPolicyContextProfileAttributeAppIDSubAttributesTemplate()
updatedAttributes := testAccNsxtPolicyContextProfileAttributeAppIDSubAttributesUpdatedTemplate()
attributesNoSub := testAccNsxtPolicyContextProfileAttributeAppIDSslTemplate()
attributesDomainName := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate()
attributesDomainName := testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(testSystemDomainName)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccNSXVersion(t, "3.0.0") },
Expand Down Expand Up @@ -244,7 +281,7 @@ func TestAccResourceNsxtPolicyContextProfile_subAttributes(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "domain_name.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "url_category.#", "0"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", "*-myfiles.sharepoint.com"),
resource.TestCheckResourceAttr(testResourceName, "domain_name.0.value.0", testSystemDomainName),
),
},
},
Expand Down Expand Up @@ -314,11 +351,11 @@ resource "nsxt_policy_context_profile" "test" {
}`, name, attributes)
}

func testAccNsxtPolicyContextProfileAttributeDomainNameTemplate() string {
return `
func testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(domain string) string {
return fmt.Sprintf(`
domain_name {
value = ["*-myfiles.sharepoint.com"]
}`
value = ["%s"]
}`, domain)
}

func testAccNsxtPolicyContextProfileAttributeAppIDTemplate() string {
Expand Down Expand Up @@ -361,3 +398,8 @@ app_id {
value = ["SSL"]
}`
}

func testAccNsxtPolicyContextProfileDependsOnTemplate(dependency string) string {
return fmt.Sprintf(`
depends_on = [%s]`, dependency)
}
2 changes: 1 addition & 1 deletion nsxt/resource_nsxt_policy_security_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,5 +839,5 @@ func testAccNsxtPolicySecurityPolicyWithProfiles(name string, direction string,
profiles := `
profiles = [nsxt_policy_context_profile.test.path]
`
return testAccNsxtPolicyContextProfileTemplate("security-policy-test-profile", testAccNsxtPolicyContextProfileAttributeDomainNameTemplate()) + testAccNsxtPolicySecurityPolicyWithRule(name, direction, protocol, ruleTag, domainName, profiles)
return testAccNsxtPolicyContextProfileTemplate("security-policy-test-profile", testAccNsxtPolicyContextProfileAttributeDomainNameTemplate(testSystemDomainName)) + testAccNsxtPolicySecurityPolicyWithRule(name, direction, protocol, ruleTag, domainName, profiles)
}
24 changes: 23 additions & 1 deletion website/docs/r/policy_context_profile.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,29 @@ resource "nsxt_policy_context_profile" "test" {
```

With a custom attribute:

```hcl
resource "nsxt_policy_context_profile_custom_attribute" "test1" {
key = "CUSTOM_URL"
attribute = "test.some.org"
}
resource "nsxt_policy_context_profile" "test2" {
display_name = "test2"
description = "Terraform provisioned ContextProfile"
custom_url {
value = ["test.some.org"]
}
depends_on = ["nsxt_policy_context_profile_custom_attribute.test1"]
}
```

## Argument Reference

The following arguments are supported:
Note: At least one of `app_id`, `domain_name`, or `url_category` must present.
Note: At least one of `app_id`, `custom_url`, domain_name`, or `url_category` must present.

* `display_name` - (Required) Display name of the resource.
* `description` - (Optional) Description of the resource.
Expand All @@ -47,6 +66,9 @@ Note: At least one of `app_id`, `domain_name`, or `url_category` must present.
* `tls_cipher_suite` - (Optional) A list of string indicating values for `tls_cipher_suite`, only applicable to `SSL`.
* `tls_version` - (Optional) A list of string indicating values for `tls_version`, only applicable to `SSL`.
* `cifs_smb_version` - (Optional) A list of string indicating values for `cifs_smb_version`, only applicable to `CIFS`.
* `custom_url` - (Optional) A block to specify custom URL attributes for the context profile. Only one block is allowed.
* `description` - (Optional) Description of the attribute.
* `value` - (Required) A list of string indicating values for the `custom_url`. Must be a subset of valid values for `custom_url` on NSX.
* `domain_name` - (Optional) A block to specify domain name (FQDN) attributes for the context profile. Only one block is allowed.
* `description` - (Optional) Description of the attribute.
* `value` - (Required) A list of string indicating values for the `domain_name`. Must be a subset of valid values for `domain_name` on NSX.
Expand Down

0 comments on commit 687b172

Please sign in to comment.