Add new site replication feature (#13311)

This change allows a set of MinIO sites (clusters) to be configured 
for mutual replication of all buckets (including bucket policies, tags, 
object-lock configuration and bucket encryption), IAM policies, 
LDAP service accounts and LDAP STS accounts.
This commit is contained in:
Aditya Manthramurthy
2021-10-06 16:36:31 -07:00
committed by GitHub
parent cb2c2905c5
commit 3a7c79e2c7
20 changed files with 2537 additions and 153 deletions
+115 -2
View File
@@ -28,6 +28,7 @@ import (
"github.com/gorilla/mux"
"github.com/minio/madmin-go"
"github.com/minio/minio/internal/auth"
"github.com/minio/minio/internal/config/dns"
"github.com/minio/minio/internal/logger"
iampolicy "github.com/minio/pkg/iam/policy"
@@ -216,7 +217,6 @@ func (a adminAPIHandlers) UpdateGroupMembers(w http.ResponseWriter, r *http.Requ
return
}
defer r.Body.Close()
data, err := ioutil.ReadAll(r.Body)
if err != nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL)
@@ -630,6 +630,34 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque
}
}
// Call hook for cluster-replication.
//
// FIXME: This wont work in an OpenID situation as the parent credential
// may not be present on peer clusters to provide inherited policies.
// Also, we should not be replicating root user's service account - as
// they are not authenticated by a common external IDP, so we skip when
// opts.ldapUser == "".
if _, isLDAPAccount := opts.claims[ldapUserN]; isLDAPAccount {
err = globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemSvcAcc,
SvcAccChange: &madmin.SRSvcAccChange{
Create: &madmin.SRSvcAccCreate{
Parent: newCred.ParentUser,
AccessKey: newCred.AccessKey,
SecretKey: newCred.SecretKey,
Groups: newCred.Groups,
Claims: opts.claims,
SessionPolicy: createReq.Policy,
Status: auth.AccountOn,
},
},
})
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
}
var createResp = madmin.AddServiceAccountResp{
Credentials: madmin.Credentials{
AccessKey: newCred.AccessKey,
@@ -741,6 +769,30 @@ func (a adminAPIHandlers) UpdateServiceAccount(w http.ResponseWriter, r *http.Re
}
}
// Call site replication hook. Only LDAP accounts are supported for
// replication operations.
svcAccClaims, err := globalIAMSys.GetClaimsForSvcAcc(ctx, accessKey)
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
if _, isLDAPAccount := svcAccClaims[ldapUserN]; isLDAPAccount {
err = globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemSvcAcc,
SvcAccChange: &madmin.SRSvcAccChange{
Update: &madmin.SRSvcAccUpdate{
AccessKey: accessKey,
SecretKey: opts.secretKey,
Status: opts.status,
SessionPolicy: updateReq.NewPolicy,
},
},
})
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
}
writeSuccessNoContent(w)
}
@@ -975,6 +1027,28 @@ func (a adminAPIHandlers) DeleteServiceAccount(w http.ResponseWriter, r *http.Re
}
}
// Call site replication hook. Only LDAP accounts are supported for
// replication operations.
svcAccClaims, err := globalIAMSys.GetClaimsForSvcAcc(ctx, serviceAccount)
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
if _, isLDAPAccount := svcAccClaims[ldapUserN]; isLDAPAccount {
err = globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemSvcAcc,
SvcAccChange: &madmin.SRSvcAccChange{
Delete: &madmin.SRSvcAccDelete{
AccessKey: serviceAccount,
},
},
})
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
}
writeSuccessNoContent(w)
}
@@ -1286,6 +1360,16 @@ func (a adminAPIHandlers) RemoveCannedPolicy(w http.ResponseWriter, r *http.Requ
logger.LogIf(ctx, nerr.Err)
}
}
// Call cluster-replication policy creation hook to replicate policy deletion to
// other minio clusters.
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemPolicy,
Name: policyName,
}); err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
}
// AddCannedPolicy - PUT /minio/admin/v3/add-canned-policy?name=<policy_name>
@@ -1314,7 +1398,13 @@ func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request
return
}
iamPolicy, err := iampolicy.ParseConfig(io.LimitReader(r.Body, r.ContentLength))
iamPolicyBytes, err := ioutil.ReadAll(io.LimitReader(r.Body, r.ContentLength))
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
iamPolicy, err := iampolicy.ParseConfig(bytes.NewReader(iamPolicyBytes))
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
@@ -1338,6 +1428,17 @@ func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request
logger.LogIf(ctx, nerr.Err)
}
}
// Call cluster-replication policy creation hook to replicate policy to
// other minio clusters.
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemPolicy,
Name: policyName,
Policy: iamPolicyBytes,
}); err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
}
// SetPolicyForUserOrGroup - PUT /minio/admin/v3/set-policy?policy=xxx&user-or-group=?[&is-group]
@@ -1380,4 +1481,16 @@ func (a adminAPIHandlers) SetPolicyForUserOrGroup(w http.ResponseWriter, r *http
logger.LogIf(ctx, nerr.Err)
}
}
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemPolicyMapping,
PolicyMapping: &madmin.SRPolicyMapping{
UserOrGroup: entityName,
IsGroup: isGroup,
Policy: policyName,
},
}); err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
}