Skip to content

Commit

Permalink
Merge pull request nutanix#219 from yannickstruyf3/feat/data_source_p…
Browse files Browse the repository at this point in the history
…ermission

added permissions for roles
  • Loading branch information
marinsalinas authored Dec 11, 2020
2 parents d21fbcd + dfeb35e commit 3b5284c
Show file tree
Hide file tree
Showing 7 changed files with 718 additions and 0 deletions.
83 changes: 83 additions & 0 deletions client/v3/v3_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ type Service interface {
GetUserGroup(userUUID string) (*UserGroupIntentResponse, error)
ListUserGroup(getEntitiesRequest *DSMetadata) (*UserGroupListResponse, error)
ListAllUserGroup(filter string) (*UserGroupListResponse, error)
GetPermission(permissionUUID string) (*PermissionIntentResponse, error)
ListPermission(getEntitiesRequest *DSMetadata) (*PermissionListResponse, error)
ListAllPermission(filter string) (*PermissionListResponse, error)
}

/*CreateVM Creates a VM
Expand Down Expand Up @@ -1827,3 +1830,83 @@ func (op Operations) ListAllUserGroup(filter string) (*UserGroupListResponse, er

return resp, nil
}

/*GePermission This operation gets a Permission.
*
* @param uuid The permission uuid - string.
* @return *PermissionIntentResponse
*/
func (op Operations) GetPermission(permissionUUID string) (*PermissionIntentResponse, error) {
ctx := context.TODO()

path := fmt.Sprintf("/permissions/%s", permissionUUID)
permission := new(PermissionIntentResponse)

req, err := op.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, err
}

return permission, op.client.Do(ctx, req, permission)
}

/*ListPermission gets a list of Permissions.
*
* @param metadata allows create filters to get specific data - *DSMetadata.
* @return *PermissionListResponse
*/
func (op Operations) ListPermission(getEntitiesRequest *DSMetadata) (*PermissionListResponse, error) {
ctx := context.TODO()
path := "/permissions/list"

PermissionList := new(PermissionListResponse)

req, err := op.client.NewRequest(ctx, http.MethodPost, path, getEntitiesRequest)
if err != nil {
return nil, err
}

return PermissionList, op.client.Do(ctx, req, PermissionList)
}

// ListAllPermission ...
func (op Operations) ListAllPermission(filter string) (*PermissionListResponse, error) {
entities := make([]*PermissionIntentResponse, 0)

resp, err := op.ListPermission(&DSMetadata{
Filter: &filter,
Kind: utils.StringPtr("permission"),
Length: utils.Int64Ptr(itemsPerPage),
})

if err != nil {
return nil, err
}

totalEntities := utils.Int64Value(resp.Metadata.TotalMatches)
remaining := totalEntities
offset := utils.Int64Value(resp.Metadata.Offset)

if totalEntities > itemsPerPage {
for hasNext(&remaining) {
resp, err = op.ListPermission(&DSMetadata{
Filter: &filter,
Kind: utils.StringPtr("permission"),
Length: utils.Int64Ptr(itemsPerPage),
Offset: utils.Int64Ptr(offset),
})

if err != nil {
return nil, err
}

entities = append(entities, resp.Entities...)

offset += itemsPerPage
}

resp.Entities = entities
}

return resp, nil
}
43 changes: 43 additions & 0 deletions client/v3/v3_structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2245,3 +2245,46 @@ type UserGroupListResponse struct {
Entities []*UserGroupIntentResponse `json:"entities,omitempty"`
Metadata *ListMetadataOutput `json:"metadata,omitempty"` // All api calls that return a list will have this metadata block
}

// Response object for intentful operations on a user_group
type PermissionIntentResponse struct {
APIVersion *string `json:"api_version,omitempty"` // API Version of the Nutanix v3 API framework.
Metadata *Metadata `json:"metadata,omitempty"` // The user_group kind metadata
Spec *PermissionSpec `json:"spec,omitempty"` // Permission Input Definition.
Status *PermissionStatus `json:"status,omitempty"` // User group status definition.
}

// Permission Input Definition.
type PermissionSpec struct {
Name *string `json:"name,omitempty"` // The name for the permission.
Description *string `json:"description,omitempty"` // The display name for the permission.
Resources *PermissionResources `json:"resources,omitempty"` // Permission Resource Definition
}

// Permission Resource Definition
type PermissionResources struct {
Operation *string `json:"operation,omitempty"`
Kind *string `json:"kind,omitempty"`
Fields *FieldsPermission `json:"fields,omitempty"`
}

type FieldsPermission struct {
FieldMode *string `json:"field_mode,omitempty"`
FieldNameList []*string `json:"field_name_list,omitempty"`
}

// Permission status definition.
type PermissionStatus struct {
Name *string `json:"name,omitempty"` // The name for the permission.
Description *string `json:"description,omitempty"` // The display name for the permission.
Resources *PermissionResources `json:"resources,omitempty"` // Permission Resource Definition
MessageList []MessageResource `json:"message_list,omitempty"`
State *string `json:"state,omitempty"` // The state of the entity.
}

