Skip to content

Commit

Permalink
Add multiple group/user policies support (#492)
Browse files Browse the repository at this point in the history
Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
  • Loading branch information
Adphi committed Jul 27, 2023
1 parent 2cac16c commit 6cdd43c
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 26 deletions.
47 changes: 37 additions & 10 deletions minio/resource_minio_iam_group_policy_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/minio/madmin-go"
)

func resourceMinioIAMGroupPolicyAttachment() *schema.Resource {
Expand Down Expand Up @@ -43,10 +44,17 @@ func minioCreateGroupPolicyAttachment(ctx context.Context, d *schema.ResourceDat
var groupName = d.Get("group_name").(string)
var policyName = d.Get("policy_name").(string)

log.Printf("[DEBUG] Attaching policy %s to group: %s", policyName, groupName)
err := minioAdmin.SetPolicy(ctx, policyName, groupName, true)
policies, err := minioReadGroupPolicies(ctx, minioAdmin, groupName)
if err != nil {
return NewResourceError("unable to attach group policy", groupName+" "+policyName, err)
return err
}
if !Contains(policies, policyName) {
log.Printf("[DEBUG] Attaching policy %s to group: %s", policyName, groupName)
policies = append(policies, policyName)
err := minioAdmin.SetPolicy(ctx, strings.Join(policies, ","), groupName, true)
if err != nil {
return NewResourceError("unable to attach group policy", groupName+" "+policyName, err)
}
}

d.SetId(id.PrefixedUniqueId(fmt.Sprintf("%s-", groupName)))
Expand All @@ -58,19 +66,19 @@ func minioReadGroupPolicyAttachment(ctx context.Context, d *schema.ResourceData,
minioAdmin := meta.(*S3MinioClient).S3Admin

var groupName = d.Get("group_name").(string)
var policyName = d.Get("policy_name").(string)

groupInfo, errGroup := minioAdmin.GetGroupDescription(ctx, groupName)
if errGroup != nil {
return NewResourceError("failed to load group infos", groupName, errGroup)
policies, err := minioReadGroupPolicies(ctx, minioAdmin, groupName)
if err != nil {
return err
}

if groupInfo.Policy == "" {
if !Contains(policies, policyName) {
log.Printf("[WARN] No such policy by name (%s) found, removing from state", d.Id())
d.SetId("")
return nil
}

if err := d.Set("policy_name", string(groupInfo.Policy)); err != nil {
if err := d.Set("policy_name", policyName); err != nil {
return NewResourceError("failed to load group infos", groupName, err)
}

Expand All @@ -81,8 +89,19 @@ func minioDeleteGroupPolicyAttachment(ctx context.Context, d *schema.ResourceDat
minioAdmin := meta.(*S3MinioClient).S3Admin

var groupName = d.Get("group_name").(string)
var policyName = d.Get("policy_name").(string)

policies, err := minioReadGroupPolicies(ctx, minioAdmin, groupName)
if err != nil {
return err
}

errIam := minioAdmin.SetPolicy(ctx, "", groupName, true)
newPolicies, found := Filter(policies, policyName)
if !found {
return nil
}

errIam := minioAdmin.SetPolicy(ctx, strings.Join(newPolicies, ","), groupName, true)
if errIam != nil {
return NewResourceError("unable to delete user policy", groupName, errIam)
}
Expand Down Expand Up @@ -110,3 +129,11 @@ func minioImportGroupPolicyAttachment(ctx context.Context, d *schema.ResourceDat
d.SetId(id.PrefixedUniqueId(fmt.Sprintf("%s-", groupName)))
return []*schema.ResourceData{d}, nil
}

func minioReadGroupPolicies(ctx context.Context, minioAdmin *madmin.AdminClient, groupName string) ([]string, diag.Diagnostics) {
groupInfo, errGroup := minioAdmin.GetGroupDescription(ctx, groupName)
if errGroup != nil {
return nil, NewResourceError("failed to load group infos", groupName, errGroup)
}
return strings.Split(groupInfo.Policy, ","), nil
}
62 changes: 46 additions & 16 deletions minio/resource_minio_iam_user_policy_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,17 @@ func minioCreateUserPolicyAttachment(ctx context.Context, d *schema.ResourceData
var userName = d.Get("user_name").(string)
var policyName = d.Get("policy_name").(string)
minioAdmin := meta.(*S3MinioClient).S3Admin
err := minioAdmin.SetPolicy(ctx, policyName, userName, false)

policies, err := minioReadUserPolicies(ctx, minioAdmin, userName)
if err != nil {
return NewResourceError("unable to Set User policy", userName+" "+policyName, err)
return err
}
if !Contains(policies, policyName) {
policies = append(policies, policyName)
err := minioAdmin.SetPolicy(ctx, strings.Join(policies, ","), userName, false)
if err != nil {
return NewResourceError("unable to Set User policy", userName+" "+policyName, err)
}
}

d.SetId(id.PrefixedUniqueId(fmt.Sprintf("%s-", userName)))
Expand All @@ -56,28 +64,20 @@ func minioCreateUserPolicyAttachment(ctx context.Context, d *schema.ResourceData
func minioReadUserPolicyAttachment(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
minioAdmin := meta.(*S3MinioClient).S3Admin
var userName = d.Get("user_name").(string)
var isLDAPUser = LDAPUserDistinguishedNamePattern.MatchString(userName)

log.Printf("[DEBUG] UserPolicyAttachment: is user '%s' an LDAP user? %t", userName, isLDAPUser)
var policyName = d.Get("policy_name").(string)

userInfo, errUser := minioAdmin.GetUserInfo(ctx, userName)
policies, errUser := minioReadUserPolicies(ctx, minioAdmin, userName)
if errUser != nil {
errUserResponse, errUserIsResponse := errUser.(madmin.ErrorResponse)

log.Printf("[DEBUG] UserPolicyAttachment: got an error, errUserIsResponse=%t, errUserResponse.Code=%s", errUserIsResponse, errUserResponse.Code)

if !isLDAPUser || !errUserIsResponse || !strings.EqualFold(errUserResponse.Code, "XMinioAdminNoSuchUser") {
return NewResourceError("failed to load user Infos", userName, errUser)
}
return errUser
}

if userInfo.PolicyName == "" {
if !Contains(policies, policyName) {
log.Printf("[WARN] No such policy by name (%s) found, removing from state", d.Id())
d.SetId("")
return nil
}

if err := d.Set("policy_name", string(userInfo.PolicyName)); err != nil {
if err := d.Set("policy_name", policyName); err != nil {
return diag.FromErr(err)
}

Expand All @@ -86,9 +86,21 @@ func minioReadUserPolicyAttachment(ctx context.Context, d *schema.ResourceData,

func minioDeleteUserPolicyAttachment(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
minioAdmin := meta.(*S3MinioClient).S3Admin

var userName = d.Get("user_name").(string)
var policyName = d.Get("policy_name").(string)

policies, err := minioReadUserPolicies(ctx, minioAdmin, userName)
if err != nil {
return err
}

errIam := minioAdmin.SetPolicy(ctx, "", userName, false)
newPolicies, found := Filter(policies, policyName)
if !found {
return nil
}

errIam := minioAdmin.SetPolicy(ctx, strings.Join(newPolicies, ","), userName, false)
if errIam != nil {
return NewResourceError("unable to delete user policy", userName, errIam)
}
Expand Down Expand Up @@ -116,3 +128,21 @@ func minioImportUserPolicyAttachment(ctx context.Context, d *schema.ResourceData
d.SetId(id.PrefixedUniqueId(fmt.Sprintf("%s-", userName)))
return []*schema.ResourceData{d}, nil
}

func minioReadUserPolicies(ctx context.Context, minioAdmin *madmin.AdminClient, userName string) ([]string, diag.Diagnostics) {
var isLDAPUser = LDAPUserDistinguishedNamePattern.MatchString(userName)

log.Printf("[DEBUG] UserPolicyAttachment: is user '%s' an LDAP user? %t", userName, isLDAPUser)

userInfo, errUser := minioAdmin.GetUserInfo(ctx, userName)
if errUser != nil {
errUserResponse, errUserIsResponse := errUser.(madmin.ErrorResponse)

log.Printf("[DEBUG] UserPolicyAttachment: got an error, errUserIsResponse=%t, errUserResponse.Code=%s", errUserIsResponse, errUserResponse.Code)

if !isLDAPUser || !errUserIsResponse || !strings.EqualFold(errUserResponse.Code, "XMinioAdminNoSuchUser") {
return nil, NewResourceError("failed to load user Infos", userName, errUser)
}
}
return strings.Split(userInfo.PolicyName, ","), nil
}
10 changes: 10 additions & 0 deletions minio/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ func Contains(slice []string, item string) bool {
return ok
}

func Filter(slice []string, item string) ([]string, bool) {
var out []string
for _, s := range slice {
if s != item {
out = append(out, s)
}
}
return out, len(out) != len(slice)
}

// HashcodeString hashes a string to a unique hashcode.
//
// crc32 returns a `uint32`, but for our use we need
Expand Down

0 comments on commit 6cdd43c

Please sign in to comment.