Added filters for SiteReplicationStatus API to support new UI changes (#14177)

This commit is contained in:
Poorna 2022-01-28 15:37:55 -08:00 committed by GitHub
parent 67f166fa02
commit 38e3c7a8f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 608 additions and 298 deletions

View File

@ -338,8 +338,9 @@ func (a adminAPIHandlers) SiteReplicationStatus(w http.ResponseWriter, r *http.R
if objectAPI == nil {
return
}
opts := getSRStatusOptions(r)
info, err := globalSiteReplicationSys.SiteReplicationStatus(ctx, objectAPI)
info, err := globalSiteReplicationSys.SiteReplicationStatus(ctx, objectAPI, opts)
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
@ -362,7 +363,8 @@ func (a adminAPIHandlers) SiteReplicationMetaInfo(w http.ResponseWriter, r *http
return
}
info, err := globalSiteReplicationSys.SiteReplicationMetaInfo(ctx, objectAPI)
opts := getSRStatusOptions(r)
info, err := globalSiteReplicationSys.SiteReplicationMetaInfo(ctx, objectAPI, opts)
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
@ -428,3 +430,14 @@ func (a adminAPIHandlers) SRPeerEdit(w http.ResponseWriter, r *http.Request) {
return
}
}
func getSRStatusOptions(r *http.Request) (opts madmin.SRStatusOptions) {
q := r.Form
opts.Buckets = q.Get("buckets") == "true"
opts.Policies = q.Get("policies") == "true"
opts.Groups = q.Get("groups") == "true"
opts.Users = q.Get("users") == "true"
opts.Entity = madmin.GetSREntityType(q.Get("entity"))
opts.EntityValue = q.Get("entityvalue")
return
}

View File

@ -1930,8 +1930,18 @@ type srGroupPolicyMapping struct {
DeploymentID string
}
type srUserInfo struct {
madmin.UserInfo
DeploymentID string
}
type srGroupDesc struct {
madmin.GroupDesc
DeploymentID string
}
// SiteReplicationStatus returns the site replication status across clusters participating in site replication.
func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI ObjectLayer) (info madmin.SRStatusInfo, err error) {
func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI ObjectLayer, opts madmin.SRStatusOptions) (info madmin.SRStatusInfo, err error) {
c.RLock()
defer c.RUnlock()
if !c.enabled {
@ -1949,7 +1959,7 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
index := index
if depIDs[index] == globalDeploymentID {
g.Go(func() error {
sris[index], sriErrs[index] = c.SiteReplicationMetaInfo(ctx, objAPI)
sris[index], sriErrs[index] = c.SiteReplicationMetaInfo(ctx, objAPI, opts)
return nil
}, index)
continue
@ -1959,7 +1969,7 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
if err != nil {
return err
}
sris[index], sriErrs[index] = admClient.SRMetaInfo(ctx)
sris[index], sriErrs[index] = admClient.SRMetaInfo(ctx, opts)
return nil
}, index)
}
@ -1990,6 +2000,8 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
policyStats := make(map[string][]srPolicy)
userPolicyStats := make(map[string][]srUserPolicyMapping)
groupPolicyStats := make(map[string][]srGroupPolicyMapping)
userInfoStats := make(map[string][]srUserInfo)
groupDescStats := make(map[string][]srGroupDesc)
numSites := len(sris)
for _, sri := range sris {
@ -2012,52 +2024,127 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
userPolicyStats[user] = append(userPolicyStats[user], srUserPolicyMapping{SRPolicyMapping: policy, DeploymentID: sri.DeploymentID})
}
for group, policy := range sri.GroupPolicies {
if _, ok := userPolicyStats[group]; !ok {
if _, ok := groupPolicyStats[group]; !ok {
groupPolicyStats[group] = make([]srGroupPolicyMapping, 0, numSites)
}
groupPolicyStats[group] = append(groupPolicyStats[group], srGroupPolicyMapping{SRPolicyMapping: policy, DeploymentID: sri.DeploymentID})
}
for u, ui := range sri.UserInfoMap {
if _, ok := userInfoStats[u]; !ok {
userInfoStats[u] = make([]srUserInfo, 0, numSites)
}
userInfoStats[u] = append(userInfoStats[u], srUserInfo{UserInfo: ui, DeploymentID: sri.DeploymentID})
}
for g, gd := range sri.GroupDescMap {
if _, ok := groupDescStats[g]; !ok {
groupDescStats[g] = make([]srGroupDesc, 0, numSites)
}
groupDescStats[g] = append(groupDescStats[g], srGroupDesc{GroupDesc: gd, DeploymentID: sri.DeploymentID})
}
}
info.StatsSummary = make(map[string]madmin.SRSiteSummary, len(c.state.Peers))
info.BucketMismatches = make(map[string]map[string]madmin.SRBucketStatsSummary)
info.PolicyMismatches = make(map[string]map[string]madmin.SRPolicyStatsSummary)
info.UserMismatches = make(map[string]map[string]madmin.SRUserStatsSummary)
info.GroupMismatches = make(map[string]map[string]madmin.SRGroupStatsSummary)
info.BucketStats = make(map[string]map[string]madmin.SRBucketStatsSummary)
info.PolicyStats = make(map[string]map[string]madmin.SRPolicyStatsSummary)
info.UserStats = make(map[string]map[string]madmin.SRUserStatsSummary)
info.GroupStats = make(map[string]map[string]madmin.SRGroupStatsSummary)
// collect user policy mapping replication status across sites
if opts.Users || opts.Entity == madmin.SRUserEntity {
for u, pslc := range userPolicyStats {
policySet := set.NewStringSet()
uPolicyCount := 0
for _, ps := range pslc {
policyBytes, err := json.Marshal(ps)
policyBytes, err := json.Marshal(ps.SRPolicyMapping)
if err != nil {
continue
}
uPolicyCount++
sum := info.StatsSummary[ps.DeploymentID]
sum.TotalUserPolicyMappingCount++
info.StatsSummary[ps.DeploymentID] = sum
if policyStr := string(policyBytes); !policySet.Contains(policyStr) {
policySet.Add(policyStr)
}
}
policyMismatch := !isReplicated(uPolicyCount, numSites, policySet)
if policyMismatch {
userPolicyMismatch := !isReplicated(uPolicyCount, numSites, policySet)
switch {
case userPolicyMismatch, opts.Entity == madmin.SRUserEntity:
for _, ps := range pslc {
dID := depIdxes[ps.DeploymentID]
_, hasUser := sris[dID].UserPolicies[u]
info.UserMismatches[u][ps.DeploymentID] = madmin.SRUserStatsSummary{
PolicyMismatch: policyMismatch,
UserMissing: !hasUser,
if len(info.UserStats[u]) == 0 {
info.UserStats[u] = make(map[string]madmin.SRUserStatsSummary)
}
info.UserStats[u][ps.DeploymentID] = madmin.SRUserStatsSummary{
PolicyMismatch: userPolicyMismatch,
HasUser: hasUser,
HasPolicyMapping: ps.Policy != "",
}
}
default:
// no mismatch
for _, s := range pslc {
sum := info.StatsSummary[s.DeploymentID]
if !s.IsGroup {
sum.ReplicatedUserPolicyMappings++
}
info.StatsSummary[s.DeploymentID] = sum
}
}
}
// collect user info replication status across sites
for u, pslc := range userInfoStats {
uiSet := set.NewStringSet()
userCount := 0
for _, ps := range pslc {
uiBytes, err := json.Marshal(ps.UserInfo)
if err != nil {
continue
}
userCount++
sum := info.StatsSummary[ps.DeploymentID]
sum.TotalUsersCount++
info.StatsSummary[ps.DeploymentID] = sum
if uiStr := string(uiBytes); !uiSet.Contains(uiStr) {
uiSet.Add(uiStr)
}
}
userInfoMismatch := !isReplicated(userCount, numSites, uiSet)
switch {
case userInfoMismatch, opts.Entity == madmin.SRUserEntity:
for _, ps := range pslc {
dID := depIdxes[ps.DeploymentID]
_, hasUser := sris[dID].UserInfoMap[u]
if len(info.UserStats[u]) == 0 {
info.UserStats[u] = make(map[string]madmin.SRUserStatsSummary)
}
umis, ok := info.UserStats[u][ps.DeploymentID]
if !ok {
umis = madmin.SRUserStatsSummary{
HasUser: hasUser,
}
}
umis.UserInfoMismatch = userInfoMismatch
info.UserStats[u][ps.DeploymentID] = umis
}
default:
// no mismatch
for _, s := range pslc {
sum := info.StatsSummary[s.DeploymentID]
sum.ReplicatedUsers++
info.StatsSummary[s.DeploymentID] = sum
}
}
}
}
// collect user policy mapping replication status across sites
if opts.Groups || opts.Entity == madmin.SRGroupEntity {
// collect group policy mapping replication status across sites
for g, pslc := range groupPolicyStats {
policySet := set.NewStringSet()
gPolicyCount := 0
for _, ps := range pslc {
policyBytes, err := json.Marshal(ps)
policyBytes, err := json.Marshal(ps.SRPolicyMapping)
if err != nil {
continue
}
@ -2065,22 +2152,85 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
if policyStr := string(policyBytes); !policySet.Contains(policyStr) {
policySet.Add(policyStr)
}
sum := info.StatsSummary[ps.DeploymentID]
sum.TotalGroupPolicyMappingCount++
info.StatsSummary[ps.DeploymentID] = sum
}
policyMismatch := !isReplicated(gPolicyCount, numSites, policySet)
if policyMismatch {
groupPolicyMismatch := !isReplicated(gPolicyCount, numSites, policySet)
switch {
case groupPolicyMismatch, opts.Entity == madmin.SRGroupEntity:
for _, ps := range pslc {
dID := depIdxes[ps.DeploymentID]
_, hasGroup := sris[dID].GroupPolicies[g]
if len(info.GroupStats[g]) == 0 {
info.GroupStats[g] = make(map[string]madmin.SRGroupStatsSummary)
}
info.GroupStats[g][ps.DeploymentID] = madmin.SRGroupStatsSummary{
PolicyMismatch: groupPolicyMismatch,
HasGroup: hasGroup,
HasPolicyMapping: ps.Policy != "",
}
}
default:
// no mismatch
for _, s := range pslc {
sum := info.StatsSummary[s.DeploymentID]
sum.ReplicatedGroupPolicyMappings++
info.StatsSummary[s.DeploymentID] = sum
}
}
}
info.GroupMismatches[g][ps.DeploymentID] = madmin.SRGroupStatsSummary{
PolicyMismatch: policyMismatch,
GroupMissing: !hasGroup,
// collect group desc replication status across sites
for g, pslc := range groupDescStats {
gdSet := set.NewStringSet()
groupCount := 0
for _, ps := range pslc {
gdBytes, err := json.Marshal(ps.GroupDesc)
if err != nil {
continue
}
groupCount++
sum := info.StatsSummary[ps.DeploymentID]
sum.TotalGroupsCount++
info.StatsSummary[ps.DeploymentID] = sum
if gdStr := string(gdBytes); !gdSet.Contains(gdStr) {
gdSet.Add(gdStr)
}
}
gdMismatch := !isReplicated(groupCount, numSites, gdSet)
switch {
case gdMismatch, opts.Entity == madmin.SRGroupEntity:
for _, ps := range pslc {
dID := depIdxes[ps.DeploymentID]
_, hasGroup := sris[dID].GroupDescMap[g]
if len(info.GroupStats[g]) == 0 {
info.GroupStats[g] = make(map[string]madmin.SRGroupStatsSummary)
}
gmis, ok := info.GroupStats[g][ps.DeploymentID]
if !ok {
gmis = madmin.SRGroupStatsSummary{
HasGroup: hasGroup,
}
} else {
gmis.GroupDescMismatch = gdMismatch
}
info.GroupStats[g][ps.DeploymentID] = gmis
}
default:
// no mismatch
for _, s := range pslc {
sum := info.StatsSummary[s.DeploymentID]
sum.ReplicatedGroups++
info.StatsSummary[s.DeploymentID] = sum
}
}
}
}
if opts.Policies || opts.Entity == madmin.SRPolicyEntity {
// collect IAM policy replication status across sites
for p, pslc := range policyStats {
var policies []*iampolicy.Policy
uPolicyCount := 0
@ -2097,16 +2247,16 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
}
policyMismatch := !isIAMPolicyReplicated(uPolicyCount, numSites, policies)
switch {
case policyMismatch:
case policyMismatch, opts.Entity == madmin.SRPolicyEntity:
for _, ps := range pslc {
dID := depIdxes[ps.DeploymentID]
_, hasPolicy := sris[dID].Policies[p]
if len(info.PolicyMismatches[p]) == 0 {
info.PolicyMismatches[p] = make(map[string]madmin.SRPolicyStatsSummary)
if len(info.PolicyStats[p]) == 0 {
info.PolicyStats[p] = make(map[string]madmin.SRPolicyStatsSummary)
}
info.PolicyMismatches[p][ps.DeploymentID] = madmin.SRPolicyStatsSummary{
info.PolicyStats[p][ps.DeploymentID] = madmin.SRPolicyStatsSummary{
PolicyMismatch: policyMismatch,
PolicyMissing: !hasPolicy,
HasPolicy: hasPolicy,
}
}
default:
@ -2121,12 +2271,15 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
}
}
}
if opts.Buckets || opts.Entity == madmin.SRBucketEntity {
// collect bucket metadata replication stats across sites
for b, slc := range bucketStats {
tagSet := set.NewStringSet()
olockConfigSet := set.NewStringSet()
var policies []*bktpolicy.Policy
var replCfgs []*sreplication.Config
var quotaCfgs []*madmin.BucketQuota
sseCfgSet := set.NewStringSet()
var tagCount, olockCfgCount, sseCfgCount int
for _, s := range slc {
@ -2141,6 +2294,17 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
}
replCfgs = append(replCfgs, cfg)
}
if s.QuotaConfig != nil {
cfgBytes, err := base64.StdEncoding.DecodeString(*s.QuotaConfig)
if err != nil {
continue
}
cfg, err := parseBucketQuota(b, cfgBytes)
if err != nil {
continue
}
quotaCfgs = append(quotaCfgs, cfg)
}
if s.Tags != nil {
tagBytes, err := base64.StdEncoding.DecodeString(*s.Tags)
if err != nil {
@ -2198,13 +2362,15 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
sseCfgMismatch := !isReplicated(sseCfgCount, numSites, sseCfgSet)
policyMismatch := !isBktPolicyReplicated(numSites, policies)
replCfgMismatch := !isBktReplCfgReplicated(numSites, replCfgs)
quotaCfgMismatch := !isBktQuotaCfgReplicated(numSites, quotaCfgs)
switch {
case tagMismatch, olockCfgMismatch, sseCfgMismatch, policyMismatch, replCfgMismatch:
info.BucketMismatches[b] = make(map[string]madmin.SRBucketStatsSummary, numSites)
for _, s := range slc {
case tagMismatch, olockCfgMismatch, sseCfgMismatch, policyMismatch, replCfgMismatch, quotaCfgMismatch, opts.Entity == madmin.SRBucketEntity:
info.BucketStats[b] = make(map[string]madmin.SRBucketStatsSummary, numSites)
for i, s := range slc {
dID := depIdxes[s.DeploymentID]
_, hasBucket := sris[dID].Buckets[s.Bucket]
info.BucketMismatches[b][s.DeploymentID] = madmin.SRBucketStatsSummary{
info.BucketStats[b][s.DeploymentID] = madmin.SRBucketStatsSummary{
DeploymentID: s.DeploymentID,
HasBucket: hasBucket,
TagMismatch: tagMismatch,
@ -2212,7 +2378,13 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
SSEConfigMismatch: sseCfgMismatch,
PolicyMismatch: policyMismatch,
ReplicationCfgMismatch: replCfgMismatch,
HasReplicationCfg: len(replCfgs) > 0,
QuotaCfgMismatch: quotaCfgMismatch,
HasReplicationCfg: s.ReplicationConfig != nil,
HasTagsSet: s.Tags != nil,
HasOLockConfigSet: s.ObjectLockConfig != nil,
HasPolicySet: s.Policy != nil,
HasQuotaCfgSet: *quotaCfgs[i] != madmin.BucketQuota{},
HasSSECfgSet: s.SSEConfig != nil,
}
}
fallthrough
@ -2236,10 +2408,11 @@ func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI O
}
}
}
}
// maximum buckets users etc seen across sites
info.MaxBuckets = len(bucketStats)
info.MaxUsers = len(userPolicyStats)
info.MaxGroups = len(groupPolicyStats)
info.MaxUsers = len(userInfoStats)
info.MaxGroups = len(groupDescStats)
info.MaxPolicies = len(policyStats)
return
}
@ -2277,6 +2450,26 @@ func isIAMPolicyReplicated(cntReplicated, total int, policies []*iampolicy.Polic
return true
}
func isBktQuotaCfgReplicated(total int, quotaCfgs []*madmin.BucketQuota) bool {
if len(quotaCfgs) > 0 && len(quotaCfgs) != total {
return false
}
var prev *madmin.BucketQuota
for i, q := range quotaCfgs {
if q == nil {
return false
}
if i == 0 {
prev = q
continue
}
if prev.Quota != q.Quota || prev.Type != q.Type {
return false
}
}
return true
}
// isBktPolicyReplicated returns true if count of replicated bucket policies matches total
// number of sites and bucket policies are identical.
func isBktPolicyReplicated(total int, policies []*bktpolicy.Policy) bool {
@ -2333,22 +2526,33 @@ func isBktReplCfgReplicated(total int, cfgs []*sreplication.Config) bool {
}
// SiteReplicationMetaInfo returns the metadata info on buckets, policies etc for the replicated site
func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI ObjectLayer) (info madmin.SRInfo, err error) {
func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI ObjectLayer, opts madmin.SRStatusOptions) (info madmin.SRInfo, err error) {
if objAPI == nil {
return info, errSRObjectLayerNotReady
}
c.RLock()
defer c.RUnlock()
if !c.enabled {
return info, nil
}
buckets, err := objAPI.ListBuckets(ctx)
info.DeploymentID = globalDeploymentID
if opts.Buckets || opts.Entity == madmin.SRBucketEntity {
var (
buckets []BucketInfo
err error
)
if opts.Entity == madmin.SRBucketEntity {
bi, err := objAPI.GetBucketInfo(ctx, opts.EntityValue)
if err != nil {
return info, nil
}
buckets = append(buckets, bi)
} else {
buckets, err = objAPI.ListBuckets(ctx)
if err != nil {
return info, errSRBackendIssue(err)
}
info.DeploymentID = globalDeploymentID
}
info.Buckets = make(map[string]madmin.SRBucketInfo, len(buckets))
for _, bucketInfo := range buckets {
bucket := bucketInfo.Name
@ -2403,6 +2607,23 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
bms.ObjectLockConfig = &objLockStr
}
// Get quota config if present
quotaConfig, err := globalBucketMetadataSys.GetQuotaConfig(bucket)
found = true
if _, ok := err.(BucketQuotaConfigNotFound); ok {
found = false
} else if err != nil {
return info, errSRBackendIssue(err)
}
if found {
quotaConfigJSON, err := json.Marshal(quotaConfig)
if err != nil {
return info, wrapSRErr(err)
}
quotaConfigStr := base64.StdEncoding.EncodeToString(quotaConfigJSON)
bms.QuotaConfig = &quotaConfigStr
}
// Get existing bucket bucket encryption settings
sseConfig, err := globalBucketMetadataSys.GetSSEConfig(bucket)
found = true
@ -2419,6 +2640,7 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
sseConfigStr := base64.StdEncoding.EncodeToString(sseConfigData)
bms.SSEConfig = &sseConfigStr
}
// Get replication config if present
rcfg, err := globalBucketMetadataSys.GetReplicationConfig(ctx, bucket)
found = true
@ -2437,13 +2659,21 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
}
info.Buckets[bucket] = bms
}
}
{
if opts.Policies || opts.Entity == madmin.SRPolicyEntity {
var allPolicies map[string]iampolicy.Policy
if opts.Entity == madmin.SRPolicyEntity {
if p, err := globalIAMSys.store.GetPolicy(opts.EntityValue); err == nil {
allPolicies = map[string]iampolicy.Policy{opts.EntityValue: p}
}
} else {
// Replicate IAM policies on local to all peers.
allPolicies, err := globalIAMSys.ListPolicies(ctx, "")
allPolicies, err = globalIAMSys.ListPolicies(ctx, "")
if err != nil {
return info, errSRBackendIssue(err)
}
}
info.Policies = make(map[string]json.RawMessage, len(allPolicies))
for pname, policy := range allPolicies {
policyJSON, err := json.Marshal(policy)
@ -2454,22 +2684,25 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
}
}
{
if opts.Users || opts.Entity == madmin.SRUserEntity {
// Replicate policy mappings on local to all peers.
userPolicyMap := make(map[string]MappedPolicy)
groupPolicyMap := make(map[string]MappedPolicy)
if opts.Entity == madmin.SRUserEntity {
if mp, ok := globalIAMSys.store.GetMappedPolicy(opts.EntityValue, false); ok {
userPolicyMap[opts.EntityValue] = mp
}
} else {
globalIAMSys.store.rlock()
errU := globalIAMSys.store.loadMappedPolicies(ctx, stsUser, false, userPolicyMap)
errG := globalIAMSys.store.loadMappedPolicies(ctx, stsUser, true, groupPolicyMap)
if err := globalIAMSys.store.loadMappedPolicies(ctx, stsUser, false, userPolicyMap); err != nil {
return info, errSRBackendIssue(err)
}
if err = globalIAMSys.store.loadMappedPolicies(ctx, regUser, false, userPolicyMap); err != nil {
return info, errSRBackendIssue(err)
}
globalIAMSys.store.runlock()
if errU != nil {
return info, errSRBackendIssue(errU)
}
if errG != nil {
return info, errSRBackendIssue(errG)
}
info.UserPolicies = make(map[string]madmin.SRPolicyMapping, len(userPolicyMap))
info.GroupPolicies = make(map[string]madmin.SRPolicyMapping, len(c.state.Peers))
for user, mp := range userPolicyMap {
info.UserPolicies[user] = madmin.SRPolicyMapping{
IsGroup: false,
@ -2477,14 +2710,70 @@ func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI
Policy: mp.Policies,
}
}
info.UserInfoMap = make(map[string]madmin.UserInfo)
if opts.Entity == madmin.SRUserEntity {
if ui, err := globalIAMSys.GetUserInfo(ctx, opts.EntityValue); err == nil {
info.UserInfoMap[opts.EntityValue] = ui
}
} else {
// get users/group info on local.
userInfoMap, errU := globalIAMSys.ListUsers()
if errU != nil {
return info, errSRBackendIssue(errU)
}
for user, ui := range userInfoMap {
info.UserInfoMap[user] = ui
}
}
}
if opts.Groups || opts.Entity == madmin.SRGroupEntity {
// Replicate policy mappings on local to all peers.
groupPolicyMap := make(map[string]MappedPolicy)
if opts.Entity == madmin.SRUserEntity {
if mp, ok := globalIAMSys.store.GetMappedPolicy(opts.EntityValue, true); ok {
groupPolicyMap[opts.EntityValue] = mp
}
} else {
globalIAMSys.store.rlock()
if err := globalIAMSys.store.loadMappedPolicies(ctx, stsUser, true, groupPolicyMap); err != nil {
return info, errSRBackendIssue(err)
}
if err := globalIAMSys.store.loadMappedPolicies(ctx, regUser, true, groupPolicyMap); err != nil {
return info, errSRBackendIssue(err)
}
globalIAMSys.store.runlock()
}
info.GroupPolicies = make(map[string]madmin.SRPolicyMapping, len(c.state.Peers))
for group, mp := range groupPolicyMap {
info.UserPolicies[group] = madmin.SRPolicyMapping{
info.GroupPolicies[group] = madmin.SRPolicyMapping{
IsGroup: true,
UserOrGroup: group,
Policy: mp.Policies,
}
}
info.GroupDescMap = make(map[string]madmin.GroupDesc)
if opts.Entity == madmin.SRGroupEntity {
if gd, err := globalIAMSys.GetGroupDescription(opts.EntityValue); err == nil {
info.GroupDescMap[opts.EntityValue] = gd
}
} else {
// get users/group info on local.
groups, errG := globalIAMSys.ListGroups(ctx)
if errG != nil {
return info, errSRBackendIssue(errG)
}
groupDescMap := make(map[string]madmin.GroupDesc, len(groups))
for _, g := range groups {
groupDescMap[g], errG = globalIAMSys.GetGroupDescription(g)
if errG != nil {
return info, errSRBackendIssue(errG)
}
}
for group, d := range groupDescMap {
info.GroupDescMap[group] = d
}
}
}
return info, nil
}

8
go.mod
View File

@ -48,7 +48,7 @@ require (
github.com/minio/csvparser v1.0.0
github.com/minio/highwayhash v1.0.2
github.com/minio/kes v0.14.0
github.com/minio/madmin-go v1.2.8
github.com/minio/madmin-go v1.2.9
github.com/minio/minio-go/v7 v7.0.21
github.com/minio/parquet-go v1.1.0
github.com/minio/pkg v1.1.15
@ -84,9 +84,9 @@ require (
go.etcd.io/etcd/client/v3 v3.5.0
go.uber.org/atomic v1.9.0
go.uber.org/zap v1.19.1
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
google.golang.org/api v0.58.0
gopkg.in/yaml.v2 v2.4.0
@ -200,7 +200,7 @@ require (
go.mongodb.org/mongo-driver v1.7.5 // indirect
go.opencensus.io v0.23.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect

12
go.sum
View File

@ -1025,8 +1025,10 @@ github.com/minio/kes v0.14.0/go.mod h1:OUensXz2BpgMfiogslKxv7Anyx/wj+6bFC6qA7BQc
github.com/minio/madmin-go v1.0.12/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
github.com/minio/madmin-go v1.1.15/go.mod h1:Iu0OnrMWNBYx1lqJTW+BFjBMx0Hi0wjw8VmqhiOs2Jo=
github.com/minio/madmin-go v1.1.23/go.mod h1:wv8zCroSCnpjjQdmgsdJEkFH2oD4w9J40OZqbhxjiJ4=
github.com/minio/madmin-go v1.2.8 h1:VmAXilCzbqsck0Y9CcGbZ4jgg+pWWc2hOFeEh/r7N5c=
github.com/minio/madmin-go v1.2.8/go.mod h1:/rOfQv4ohkXJ+7EaSnhg9IJEX7cobX08zkSLfh8G3Ks=
github.com/minio/madmin-go v1.2.9-0.20220128001305-0caee84bf61e h1:LdfcLSlykM0Yjwb3sI2Cy0kuo/X5WWv/mKRvgnXEUoI=
github.com/minio/madmin-go v1.2.9-0.20220128001305-0caee84bf61e/go.mod h1:b+BL64YlLY/NnE/LCPGbSgIcNX6WSWHx8BOb9wrYShk=
github.com/minio/madmin-go v1.2.9 h1:2NzZ3Ri75Mk/vsLOVf1Dj3ZMBcdTbdb7jZguvYXvhA4=
github.com/minio/madmin-go v1.2.9/go.mod h1:b+BL64YlLY/NnE/LCPGbSgIcNX6WSWHx8BOb9wrYShk=
github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2 h1:xocb1RGyrDJ8PxkNn0NSbaBlfdU6J/Ag9QK62pb7nR8=
github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2/go.mod h1:siI9jWTzj1KsNXgz6NOL/S7OTaAUM0OMi+zEkF08gnA=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
@ -1588,6 +1590,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed h1:YoWVYYAfvQ4ddHv3OKmIvX7NCAhFGTj62VP2l2kfBbA=
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1693,6 +1697,8 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba h1:6u6sik+bn/y7vILcYkK3iwTBWN7WtBvB0+SZswQnbf8=
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1834,6 +1840,8 @@ golang.org/x/sys v0.0.0-20211015200801-69063c4bb744/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=