// Response object for intentful operation of Permissions
type PermissionListResponse struct {
APIVersion *string `json:"api_version,omitempty"` // API Version of the Nutanix v3 API framework.
Entities []*PermissionIntentResponse `json:"entities,omitempty"`
Metadata *ListMetadataOutput `json:"metadata,omitempty"` // All api calls that return a list will have this metadata block
}
256 changes: 256 additions & 0 deletions nutanix/data_source_nutanix_permission.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
package nutanix

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
v3 "github.com/terraform-providers/terraform-provider-nutanix/client/v3"
"github.com/terraform-providers/terraform-provider-nutanix/utils"
)

func dataSourceNutanixPermission() *schema.Resource {
return &schema.Resource{
Read: dataSourceNutanixPermissionRead,
Schema: map[string]*schema.Schema{
"permission_id": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"permission_name"},
},
"permission_name": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"permission_id"},
},
"api_version": {
Type: schema.TypeString,
Computed: true,
},
"metadata": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"last_update_time": {
Type: schema.TypeString,
Computed: true,
},
"kind": {
Type: schema.TypeString,
Computed: true,
},
"uuid": {
Type: schema.TypeString,
Computed: true,
},
"creation_time": {
Type: schema.TypeString,
Computed: true,
},
"spec_version": {
Type: schema.TypeString,
Computed: true,
},
"spec_hash": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"categories": categoriesSchema(),
"owner_reference": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"kind": {
Type: schema.TypeString,
Computed: true,
},
"uuid": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"project_reference": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"kind": {
Type: schema.TypeString,
Computed: true,
},
"uuid": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"state": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"operation": {
Type: schema.TypeString,
Computed: true,
},
"kind": {
Type: schema.TypeString,
Computed: true,
},
"fields": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"field_mode": {
Type: schema.TypeString,
Computed: true,
},
"field_name_list": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
}
}

func dataSourceNutanixPermissionRead(d *schema.ResourceData, meta interface{}) error {
// Get client connection
conn := meta.(*Client).API

permissionID, iok := d.GetOk("permission_id")
permissionName, rnOk := d.GetOk("permission_name")

if !iok && !rnOk {
return fmt.Errorf("please provide `permission_id` or `permission_name`")
}

var err error
var resp *v3.PermissionIntentResponse

if iok {
resp, err = conn.V3.GetPermission(permissionID.(string))
}
if rnOk {
resp, err = findPermissionByName(conn, permissionName.(string))
}
utils.PrintToJSON(resp, "Permission: ")
if err != nil {
return err
}

m, c := setRSEntityMetadata(resp.Metadata)

if err := d.Set("metadata", m); err != nil {
return err
}
if err := d.Set("categories", c); err != nil {
return err
}
if err := d.Set("project_reference", flattenReferenceValues(resp.Metadata.ProjectReference)); err != nil {
return err
}
if err := d.Set("owner_reference", flattenReferenceValues(resp.Metadata.OwnerReference)); err != nil {
return err
}
if err := d.Set("api_version", resp.APIVersion); err != nil {
return err
}

if status := resp.Status; status != nil {
if err := d.Set("name", utils.StringValue(resp.Status.Name)); err != nil {
return err
}
if err := d.Set("description", utils.StringValue(resp.Status.Description)); err != nil {
return err
}
if err := d.Set("state", utils.StringValue(resp.Status.State)); err != nil {
return err
}

if res := status.Resources; res != nil {
if err := d.Set("operation", utils.StringValue(res.Operation)); err != nil {
return err
}
if err := d.Set("kind", utils.StringValue(res.Kind)); err != nil {
return err
}
if err := d.Set("fields", flattenFieldsPermission(res.Fields)); err != nil {
return err
}
}
}
d.SetId(utils.StringValue(resp.Metadata.UUID))

return nil
}

func flattenFieldsPermission(fieldPermissions *v3.FieldsPermission) []map[string]interface{} {
flatFieldsPermissions := make([]map[string]interface{}, 0)
n := map[string]interface{}{
"field_mode": fieldPermissions.FieldMode,
"field_name_list": fieldPermissions.FieldNameList,
}
flatFieldsPermissions = append(flatFieldsPermissions, n)
return flatFieldsPermissions
}

func findPermissionByName(conn *v3.Client, name string) (*v3.PermissionIntentResponse, error) {
filter := fmt.Sprintf("name==%s", name)
resp, err := conn.V3.ListAllPermission(filter)
if err != nil {
return nil, err
}

entities := resp.Entities

found := make([]*v3.PermissionIntentResponse, 0)
for _, v := range entities {
if *v.Spec.Name == name {
found = append(found, v)
}
}

if len(found) > 1 {
return nil, fmt.Errorf("your query returned more than one result. Please use permission_id argument instead")
}

if len(found) == 0 {
return nil, fmt.Errorf("permission with the given name, not found")
}
found[0].APIVersion = resp.APIVersion
return found[0], nil
}
Loading

0 comments on commit 3b5284c

Please sign in to comment.