Skip to content

Commit dcb04f8

Browse files
authored
Add Principle Identity resource (#1021)
This PR adds support of Principle Identity resource. Due to limitations in API, PI in terraform is treated as immutable resource. Any changes to the definition will force a resource recreation. This change also refactos role schema. Now for both PI and role bindings, roles for a path can be defined as a list, rather than sub resources for convenience. Signed-off-by: Shawn Wang <[email protected]>
1 parent 18e6e5a commit dcb04f8

8 files changed

+520
-95
lines changed

nsxt/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ func Provider() *schema.Provider {
426426
"nsxt_manager_cluster": resourceNsxtManagerCluster(),
427427
"nsxt_policy_uplink_host_switch_profile": resourceNsxtUplinkHostSwitchProfile(),
428428
"nsxt_node_user": resourceNsxtUsers(),
429+
"nsxt_principle_identity": resourceNsxtPrincipleIdentity(),
429430
"nsxt_transport_node": resourceNsxtTransportNode(),
430431
"nsxt_failure_domain": resourceNsxtFailureDomain(),
431432
"nsxt_cluster_virtual_ip": resourceNsxtClusterVirualIP(),

nsxt/resource_nsxt_policy_role_binding.go

+46-59
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,17 @@ package nsxt
66
import (
77
"fmt"
88
"log"
9-
"regexp"
109

1110
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1211
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1312
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/aaa"
1413
nsxModel "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
1514
)
1615

17-
// Only support local user at the moment
1816
var roleBindingUserTypes = [](string){
1917
nsxModel.RoleBinding_TYPE_LOCAL_USER,
2018
nsxModel.RoleBinding_TYPE_REMOTE_USER,
2119
nsxModel.RoleBinding_TYPE_REMOTE_GROUP,
22-
nsxModel.RoleBinding_TYPE_PRINCIPAL_IDENTITY,
2320
}
2421

2522
var roleBindingIdentitySourceTypes = [](string){
@@ -71,40 +68,31 @@ func resourceNsxtPolicyUserManagementRoleBinding() *schema.Resource {
7168
Optional: true,
7269
ValidateFunc: validation.StringInSlice(roleBindingIdentitySourceTypes, false),
7370
},
74-
"roles_for_path": {
75-
Type: schema.TypeList,
76-
Description: "List of roles that are associated with the user, limiting them to a path",
77-
Required: true,
78-
Elem: &schema.Resource{
79-
Schema: map[string]*schema.Schema{
80-
"path": {
81-
Type: schema.TypeString,
82-
Description: "Path of the entity in parent hierarchy.",
83-
Required: true,
84-
},
85-
"role": {
86-
Type: schema.TypeList,
87-
Description: "Applicable roles",
88-
Required: true,
89-
Elem: &schema.Resource{
90-
Schema: map[string]*schema.Schema{
91-
"role": {
92-
Type: schema.TypeString,
93-
Description: "Short identifier for the role",
94-
Required: true,
95-
ValidateFunc: validation.StringMatch(
96-
regexp.MustCompile(
97-
`^[_a-z0-9-]+$`),
98-
"Must be a valid role identifier matching: ^[_a-z0-9-]+$"),
99-
},
100-
"role_display_name": {
101-
Type: schema.TypeString,
102-
Description: "Display name for role",
103-
Computed: true,
104-
},
105-
},
106-
},
107-
},
71+
"roles_for_path": getRolesForPathSchema(false),
72+
},
73+
}
74+
}
75+
76+
// getRolesForPathSchema return schema for RolesForPath, which is shared between role bindings and PI
77+
func getRolesForPathSchema(forceNew bool) *schema.Schema {
78+
return &schema.Schema{
79+
Type: schema.TypeList,
80+
Description: "List of roles that are associated with the user, limiting them to a path",
81+
Required: true,
82+
ForceNew: forceNew,
83+
Elem: &schema.Resource{
84+
Schema: map[string]*schema.Schema{
85+
"path": {
86+
Type: schema.TypeString,
87+
Description: "Path of the entity in parent hierarchy.",
88+
Required: true,
89+
},
90+
"roles": {
91+
Type: schema.TypeSet,
92+
Description: "Applicable roles",
93+
Required: true,
94+
Elem: &schema.Schema{
95+
Type: schema.TypeString,
10896
},
10997
},
11098
},
@@ -121,12 +109,10 @@ func getRolesForPathFromSchema(d *schema.ResourceData) rolesForPath {
121109
for _, rolesPerPathInput := range rolesForPathInput {
122110
data := rolesPerPathInput.(map[string]interface{})
123111
path := data["path"].(string)
124-
roles := data["role"].([]interface{})
112+
roles := interface2StringList(data["roles"].(*schema.Set).List())
125113
rolesPerPathMap := make(rolesPerPath)
126114
for _, role := range roles {
127-
roleData := role.(map[string]interface{})
128-
roleInput := roleData["role"].(string)
129-
rolesPerPathMap[roleInput] = true
115+
rolesPerPathMap[role] = true
130116
}
131117
rolesForPathMap[path] = rolesPerPathMap
132118
}
@@ -139,14 +125,11 @@ func setRolesForPathInSchema(d *schema.ResourceData, nsxRolesForPathList []nsxMo
139125
for _, nsxRolesForPath := range nsxRolesForPathList {
140126
elem := make(map[string]interface{})
141127
elem["path"] = nsxRolesForPath.Path
142-
var roles []map[string]interface{}
128+
roles := make([]string, 0, len(nsxRolesForPath.Roles))
143129
for _, nsxRole := range nsxRolesForPath.Roles {
144-
rElem := make(map[string]interface{})
145-
rElem["role"] = nsxRole.Role
146-
rElem["role_display_name"] = nsxRole.RoleDisplayName
147-
roles = append(roles, rElem)
130+
roles = append(roles, *nsxRole.Role)
148131
}
149-
elem["role"] = roles
132+
elem["roles"] = roles
150133
rolesForPathList = append(rolesForPathList, elem)
151134
}
152135
err := d.Set("roles_for_path", rolesForPathList)
@@ -155,15 +138,8 @@ func setRolesForPathInSchema(d *schema.ResourceData, nsxRolesForPathList []nsxMo
155138
}
156139
}
157140

158-
func getRoleBindingObject(d *schema.ResourceData) *nsxModel.RoleBinding {
141+
func getRolesForPathList(d *schema.ResourceData) []nsxModel.RolesForPath {
159142
boolTrue := true
160-
displayName := d.Get("display_name").(string)
161-
description := d.Get("description").(string)
162-
tags := getPolicyTagsFromSchema(d)
163-
name := d.Get("name").(string)
164-
identitySrcID := d.Get("identity_source_id").(string)
165-
identitySrcType := d.Get("identity_source_type").(string)
166-
roleBindingType := d.Get("type").(string)
167143
rolesPerPathMap := getRolesForPathFromSchema(d)
168144
nsxRolesForPaths := make([]nsxModel.RolesForPath, 0)
169145

@@ -193,19 +169,30 @@ func getRoleBindingObject(d *schema.ResourceData) *nsxModel.RoleBinding {
193169
continue
194170
}
195171
// Add one role in the list to make NSX happy
196-
roles := data["role"].([]interface{})
172+
roles := interface2StringList(data["roles"].(*schema.Set).List())
197173
if len(roles) == 0 {
198174
continue
199175
}
200-
roleData := roles[0].(map[string]interface{})
201-
roleID := roleData["role"].(string)
202176
nsxRolesForPaths = append(nsxRolesForPaths, nsxModel.RolesForPath{
203177
Path: &path,
204178
DeletePath: &boolTrue,
205-
Roles: []nsxModel.Role{{Role: &roleID}},
179+
Roles: []nsxModel.Role{{Role: &roles[0]}},
206180
})
207181
}
208182
}
183+
return nsxRolesForPaths
184+
}
185+
186+
func getRoleBindingObject(d *schema.ResourceData) *nsxModel.RoleBinding {
187+
boolTrue := true
188+
displayName := d.Get("display_name").(string)
189+
description := d.Get("description").(string)
190+
tags := getPolicyTagsFromSchema(d)
191+
name := d.Get("name").(string)
192+
identitySrcID := d.Get("identity_source_id").(string)
193+
identitySrcType := d.Get("identity_source_type").(string)
194+
roleBindingType := d.Get("type").(string)
195+
nsxRolesForPaths := getRolesForPathList(d)
209196

210197
obj := nsxModel.RoleBinding{
211198
DisplayName: &displayName,

nsxt/resource_nsxt_policy_role_binding_test.go

+12-23
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ func TestAccResourceNsxtPolicyRoleBinding_basic(t *testing.T) {
5050
resource.TestCheckResourceAttr(testResourceName, "identity_source_type", identType),
5151
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.#", "2"),
5252
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.path", "/"),
53-
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.role.#", "1"),
54-
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.role.0.role", "auditor"),
53+
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.roles.#", "1"),
54+
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.roles.0", "auditor"),
5555
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.1.path", "/orgs/default"),
56-
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.1.role.#", "1"),
57-
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.1.role.0.role", "org_admin"),
56+
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.1.roles.#", "1"),
57+
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.1.roles.0", "org_admin"),
5858

59-
resource.TestCheckResourceAttrSet(testResourceName, "nsx_id"),
6059
resource.TestCheckResourceAttrSet(testResourceName, "revision"),
6160
),
6261
},
@@ -71,10 +70,9 @@ func TestAccResourceNsxtPolicyRoleBinding_basic(t *testing.T) {
7170
resource.TestCheckResourceAttr(testResourceName, "identity_source_type", identType),
7271
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.#", "1"),
7372
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.path", "/"),
74-
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.role.#", "1"),
75-
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.role.0.role", "auditor"),
73+
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.roles.#", "1"),
74+
resource.TestCheckResourceAttr(testResourceName, "roles_for_path.0.roles.0", "auditor"),
7675

77-
resource.TestCheckResourceAttrSet(testResourceName, "nsx_id"),
7876
resource.TestCheckResourceAttrSet(testResourceName, "revision"),
7977
),
8078
},
@@ -172,19 +170,13 @@ resource "nsxt_policy_user_management_role_binding" "test" {
172170
identity_source_type = "%s"
173171
174172
roles_for_path {
175-
path = "/"
176-
177-
role {
178-
role = "auditor"
179-
}
173+
path = "/"
174+
roles = ["auditor"]
180175
}
181176
182177
roles_for_path {
183-
path = "/orgs/default"
184-
185-
role {
186-
role = "org_admin"
187-
}
178+
path = "/orgs/default"
179+
roles = ["org_admin"]
188180
}
189181
}`, attrMap["display_name"], attrMap["description"], user, userType, identType)
190182
}
@@ -200,11 +192,8 @@ resource "nsxt_policy_user_management_role_binding" "test" {
200192
identity_source_type = "%s"
201193
202194
roles_for_path {
203-
path = "/"
204-
205-
role {
206-
role = "auditor"
207-
}
195+
path = "/"
196+
roles = ["auditor"]
208197
}
209198
}`, attrMap["display_name"], attrMap["description"], user, userType, identType)
210199
}

0 commit comments

Comments
 (0)