2022-11-14 23:16:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright (c) 2015-2022 MinIO, Inc.
  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of MinIO Object Storage stack
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/base64" 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-14 23:16:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/binary" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/xml" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"reflect" 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 00:09:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"sort" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-20 08:53:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/madmin-go/v3" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									minioClient  "github.com/minio/minio-go/v7" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/credentials" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/replication" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/set" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/auth" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sreplication  "github.com/minio/minio/internal/bucket/replication" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/logger" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bktpolicy  "github.com/minio/pkg/bucket/policy" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									iampolicy  "github.com/minio/pkg/iam/policy" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srStatePrefix  =  minioConfigPrefix  +  "/site-replication" 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srStateFile    =  "state.json" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srStateFormatVersion1  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errSRCannotJoin  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "this site is already configured for site-replication" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errSRDuplicateSites  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "duplicate sites provided for site-replication" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errSRSelfNotFound  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "none of the given sites correspond to the current one" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errSRPeerNotFound  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "peer not found" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errSRRequestorNotFound  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "requesting site not found in site replication config" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errSRNotEnabled  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "site replication is not enabled" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-14 23:16:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errSRResyncStarted  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "site replication resync is already in progress" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errSRResyncCanceled  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "site replication resync is already canceled" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errSRNoResync  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "no resync in progress" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errSRResyncToSelf  =  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  errors . New ( "invalid peer specified - cannot resync to self" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  errSRInvalidRequest ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationInvalidRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  errSRPeerResp ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationPeerResp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  errSRBackendIssue ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationBackendIssue , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  errSRServiceAccount ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationServiceAccountError , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  errSRBucketConfigError ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationBucketConfigError , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  errSRBucketMetaError ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationBucketMetaError , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  errSRIAMError ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationIAMError , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 03:40:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  errSRConfigMissingError ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cause :  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :   ErrSiteReplicationConfigMissing , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  errSRObjectLayerNotReady  =  SRError {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Cause :  fmt . Errorf ( "object layer not ready" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Code :   ErrServerNotInitialized , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getSRStateFilePath ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  srStatePrefix  +  SlashSeparator  +  srStateFile 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SRError - wrapped error for site replication.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  SRError  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Cause  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Code   APIErrorCode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  SRError )  Error ( )  string  {  
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . Cause  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  c . Cause . Error ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  "<nil>" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  SRError )  Unwrap ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  c . Cause 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  wrapSRErr ( err  error )  SRError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SRError { Cause :  err ,  Code :  ErrInternalError } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SiteReplicationSys - manages cluster-level replication.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  SiteReplicationSys  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sync . RWMutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									enabled  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// In-memory and persisted multi-site replication state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									state  srState 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 13:16:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									iamMetaCache  srIAMCache 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srState  srStateV1  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// srStateV1 represents version 1 of the site replication state persistence
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// format.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srStateV1  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Name  string  ` json:"name" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Peers maps peers by their deploymentID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Peers                    map [ string ] madmin . PeerInfo  ` json:"peers" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ServiceAccountAccessKey  string                      ` json:"serviceAccountAccessKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// srStateData represents the format of the current `srStateFile`.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srStateData  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Version  int  ` json:"version" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SRState  srStateV1  ` json:"srState" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Init - initialize the site replication manager.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  Init ( ctx  context . Context ,  objAPI  ObjectLayer )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									go  c . startHealRoutine ( ctx ,  objAPI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									err  :=  c . loadFromDisk ( ctx ,  objAPI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  errConfigNotFound  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  c . enabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 05:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . Info ( "Cluster replication initialized" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  loadFromDisk ( ctx  context . Context ,  objAPI  ObjectLayer )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf ,  err  :=  readConfig ( ctx ,  objAPI ,  getSRStateFilePath ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 01:19:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  errors . Is ( err ,  errConfigNotFound )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  c . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . state  =  srState { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . enabled  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// attempt to read just the version key in the state file to ensure we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// are reading a compatible version.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ver  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Version  int  ` json:"version" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  json . Unmarshal ( buf ,  & ver ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ver . Version  !=  srStateFormatVersion1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Unexpected ClusterRepl state version: %d" ,  ver . Version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  sdata  srStateData 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  json . Unmarshal ( buf ,  & sdata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . state  =  srState ( sdata . SRState ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 05:32:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . enabled  =  len ( c . state . Peers )  !=  0 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  saveToDisk ( ctx  context . Context ,  state  srState )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdata  :=  srStateData { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Version :  srStateFormatVersion1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SRState :  srStateV1 ( state ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf ,  err  :=  json . Marshal ( sdata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objAPI  :=  newObjectLayerFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errServerNotInitialized 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  saveConfig ( ctx ,  objAPI ,  getSRStateFilePath ( ) ,  buf ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  err  :=  range  globalNotificationSys . ReloadSiteReplicationConfig ( ctx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . state  =  state 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . enabled  =  len ( c . state . Peers )  !=  0 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 05:32:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  removeFromDisk ( ctx  context . Context )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objAPI  :=  newObjectLayerFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errServerNotInitialized 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  deleteConfig ( ctx ,  objAPI ,  getSRStateFilePath ( ) ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  err  :=  range  globalNotificationSys . ReloadSiteReplicationConfig ( ctx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . state  =  srState { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . enabled  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Access key of service account used for perform cluster-replication
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// operations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									siteReplicatorSvcAcc  =  "site-replicator-0" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PeerSiteInfo is a wrapper struct around madmin.PeerSite with extra info on site status
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  PeerSiteInfo  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . PeerSite 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									self          bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DeploymentID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Replicated    bool  // true if already participating in site replication
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Empty         bool  // true if cluster has no buckets
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getSiteStatuses gathers more info on the sites being added
  
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  getSiteStatuses ( ctx  context . Context ,  sites  ... madmin . PeerSite )  ( psi  [ ] PeerSiteInfo ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									psi  =  make ( [ ] PeerSiteInfo ,  0 ,  len ( sites ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  sites  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  getAdminClient ( v . Endpoint ,  v . AccessKey ,  v . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  psi ,  errSRPeerResp ( fmt . Errorf ( "unable to create admin client for %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										info ,  err  :=  admClient . ServerInfo ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  psi ,  errSRPeerResp ( fmt . Errorf ( "unable to fetch server info for %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s3Client ,  err  :=  getS3Client ( v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  psi ,  errSRPeerResp ( fmt . Errorf ( "unable to create s3 client for %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										buckets ,  err  :=  s3Client . ListBuckets ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  psi ,  errSRPeerResp ( fmt . Errorf ( "unable to list buckets for %s: %v" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										psi  =  append ( psi ,  PeerSiteInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PeerSite :      v , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DeploymentID :  info . DeploymentID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Empty :         len ( buckets )  ==  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											self :          info . DeploymentID  ==  globalDeploymentID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// AddPeerClusters - add cluster sites for replication configuration.
  
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  AddPeerClusters ( ctx  context . Context ,  psites  [ ] madmin . PeerSite )  ( madmin . ReplicateAddStatus ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sites ,  serr  :=  c . getSiteStatuses ( ctx ,  psites ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  serr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  serr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										currSites             madmin . SiteReplicationInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										currDeploymentIDsSet  =  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err                   error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									currSites ,  err  =  c . GetClusterInfo ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  currSites . Sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										currDeploymentIDsSet . Add ( v . DeploymentID ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									deploymentIDsSet  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									localHasBuckets  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nonLocalPeerWithBuckets  :=  "" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									selfIdx  :=  - 1 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i ,  v  :=  range  sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// deploymentIDs must be unique
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  deploymentIDsSet . Contains ( v . DeploymentID )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  madmin . ReplicateAddStatus { } ,  errSRDuplicateSites 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										deploymentIDsSet . Add ( v . DeploymentID ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  v . self  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											selfIdx  =  i 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											localHasBuckets  =  ! v . Empty 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! v . Empty  &&  ! currDeploymentIDsSet . Contains ( v . DeploymentID )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											nonLocalPeerWithBuckets  =  v . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-26 02:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  selfIdx  ==  - 1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  errSRBackendIssue ( fmt . Errorf ( "global deployment ID %s mismatch, expected one of %s" ,  globalDeploymentID ,  deploymentIDsSet ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! currDeploymentIDsSet . IsEmpty ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// If current cluster is already SR enabled and no new site being added ,fail.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  currDeploymentIDsSet . Equals ( deploymentIDsSet )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  madmin . ReplicateAddStatus { } ,  errSRCannotJoin 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( currDeploymentIDsSet . Intersection ( deploymentIDsSet ) )  !=  len ( currDeploymentIDsSet )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											diffSlc  :=  getMissingSiteNames ( currDeploymentIDsSet ,  deploymentIDsSet ,  currSites . Sites ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  madmin . ReplicateAddStatus { } ,  errSRInvalidRequest ( fmt . Errorf ( "all existing replicated sites must be specified - missing %s" ,  strings . Join ( diffSlc ,  " " ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// validate that all clusters are using the same IDP settings.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pass ,  err  :=  c . validateIDPSettings ( ctx ,  sites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! pass  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  errSRInvalidRequest ( errors . New ( "all cluster sites must have the same IAM/IDP settings" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// For this `add` API, either all clusters must be empty or the local
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// cluster must be the only one having some buckets.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  localHasBuckets  &&  nonLocalPeerWithBuckets  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  errSRInvalidRequest ( errors . New ( "only one cluster may have data when configuring site replication" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! localHasBuckets  &&  nonLocalPeerWithBuckets  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  errSRInvalidRequest ( fmt . Errorf ( "please send your request to the cluster containing data/buckets: %s" ,  nonLocalPeerWithBuckets ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// FIXME: Ideally, we also need to check if there are any global IAM
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// policies and any (LDAP user created) service accounts on the other
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// peer clusters, and if so, reject the cluster replicate add request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This is not yet implemented.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// VALIDATIONS COMPLETE.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create a common service account for all clusters, with root
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// permissions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create a local service account.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate a secret key for the service account if not created already.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  secretKey  string 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  svcCred  auth . Credentials 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sa ,  _ ,  err  :=  globalIAMSys . getServiceAccount ( ctx ,  siteReplicatorSvcAcc ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  err  ==  errNoSuchServiceAccount : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  secretKey ,  err  =  auth . GenerateCredentials ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  madmin . ReplicateAddStatus { } ,  errSRServiceAccount ( fmt . Errorf ( "unable to create local service account: %w" ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										svcCred ,  _ ,  err  =  globalIAMSys . NewServiceAccount ( ctx ,  sites [ selfIdx ] . AccessKey ,  nil ,  newServiceAccountOpts { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 03:24:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :                   siteReplicatorSvcAcc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :                   secretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allowSiteReplicatorAccount :  true , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  madmin . ReplicateAddStatus { } ,  errSRServiceAccount ( fmt . Errorf ( "unable to create local service account: %w" ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  err  ==  nil : 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										svcCred  =  sa . Credentials 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										secretKey  =  svcCred . SecretKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { } ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-27 15:10:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									joinReq  :=  madmin . SRPeerJoinReq { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										SvcAcctAccessKey :  svcCred . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										SvcAcctSecretKey :  secretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Peers :             make ( map [ string ] madmin . PeerInfo ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										joinReq . Peers [ v . DeploymentID ]  =  madmin . PeerInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											Endpoint :      v . Endpoint , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Name :          v . Name , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											DeploymentID :  v . DeploymentID , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addedCount  :=  0 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										peerAddErr  error 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										admClient   * madmin . AdminClient 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  v . self  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  currDeploymentIDsSet . Contains ( v . DeploymentID ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											admClient ,  err  =  c . getAdminClient ( ctx ,  v . DeploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											admClient ,  err  =  getAdminClient ( v . Endpoint ,  v . AccessKey ,  v . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											peerAddErr  =  errSRPeerResp ( fmt . Errorf ( "unable to create admin client for %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										joinReq . SvcAcctParent  =  v . AccessKey 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-27 15:10:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  admClient . SRPeerJoin ( ctx ,  joinReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											peerAddErr  =  errSRPeerResp ( fmt . Errorf ( "unable to link with peer %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addedCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  peerAddErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  addedCount  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  madmin . ReplicateAddStatus { } ,  peerAddErr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// In this case, it means at least one cluster was added
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// successfully, we need to send a response to the client with
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// some details - FIXME: the disks on this cluster would need to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// be cleaned to recover.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										partial  :=  madmin . ReplicateAddStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Status :     madmin . ReplicateAddStatusPartial , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ErrDetail :  peerAddErr . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  partial ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Other than handling existing buckets, we can now save the cluster
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// replication configuration state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									state  :=  srState { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :                     sites [ selfIdx ] . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Peers :                    joinReq . Peers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ServiceAccountAccessKey :  svcCred . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  c . saveToDisk ( ctx ,  state ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateAddStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Status :     madmin . ReplicateAddStatusPartial , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ErrDetail :  fmt . Sprintf ( "unable to save cluster-replication state on local: %v" ,  err ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									result  :=  madmin . ReplicateAddStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Success :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Status :   madmin . ReplicateAddStatusSuccess , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  c . syncToAllPeers ( ctx ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										result . InitialSyncErrorMessage  =  err . Error ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  result ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 03:24:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PeerJoinReq - internal API handler to respond to a peer cluster's request to join.
  
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerJoinReq ( ctx  context . Context ,  arg  madmin . SRPeerJoinReq )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  ourName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  d ,  p  :=  range  arg . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  d  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ourName  =  p . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ourName  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  errSRSelfNotFound 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  _ ,  err  :=  globalIAMSys . GetServiceAccount ( ctx ,  arg . SvcAcctAccessKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  errNoSuchServiceAccount  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  _ ,  err  =  globalIAMSys . NewServiceAccount ( ctx ,  arg . SvcAcctParent ,  nil ,  newServiceAccountOpts { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 03:24:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :                   arg . SvcAcctAccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :                   arg . SvcAcctSecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allowSiteReplicatorAccount :  arg . SvcAcctAccessKey  ==  siteReplicatorSvcAcc , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRServiceAccount ( fmt . Errorf ( "unable to create service account on %s: %v" ,  ourName ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									state  :=  srState { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :                     ourName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Peers :                    arg . Peers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ServiceAccountAccessKey :  arg . SvcAcctAccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  c . saveToDisk ( ctx ,  state ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-05 07:10:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  errSRBackendIssue ( fmt . Errorf ( "unable to save cluster-replication state to drive on %s: %v" ,  ourName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetIDPSettings returns info about the configured identity provider. It is
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// used to validate that all peers have the same IDP.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  GetIDPSettings ( ctx  context . Context )  madmin . IDPSettings  {  
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s  :=  madmin . IDPSettings { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . LDAP  =  madmin . LDAPSettings { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:37:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										IsLDAPEnabled :           globalIAMSys . LDAPConfig . Enabled ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LDAPUserDNSearchBase :    globalIAMSys . LDAPConfig . LDAP . UserDNSearchBaseDistName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LDAPUserDNSearchFilter :  globalIAMSys . LDAPConfig . LDAP . UserDNSearchFilter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LDAPGroupSearchBase :     globalIAMSys . LDAPConfig . LDAP . GroupSearchBaseDistName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LDAPGroupSearchFilter :   globalIAMSys . LDAPConfig . LDAP . GroupSearchFilter , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 13:01:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . OpenID  =  globalIAMSys . OpenIDConfig . GetSettings ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s . OpenID . Enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . OpenID . Region  =  globalSite . Region 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  validateIDPSettings ( ctx  context . Context ,  peers  [ ] PeerSiteInfo )  ( bool ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									s  :=  make ( [ ] madmin . IDPSettings ,  0 ,  len ( peers ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  v . self  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											s  =  append ( s ,  c . GetIDPSettings ( ctx ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  getAdminClient ( v . Endpoint ,  v . AccessKey ,  v . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  errSRPeerResp ( fmt . Errorf ( "unable to create admin client for %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-27 15:10:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										is ,  err  :=  admClient . SRPeerGetIDPSettings ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  errSRPeerResp ( fmt . Errorf ( "unable to fetch IDP settings from %s: %v" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  =  append ( s ,  is ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  1 ;  i  <  len ( s ) ;  i ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! reflect . DeepEqual ( s [ i ] ,  s [ 0 ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  false ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  true ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetClusterInfo - returns site replication information.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  GetClusterInfo ( ctx  context . Context )  ( info  madmin . SiteReplicationInfo ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . Enabled  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . Name  =  c . state . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . Sites  =  make ( [ ] madmin . PeerInfo ,  0 ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  peer  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info . Sites  =  append ( info . Sites ,  peer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-13 04:22:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sort . Slice ( info . Sites ,  func ( i ,  j  int )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  info . Sites [ i ] . Name  <  info . Sites [ j ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . ServiceAccountAccessKey  =  c . state . ServiceAccountAccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  info ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									makeBucketWithVersion    =  "MakeBucketWithVersioning" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configureReplication     =  "ConfigureReplication" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									deleteBucket             =  "DeleteBucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									replicateIAMItem         =  "SRPeerReplicateIAMItem" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									replicateBucketMetadata  =  "SRPeerReplicateBucketMeta" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// MakeBucketHook - called during a regular make bucket call when cluster
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// replication is enabled. It is responsible for the creation of the same bucket
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// on remote clusters, and creating replication rules on local and peer
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// clusters.
  
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  MakeBucketHook ( ctx  context . Context ,  bucket  string ,  opts  MakeBucketOptions )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// At this point, the local bucket is created.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									optsMap  :=  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  opts . LockEnabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										optsMap [ "lockEnabled" ]  =  "true" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										optsMap [ "versioningEnabled" ]  =  "true" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  opts . VersioningEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										optsMap [ "versioningEnabled" ]  =  "true" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:44:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . ForceCreate  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										optsMap [ "forceCreate" ]  =  "true" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									createdAt ,  _  :=  globalBucketMetadataSys . CreatedAt ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 00:46:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									optsMap [ "createdAt" ]  =  createdAt . UTC ( ) . Format ( time . RFC3339Nano ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts . CreatedAt  =  createdAt 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create bucket and enable versioning on all peers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									makeBucketConcErr  :=  c . concDo ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										func ( )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  c . annotateErr ( makeBucketWithVersion ,  c . PeerBucketMakeWithVersioningHandler ( ctx ,  bucket ,  opts ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										func ( deploymentID  string ,  p  madmin . PeerInfo )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											admClient ,  err  :=  c . getAdminClient ( ctx ,  deploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  c . annotatePeerErr ( p . Name ,  makeBucketWithVersion ,  admClient . SRPeerBucketOps ( ctx ,  bucket ,  madmin . MakeWithVersioningBktOp ,  optsMap ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										makeBucketWithVersion , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Create bucket remotes and add replication rules for the bucket on self and peers.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									makeRemotesConcErr  :=  c . concDo ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										func ( )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  c . annotateErr ( configureReplication ,  c . PeerBucketConfigureReplHandler ( ctx ,  bucket ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										func ( deploymentID  string ,  p  madmin . PeerInfo )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											admClient ,  err  :=  c . getAdminClient ( ctx ,  deploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  c . annotatePeerErr ( p . Name ,  configureReplication ,  admClient . SRPeerBucketOps ( ctx ,  bucket ,  madmin . ConfigureReplBktOp ,  nil ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										configureReplication , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  errors . Unwrap ( makeBucketConcErr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  errors . Unwrap ( makeRemotesConcErr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// DeleteBucketHook - called during a regular delete bucket call when cluster
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// replication is enabled. It is responsible for the deletion of the same bucket
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// on remote clusters.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  DeleteBucketHook ( ctx  context . Context ,  bucket  string ,  forceDelete  bool )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// At this point, the local bucket is deleted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									op  :=  madmin . DeleteBucketBktOp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  forceDelete  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										op  =  madmin . ForceDeleteBucketBktOp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Send bucket delete to other clusters.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cerr  :=  c . concDo ( nil ,  func ( deploymentID  string ,  p  madmin . PeerInfo )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  deploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  c . annotatePeerErr ( p . Name ,  deleteBucket ,  admClient . SRPeerBucketOps ( ctx ,  bucket ,  op ,  nil ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										deleteBucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  errors . Unwrap ( cerr ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerBucketMakeWithVersioningHandler - creates bucket and enables versioning.
  
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketMakeWithVersioningHandler ( ctx  context . Context ,  bucket  string ,  opts  MakeBucketOptions )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									objAPI  :=  newObjectLayerFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errServerNotInitialized 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-23 23:46:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  :=  objAPI . MakeBucket ( ctx ,  bucket ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Check if this is a bucket exists error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  ok1  :=  err . ( BucketExists ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  ok2  :=  err . ( BucketAlreadyExists ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok1  &&  ! ok2  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  wrapSRErr ( c . annotateErr ( makeBucketWithVersion ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Load updated bucket metadata into memory as new
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// bucket was created.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalNotificationSys . LoadBucketMetadata ( GlobalContext ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									meta ,  err  :=  globalBucketMetadataSys . Get ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  wrapSRErr ( c . annotateErr ( makeBucketWithVersion ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									meta . SetCreatedAt ( opts . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									meta . VersioningConfigXML  =  enabledBucketVersioningConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  opts . LockEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										meta . ObjectLockConfigXML  =  enabledBucketObjectLockConfig 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  meta . Save ( context . Background ( ) ,  objAPI ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalBucketMetadataSys . Set ( bucket ,  meta ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Load updated bucket metadata into memory as new metadata updated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalNotificationSys . LoadBucketMetadata ( GlobalContext ,  bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerBucketConfigureReplHandler - configures replication remote and
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// replication rules to all other peers for the local bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketConfigureReplHandler ( ctx  context . Context ,  bucket  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									creds ,  err  :=  c . getPeerCreds ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The following function, creates a bucket remote and sets up a bucket
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// replication rule for the given peer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configurePeerFn  :=  func ( d  string ,  peer  madmin . PeerInfo )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Create bucket replication rule to this peer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// To add the bucket replication rule, we fetch the current
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// server configuration, and convert it to minio-go's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// replication configuration type (by converting to xml and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// parsing it back), use minio-go's add rule function, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// finally convert it back to the server type (again via xml).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This is needed as there is no add-rule function in the server
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// yet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Though we do not check if the rule already exists, this is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// not a problem as we are always using the same replication
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// rule ID - if the rule already exists, it is just replaced.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										replicationConfigS ,  _ ,  err  :=  globalBucketMetadataSys . GetReplicationConfig ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_ ,  ok  :=  err . ( BucketReplicationConfigNotFound ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  replicationConfig  replication . Config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  replicationConfigS  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											replCfgSBytes ,  err  :=  xml . Marshal ( replicationConfigS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  xml . Unmarshal ( replCfgSBytes ,  & replicationConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ruleID   =  fmt . Sprintf ( "site-repl-%s" ,  d ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hasRule  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ruleARN  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  r  :=  range  replicationConfig . Rules  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  r . ID  ==  ruleID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												hasRule  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ruleARN  =  r . Destination . Bucket 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ep ,  _  :=  url . Parse ( peer . Endpoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  targets  [ ] madmin . BucketTarget 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  targetsPtr ,  _  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) ;  targetsPtr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targets  =  targetsPtr . Targets 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										targetARN  :=  "" 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  updateTgt  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  targetToUpdate  madmin . BucketTarget 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										for  _ ,  target  :=  range  targets  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  target . Arn  ==  ruleARN  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												targetARN  =  ruleARN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  target . URL ( ) . String ( )  !=  peer . Endpoint  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													updateTgt  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													targetToUpdate  =  target 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// replication config had a stale target ARN - update the endpoint
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  updateTgt  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetToUpdate . Endpoint  =  ep . Host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetToUpdate . Secure  =  ep . Scheme  ==  "https" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetToUpdate . Credentials  =  & madmin . Credentials { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AccessKey :  creds . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SecretKey :  creds . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! peer . SyncState . Empty ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												targetToUpdate . ReplicationSync  =  ( peer . SyncState  ==  madmin . SyncEnabled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  :=  globalBucketTargetSys . SetTarget ( ctx ,  bucket ,  & targetToUpdate ,  true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  c . annotatePeerErr ( peer . Name ,  "Bucket target update error" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targets ,  err  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tgtBytes ,  err  :=  json . Marshal ( & targets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTargetsFile ,  tgtBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// no replication rule for this peer or target ARN missing in bucket targets
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  targetARN  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketTarget  :=  madmin . BucketTarget { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SourceBucket :  bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Endpoint :      ep . Host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Credentials :  & madmin . Credentials { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													AccessKey :  creds . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SecretKey :  creds . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												TargetBucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Secure :           ep . Scheme  ==  "https" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												API :              "s3v4" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :             madmin . ReplicationService , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Region :           "" , 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ReplicationSync :  peer . SyncState  ==  madmin . SyncEnabled , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-14 19:24:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  exists  bool  // true if ARN already exists
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketTarget . Arn ,  exists  =  globalBucketTargetSys . getRemoteARN ( bucket ,  & bucketTarget ,  peer . DeploymentID ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-14 19:24:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! exists  {  // persist newly generated ARN to targets and metadata on disk
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  :=  globalBucketTargetSys . SetTarget ( ctx ,  bucket ,  & bucketTarget ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotatePeerErr ( peer . Name ,  "Bucket target creation error" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												targets ,  err  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tgtBytes ,  err  :=  json . Marshal ( & targets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTargetsFile ,  tgtBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetARN  =  bucketTarget . Arn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										opts  :=  replication . Options { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Set the ID so we can identify the rule as being
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// created for site-replication and include the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// destination cluster's deployment ID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ID :  ruleID , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Use a helper to generate unique priority numbers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Priority :  fmt . Sprintf ( "%d" ,  getPriorityHelper ( replicationConfig ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Op :          replication . AddOption , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											RuleStatus :  "enable" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DestBucket :  targetARN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Replicate everything!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ReplicateDeletes :         "enable" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ReplicateDeleteMarkers :   "enable" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ReplicaSync :              "enable" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ExistingObjectReplicate :  "enable" , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  hasRule : 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-27 08:57:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ruleARN  !=  opts . DestBucket  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// remove stale replication rule and replace rule with correct target ARN
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  len ( replicationConfig . Rules )  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													err  =  replicationConfig . RemoveRule ( opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													replicationConfig  =  replication . Config { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													err  =  replicationConfig . AddRule ( opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  replicationConfig . EditRule ( opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  replicationConfig . AddRule ( opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  c . annotatePeerErr ( peer . Name ,  "Error adding bucket replication rule" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Now convert the configuration back to server's type so we can
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// do some validation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newReplCfgBytes ,  err  :=  xml . Marshal ( replicationConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newReplicationConfig ,  err  :=  sreplication . ParseConfig ( bytes . NewReader ( newReplCfgBytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-27 08:57:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sameTarget ,  apiErr  :=  validateReplicationDestination ( ctx ,  bucket ,  newReplicationConfig ,  true ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  apiErr  !=  noError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  fmt . Errorf ( "bucket replication config validation error: %#v" ,  apiErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  newReplicationConfig . Validate ( bucket ,  sameTarget ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Config looks good, so we save it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										replCfgData ,  err  :=  xml . Marshal ( newReplicationConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketReplicationConfig ,  replCfgData ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  c . annotatePeerErr ( peer . Name ,  "Error updating replication configuration" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									errMap  :=  make ( map [ string ] error ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  d ,  peer  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  d  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										errMap [ d ]  =  configurePeerFn ( d ,  peer ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  c . toErrorFromErrMap ( errMap ,  configureReplication ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerBucketDeleteHandler - deletes bucket on local in response to a delete
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// bucket request from a peer.
  
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketDeleteHandler ( ctx  context . Context ,  bucket  string ,  opts  DeleteBucketOptions )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRNotEnabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objAPI  :=  newObjectLayerFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errServerNotInitialized 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalDNSConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  globalDNSConfig . Delete ( bucket ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  :=  objAPI . DeleteBucket ( ctx ,  bucket ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  globalDNSConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err2  :=  globalDNSConfig . Put ( bucket ) ;  err2  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to restore bucket DNS entry %w, please fix it manually" ,  err2 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalNotificationSys . DeleteBucketMetadata ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// IAMChangeHook - called when IAM items need to be replicated to peer clusters.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This includes named policy creation, policy mapping changes and service
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// account changes.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// All policies are replicated.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Policy mappings are only replicated when they are for LDAP users or groups
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (as an external IDP is always assumed when SR is used). In the case of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// OpenID, such mappings are provided from the IDP directly and so are not
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// applicable here.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Service accounts are replicated as long as they are not meant for the root
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// user.
  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// STS accounts are replicated, but only if the session token is verifiable
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// using the local cluster's root credential.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  IAMChangeHook ( ctx  context . Context ,  item  madmin . SRIAMItem )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The IAM item has already been applied to the local cluster at this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// point, and only needs to be updated on all remote peer clusters.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cerr  :=  c . concDo ( nil ,  func ( d  string ,  p  madmin . PeerInfo )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  d ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  c . annotatePeerErr ( p . Name ,  replicateIAMItem ,  admClient . SRPeerReplicateIAMItem ( ctx ,  item ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										replicateIAMItem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  errors . Unwrap ( cerr ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerAddPolicyHandler - copies IAM policy to local. A nil policy argument,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// causes the named policy to be deleted.
  
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerAddPolicyHandler ( ctx  context . Context ,  policyName  string ,  p  * iampolicy . Policy ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  p ,  err  :=  globalIAMSys . store . GetPolicyDoc ( policyName ) ;  err  ==  nil  &&  p . UpdateDate . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  p  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 06:38:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  globalIAMSys . DeletePolicy ( ctx ,  policyName ,  true ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalIAMSys . SetPolicy ( ctx ,  policyName ,  * p ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PeerIAMUserChangeHandler - copies IAM user to local.
  
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerIAMUserChangeHandler ( ctx  context . Context ,  change  * madmin . SRIAMUser ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  change  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRInvalidRequest ( errInvalidArgument ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ui ,  err  :=  globalIAMSys . GetUserInfo ( ctx ,  change . AccessKey ) ;  err  ==  nil  &&  ui . UpdatedAt . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  change . IsDeleteReq  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  globalIAMSys . DeleteUser ( ctx ,  change . AccessKey ,  true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  change . UserReq  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRInvalidRequest ( errInvalidArgument ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										userReq  :=  * change . UserReq 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  userReq . Status  !=  ""  &&  userReq . SecretKey  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Status is set without secretKey updates means we are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// only changing the account status.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_ ,  err  =  globalIAMSys . SetUserStatus ( ctx ,  change . AccessKey ,  userReq . Status ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_ ,  err  =  globalIAMSys . CreateUser ( ctx ,  change . AccessKey ,  userReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerGroupInfoChangeHandler - copies group changes to local.
  
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerGroupInfoChangeHandler ( ctx  context . Context ,  change  * madmin . SRGroupInfo ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  change  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRInvalidRequest ( errInvalidArgument ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									updReq  :=  change . UpdateReq 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  gd ,  err  :=  globalIAMSys . GetGroupDescription ( updReq . Group ) ;  err  ==  nil  &&  gd . UpdatedAt . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  updReq . IsRemove  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalIAMSys . RemoveUsersFromGroup ( ctx ,  updReq . Group ,  updReq . Members ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  updReq . Status  !=  ""  &&  len ( updReq . Members )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_ ,  err  =  globalIAMSys . SetGroupStatus ( ctx ,  updReq . Group ,  updReq . Status  ==  madmin . GroupEnabled ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_ ,  err  =  globalIAMSys . AddUsersToGroup ( ctx ,  updReq . Group ,  updReq . Members ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-10 06:17:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  ==  nil  &&  updReq . Status  !=  madmin . GroupEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  err  =  globalIAMSys . SetGroupStatus ( ctx ,  updReq . Group ,  updReq . Status  ==  madmin . GroupEnabled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// PeerSvcAccChangeHandler - copies service-account change to local.
  
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerSvcAccChangeHandler ( ctx  context . Context ,  change  * madmin . SRSvcAccChange ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  change  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  errSRInvalidRequest ( errInvalidArgument ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  change . Create  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  sp  * iampolicy . Policy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( change . Create . SessionPolicy )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sp ,  err  =  iampolicy . ParseConfig ( bytes . NewReader ( change . Create . SessionPolicy ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! updatedAt . IsZero ( )  &&  change . Create . AccessKey  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  sa ,  _ ,  err  :=  globalIAMSys . getServiceAccount ( ctx ,  change . Create . AccessKey ) ;  err  ==  nil  &&  sa . UpdatedAt . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										opts  :=  newServiceAccountOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :      change . Create . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :      change . Create . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sessionPolicy :  sp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											claims :         change . Create . Claims , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 08:05:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											name :           change . Create . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											description :    change . Create . Description , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 02:10:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expiration :     change . Create . Expiration , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  _ ,  err  =  globalIAMSys . NewServiceAccount ( ctx ,  change . Create . Parent ,  change . Create . Groups ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  change . Update  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  sp  * iampolicy . Policy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( change . Update . SessionPolicy )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sp ,  err  =  iampolicy . ParseConfig ( bytes . NewReader ( change . Update . SessionPolicy ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  sa ,  _ ,  err  :=  globalIAMSys . getServiceAccount ( ctx ,  change . Update . AccessKey ) ;  err  ==  nil  &&  sa . UpdatedAt . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										opts  :=  updateServiceAccountOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :      change . Update . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											status :         change . Update . Status , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 08:05:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											name :           change . Update . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											description :    change . Update . Description , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											sessionPolicy :  sp , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 02:10:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expiration :     change . Update . Expiration , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalIAMSys . UpdateServiceAccount ( ctx ,  change . Update . AccessKey ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  change . Delete  !=  nil : 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  sa ,  _ ,  err  :=  globalIAMSys . getServiceAccount ( ctx ,  change . Delete . AccessKey ) ;  err  ==  nil  &&  sa . UpdatedAt . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  globalIAMSys . DeleteServiceAccount ( ctx ,  change . Delete . AccessKey ,  true ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerPolicyMappingHandler - copies policy mapping to local.
  
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerPolicyMappingHandler ( ctx  context . Context ,  mapping  * madmin . SRPolicyMapping ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  mapping  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  errSRInvalidRequest ( errInvalidArgument ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mp ,  ok  :=  globalIAMSys . store . GetMappedPolicy ( mapping . Policy ,  mapping . IsGroup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ok  &&  mp . UpdatedAt . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  globalIAMSys . PolicyDBSet ( ctx ,  mapping . UserOrGroup ,  mapping . Policy ,  IAMUserType ( mapping . UserType ) ,  mapping . IsGroup ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerSTSAccHandler - replicates STS credential locally.
  
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerSTSAccHandler ( ctx  context . Context ,  stsCred  * madmin . SRSTSCredential ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  stsCred  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  errSRInvalidRequest ( errInvalidArgument ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// skip overwrite of local update if peer sent stale info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-22 23:26:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  u ,  _ ,  err  :=  globalIAMSys . getTempAccount ( ctx ,  stsCred . AccessKey ) ;  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  u . UpdatedAt . After ( updatedAt )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:50:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Verify the session token of the stsCred
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									claims ,  err  :=  auth . ExtractClaims ( stsCred . SessionToken ,  globalActiveCred . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "STS credential could not be verified: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mapClaims  :=  claims . Map ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expiry ,  err  :=  auth . ExpToInt64 ( mapClaims [ "exp" ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Expiry claim was not found: %v: %w" ,  mapClaims ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cred  :=  auth . Credentials { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AccessKey :     stsCred . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SecretKey :     stsCred . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Expiration :    time . Unix ( expiry ,  0 ) . UTC ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SessionToken :  stsCred . SessionToken , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ParentUser :    stsCred . ParentUser , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Status :        auth . AccountOn , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Extract the username and lookup DN and groups in LDAP.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ldapUser ,  isLDAPSTS  :=  claims . Lookup ( ldapUserN ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-07 00:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isLDAPSTS  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Need to lookup the groups from LDAP.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:37:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  ldapGroups ,  err  :=  globalIAMSys . LDAPConfig . LookupUserDN ( ldapUser ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  fmt . Errorf ( "unable to query LDAP server for %s: %w" ,  ldapUser ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cred . Groups  =  ldapGroups 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set these credentials to IAM.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  globalIAMSys . SetTempUser ( ctx ,  cred . AccessKey ,  cred ,  stsCred . ParentPolicyMapping ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "unable to save STS credential and/or parent policy mapping: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// BucketMetaHook - called when bucket meta changes happen and need to be
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// replicated to peer clusters.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  BucketMetaHook ( ctx  context . Context ,  item  madmin . SRBucketMeta )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The change has already been applied to the local cluster at this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// point, and only needs to be updated on all remote peer clusters.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cerr  :=  c . concDo ( nil ,  func ( d  string ,  p  madmin . PeerInfo )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  d ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  c . annotatePeerErr ( p . Name ,  replicateBucketMetadata ,  admClient . SRPeerReplicateBucketMeta ( ctx ,  item ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										replicateBucketMetadata , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  errors . Unwrap ( cerr ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PeerBucketVersioningHandler - updates versioning config to local cluster.
  
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketVersioningHandler ( ctx  context . Context ,  bucket  string ,  versioning  * string ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  versioning  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// skip overwrite if local update is newer than peer update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  updateTm ,  err  :=  globalBucketMetadataSys . GetVersioningConfig ( bucket ) ;  err  ==  nil  &&  updateTm . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										configData ,  err  :=  base64 . StdEncoding . DecodeString ( * versioning ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketVersioningConfig ,  configData ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// PeerBucketPolicyHandler - copies/deletes policy to local cluster.
  
						 
					
						
							
								
									
										
										
										
											2022-12-06 03:18:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketPolicyHandler ( ctx  context . Context ,  bucket  string ,  policy  * bktpolicy . Policy ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// skip overwrite if local update is newer than peer update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  updateTm ,  err  :=  globalBucketMetadataSys . GetPolicyConfig ( bucket ) ;  err  ==  nil  &&  updateTm . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  policy  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configData ,  err  :=  json . Marshal ( policy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketPolicyConfig ,  configData ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Delete the bucket policy
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 08:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  globalBucketMetadataSys . Delete ( ctx ,  bucket ,  bucketPolicyConfig ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerBucketTaggingHandler - copies/deletes tags to local cluster.
  
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketTaggingHandler ( ctx  context . Context ,  bucket  string ,  tags  * string ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// skip overwrite if local update is newer than peer update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  updateTm ,  err  :=  globalBucketMetadataSys . GetTaggingConfig ( bucket ) ;  err  ==  nil  &&  updateTm . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  tags  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configData ,  err  :=  base64 . StdEncoding . DecodeString ( * tags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTaggingConfig ,  configData ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Delete the tags
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 08:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  globalBucketMetadataSys . Delete ( ctx ,  bucket ,  bucketTaggingConfig ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerBucketObjectLockConfigHandler - sets object lock on local bucket.
  
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketObjectLockConfigHandler ( ctx  context . Context ,  bucket  string ,  objectLockData  * string ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  objectLockData  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// skip overwrite if local update is newer than peer update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  updateTm ,  err  :=  globalBucketMetadataSys . GetObjectLockConfig ( bucket ) ;  err  ==  nil  &&  updateTm . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										configData ,  err  :=  base64 . StdEncoding . DecodeString ( * objectLockData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  objectLockConfig ,  configData ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PeerBucketSSEConfigHandler - copies/deletes SSE config to local cluster.
  
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketSSEConfigHandler ( ctx  context . Context ,  bucket  string ,  sseConfig  * string ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// skip overwrite if local update is newer than peer update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  updateTm ,  err  :=  globalBucketMetadataSys . GetSSEConfig ( bucket ) ;  err  ==  nil  &&  updateTm . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  sseConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configData ,  err  :=  base64 . StdEncoding . DecodeString ( * sseConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketSSEConfig ,  configData ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Delete sse config
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 08:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  globalBucketMetadataSys . Delete ( ctx ,  bucket ,  bucketSSEConfig ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PeerBucketQuotaConfigHandler - copies/deletes policy to local cluster.
  
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerBucketQuotaConfigHandler ( ctx  context . Context ,  bucket  string ,  quota  * madmin . BucketQuota ,  updatedAt  time . Time )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// skip overwrite if local update is newer than peer update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! updatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  updateTm ,  err  :=  globalBucketMetadataSys . GetQuotaConfig ( ctx ,  bucket ) ;  err  ==  nil  &&  updateTm . After ( updatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  quota  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										quotaData ,  err  :=  json . Marshal ( quota ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketQuotaConfigFile ,  quotaData ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Delete the bucket policy
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 08:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  globalBucketMetadataSys . Delete ( ctx ,  bucket ,  bucketQuotaConfigFile ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// getAdminClient - NOTE: ensure to take at least a read lock on SiteReplicationSys
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// before calling this.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  getAdminClient ( ctx  context . Context ,  deploymentID  string )  ( * madmin . AdminClient ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									creds ,  err  :=  c . getPeerCreds ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									peer ,  ok  :=  c . state . Peers [ deploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errSRPeerNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  getAdminClient ( peer . Endpoint ,  creds . AccessKey ,  creds . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getAdminClientWithEndpoint - NOTE: ensure to take at least a read lock on SiteReplicationSys
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// before calling this.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  getAdminClientWithEndpoint ( ctx  context . Context ,  deploymentID ,  endpoint  string )  ( * madmin . AdminClient ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									creds ,  err  :=  c . getPeerCreds ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  ok  :=  c . state . Peers [ deploymentID ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errSRPeerNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  getAdminClient ( endpoint ,  creds . AccessKey ,  creds . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  getPeerCreds ( )  ( * auth . Credentials ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									u ,  ok  :=  globalIAMSys . store . GetUser ( c . state . ServiceAccountAccessKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "site replication service account not found" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  & u . Credentials ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// listBuckets returns a consistent common view of latest unique buckets across
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// sites, this is used for replication.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  listBuckets ( ctx  context . Context )  ( [ ] BucketInfo ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// If local has buckets, enable versioning on them, create them on peers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// and setup replication rules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objAPI  :=  newObjectLayerFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errSRObjectLayerNotReady 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  objAPI . ListBuckets ( ctx ,  BucketOptions { Deleted :  true } ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// syncToAllPeers is used for syncing local data to all remote peers, it is
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// called once during initial "AddPeerClusters" request.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  syncToAllPeers ( ctx  context . Context )  error  {  
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objAPI  :=  newObjectLayerFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRObjectLayerNotReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buckets ,  err  :=  objAPI . ListBuckets ( ctx ,  BucketOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  _ ,  bucketInfo  :=  range  buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucket  :=  bucketInfo . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										meta ,  err  :=  globalBucketMetadataSys . GetConfigFromDisk ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  &&  ! errors . Is ( err ,  errConfigNotFound )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-23 03:05:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										opts  :=  MakeBucketOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											LockEnabled :  meta . ObjectLocking ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CreatedAt :    bucketInfo . Created . UTC ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Now call the MakeBucketHook on existing bucket - this will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// create buckets and replication rules on peer clusters.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  c . MakeBucketHook ( ctx ,  bucket ,  opts ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  errSRBucketConfigError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate bucket policy if present.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										policyJSON ,  tm  :=  meta . PolicyConfigJSON ,  meta . PolicyConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( policyJSON )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											err  =  c . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Type :       madmin . SRBucketMetaTypePolicy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Policy :     policyJSON , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UpdatedAt :  tm , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRBucketMetaError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate bucket tags if present.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tagCfg ,  tm  :=  meta . TaggingConfigXML ,  meta . TaggingConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( tagCfg )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											tagCfgStr  :=  base64 . StdEncoding . EncodeToString ( tagCfg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  c . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Type :       madmin . SRBucketMetaTypeTags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Tags :       & tagCfgStr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UpdatedAt :  tm , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRBucketMetaError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate object-lock config if present.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objLockCfgData ,  tm  :=  meta . ObjectLockConfigXML ,  meta . ObjectLockConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( objLockCfgData )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											objLockStr  :=  base64 . StdEncoding . EncodeToString ( objLockCfgData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  c . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Type :       madmin . SRBucketMetaTypeObjectLockConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Tags :       & objLockStr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UpdatedAt :  tm , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRBucketMetaError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate existing bucket bucket encryption settings
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sseConfigData ,  tm  :=  meta . EncryptionConfigXML ,  meta . EncryptionConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( sseConfigData )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											sseConfigStr  :=  base64 . StdEncoding . EncodeToString ( sseConfigData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  c . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :       madmin . SRBucketMetaTypeSSEConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SSEConfig :  & sseConfigStr , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  tm , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRBucketMetaError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										quotaConfigJSON ,  tm  :=  meta . QuotaConfigJSON ,  meta . QuotaConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( quotaConfigJSON )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  c . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Type :       madmin . SRBucketMetaTypeQuotaConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Quota :      quotaConfigJSON , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UpdatedAt :  tm , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRBucketMetaError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Order matters from now on how the information is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// synced to remote sites.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Policies should be synced first.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate IAM policies on local to all peers.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										allPolicyDocs ,  err  :=  globalIAMSys . ListPolicyDocs ( ctx ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  pname ,  pdoc  :=  range  allPolicyDocs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											policyJSON ,  err  :=  json . Marshal ( pdoc . Policy ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Type :       madmin . SRIAMItemPolicy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Name :       pname , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Policy :     policyJSON , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UpdatedAt :  pdoc . UpdateDate , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRIAMError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Next should be userAccounts those are local users, OIDC and LDAP will not
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// may not have any local users.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										userAccounts  :=  make ( map [ string ] UserIdentity ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  globalIAMSys . store . loadUsers ( ctx ,  regUser ,  userAccounts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  acc  :=  range  userAccounts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemIAMUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IAMUser :  & madmin . SRIAMUser { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													AccessKey :    acc . Credentials . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													IsDeleteReq :  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													UserReq :  & madmin . AddOrUpdateUserReq { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														SecretKey :  acc . Credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Status :     madmin . AccountStatus ( acc . Credentials . Status ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  acc . UpdatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  errSRIAMError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Next should be Groups for some of these users, LDAP might have some Group
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// DNs here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										groups  :=  make ( map [ string ] GroupInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  globalIAMSys . store . loadGroups ( ctx ,  groups ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  gname ,  group  :=  range  groups  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemGroupInfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												GroupInfo :  & madmin . SRGroupInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													UpdateReq :  madmin . GroupAddRemove { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Group :     gname , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Members :   group . Members , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Status :    madmin . GroupStatus ( group . Status ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														IsRemove :  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  group . UpdatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  errSRIAMError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Followed by group policy mapping
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate policy mappings on local to all peers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										groupPolicyMap  :=  make ( map [ string ] MappedPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errG  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  unknownIAMUserType ,  true ,  groupPolicyMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  errG  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( errG ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  group ,  mp  :=  range  groupPolicyMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemPolicyMapping , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PolicyMapping :  & madmin . SRPolicyMapping { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													UserOrGroup :  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													UserType :     - 1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													IsGroup :      true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Policy :       mp . Policies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UpdatedAt :  mp . UpdatedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRIAMError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Service accounts are the static accounts that should be synced with
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// valid claims.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										serviceAccounts  :=  make ( map [ string ] UserIdentity ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										err  :=  globalIAMSys . store . loadUsers ( ctx ,  svcUser ,  serviceAccounts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										for  user ,  acc  :=  range  serviceAccounts  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 07:52:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  user  ==  siteReplicatorSvcAcc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// skip the site replicate svc account as it is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// already replicated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											claims ,  err  :=  globalIAMSys . GetClaimsForSvcAcc ( ctx ,  acc . Credentials . AccessKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_ ,  policy ,  err  :=  globalIAMSys . GetServiceAccount ( ctx ,  acc . Credentials . AccessKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											var  policyJSON  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  policy  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												policyJSON ,  err  =  json . Marshal ( policy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											err  =  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemSvcAcc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SvcAccChange :  & madmin . SRSvcAccChange { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Create :  & madmin . SRSvcAccCreate { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Parent :         acc . Credentials . ParentUser , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														AccessKey :      user , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														SecretKey :      acc . Credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Groups :         acc . Credentials . Groups , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														Claims :         claims , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														SessionPolicy :  json . RawMessage ( policyJSON ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Status :         acc . Credentials . Status , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 08:05:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Name :           acc . Credentials . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Description :    acc . Credentials . Description , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 02:10:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Expiration :     & acc . Credentials . Expiration , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  acc . UpdatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRIAMError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Followed by policy mapping for the userAccounts we previously synced.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate policy mappings on local to all peers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										userPolicyMap  :=  make ( map [ string ] MappedPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errU  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  regUser ,  false ,  userPolicyMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  errU  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( errU ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  user ,  mp  :=  range  userPolicyMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemPolicyMapping , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PolicyMapping :  & madmin . SRPolicyMapping { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													UserOrGroup :  user , 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													UserType :     int ( regUser ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													IsGroup :      false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Policy :       mp . Policies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  mp . UpdatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRIAMError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// and finally followed by policy mappings for for STS users.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate policy mappings on local to all peers.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										stsPolicyMap  :=  make ( map [ string ] MappedPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errU  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  stsUser ,  false ,  stsPolicyMap ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  errU  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRBackendIssue ( errU ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  user ,  mp  :=  range  stsPolicyMap  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemPolicyMapping , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PolicyMapping :  & madmin . SRPolicyMapping { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													UserOrGroup :  user , 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													UserType :     int ( stsUser ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													IsGroup :      false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Policy :       mp . Policies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  mp . UpdatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  errSRIAMError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Concurrency helpers
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  concErr  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errMap      map [ string ] error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									summaryErr  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  concErr )  Error ( )  string  {  
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . summaryErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  c . summaryErr . Error ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  "<nil>" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  concErr )  Unwrap ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  c . summaryErr 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  toErrorFromErrMap ( errMap  map [ string ] error ,  actionName  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  len ( errMap )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  success  int 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									msgs  :=  [ ] string { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  d ,  err  :=  range  errMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										name  :=  c . state . Peers [ d ] . Name 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											msgs  =  append ( msgs ,  fmt . Sprintf ( "'%s' on site %s (%s): succeeded" ,  actionName ,  name ,  d ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											success ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											msgs  =  append ( msgs ,  fmt . Sprintf ( "'%s' on site %s (%s): failed(%v)" ,  actionName ,  name ,  d ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  success  ==  len ( errMap )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fmt . Errorf ( "Site replication error(s): \n%s" ,  strings . Join ( msgs ,  "\n" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  newConcErr ( errMap  map [ string ] error ,  actionName  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  concErr { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errMap :      errMap , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										summaryErr :  c . toErrorFromErrMap ( errMap ,  actionName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// concDo calls actions concurrently. selfActionFn is run for the current
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// cluster and peerActionFn is run for each peer replication cluster.
  
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  concDo ( selfActionFn  func ( )  error ,  peerActionFn  func ( deploymentID  string ,  p  madmin . PeerInfo )  error ,  actionName  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									depIDs  :=  make ( [ ] string ,  0 ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  d  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										depIDs  =  append ( depIDs ,  d ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errs  :=  make ( [ ] error ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									wg . Add ( len ( depIDs ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  i  :=  range  depIDs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  func ( i  int )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											defer  wg . Done ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  depIDs [ i ]  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  selfActionFn  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													errs [ i ]  =  selfActionFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												errs [ i ]  =  peerActionFn ( depIDs [ i ] ,  c . state . Peers [ depIDs [ i ] ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errMap  :=  make ( map [ string ] error ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  depID  :=  range  depIDs  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										errMap [ depID ]  =  errs [ i ] 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  c . newConcErr ( errMap ,  actionName ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  annotateErr ( annotation  string ,  err  error )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  fmt . Errorf ( "%s: %s: %w" ,  c . state . Name ,  annotation ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  annotatePeerErr ( dstPeer  string ,  annotation  string ,  err  error )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  fmt . Errorf ( "%s->%s: %s: %w" ,  c . state . Name ,  dstPeer ,  annotation ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 02:37:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// isEnabled returns true if site replication is enabled
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  isEnabled ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  c . enabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-19 02:10:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  errMissingSRConfig  =  fmt . Errorf ( "unable to find site replication configuration" )  
						 
					
						
							
								
									
										
										
										
											2022-05-07 03:40:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RemovePeerCluster - removes one or more clusters from site replication configuration.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  RemovePeerCluster ( ctx  context . Context ,  objectAPI  ObjectLayer ,  rreq  madmin . SRRemoveReq )  ( st  madmin . ReplicateRemoveStatus ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . isEnabled ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  st ,  errSRNotEnabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info ,  err  :=  c . GetClusterInfo ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  st ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									peerMap  :=  make ( map [ string ] madmin . PeerInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  rmvEndpoints  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									siteNames  :=  rreq . SiteNames 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									updatedPeers  :=  make ( map [ string ] madmin . PeerInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  pi  :=  range  info . Sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										updatedPeers [ pi . DeploymentID ]  =  pi 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerMap [ pi . Name ]  =  pi 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rreq . RemoveAll  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											siteNames  =  append ( siteNames ,  pi . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  s  :=  range  siteNames  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pinfo ,  ok  :=  peerMap [ s ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 03:40:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  st ,  errSRConfigMissingError ( errMissingSRConfig ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rmvEndpoints  =  append ( rmvEndpoints ,  pinfo . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delete ( updatedPeers ,  pinfo . DeploymentID ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errs  :=  make ( map [ string ] error ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  info . Sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  v . DeploymentID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  :=  c . RemoveRemoteTargetsForEndpoint ( ctx ,  objectAPI ,  rmvEndpoints ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												errs [ globalDeploymentID ]  =  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  func ( pi  madmin . PeerInfo )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											admClient ,  err  :=  c . getAdminClient ( ctx ,  pi . DeploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												errs [ pi . DeploymentID ]  =  errSRPeerResp ( fmt . Errorf ( "unable to create admin client for %s: %w" ,  pi . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// set the requesting site's deploymentID for verification of peer request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rreq . RequestingDepID  =  globalDeploymentID 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  =  admClient . SRPeerRemove ( ctx ,  rreq ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-19 02:10:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  errors . Is ( err ,  errMissingSRConfig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// ignore if peer is already removed.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 03:40:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												errs [ pi . DeploymentID ]  =  errSRPeerResp ( fmt . Errorf ( "unable to update peer %s: %w" ,  pi . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 05:32:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errdID  :=  "" 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									selfTgtsDeleted  :=  errs [ globalDeploymentID ]  ==  nil  // true if all remote targets and replication config cleared successfully on local cluster
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  dID ,  err  :=  range  errs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! rreq . RemoveAll  &&  ! selfTgtsDeleted  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 05:32:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  madmin . ReplicateRemoveStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Status :     madmin . ReplicateRemoveStatusPartial , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ,  errSRPeerResp ( fmt . Errorf ( "unable to update peer %s: %w" ,  c . state . Peers [ dID ] . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											errdID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// force local config to be cleared even if peers failed since the remote targets are deleted
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// by now from the replication config and user intended to forcibly clear all site replication
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rreq . RemoveAll  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  c . removeFromDisk ( ctx ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  madmin . ReplicateRemoveStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Status :     madmin . ReplicateRemoveStatusPartial , 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 05:32:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ErrDetail :  fmt . Sprintf ( "unable to remove cluster-replication state on local: %v" ,  err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 05:32:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  errdID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  errs [ errdID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  madmin . ReplicateRemoveStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Status :     madmin . ReplicateRemoveStatusPartial , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateRemoveStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Status :  madmin . ReplicateRemoveStatusSuccess , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 05:32:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Update cluster state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  state  srState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( updatedPeers )  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state  =  srState { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Name :                     info . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Peers :                    updatedPeers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ServiceAccountAccessKey :  info . ServiceAccountAccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  c . saveToDisk ( ctx ,  state ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateRemoveStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Status :     madmin . ReplicateRemoveStatusPartial , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ErrDetail :  fmt . Sprintf ( "unable to save cluster-replication state on local: %v" ,  err ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									st  =  madmin . ReplicateRemoveStatus { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Status :  madmin . ReplicateRemoveStatusSuccess , 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  errs [ errdID ]  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										st . Status  =  madmin . ReplicateRemoveStatusPartial 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										st . ErrDetail  =  errs [ errdID ] . Error ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  st ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// InternalRemoveReq - sends an unlink request to peer cluster to remove one or more sites
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// from the site replication configuration.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  InternalRemoveReq ( ctx  context . Context ,  objectAPI  ObjectLayer ,  rreq  madmin . SRRemoveReq )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-05-07 03:40:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! c . isEnabled ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRNotEnabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-22 17:31:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  rreq . RequestingDepID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// validate if requesting site is still part of site replication
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  foundRequestor  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  p  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  p . DeploymentID  ==  rreq . RequestingDepID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												foundRequestor  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! foundRequestor  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  errSRRequestorNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 03:40:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ourName  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									peerMap  :=  make ( map [ string ] madmin . PeerInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									updatedPeers  :=  make ( map [ string ] madmin . PeerInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									siteNames  :=  rreq . SiteNames 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  p  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerMap [ p . Name ]  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  p . DeploymentID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ourName  =  p . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										updatedPeers [ p . DeploymentID ]  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rreq . RemoveAll  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											siteNames  =  append ( siteNames ,  p . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  rmvEndpoints  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  unlinkSelf  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  s  :=  range  siteNames  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info ,  ok  :=  peerMap [ s ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 03:40:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  errMissingSRConfig 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  info . DeploymentID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unlinkSelf  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delete ( updatedPeers ,  info . DeploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rmvEndpoints  =  append ( rmvEndpoints ,  info . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  c . RemoveRemoteTargetsForEndpoint ( ctx ,  objectAPI ,  rmvEndpoints ,  unlinkSelf ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  state  srState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! unlinkSelf  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state  =  srState { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Name :                     c . state . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Peers :                    updatedPeers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ServiceAccountAccessKey :  c . state . ServiceAccountAccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  c . saveToDisk ( ctx ,  state ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-05 07:10:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  errSRBackendIssue ( fmt . Errorf ( "unable to save cluster-replication state to drive on %s: %v" ,  ourName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// RemoveRemoteTargetsForEndpoint removes replication targets corresponding to endpoint
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  RemoveRemoteTargetsForEndpoint ( ctx  context . Context ,  objectAPI  ObjectLayer ,  endpoints  [ ] string ,  unlinkSelf  bool )  ( err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									targets  :=  globalBucketTargetSys . ListTargets ( ctx ,  "" ,  string ( madmin . ReplicationService ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m  :=  make ( map [ string ] madmin . BucketTarget ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  t  :=  range  targets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  endpoint  :=  range  endpoints  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ep ,  _  :=  url . Parse ( endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  t . Endpoint  ==  ep . Host  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Secure  ==  ( ep . Scheme  ==  "https" )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Type  ==  madmin . ReplicationService  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												m [ t . Arn ]  =  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// all remote targets from self are to be delinked
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  unlinkSelf  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m [ t . Arn ]  =  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									buckets ,  err  :=  objectAPI . ListBuckets ( ctx ,  BucketOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  b  :=  range  buckets  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										config ,  _ ,  err  :=  globalBucketMetadataSys . GetReplicationConfig ( ctx ,  b . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 05:11:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  errors . Is ( err ,  BucketReplicationConfigNotFound { Bucket :  b . Name } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  nRules  [ ] sreplication . Rule 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  r  :=  range  config . Rules  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  ok  :=  m [ r . Destination . Bucket ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nRules  =  append ( nRules ,  r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( nRules )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											config . Rules  =  nRules 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											configData ,  err  :=  xml . Marshal ( config ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  b . Name ,  bucketReplicationConfig ,  configData ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 08:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  :=  globalBucketMetadataSys . Delete ( ctx ,  b . Name ,  bucketReplicationConfig ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  arn ,  t  :=  range  m  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  globalBucketTargetSys . RemoveTarget ( ctx ,  t . SourceBucket ,  arn ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 05:11:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  errors . Is ( err ,  BucketRemoteTargetNotFound { Bucket :  t . SourceBucket } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 01:19:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										targets ,  terr  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  t . SourceBucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  terr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tgtBytes ,  terr  :=  json . Marshal ( & targets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  terr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  t . SourceBucket ,  bucketTargetsFile ,  tgtBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 09:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Other helpers
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getAdminClient ( endpoint ,  accessKey ,  secretKey  string )  ( * madmin . AdminClient ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-08-09 02:12:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									epURL ,  err  :=  url . Parse ( endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-17 08:46:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalBucketTargetSys . isOffline ( epURL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  RemoteTargetConnectionErr { Endpoint :  epURL . String ( ) ,  Err :  fmt . Errorf ( "remote target is offline for endpoint %s" ,  epURL . String ( ) ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									client ,  err  :=  madmin . New ( epURL . Host ,  accessKey ,  secretKey ,  epURL . Scheme  ==  "https" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-23 07:28:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									client . SetCustomTransport ( globalRemoteTargetTransport ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  client ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getS3Client ( pc  madmin . PeerSite )  ( * minioClient . Client ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-01-20 12:02:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ep ,  err  :=  url . Parse ( pc . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-17 08:46:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalBucketTargetSys . isOffline ( ep )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  RemoteTargetConnectionErr { Endpoint :  ep . String ( ) ,  Err :  fmt . Errorf ( "remote target is offline for endpoint %s" ,  ep . String ( ) ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  minioClient . New ( ep . Host ,  & minioClient . Options { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Creds :      credentials . NewStaticV4 ( pc . AccessKey ,  pc . SecretKey ,  "" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Secure :     ep . Scheme  ==  "https" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-23 07:28:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Transport :  globalRemoteTargetTransport , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getPriorityHelper ( replicationConfig  replication . Config )  int  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									maxPrio  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  rule  :=  range  replicationConfig . Rules  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rule . Priority  >  maxPrio  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maxPrio  =  rule . Priority 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// leave some gaps in priority numbers for flexibility
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  maxPrio  +  10 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-12-01 05:16:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// returns a slice with site names participating in site replciation but unspecified while adding
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// a new site.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getMissingSiteNames ( oldDeps ,  newDeps  set . StringSet ,  currSites  [ ] madmin . PeerInfo )  [ ] string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									diff  :=  oldDeps . Difference ( newDeps ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  diffSlc  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  currSites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff . Contains ( v . DeploymentID )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											diffSlc  =  append ( diffSlc ,  v . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  diffSlc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srBucketMetaInfo  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . SRBucketInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DeploymentID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srPolicy  struct  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									madmin . SRIAMPolicy 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DeploymentID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  srPolicyMapping  struct  {  
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									madmin . SRPolicyMapping 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DeploymentID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  srUserInfo  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . UserInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DeploymentID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srGroupDesc  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . GroupDesc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DeploymentID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// SiteReplicationStatus returns the site replication status across clusters participating in site replication.
  
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  SiteReplicationStatus ( ctx  context . Context ,  objAPI  ObjectLayer ,  opts  madmin . SRStatusOptions )  ( info  madmin . SRStatusInfo ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sinfo ,  err  :=  c . siteReplicationStatus ( ctx ,  objAPI ,  opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info  =  madmin . SRStatusInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Enabled :       sinfo . Enabled , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MaxBuckets :    sinfo . MaxBuckets , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MaxUsers :      sinfo . MaxUsers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MaxGroups :     sinfo . MaxGroups , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MaxPolicies :   sinfo . MaxPolicies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Sites :         sinfo . Sites , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										StatsSummary :  sinfo . StatsSummary , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . BucketStats  =  make ( map [ string ] map [ string ] madmin . SRBucketStatsSummary ,  len ( sinfo . Sites ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									numSites  :=  len ( info . Sites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  b ,  stat  :=  range  sinfo . BucketStats  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  dID ,  st  :=  range  stat  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  st . TagMismatch  || 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												st . VersioningConfigMismatch  || 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												st . OLockConfigMismatch  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												st . SSEConfigMismatch  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												st . PolicyMismatch  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												st . ReplicationCfgMismatch  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												st . QuotaCfgMismatch  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												opts . Entity  ==  madmin . SRBucketEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  info . BucketStats [ b ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													info . BucketStats [ b ]  =  make ( map [ string ] madmin . SRBucketStatsSummary ,  numSites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . BucketStats [ b ] [ dID ]  =  st . SRBucketStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  u ,  stat  :=  range  sinfo . UserStats  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  dID ,  st  :=  range  stat  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  st . PolicyMismatch  ||  st . UserInfoMismatch  ||  opts . Entity  ==  madmin . SRUserEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  info . UserStats [ u ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													info . UserStats [ u ]  =  make ( map [ string ] madmin . SRUserStatsSummary ,  numSites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . UserStats [ u ] [ dID ]  =  st . SRUserStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  g ,  stat  :=  range  sinfo . GroupStats  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  dID ,  st  :=  range  stat  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  st . PolicyMismatch  ||  st . GroupDescMismatch  ||  opts . Entity  ==  madmin . SRGroupEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  info . GroupStats [ g ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													info . GroupStats [ g ]  =  make ( map [ string ] madmin . SRGroupStatsSummary ,  numSites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . GroupStats [ g ] [ dID ]  =  st . SRGroupStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  p ,  stat  :=  range  sinfo . PolicyStats  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  dID ,  st  :=  range  stat  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  st . PolicyMismatch  ||  opts . Entity  ==  madmin . SRPolicyEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  info . PolicyStats [ p ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													info . PolicyStats [ p ]  =  make ( map [ string ] madmin . SRPolicyStatsSummary ,  numSites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . PolicyStats [ p ] [ dID ]  =  st . SRPolicyStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									replicationStatus  =  "ReplicationStatus" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// siteReplicationStatus returns the site replication status across clusters participating in site replication.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  siteReplicationStatus ( ctx  context . Context ,  objAPI  ObjectLayer ,  opts  madmin . SRStatusOptions )  ( info  srStatusInfo ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sris  :=  make ( [ ] madmin . SRInfo ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									depIdx  :=  make ( map [ string ] int ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									i  :=  0 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  d  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										depIdx [ d ]  =  i 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										i ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									metaInfoConcErr  :=  c . concDo ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										func ( )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											srInfo ,  err  :=  c . SiteReplicationMetaInfo ( ctx ,  objAPI ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sris [ depIdx [ globalDeploymentID ] ]  =  srInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										func ( deploymentID  string ,  p  madmin . PeerInfo )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											admClient ,  err  :=  c . getAdminClient ( ctx ,  deploymentID ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											srInfo ,  err  :=  admClient . SRMetaInfo ( ctx ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sris [ depIdx [ deploymentID ] ]  =  srInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										replicationStatus , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  errors . Unwrap ( metaInfoConcErr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-21 07:20:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									info . Enabled  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . Sites  =  make ( map [ string ] madmin . PeerInfo ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  d ,  peer  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info . Sites [ d ]  =  peer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  maxBuckets  int 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  sri  :=  range  sris  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  len ( sri . Buckets )  >  maxBuckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maxBuckets  =  len ( sri . Buckets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// mapping b/w entity and entity config across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketStats  :=  make ( map [ string ] [ ] srBucketMetaInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policyStats  :=  make ( map [ string ] [ ] srPolicy ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									userPolicyStats  :=  make ( map [ string ] [ ] srPolicyMapping ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									groupPolicyStats  :=  make ( map [ string ] [ ] srPolicyMapping ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									userInfoStats  :=  make ( map [ string ] [ ] srUserInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									groupDescStats  :=  make ( map [ string ] [ ] srGroupDesc ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									numSites  :=  len ( sris ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									allBuckets  :=  set . NewStringSet ( )  // across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									allUsers  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									allUserWPolicies  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									allGroups  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									allGroupWPolicies  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									allPolicies  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  sri  :=  range  sris  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  b  :=  range  sri . Buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allBuckets . Add ( b ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  u  :=  range  sri . UserInfoMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allUsers . Add ( u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  g  :=  range  sri . GroupDescMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allGroups . Add ( g ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  p  :=  range  sri . Policies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allPolicies . Add ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  u  :=  range  sri . UserPolicies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allUserWPolicies . Add ( u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  g  :=  range  sri . GroupPolicies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allGroupWPolicies . Add ( g ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  sri  :=  range  sris  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  b  :=  range  allBuckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  ok  :=  bucketStats [ b ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketStats [ b ]  =  make ( [ ] srBucketMetaInfo ,  numSites ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											si ,  ok  :=  sri . Buckets [ b ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												si  =  madmin . SRBucketInfo { Bucket :  b } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketStats [ b ] [ i ]  =  srBucketMetaInfo { SRBucketInfo :  si ,  DeploymentID :  sri . DeploymentID } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  pname  :=  range  allPolicies  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  policyStats [ pname ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												policyStats [ pname ]  =  make ( [ ] srPolicy ,  numSites ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// if pname is not present in the map, the zero value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// will be returned.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pi  :=  sri . Policies [ pname ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											policyStats [ pname ] [ i ]  =  srPolicy { SRIAMPolicy :  pi ,  DeploymentID :  sri . DeploymentID } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  user  :=  range  allUserWPolicies  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  userPolicyStats [ user ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												userPolicyStats [ user ]  =  make ( [ ] srPolicyMapping ,  numSites ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											up  :=  sri . UserPolicies [ user ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											userPolicyStats [ user ] [ i ]  =  srPolicyMapping { SRPolicyMapping :  up ,  DeploymentID :  sri . DeploymentID } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  group  :=  range  allGroupWPolicies  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  groupPolicyStats [ group ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												groupPolicyStats [ group ]  =  make ( [ ] srPolicyMapping ,  numSites ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											up  :=  sri . GroupPolicies [ group ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											groupPolicyStats [ group ] [ i ]  =  srPolicyMapping { SRPolicyMapping :  up ,  DeploymentID :  sri . DeploymentID } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  u  :=  range  allUsers  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  userInfoStats [ u ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												userInfoStats [ u ]  =  make ( [ ] srUserInfo ,  numSites ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ui  :=  sri . UserInfoMap [ u ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											userInfoStats [ u ] [ i ]  =  srUserInfo { UserInfo :  ui ,  DeploymentID :  sri . DeploymentID } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  g  :=  range  allGroups  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  groupDescStats [ g ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												groupDescStats [ g ]  =  make ( [ ] srGroupDesc ,  numSites ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gd  :=  sri . GroupDescMap [ g ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											groupDescStats [ g ] [ i ]  =  srGroupDesc { GroupDesc :  gd ,  DeploymentID :  sri . DeploymentID } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									info . StatsSummary  =  make ( map [ string ] madmin . SRSiteSummary ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									info . BucketStats  =  make ( map [ string ] map [ string ] srBucketStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . PolicyStats  =  make ( map [ string ] map [ string ] srPolicyStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . UserStats  =  make ( map [ string ] map [ string ] srUserStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . GroupStats  =  make ( map [ string ] map [ string ] srGroupStatsSummary ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// collect user policy mapping replication status across sites
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . Users  ||  opts . Entity  ==  madmin . SRUserEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  u ,  pslc  :=  range  userPolicyStats  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( info . UserStats [ u ] )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . UserStats [ u ]  =  make ( map [ string ] srUserStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  policyMappings  [ ] madmin . SRPolicyMapping 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											uPolicyCount  :=  0 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												policyMappings  =  append ( policyMappings ,  ps . SRPolicyMapping ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												uPolicyCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum . TotalUserPolicyMappingCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											userPolicyMismatch  :=  ! isPolicyMappingReplicated ( uPolicyCount ,  numSites ,  policyMappings ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dID  :=  depIdx [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  hasUser  :=  sris [ dID ] . UserPolicies [ u ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . UserStats [ u ] [ ps . DeploymentID ]  =  srUserStatsSummary { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SRUserStatsSummary :  madmin . SRUserStatsSummary { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														PolicyMismatch :    userPolicyMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														HasUser :           hasUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														HasPolicyMapping :  ps . Policy  !=  "" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													userPolicy :  ps , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! userPolicyMismatch  ||  opts . Entity  !=  madmin . SRUserEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ! ps . IsGroup  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														sum . ReplicatedUserPolicyMappings ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// collect user info replication status across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  u ,  pslc  :=  range  userInfoStats  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  uiSlc  [ ] madmin . UserInfo 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											userCount  :=  0 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												uiSlc  =  append ( uiSlc ,  ps . UserInfo ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												userCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum . TotalUsersCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											userInfoMismatch  :=  ! isUserInfoReplicated ( userCount ,  numSites ,  uiSlc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dID  :=  depIdx [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  hasUser  :=  sris [ dID ] . UserInfoMap [ u ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  len ( info . UserStats [ u ] )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													info . UserStats [ u ]  =  make ( map [ string ] srUserStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												umis ,  ok  :=  info . UserStats [ u ] [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													umis  =  srUserStatsSummary { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														SRUserStatsSummary :  madmin . SRUserStatsSummary { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															HasUser :  hasUser , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												umis . UserInfoMismatch  =  userInfoMismatch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												umis . userInfo  =  ps 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . UserStats [ u ] [ ps . DeploymentID ]  =  umis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! userInfoMismatch  ||  opts . Entity  !=  madmin . SRUserEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													sum . ReplicatedUsers ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . Groups  ||  opts . Entity  ==  madmin . SRGroupEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// collect group policy mapping replication status across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  g ,  pslc  :=  range  groupPolicyStats  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  policyMappings  [ ] madmin . SRPolicyMapping 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gPolicyCount  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												policyMappings  =  append ( policyMappings ,  ps . SRPolicyMapping ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												gPolicyCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum . TotalGroupPolicyMappingCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											groupPolicyMismatch  :=  ! isPolicyMappingReplicated ( gPolicyCount ,  numSites ,  policyMappings ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( info . GroupStats [ g ] )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . GroupStats [ g ]  =  make ( map [ string ] srGroupStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dID  :=  depIdx [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  hasGroup  :=  sris [ dID ] . GroupPolicies [ g ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . GroupStats [ g ] [ ps . DeploymentID ]  =  srGroupStatsSummary { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SRGroupStatsSummary :  madmin . SRGroupStatsSummary { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														PolicyMismatch :    groupPolicyMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														HasGroup :          hasGroup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														HasPolicyMapping :  ps . Policy  !=  "" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														DeploymentID :      ps . DeploymentID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													groupPolicy :  ps , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! groupPolicyMismatch  &&  opts . Entity  !=  madmin . SRGroupEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													sum . ReplicatedGroupPolicyMappings ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// collect group desc replication status across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  g ,  pslc  :=  range  groupDescStats  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  gds  [ ] madmin . GroupDesc 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											groupCount  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												groupCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum . TotalGroupsCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												gds  =  append ( gds ,  ps . GroupDesc ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gdMismatch  :=  ! isGroupDescReplicated ( groupCount ,  numSites ,  gds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dID  :=  depIdx [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  hasGroup  :=  sris [ dID ] . GroupDescMap [ g ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  len ( info . GroupStats [ g ] )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													info . GroupStats [ g ]  =  make ( map [ string ] srGroupStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												gmis ,  ok  :=  info . GroupStats [ g ] [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													gmis  =  srGroupStatsSummary { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														SRGroupStatsSummary :  madmin . SRGroupStatsSummary { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															HasGroup :  hasGroup , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												gmis . GroupDescMismatch  =  gdMismatch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												gmis . groupDesc  =  ps 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . GroupStats [ g ] [ ps . DeploymentID ]  =  gmis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! gdMismatch  &&  opts . Entity  !=  madmin . SRGroupEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													sum . ReplicatedGroups ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												plcy ,  err  :=  iampolicy . ParseConfig ( bytes . NewReader ( [ ] byte ( ps . SRIAMPolicy . Policy ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												policies  =  append ( policies ,  plcy ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												uPolicyCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum . TotalIAMPoliciesCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( info . PolicyStats [ p ] )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . PolicyStats [ p ]  =  make ( map [ string ] srPolicyStatsSummary ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											policyMismatch  :=  ! isIAMPolicyReplicated ( uPolicyCount ,  numSites ,  policies ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  _ ,  ps  :=  range  pslc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dID  :=  depIdx [ ps . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  hasPolicy  :=  sris [ dID ] . Policies [ p ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . PolicyStats [ p ] [ ps . DeploymentID ]  =  srPolicyStatsSummary { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SRPolicyStatsSummary :  madmin . SRPolicyStatsSummary { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														PolicyMismatch :  policyMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														HasPolicy :       hasPolicy , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													policy :  ps , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  policyMismatch ,  opts . Entity  ==  madmin . SRPolicyEntity : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum  :=  info . StatsSummary [ ps . DeploymentID ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ! policyMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														sum . ReplicatedIAMPolicies ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													info . StatsSummary [ ps . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											policies  :=  make ( [ ] * bktpolicy . Policy ,  numSites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											replCfgs  :=  make ( [ ] * sreplication . Config ,  numSites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											quotaCfgs  :=  make ( [ ] * madmin . BucketQuota ,  numSites ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											sseCfgSet  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											versionCfgSet  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  tagCount ,  olockCfgCount ,  sseCfgCount ,  versionCfgCount  int 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  i ,  s  :=  range  slc  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  s . ReplicationConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cfgBytes ,  err  :=  base64 . StdEncoding . DecodeString ( * s . ReplicationConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cfg ,  err  :=  sreplication . ParseConfig ( bytes . NewReader ( cfgBytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													replCfgs [ i ]  =  cfg 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  s . Versioning  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													configData ,  err  :=  base64 . StdEncoding . DecodeString ( * s . Versioning ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													versionCfgCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ! versionCfgSet . Contains ( string ( configData ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														versionCfgSet . Add ( string ( configData ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  s . QuotaConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cfgBytes ,  err  :=  base64 . StdEncoding . DecodeString ( * s . QuotaConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cfg ,  err  :=  parseBucketQuota ( b ,  cfgBytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													quotaCfgs [ i ]  =  cfg 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  s . Tags  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													tagBytes ,  err  :=  base64 . StdEncoding . DecodeString ( * s . Tags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													tagCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ! tagSet . Contains ( string ( tagBytes ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														tagSet . Add ( string ( tagBytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  len ( s . Policy )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													plcy ,  err  :=  bktpolicy . ParseConfig ( bytes . NewReader ( s . Policy ) ,  b ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													policies [ i ]  =  plcy 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  s . ObjectLockConfig  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													configData ,  err  :=  base64 . StdEncoding . DecodeString ( * s . ObjectLockConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													olockCfgCount ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ! olockConfigSet . Contains ( string ( configData ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														olockConfigSet . Add ( string ( configData ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  s . SSEConfig  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													configData ,  err  :=  base64 . StdEncoding . DecodeString ( * s . SSEConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													sseCfgCount ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ! sseCfgSet . Contains ( string ( configData ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														sseCfgSet . Add ( string ( configData ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ss ,  ok  :=  info . StatsSummary [ s . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ss  =  madmin . SRSiteSummary { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// increment total number of replicated buckets
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  len ( slc )  ==  numSites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ss . ReplicatedBuckets ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ss . TotalBucketsCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  tagCount  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ss . TotalTagsCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  olockCfgCount  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ss . TotalLockConfigCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  sseCfgCount  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ss . TotalSSEConfigCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  versionCfgCount  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ss . TotalVersioningConfigCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  len ( policies )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ss . TotalBucketPoliciesCount ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . StatsSummary [ s . DeploymentID ]  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tagMismatch  :=  ! isReplicated ( tagCount ,  numSites ,  tagSet ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											olockCfgMismatch  :=  ! isReplicated ( olockCfgCount ,  numSites ,  olockConfigSet ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sseCfgMismatch  :=  ! isReplicated ( sseCfgCount ,  numSites ,  sseCfgSet ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											versionCfgMismatch  :=  ! isReplicated ( versionCfgCount ,  numSites ,  versionCfgSet ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											policyMismatch  :=  ! isBktPolicyReplicated ( numSites ,  policies ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											replCfgMismatch  :=  ! isBktReplCfgReplicated ( numSites ,  replCfgs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											quotaCfgMismatch  :=  ! isBktQuotaCfgReplicated ( numSites ,  quotaCfgs ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											info . BucketStats [ b ]  =  make ( map [ string ] srBucketStatsSummary ,  numSites ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  i ,  s  :=  range  slc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dIdx  :=  depIdx [ s . DeploymentID ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												var  hasBucket ,  isBucketMarkedDeleted  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bi ,  ok  :=  sris [ dIdx ] . Buckets [ s . Bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													isBucketMarkedDeleted  =  ! bi . DeletedAt . IsZero ( )  &&  ( bi . CreatedAt . IsZero ( )  ||  bi . DeletedAt . After ( bi . CreatedAt ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hasBucket  =  ! bi . CreatedAt . IsZero ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-15 05:27:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												quotaCfgSet  :=  hasBucket  &&  quotaCfgs [ i ]  !=  nil  &&  * quotaCfgs [ i ]  !=  madmin . BucketQuota { } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ss  :=  madmin . SRBucketStatsSummary { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													DeploymentID :              s . DeploymentID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													HasBucket :                 hasBucket , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													BucketMarkedDeleted :       isBucketMarkedDeleted , 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													TagMismatch :               tagMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													OLockConfigMismatch :       olockCfgMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SSEConfigMismatch :         sseCfgMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													VersioningConfigMismatch :  versionCfgMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PolicyMismatch :            policyMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ReplicationCfgMismatch :    replCfgMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													QuotaCfgMismatch :          quotaCfgMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													HasReplicationCfg :         s . ReplicationConfig  !=  nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													HasTagsSet :                s . Tags  !=  nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													HasOLockConfigSet :         s . ObjectLockConfig  !=  nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													HasPolicySet :              s . Policy  !=  nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													HasQuotaCfgSet :            quotaCfgSet , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													HasSSECfgSet :              s . SSEConfig  !=  nil , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												var  m  srBucketMetaInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  len ( bucketStats [ s . Bucket ] )  >  dIdx  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													m  =  bucketStats [ s . Bucket ] [ dIdx ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . BucketStats [ b ] [ s . DeploymentID ]  =  srBucketStatsSummary { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SRBucketStatsSummary :  ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													meta :                  m , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// no mismatch
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  s  :=  range  slc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sum  :=  info . StatsSummary [ s . DeploymentID ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! olockCfgMismatch  &&  olockCfgCount  ==  numSites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum . ReplicatedLockConfig ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! versionCfgMismatch  &&  versionCfgCount  ==  numSites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum . ReplicatedVersioningConfig ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! sseCfgMismatch  &&  sseCfgCount  ==  numSites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum . ReplicatedSSEConfig ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! policyMismatch  &&  len ( policies )  ==  numSites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum . ReplicatedBucketPolicies ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! tagMismatch  &&  tagCount  ==  numSites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sum . ReplicatedTags ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . StatsSummary [ s . DeploymentID ]  =  sum 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// maximum buckets users etc seen across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . MaxBuckets  =  len ( bucketStats ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									info . MaxUsers  =  len ( userInfoStats ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . MaxGroups  =  len ( groupDescStats ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									info . MaxPolicies  =  len ( policyStats ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// isReplicated returns true if count of replicated matches the number of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// sites and there is atmost one unique entry in the set.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isReplicated ( cntReplicated ,  total  int ,  valSet  set . StringSet )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cntReplicated  >  0  &&  cntReplicated  <  total  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( valSet )  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// mismatch - one or more sites has differing tags/policy
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// isIAMPolicyReplicated returns true if count of replicated IAM policies matches total
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// number of sites and IAM policies are identical.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isIAMPolicyReplicated ( cntReplicated ,  total  int ,  policies  [ ] * iampolicy . Policy )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cntReplicated  >  0  &&  cntReplicated  !=  total  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if policies match between sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  prev  * iampolicy . Policy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  p  :=  range  policies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  i  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! prev . Equals ( * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// isPolicyMappingReplicated returns true if count of replicated IAM policy mappings matches total
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// number of sites and IAM policy mappings are identical.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isPolicyMappingReplicated ( cntReplicated ,  total  int ,  policies  [ ] madmin . SRPolicyMapping )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cntReplicated  >  0  &&  cntReplicated  !=  total  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if policies match between sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  prev  madmin . SRPolicyMapping 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  p  :=  range  policies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  i  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  prev . IsGroup  !=  p . IsGroup  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev . Policy  !=  p . Policy  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev . UserOrGroup  !=  p . UserOrGroup  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isUserInfoReplicated ( cntReplicated ,  total  int ,  uis  [ ] madmin . UserInfo )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cntReplicated  >  0  &&  cntReplicated  !=  total  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if policies match between sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  prev  madmin . UserInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  ui  :=  range  uis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  i  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev  =  ui 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! isUserInfoEqual ( prev ,  ui )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isGroupDescReplicated ( cntReplicated ,  total  int ,  gds  [ ] madmin . GroupDesc )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cntReplicated  >  0  &&  cntReplicated  !=  total  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if policies match between sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  prev  madmin . GroupDesc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  gd  :=  range  gds  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  i  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev  =  gd 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! isGroupDescEqual ( prev ,  gd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  isBktQuotaCfgReplicated ( total  int ,  quotaCfgs  [ ] * madmin . BucketQuota )  bool  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									numquotaCfgs  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  q  :=  range  quotaCfgs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  q  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										numquotaCfgs ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-16 10:38:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  numquotaCfgs  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  numquotaCfgs  >  0  &&  numquotaCfgs  !=  total  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 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  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									numPolicies  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  p  :=  range  policies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  p  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										numPolicies ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  numPolicies  >  0  &&  numPolicies  !=  total  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if policies match between sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  prev  * bktpolicy . Policy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  p  :=  range  policies  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  p  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  i  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! prev . Equals ( * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// isBktReplCfgReplicated returns true if all the sites have same number
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// of replication rules with all replication features enabled.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isBktReplCfgReplicated ( total  int ,  cfgs  [ ] * sreplication . Config )  bool  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cntReplicated  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  c  :=  range  cfgs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  c  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cntReplicated ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cntReplicated  >  0  &&  cntReplicated  !=  total  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if policies match between sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  prev  * sreplication . Config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  c  :=  range  cfgs  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  c  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  i  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prev  =  c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( prev . Rules )  !=  len ( c . Rules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( c . Rules )  !=  total - 1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  r  :=  range  c . Rules  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! strings . HasPrefix ( r . ID ,  "site-repl-" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  r . DeleteMarkerReplication . Status  ==  sreplication . Disabled  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . DeleteReplication . Status  ==  sreplication . Disabled  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . ExistingObjectReplication . Status  ==  sreplication . Disabled  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . SourceSelectionCriteria . ReplicaModifications . Status  ==  sreplication . Disabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 13:16:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// cache of IAM info fetched in last SiteReplicationMetaInfo call
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srIAMCache  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sync . RWMutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lastUpdate  time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srIAMInfo   madmin . SRInfo  // caches IAM info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  getSRCachedIAMInfo ( )  ( info  madmin . SRInfo ,  ok  bool )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . iamMetaCache . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . iamMetaCache . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  c . iamMetaCache . lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ,  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  time . Since ( c . iamMetaCache . lastUpdate )  <  siteHealTimeInterval  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  c . iamMetaCache . srIAMInfo ,  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  info ,  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  srCacheIAMInfo ( info  madmin . SRInfo )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . iamMetaCache . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . iamMetaCache . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . iamMetaCache . srIAMInfo  =  info 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . iamMetaCache . lastUpdate  =  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// SiteReplicationMetaInfo returns the metadata info on buckets, policies etc for the replicated site
  
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  SiteReplicationMetaInfo ( ctx  context . Context ,  objAPI  ObjectLayer ,  opts  madmin . SRStatusOptions )  ( info  madmin . SRInfo ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ,  errSRObjectLayerNotReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . DeploymentID  =  globalDeploymentID 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . Buckets  ||  opts . Entity  ==  madmin . SRBucketEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buckets  [ ] BucketInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err      error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  opts . Entity  ==  madmin . SRBucketEntity  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bi ,  err  :=  objAPI . GetBucketInfo ( ctx ,  opts . EntityValue ,  BucketOptions { Deleted :  opts . ShowDeleted } ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  isErrBucketNotFound ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  info ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											buckets  =  append ( buckets ,  bi ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											buckets ,  err  =  objAPI . ListBuckets ( ctx ,  BucketOptions { Deleted :  opts . ShowDeleted } ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info . Buckets  =  make ( map [ string ] madmin . SRBucketInfo ,  len ( buckets ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  bucketInfo  :=  range  buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket  :=  bucketInfo . Name 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketExists  :=  bucketInfo . Deleted . IsZero ( )  ||  ( ! bucketInfo . Created . IsZero ( )  &&  bucketInfo . Created . After ( bucketInfo . Deleted ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bms  :=  madmin . SRBucketInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												CreatedAt :  bucketInfo . Created . UTC ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DeletedAt :  bucketInfo . Deleted . UTC ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! bucketExists  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . Buckets [ bucket ]  =  bms 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											meta ,  err  :=  globalBucketMetadataSys . GetConfigFromDisk ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  &&  ! errors . Is ( err ,  errConfigNotFound )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bms . Policy  =  meta . PolicyConfigJSON 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bms . PolicyUpdatedAt  =  meta . PolicyConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( meta . TaggingConfigXML )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tagCfgStr  :=  base64 . StdEncoding . EncodeToString ( meta . TaggingConfigXML ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . Tags  =  & tagCfgStr 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . TagConfigUpdatedAt  =  meta . TaggingConfigUpdatedAt 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( meta . VersioningConfigXML )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												versioningCfgStr  :=  base64 . StdEncoding . EncodeToString ( meta . VersioningConfigXML ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 17:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . Versioning  =  & versioningCfgStr 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . VersioningConfigUpdatedAt  =  meta . VersioningConfigUpdatedAt 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 17:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( meta . ObjectLockConfigXML )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												objLockStr  :=  base64 . StdEncoding . EncodeToString ( meta . ObjectLockConfigXML ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . ObjectLockConfig  =  & objLockStr 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . ObjectLockConfigUpdatedAt  =  meta . ObjectLockConfigUpdatedAt 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( meta . QuotaConfigJSON )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												quotaConfigStr  :=  base64 . StdEncoding . EncodeToString ( meta . QuotaConfigJSON ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . QuotaConfig  =  & quotaConfigStr 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . QuotaConfigUpdatedAt  =  meta . QuotaConfigUpdatedAt 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( meta . EncryptionConfigXML )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sseConfigStr  :=  base64 . StdEncoding . EncodeToString ( meta . EncryptionConfigXML ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . SSEConfig  =  & sseConfigStr 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . SSEConfigUpdatedAt  =  meta . EncryptionConfigUpdatedAt 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( meta . ReplicationConfigXML )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rcfgXMLStr  :=  base64 . StdEncoding . EncodeToString ( meta . ReplicationConfigXML ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . ReplicationConfig  =  & rcfgXMLStr 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bms . ReplicationConfigUpdatedAt  =  meta . ReplicationConfigUpdatedAt 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 13:44:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											info . Buckets [ bucket ]  =  bms 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 13:16:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . Users  &&  opts . Groups  &&  opts . Policies  &&  ! opts . Buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// serialize SiteReplicationMetaInfo calls - if data in cache is within
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// healing interval, avoid fetching IAM data again from disk.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  metaInfo ,  ok  :=  c . getSRCachedIAMInfo ( ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  metaInfo ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . Policies  ||  opts . Entity  ==  madmin . SRPolicyEntity  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  allPolicies  map [ string ] PolicyDoc 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  opts . Entity  ==  madmin . SRPolicyEntity  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  p ,  err  :=  globalIAMSys . store . GetPolicyDoc ( opts . EntityValue ) ;  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												allPolicies  =  map [ string ] PolicyDoc { opts . EntityValue :  p } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Replicate IAM policies on local to all peers.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 13:16:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											allPolicies ,  err  =  globalIAMSys . store . listPolicyDocs ( ctx ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										info . Policies  =  make ( map [ string ] madmin . SRIAMPolicy ,  len ( allPolicies ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  pname ,  policyDoc  :=  range  allPolicies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											policyJSON ,  err  :=  json . Marshal ( policyDoc . Policy ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											info . Policies [ pname ]  =  madmin . SRIAMPolicy { Policy :  json . RawMessage ( policyJSON ) ,  UpdatedAt :  policyDoc . UpdateDate } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . Users  ||  opts . Entity  ==  madmin . SRUserEntity  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Replicate policy mappings on local to all peers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										userPolicyMap  :=  make ( map [ string ] MappedPolicy ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  opts . Entity  ==  madmin . SRUserEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  mp ,  ok  :=  globalIAMSys . store . GetMappedPolicy ( opts . EntityValue ,  false ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												userPolicyMap [ opts . EntityValue ]  =  mp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-28 01:26:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											stsErr  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  stsUser ,  false ,  userPolicyMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  stsErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( stsErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-28 01:26:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											usrErr  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  regUser ,  false ,  userPolicyMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  usrErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( usrErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-05 01:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											svcErr  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  svcUser ,  false ,  userPolicyMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  svcErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( svcErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info . UserPolicies  =  make ( map [ string ] madmin . SRPolicyMapping ,  len ( userPolicyMap ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  user ,  mp  :=  range  userPolicyMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info . UserPolicies [ user ]  =  madmin . SRPolicyMapping { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsGroup :      false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UserOrGroup :  user , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Policy :       mp . Policies , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :    mp . UpdatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-05 01:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											userAccounts  :=  make ( map [ string ] UserIdentity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uerr  :=  globalIAMSys . store . loadUsers ( ctx ,  regUser ,  userAccounts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  uerr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( uerr ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-05 01:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											serr  :=  globalIAMSys . store . loadUsers ( ctx ,  svcUser ,  userAccounts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  serr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( serr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											terr  :=  globalIAMSys . store . loadUsers ( ctx ,  stsUser ,  userAccounts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  terr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( terr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  k ,  v  :=  range  userAccounts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  k  ==  siteReplicatorSvcAcc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// skip the site replicate svc account as it is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// already replicated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-05 01:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  v . Credentials . ParentUser  !=  ""  &&  v . Credentials . ParentUser  ==  globalActiveCred . AccessKey  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// skip all root user service accounts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-05 01:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												info . UserInfoMap [ k ]  =  madmin . UserInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Status :  madmin . AccountStatus ( v . Credentials . Status ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  opts . Groups  ||  opts . Entity  ==  madmin . SRGroupEntity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Replicate policy mappings on local to all peers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										groupPolicyMap  :=  make ( map [ string ] MappedPolicy ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-05 01:19:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  opts . Entity  ==  madmin . SRGroupEntity  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  mp ,  ok  :=  globalIAMSys . store . GetMappedPolicy ( opts . EntityValue ,  true ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												groupPolicyMap [ opts . EntityValue ]  =  mp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-28 01:26:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											stsErr  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  stsUser ,  true ,  groupPolicyMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  stsErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( stsErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-28 01:26:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											userErr  :=  globalIAMSys . store . loadMappedPolicies ( ctx ,  regUser ,  true ,  groupPolicyMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  userErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  info ,  errSRBackendIssue ( userErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										info . GroupPolicies  =  make ( map [ string ] madmin . SRPolicyMapping ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  group ,  mp  :=  range  groupPolicyMap  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											info . GroupPolicies [ group ]  =  madmin . SRPolicyMapping { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsGroup :      true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UserOrGroup :  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Policy :       mp . Policies , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :    mp . UpdatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 13:16:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											groups ,  errG  :=  globalIAMSys . store . listGroups ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 07:37:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 13:16:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// cache SR metadata info for IAM
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  opts . Users  &&  opts . Groups  &&  opts . Policies  &&  ! opts . Buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . srCacheIAMInfo ( info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-05 18:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  info ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// EditPeerCluster - edits replication configuration and updates peer endpoint.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  EditPeerCluster ( ctx  context . Context ,  peer  madmin . PeerInfo )  ( madmin . ReplicateEditStatus ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sites ,  err  :=  c . GetClusterInfo ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateEditStatus { } ,  errSRBackendIssue ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! sites . Enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateEditStatus { } ,  errSRNotEnabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										found      bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient  * madmin . AdminClient 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 03:44:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalDeploymentID  ==  peer . DeploymentID  &&  ! peer . SyncState . Empty ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateEditStatus { } ,  errSRInvalidRequest ( fmt . Errorf ( "A peer cluster, rather than the local cluster (endpoint=%s, deployment-id=%s) needs to be specified while setting a 'sync' replication mode" ,  peer . Endpoint ,  peer . DeploymentID ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  sites . Sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  peer . DeploymentID  ==  v . DeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											found  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 03:44:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! peer . SyncState . Empty ( )  &&  peer . Endpoint  ==  ""  {  // peer.Endpoint may be "" if only sync state is being updated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  peer . Endpoint  ==  v . Endpoint  &&  peer . SyncState . Empty ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  madmin . ReplicateEditStatus { } ,  errSRInvalidRequest ( fmt . Errorf ( "Endpoint %s entered for deployment id %s already configured in site replication" ,  v . Endpoint ,  v . DeploymentID ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											admClient ,  err  =  c . getAdminClientWithEndpoint ( ctx ,  v . DeploymentID ,  peer . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  madmin . ReplicateEditStatus { } ,  errSRPeerResp ( fmt . Errorf ( "unable to create admin client for %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// check if endpoint is reachable
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-04 07:23:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											info ,  err  :=  admClient . ServerInfo ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  madmin . ReplicateEditStatus { } ,  errSRInvalidRequest ( fmt . Errorf ( "Endpoint %s not reachable: %w" ,  peer . Endpoint ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  info . DeploymentID  !=  v . DeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  madmin . ReplicateEditStatus { } ,  errSRInvalidRequest ( fmt . Errorf ( "Endpoint %s does not belong to deployment expected: %s (found %s) " ,  v . Endpoint ,  v . DeploymentID ,  info . DeploymentID ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! found  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateEditStatus { } ,  errSRInvalidRequest ( fmt . Errorf ( "%s not found in existing replicated sites" ,  peer . DeploymentID ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pi  :=  c . state . Peers [ peer . DeploymentID ] 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prevPeerInfo  :=  pi 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! peer . SyncState . Empty ( )  {  // update replication to peer to be sync/async
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pi . SyncState  =  peer . SyncState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . state . Peers [ peer . DeploymentID ]  =  pi 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  peer . Endpoint  !=  ""  {  // `admin replicate update` requested an endpoint change
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pi . Endpoint  =  peer . Endpoint 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  admClient  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errs  :=  make ( map [ string ] error ,  len ( c . state . Peers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  i ,  v  :=  range  sites . Sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  v . DeploymentID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												c . state . Peers [ peer . DeploymentID ]  =  pi 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											go  func ( pi  madmin . PeerInfo ,  i  int )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												v  :=  sites . Sites [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												admClient ,  err  :=  c . getAdminClient ( ctx ,  v . DeploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  v . DeploymentID  ==  peer . DeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													admClient ,  err  =  c . getAdminClientWithEndpoint ( ctx ,  v . DeploymentID ,  peer . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													errs [ v . DeploymentID ]  =  errSRPeerResp ( fmt . Errorf ( "unable to create admin client for %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  =  admClient . SRPeerEdit ( ctx ,  pi ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													errs [ v . DeploymentID ]  =  errSRPeerResp ( fmt . Errorf ( "unable to update peer %s: %w" ,  v . Name ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ( pi ,  i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  dID ,  err  :=  range  errs  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  madmin . ReplicateEditStatus { } ,  errSRPeerResp ( fmt . Errorf ( "unable to update peer %s: %w" ,  c . state . Peers [ dID ] . Name ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// we can now save the cluster replication configuration state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  c . saveToDisk ( ctx ,  c . state ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  madmin . ReplicateEditStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Status :     madmin . ReplicateAddStatusPartial , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ErrDetail :  fmt . Sprintf ( "unable to save cluster-replication state on local: %v" ,  err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  c . updateTargetEndpoints ( ctx ,  prevPeerInfo ,  pi ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  madmin . ReplicateEditStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Status :     madmin . ReplicateAddStatusPartial , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ErrDetail :  fmt . Sprintf ( "unable to update peer targets on local: %v" ,  err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									result  :=  madmin . ReplicateEditStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Success :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Status :   fmt . Sprintf ( "Cluster replication configuration updated with endpoint %s for peer %s successfully" ,  peer . Endpoint ,  peer . Name ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  result ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  updateTargetEndpoints ( ctx  context . Context ,  prevInfo ,  peer  madmin . PeerInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objAPI  :=  newObjectLayerFn ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errSRObjectLayerNotReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buckets ,  err  :=  objAPI . ListBuckets ( ctx ,  BucketOptions { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  bucketInfo  :=  range  buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucket  :=  bucketInfo . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ep ,  _  :=  url . Parse ( peer . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prevEp ,  _  :=  url . Parse ( prevInfo . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targets ,  err  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue  // site healing will take care of configuring new targets
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  target  :=  range  targets . Targets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  target . SourceBucket  ==  bucket  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target . TargetBucket  ==  bucket  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target . Endpoint  ==  prevEp . Host  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target . Secure  ==  ( prevEp . Scheme  ==  "https" )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target . Type  ==  madmin . ReplicationService  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketTarget  :=  target 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketTarget . Secure  =  ep . Scheme  ==  "https" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketTarget . Endpoint  =  ep . Host 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-25 05:41:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! peer . SyncState . Empty ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bucketTarget . ReplicationSync  =  ( peer . SyncState  ==  madmin . SyncEnabled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												err  :=  globalBucketTargetSys . SetTarget ( ctx ,  bucket ,  & bucketTarget ,  true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													logger . LogIf ( ctx ,  c . annotatePeerErr ( peer . Name ,  "Bucket target creation error" ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												targets ,  err  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tgtBytes ,  err  :=  json . Marshal ( & targets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTargetsFile ,  tgtBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PeerEditReq - internal API handler to respond to a peer cluster's request
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to edit endpoint.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  PeerEditReq ( ctx  context . Context ,  arg  madmin . PeerInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ourName  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p  :=  c . state . Peers [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  p . DeploymentID  ==  arg . DeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p . Endpoint  =  arg . Endpoint 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . state . Peers [ arg . DeploymentID ]  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  p . DeploymentID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ourName  =  p . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  c . saveToDisk ( ctx ,  c . state ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-05 07:10:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  errSRBackendIssue ( fmt . Errorf ( "unable to save cluster-replication state to drive on %s: %v" ,  ourName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 00:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 00:09:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  siteHealTimeInterval  =  30  *  time . Second  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  startHealRoutine ( ctx  context . Context ,  objAPI  ObjectLayer )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-09 00:55:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancel  :=  globalLeaderLock . GetLock ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  cancel ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 04:46:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									healTimer  :=  time . NewTimer ( siteHealTimeInterval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  healTimer . Stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 00:09:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  maxRefreshDurationSecondsForLog  float64  =  10  // 10 seconds..
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  <- healTimer . C : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enabled  :=  c . enabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . RUnlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-19 06:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  enabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 00:09:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												refreshStart  :=  time . Now ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-19 06:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												c . healIAMSystem ( ctx ,  objAPI )  // heal IAM system first
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												c . healBuckets ( ctx ,  objAPI )    // heal buckets subsequently
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 00:09:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												took  :=  time . Since ( refreshStart ) . Seconds ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  took  >  maxRefreshDurationSecondsForLog  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Log if we took a lot of time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													logger . Info ( "Site replication healing refresh took %.2fs" ,  took ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// wait for 200 millisecond, if we are experience lot of I/O
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												waitForLowIO ( runtime . GOMAXPROCS ( 0 ) ,  200 * time . Millisecond ,  currentHTTPIO ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-19 06:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											healTimer . Reset ( siteHealTimeInterval ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srBucketStatsSummary  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . SRBucketStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									meta  srBucketMetaInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srPolicyStatsSummary  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . SRPolicyStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policy  srPolicy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srUserStatsSummary  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . SRUserStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									userInfo    srUserInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									userPolicy  srPolicyMapping 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srGroupStatsSummary  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . SRGroupStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									groupDesc    srGroupDesc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									groupPolicy  srPolicyMapping 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srStatusInfo  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// SRStatusInfo returns detailed status on site replication status
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Enabled       bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MaxBuckets    int                              // maximum buckets seen across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MaxUsers      int                              // maximum users seen across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MaxGroups     int                              // maximum groups seen across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MaxPolicies   int                              // maximum policies across sites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Sites         map [ string ] madmin . PeerInfo       // deployment->sitename
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatsSummary  map [ string ] madmin . SRSiteSummary  // map of deployment id -> site stat
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// BucketStats map of bucket to slice of deployment IDs with stats. This is populated only if there are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// mismatches or if a specific bucket's stats are requested
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketStats  map [ string ] map [ string ] srBucketStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// PolicyStats map of policy to slice of deployment IDs with stats. This is populated only if there are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// mismatches or if a specific bucket's stats are requested
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PolicyStats  map [ string ] map [ string ] srPolicyStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// UserStats map of user to slice of deployment IDs with stats. This is populated only if there are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// mismatches or if a specific bucket's stats are requested
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UserStats  map [ string ] map [ string ] srUserStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// GroupStats map of group to slice of deployment IDs with stats. This is populated only if there are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// mismatches or if a specific bucket's stats are requested
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GroupStats  map [ string ] map [ string ] srGroupStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// SRBucketDeleteOp - type of delete op
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  SRBucketDeleteOp  string  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// MarkDelete creates .minio.sys/buckets/.deleted/<bucket> vol entry to hold onto deleted bucket's state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// until peers are synced in site replication setup.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MarkDelete  SRBucketDeleteOp  =  "MarkDelete" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Purge deletes the .minio.sys/buckets/.deleted/<bucket> vol entry
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Purge  SRBucketDeleteOp  =  "Purge" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// NoOp no action needed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NoOp  SRBucketDeleteOp  =  "NoOp" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Empty returns true if this Op is not set
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  SRBucketDeleteOp )  Empty ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  string ( s )  ==  ""  ||  string ( s )  ==  string ( NoOp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getSRBucketDeleteOp ( isSiteReplicated  bool )  SRBucketDeleteOp  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! isSiteReplicated  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NoOp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  MarkDelete 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healBuckets ( ctx  context . Context ,  objAPI  ObjectLayer )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									buckets ,  err  :=  c . listBuckets ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  bi  :=  range  buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucket  :=  bi . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info ,  err  :=  c . siteReplicationStatus ( ctx ,  objAPI ,  madmin . SRStatusOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Entity :       madmin . SRBucketEntity , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EntityValue :  bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ShowDeleted :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . healBucket ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  bi . Deleted . IsZero ( )  ||  ( ! bi . Created . IsZero ( )  &&  bi . Deleted . Before ( bi . Created ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . healVersioningMetadata ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . healOLockConfigMetadata ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . healSSEMetadata ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . healBucketReplicationConfig ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . healBucketPolicies ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . healTagMetadata ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . healBucketQuotaConfig ( ctx ,  objAPI ,  bucket ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Notification and ILM are site specific settings.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healTagMetadata ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestTaggingConfig       * string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . TagConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestTaggingConfig  =  ss . meta . Tags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// avoid considering just created buckets as latest. Perhaps this site
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just joined cluster replication and yet to be sync'd
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . CreatedAt . Equal ( ss . meta . TagConfigUpdatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . TagConfigUpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . TagConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestTaggingConfig  =  ss . meta . Tags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  latestTaggingConfigBytes  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestTaggingConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestTaggingConfigBytes ,  err  =  base64 . StdEncoding . DecodeString ( * latestTaggingConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  bStatus  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bStatus . TagMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isBucketMetadataEqual ( latestTaggingConfig ,  bStatus . meta . Tags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTaggingConfig ,  latestTaggingConfigBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal tagging metadata from peer site %s : %w" ,  latestPeerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  admClient . SRPeerReplicateBucketMeta ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Type :    madmin . SRBucketMetaTypeTags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bucket :  bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Tags :    latestTaggingConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  c . annotatePeerErr ( peerName ,  replicateBucketMetadata , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Errorf ( "Unable to heal tagging metadata for peer %s from peer %s : %w" ,  peerName ,  latestPeerName ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healBucketPolicies ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestIAMPolicy           json . RawMessage 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . PolicyUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestIAMPolicy  =  ss . meta . Policy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// avoid considering just created buckets as latest. Perhaps this site
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just joined cluster replication and yet to be sync'd
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . CreatedAt . Equal ( ss . meta . PolicyUpdatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . PolicyUpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . PolicyUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestIAMPolicy  =  ss . meta . Policy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  bStatus  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bStatus . PolicyMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . EqualFold ( string ( latestIAMPolicy ) ,  string ( bStatus . meta . Policy ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketPolicyConfig ,  latestIAMPolicy ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal bucket policy metadata from peer site %s : %w" ,  latestPeerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  admClient . SRPeerReplicateBucketMeta ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Type :       madmin . SRBucketMetaTypePolicy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Policy :     latestIAMPolicy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  c . annotatePeerErr ( peerName ,  replicateBucketMetadata , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Errorf ( "Unable to heal bucket policy metadata for peer %s from peer %s : %w" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													peerName ,  latestPeerName ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healBucketQuotaConfig ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestQuotaConfig         * string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestQuotaConfigBytes    [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . QuotaConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestQuotaConfig  =  ss . meta . QuotaConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// avoid considering just created buckets as latest. Perhaps this site
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just joined cluster replication and yet to be sync'd
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . CreatedAt . Equal ( ss . meta . QuotaConfigUpdatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . QuotaConfigUpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . QuotaConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestQuotaConfig  =  ss . meta . QuotaConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestQuotaConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestQuotaConfigBytes ,  err  =  base64 . StdEncoding . DecodeString ( * latestQuotaConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  bStatus  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bStatus . QuotaCfgMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isBucketMetadataEqual ( latestQuotaConfig ,  bStatus . meta . QuotaConfig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketQuotaConfigFile ,  latestQuotaConfigBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal quota metadata from peer site %s : %w" ,  latestPeerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  admClient . SRPeerReplicateBucketMeta ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Type :       madmin . SRBucketMetaTypeQuotaConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Quota :      latestQuotaConfigBytes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  c . annotatePeerErr ( peerName ,  replicateBucketMetadata , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Errorf ( "Unable to heal quota config metadata for peer %s from peer %s : %w" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													peerName ,  latestPeerName ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healVersioningMetadata ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestVersioningConfig    * string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . VersioningConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestVersioningConfig  =  ss . meta . Versioning 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// avoid considering just created buckets as latest. Perhaps this site
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just joined cluster replication and yet to be sync'd
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . CreatedAt . Equal ( ss . meta . VersioningConfigUpdatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . VersioningConfigUpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . VersioningConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestVersioningConfig  =  ss . meta . Versioning 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  latestVersioningConfigBytes  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestVersioningConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestVersioningConfigBytes ,  err  =  base64 . StdEncoding . DecodeString ( * latestVersioningConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  bStatus  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bStatus . VersioningConfigMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isBucketMetadataEqual ( latestVersioningConfig ,  bStatus . meta . Versioning )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketVersioningConfig ,  latestVersioningConfigBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal versioning metadata from peer site %s : %w" ,  latestPeerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  admClient . SRPeerReplicateBucketMeta ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Type :        madmin . SRBucketMetaTypeVersionConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bucket :      bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Versioning :  latestVersioningConfig , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											UpdatedAt :   lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  c . annotatePeerErr ( peerName ,  replicateBucketMetadata , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Errorf ( "Unable to heal versioning config metadata for peer %s from peer %s : %w" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													peerName ,  latestPeerName ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 09:39:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healSSEMetadata ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestSSEConfig           * string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . SSEConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestSSEConfig  =  ss . meta . SSEConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// avoid considering just created buckets as latest. Perhaps this site
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just joined cluster replication and yet to be sync'd
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . CreatedAt . Equal ( ss . meta . SSEConfigUpdatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . SSEConfigUpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . SSEConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestSSEConfig  =  ss . meta . SSEConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  latestSSEConfigBytes  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestSSEConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestSSEConfigBytes ,  err  =  base64 . StdEncoding . DecodeString ( * latestSSEConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  bStatus  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bStatus . SSEConfigMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isBucketMetadataEqual ( latestSSEConfig ,  bStatus . meta . SSEConfig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketSSEConfig ,  latestSSEConfigBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal sse metadata from peer site %s : %w" ,  latestPeerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  admClient . SRPeerReplicateBucketMeta ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Type :       madmin . SRBucketMetaTypeSSEConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SSEConfig :  latestSSEConfig , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  c . annotatePeerErr ( peerName ,  replicateBucketMetadata , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Errorf ( "Unable to heal SSE config metadata for peer %s from peer %s : %w" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													peerName ,  latestPeerName ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healOLockConfigMetadata ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestObjLockConfig       * string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . ObjectLockConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestObjLockConfig  =  ss . meta . ObjectLockConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// avoid considering just created buckets as latest. Perhaps this site
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just joined cluster replication and yet to be sync'd
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . CreatedAt . Equal ( ss . meta . ObjectLockConfigUpdatedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . meta . ObjectLockConfig  !=  nil  &&  ss . meta . ObjectLockConfigUpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . meta . ObjectLockConfigUpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestObjLockConfig  =  ss . meta . ObjectLockConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  latestObjLockConfigBytes  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestObjLockConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestObjLockConfigBytes ,  err  =  base64 . StdEncoding . DecodeString ( * latestObjLockConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  bStatus  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bStatus . OLockConfigMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isBucketMetadataEqual ( latestObjLockConfig ,  bStatus . meta . ObjectLockConfig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  objectLockConfig ,  latestObjLockConfigBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal objectlock config metadata from peer site %s : %w" ,  latestPeerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  wrapSRErr ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  admClient . SRPeerReplicateBucketMeta ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Type :       madmin . SRBucketMetaTypeObjectLockConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Tags :       latestObjLockConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  c . annotatePeerErr ( peerName ,  replicateBucketMetadata , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Errorf ( "Unable to heal object lock config metadata for peer %s from peer %s : %w" , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													peerName ,  latestPeerName ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  purgeDeletedBucket ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									z ,  ok  :=  objAPI . ( * erasureServerPools ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 22:07:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									z . s3Peer . DeleteBucket ( context . Background ( ) ,  pathJoin ( minioMetaBucket ,  bucketMetaPrefix ,  deletedBucketsPrefix ,  bucket ) ,  DeleteBucketOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// healBucket creates/deletes the bucket according to latest state across clusters participating in site replication.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healBucket ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									numSites  :=  len ( c . state . Peers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mostRecent  :=  func ( d1 ,  d2  time . Time )  time . Time  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  d1 . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  d2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  d2 . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  d1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  d1 . After ( d2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  d1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  d2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID    string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate  time . Time 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										withB       [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										missingB    [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										deletedCnt  int 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											lastUpdate  =  mostRecent ( ss . meta . CreatedAt ,  ss . meta . DeletedAt ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										recentUpdt  :=  mostRecent ( ss . meta . CreatedAt ,  ss . meta . DeletedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  recentUpdt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  recentUpdt 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ss . BucketMarkedDeleted  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											deletedCnt ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . HasBucket  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											withB  =  append ( withB ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											missingB  =  append ( missingB ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latestPeerName  :=  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bStatus  :=  info . BucketStats [ bucket ] [ latestID ] . meta 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									isMakeBucket  :=  len ( missingB )  >  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									deleteOp  :=  NoOp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestID  !=  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  lastUpdate . Equal ( bStatus . DeletedAt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										isMakeBucket  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  len ( withB )  ==  numSites  &&  deletedCnt  ==  numSites : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											deleteOp  =  NoOp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  len ( withB )  ==  0  &&  len ( missingB )  ==  numSites : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											deleteOp  =  Purge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											deleteOp  =  MarkDelete 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isMakeBucket  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  opts  MakeBucketOptions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										optsMap  :=  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										optsMap [ "versioningEnabled" ]  =  "true" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										opts . VersioningEnabled  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										opts . CreatedAt  =  bStatus . CreatedAt 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 00:46:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										optsMap [ "createdAt" ]  =  bStatus . CreatedAt . UTC ( ) . Format ( time . RFC3339Nano ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  bStatus . ObjectLockConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											config ,  err  :=  base64 . StdEncoding . DecodeString ( * bStatus . ObjectLockConfig ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  bytes . Equal ( [ ] byte ( string ( config ) ) ,  enabledBucketObjectLockConfig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												optsMap [ "lockEnabled" ]  =  "true" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												opts . LockEnabled  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  dID  :=  range  missingB  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  :=  c . PeerBucketMakeWithVersioningHandler ( ctx ,  bucket ,  opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotateErr ( makeBucketWithVersion ,  fmt . Errorf ( "error healing bucket for site replication %w from %s -> %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														err ,  latestPeerName ,  peerName ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotateErr ( configureReplication ,  fmt . Errorf ( "unable to use admin client for %s: %w" ,  dID ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  =  admClient . SRPeerBucketOps ( ctx ,  bucket ,  madmin . MakeWithVersioningBktOp ,  optsMap ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotatePeerErr ( peerName ,  makeBucketWithVersion ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  =  admClient . SRPeerBucketOps ( ctx ,  bucket ,  madmin . ConfigureReplBktOp ,  nil ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotatePeerErr ( peerName ,  configureReplication ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( missingB )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// configure replication from current cluster to other clusters
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  c . PeerBucketConfigureReplHandler ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  c . annotateErr ( configureReplication ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// all buckets are marked deleted across sites at this point. It should be safe to purge the .minio.sys/buckets/.deleted/<bucket> entry
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// from disk
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  deleteOp  ==  Purge  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  dID  :=  range  missingB  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												c . purgeDeletedBucket ( ctx ,  objAPI ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotateErr ( configureReplication ,  fmt . Errorf ( "unable to use admin client for %s: %w" ,  dID ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  =  admClient . SRPeerBucketOps ( ctx ,  bucket ,  madmin . PurgeDeletedBucketOp ,  nil ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotatePeerErr ( peerName ,  deleteBucket ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Mark buckets deleted on remaining peers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  deleteOp  ==  MarkDelete  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  dID  :=  range  withB  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  :=  c . PeerBucketDeleteHandler ( ctx ,  bucket ,  DeleteBucketOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Force :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotateErr ( deleteBucket ,  fmt . Errorf ( "error healing bucket for site replication %w from %s -> %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														err ,  latestPeerName ,  peerName ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												admClient ,  err  :=  c . getAdminClient ( ctx ,  dID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotateErr ( configureReplication ,  fmt . Errorf ( "unable to use admin client for %s: %w" ,  dID ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  =  admClient . SRPeerBucketOps ( ctx ,  bucket ,  madmin . ForceDeleteBucketBktOp ,  nil ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  c . annotatePeerErr ( peerName ,  deleteBucket ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healBucketReplicationConfig ( ctx  context . Context ,  objAPI  ObjectLayer ,  bucket  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bs  :=  info . BucketStats [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  replMismatch  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  ss  :=  range  bs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ss . ReplicationCfgMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											replMismatch  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-27 08:57:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rcfg ,  _ ,  err  :=  globalBucketMetadataSys . GetReplicationConfig ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 03:34:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  ok  :=  err . ( BucketReplicationConfigNotFound ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-27 08:57:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										replMismatch  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										epDeplIDMap  =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arnTgtMap    =  make ( map [ string ] madmin . BucketTarget ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  targetsPtr ,  _  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) ;  targetsPtr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  t  :=  range  targetsPtr . Targets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arnTgtMap [ t . Arn ]  =  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  p  :=  range  c . state . Peers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										epDeplIDMap [ p . Endpoint ]  =  p . DeploymentID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// fix stale ARN's in replication config and endpoint mismatch between site config and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// targets associated to this config.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 03:34:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  rcfg  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 18:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  rule  :=  range  rcfg . Rules  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  rule . Status  !=  sreplication . Status ( replication . Disabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tgt ,  isValidARN  :=  arnTgtMap [ rule . Destination . ARN ]  // detect stale ARN in replication config
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  epFound  :=  epDeplIDMap [ tgt . URL ( ) . String ( ) ]       // detect end point change at site level
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! isValidARN  ||  ! epFound  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													replMismatch  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rcfg  !=  nil  &&  ! replMismatch  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 03:34:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// validate remote targets on current cluster for this bucket
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  apiErr  :=  validateReplicationDestination ( ctx ,  bucket ,  rcfg ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  apiErr  !=  noError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											replMismatch  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-27 08:57:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 03:34:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  replMismatch  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  c . annotateErr ( configureReplication ,  c . PeerBucketConfigureReplHandler ( ctx ,  bucket ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isBucketMetadataEqual ( one ,  two  * string )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  one  ==  nil  &&  two  ==  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  one  ==  nil  ||  two  ==  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  strings . EqualFold ( * one ,  * two ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healIAMSystem ( ctx  context . Context ,  objAPI  ObjectLayer )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info ,  err  :=  c . siteReplicationStatus ( ctx ,  objAPI ,  madmin . SRStatusOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Users :     true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Policies :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Groups :    true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  policy  :=  range  info . PolicyStats  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . healPolicies ( ctx ,  objAPI ,  policy ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  user  :=  range  info . UserStats  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . healUsers ( ctx ,  objAPI ,  user ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  group  :=  range  info . GroupStats  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . healGroups ( ctx ,  objAPI ,  group ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  user  :=  range  info . UserStats  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . healUserPolicies ( ctx ,  objAPI ,  user ,  info ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  group  :=  range  info . GroupStats  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . healGroupPolicies ( ctx ,  objAPI ,  group ,  info ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// heal iam policies present on this site to peers, provided current cluster has the most recent update.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healPolicies ( ctx  context . Context ,  objAPI  ObjectLayer ,  policy  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create IAM policy on peer cluster if missing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ps  :=  info . PolicyStats [ policy ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestPolicyStat          srPolicyStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  ps  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . policy . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestPolicyStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ss . policy . UpdatedAt . IsZero ( )  &&  ss . policy . UpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . policy . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestPolicyStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestID  !=  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// heal only from the site with latest info.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// heal policy of peers if peer does not have it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  pStatus  :=  range  ps  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! pStatus . PolicyMismatch  &&  pStatus . HasPolicy  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Type :       madmin . SRIAMItemPolicy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Name :       policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Policy :     latestPolicyStat . policy . Policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal IAM policy %s from peer site %s -> site %s : %w" ,  policy ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// heal user policy mappings present on this site to peers, provided current cluster has the most recent update.
  
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healUserPolicies ( ctx  context . Context ,  objAPI  ObjectLayer ,  user  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// create user policy mapping on peer cluster if missing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									us  :=  info . UserStats [ user ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestUserStat            srUserStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  us  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . userPolicy . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestUserStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ss . userPolicy . UpdatedAt . IsZero ( )  &&  ss . userPolicy . UpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . userPolicy . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestUserStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestID  !=  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// heal only from the site with latest info.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// heal policy of peers if peer does not have it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  pStatus  :=  range  us  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! pStatus . PolicyMismatch  &&  pStatus . HasPolicyMapping  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isPolicyMappingEqual ( pStatus . userPolicy ,  latestUserStat . userPolicy )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Type :  madmin . SRIAMItemPolicyMapping , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PolicyMapping :  & madmin . SRPolicyMapping { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UserOrGroup :  user , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsGroup :      false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Policy :       latestUserStat . userPolicy . Policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal IAM user policy mapping for %s from peer site %s -> site %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// heal group policy mappings present on this site to peers, provided current cluster has the most recent update.
  
						 
					
						
							
								
									
										
										
										
											2022-08-24 02:11:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healGroupPolicies ( ctx  context . Context ,  objAPI  ObjectLayer ,  group  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// create group policy mapping on peer cluster if missing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gs  :=  info . GroupStats [ group ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestGroupStat           srGroupStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  gs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . groupPolicy . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestGroupStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ss . groupPolicy . UpdatedAt . IsZero ( )  &&  ss . groupPolicy . UpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . groupPolicy . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestGroupStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestID  !=  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// heal only from the site with latest info.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// heal policy of peers if peer does not have it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  pStatus  :=  range  gs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! pStatus . PolicyMismatch  &&  pStatus . HasPolicyMapping  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isPolicyMappingEqual ( pStatus . groupPolicy ,  latestGroupStat . groupPolicy )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Type :  madmin . SRIAMItemPolicyMapping , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PolicyMapping :  & madmin . SRPolicyMapping { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UserOrGroup :  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsGroup :      true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Policy :       latestGroupStat . groupPolicy . Policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal IAM group policy mapping for %s from peer site %s -> site %s : %w" ,  group ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-05 01:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// heal all users and their service accounts that are present on this site,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// provided current cluster has the most recent update.
  
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healUsers ( ctx  context . Context ,  objAPI  ObjectLayer ,  user  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create user if missing; fix user policy mapping if missing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									us  :=  info . UserStats [ user ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestUserStat            srUserStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  us  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . userInfo . UserInfo . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestUserStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ss . userInfo . UserInfo . UpdatedAt . IsZero ( )  &&  ss . userInfo . UserInfo . UpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . userInfo . UserInfo . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestUserStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestID  !=  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// heal only from the site with latest info.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  uStatus  :=  range  us  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! uStatus . UserInfoMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isUserInfoEqual ( latestUserStat . userInfo . UserInfo ,  uStatus . userInfo . UserInfo )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										u ,  ok  :=  globalIAMSys . GetUser ( ctx ,  user ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creds  :=  u . Credentials 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  creds . IsServiceAccount ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											claims ,  err  :=  globalIAMSys . GetClaimsForSvcAcc ( ctx ,  creds . AccessKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal service account %s from peer site %s -> %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_ ,  policy ,  err  :=  globalIAMSys . GetServiceAccount ( ctx ,  creds . AccessKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal service account %s from peer site %s -> %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  policyJSON  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  policy  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												policyJSON ,  err  =  json . Marshal ( policy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal service account %s from peer site %s -> %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemSvcAcc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SvcAccChange :  & madmin . SRSvcAccChange { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Create :  & madmin . SRSvcAccCreate { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Parent :         creds . ParentUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														AccessKey :      creds . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														SecretKey :      creds . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Groups :         creds . Groups , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Claims :         claims , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														SessionPolicy :  json . RawMessage ( policyJSON ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Status :         creds . Status , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 08:05:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Name :           creds . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Description :    creds . Description , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 02:10:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Expiration :     & creds . Expiration , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal service account %s from peer site %s -> %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  creds . IsTemp ( )  &&  ! creds . IsExpired ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-11 08:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  parentPolicy  string 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											u ,  err  :=  globalIAMSys . GetUserInfo ( ctx ,  creds . ParentUser ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-11 08:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Parent may be "virtual" (for ldap, oidc, client tls auth,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// custom auth plugin), so in such cases we apply no parent
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// policy. The session token will contain info about policy to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// be applied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! errors . Is ( err ,  errNoSuchUser )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal temporary credentials %s from peer site %s -> %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parentPolicy  =  u . PolicyName 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Call hook for site replication.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  madmin . SRIAMItemSTSAcc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												STSCredential :  & madmin . SRSTSCredential { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													AccessKey :            creds . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SecretKey :            creds . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SessionToken :         creds . SessionToken , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ParentUser :           creds . ParentUser , 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-11 08:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ParentPolicyMapping :  parentPolicy , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal temporary credentials %s from peer site %s -> %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 17:39:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Type :  madmin . SRIAMItemIAMUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											IAMUser :  & madmin . SRIAMUser { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AccessKey :    user , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsDeleteReq :  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UserReq :  & madmin . AddOrUpdateUserReq { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SecretKey :  creds . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Status :     latestUserStat . userInfo . Status , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal user %s from peer site %s -> %s : %w" ,  user ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  healGroups ( ctx  context . Context ,  objAPI  ObjectLayer ,  group  string ,  info  srStatusInfo )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestID ,  latestPeerName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lastUpdate                time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestGroupStat           srGroupStatsSummary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create group if missing; fix group policy mapping if missing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gs ,  ok  :=  info . GroupStats [ group ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  ss  :=  range  gs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lastUpdate . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . groupDesc . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestGroupStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ss . groupDesc . UpdatedAt . IsZero ( )  &&  ss . groupDesc . UpdatedAt . After ( lastUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lastUpdate  =  ss . groupDesc . UpdatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestID  =  dID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestGroupStat  =  ss 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestID  !=  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// heal only from the site with latest info.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestPeerName  =  info . Sites [ latestID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  dID ,  gStatus  :=  range  gs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! gStatus . GroupDescMismatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isGroupDescEqual ( latestGroupStat . groupDesc . GroupDesc ,  gStatus . groupDesc . GroupDesc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peerName  :=  info . Sites [ dID ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  c . IAMChangeHook ( ctx ,  madmin . SRIAMItem { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Type :  madmin . SRIAMItemGroupInfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											GroupInfo :  & madmin . SRGroupInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UpdateReq :  madmin . GroupAddRemove { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Group :     group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Status :    madmin . GroupStatus ( latestGroupStat . groupDesc . Status ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Members :   latestGroupStat . groupDesc . Members , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													IsRemove :  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-02 04:19:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											UpdatedAt :  lastUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-27 03:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to heal group %s from peer site %s -> site %s : %w" ,  group ,  latestPeerName ,  peerName ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isGroupDescEqual ( g1 ,  g2  madmin . GroupDesc )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  g1 . Name  !=  g2 . Name  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										g1 . Status  !=  g2 . Status  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										g1 . Policy  !=  g2 . Policy  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( g1 . Members )  !=  len ( g2 . Members )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v1  :=  range  g1 . Members  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  found  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  v2  :=  range  g2 . Members  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  v1  ==  v2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												found  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! found  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isUserInfoEqual ( u1 ,  u2  madmin . UserInfo )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  u1 . PolicyName  !=  u2 . PolicyName  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u1 . Status  !=  u2 . Status  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u1 . SecretKey  !=  u2 . SecretKey  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  len ( u1 . MemberOf )  !=  len ( u2 . MemberOf )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v1  :=  range  u1 . MemberOf  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  found  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  v2  :=  range  u2 . MemberOf  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  v1  ==  v2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												found  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! found  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isPolicyMappingEqual ( p1 ,  p2  srPolicyMapping )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  p1 . Policy  ==  p2 . Policy  &&  p1 . IsGroup  ==  p2 . IsGroup  &&  p1 . UserOrGroup  ==  p2 . UserOrGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-10-26 01:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  srPeerInfo  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									madmin . PeerInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									EndpointURL  * url . URL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// getPeerForUpload returns the site replication peer handling this upload. Defaults to local cluster otherwise
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  getPeerForUpload ( deplID  string )  ( pi  srPeerInfo ,  local  bool )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ci ,  _  :=  c . GetClusterInfo ( GlobalContext ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ci . Enabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  pi ,  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  site  :=  range  ci . Sites  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  deplID  ==  site . DeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ep ,  _  :=  url . Parse ( site . Endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pi  =  srPeerInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PeerInfo :     site , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EndpointURL :  ep , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  pi ,  site . DeploymentID  ==  globalDeploymentID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  pi ,  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-11-14 23:16:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// startResync initiates resync of data to peerSite specified. The overall site resync status
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is maintained in .minio.sys/buckets/site-replication/resync/<deployment-id.meta>, while collecting
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// individual bucket resync status in .minio.sys/buckets/<bucket-name>/replication/resync.bin
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  startResync ( ctx  context . Context ,  objAPI  ObjectLayer ,  peer  madmin . PeerInfo )  ( res  madmin . SRResyncOpStatus ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . isEnabled ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRNotEnabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRObjectLayerNotReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  peer . DeploymentID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRResyncToSelf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  ok  :=  c . state . Peers [ peer . DeploymentID ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRPeerNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rs ,  err  :=  globalSiteResyncMetrics . siteStatus ( ctx ,  objAPI ,  peer . DeploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rs . Status  ==  ResyncStarted  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRResyncStarted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  buckets  [ ] BucketInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buckets ,  err  =  objAPI . ListBuckets ( ctx ,  BucketOptions { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rs  =  newSiteResyncStatus ( peer . DeploymentID ,  buckets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rs . Status  =  ResyncFailed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											saveSiteResyncMetadata ( ctx ,  rs ,  objAPI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											globalSiteResyncMetrics . updateState ( rs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalSiteResyncMetrics . updateState ( rs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  saveSiteResyncMetadata ( ctx ,  rs ,  objAPI ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  bi  :=  range  buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucket  :=  bi . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  err  :=  getReplicationConfig ( ctx ,  bucket ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Status :     ResyncFailed . String ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// mark remote target for this deployment with the new reset id
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tgtArn  :=  globalBucketTargetSys . getRemoteARNForPeer ( bucket ,  peer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  tgtArn  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  fmt . Sprintf ( "no valid remote target found for this peer %s (%s)" ,  peer . Name ,  peer . DeploymentID ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										target  :=  globalBucketTargetSys . GetRemoteBucketTargetByArn ( ctx ,  bucket ,  tgtArn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										target . ResetBeforeDate  =  UTCNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										target . ResetID  =  rs . ResyncID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  globalBucketTargetSys . SetTarget ( ctx ,  bucket ,  & target ,  true ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targets ,  err  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tgtBytes ,  err  :=  json . Marshal ( & targets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTargetsFile ,  tgtBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  globalReplicationPool . resyncer . start ( ctx ,  objAPI ,  resyncOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket :    bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arn :       tgtArn , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											resyncID :  rs . ResyncID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  madmin . SRResyncOpStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Status :    ResyncStarted . String ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										OpType :    "start" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ResyncID :  rs . ResyncID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( res . Buckets )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res . ErrDetail  =  "partial failure in starting site resync" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// cancelResync stops an ongoing site level resync for the peer specified.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * SiteReplicationSys )  cancelResync ( ctx  context . Context ,  objAPI  ObjectLayer ,  peer  madmin . PeerInfo )  ( res  madmin . SRResyncOpStatus ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! c . isEnabled ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRNotEnabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRObjectLayerNotReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  peer . DeploymentID  ==  globalDeploymentID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRResyncToSelf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  ok  :=  c . state . Peers [ peer . DeploymentID ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRPeerNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rs ,  err  :=  globalSiteResyncMetrics . siteStatus ( ctx ,  objAPI ,  peer . DeploymentID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  rs . Status  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ResyncCanceled : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRResyncCanceled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ResyncCompleted ,  NoResync : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRNoResync 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  madmin . SRResyncOpStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Status :    rs . Status . String ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										OpType :    "cancel" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ResyncID :  rs . ResyncID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  rs . Status  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ResyncCanceled : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRResyncCanceled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ResyncCompleted ,  NoResync : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  errSRNoResync 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									targets  :=  globalBucketTargetSys . ListTargets ( ctx ,  "" ,  string ( madmin . ReplicationService ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// clear the remote target resetID set while initiating resync to stop replication
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  t  :=  range  targets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  t . ResetID  ==  rs . ResyncID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// get tgt with credentials
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tgt  :=  globalBucketTargetSys . GetRemoteBucketTargetByArn ( ctx ,  t . SourceBucket ,  t . Arn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tgt . ResetID  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket  :=  t . SourceBucket 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  =  globalBucketTargetSys . SetTarget ( ctx ,  bucket ,  & tgt ,  true ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targets ,  err  :=  globalBucketTargetSys . ListBucketTargets ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tgtBytes ,  err  :=  json . Marshal ( & targets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  err  =  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTargetsFile ,  tgtBytes ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res . Buckets  =  append ( res . Buckets ,  madmin . ResyncBucketStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ErrDetail :  err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// update resync state for the bucket
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											globalReplicationPool . resyncer . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m ,  ok  :=  globalReplicationPool . resyncer . statusMap [ bucket ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												m  =  newBucketResyncStatus ( bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  st ,  ok  :=  m . TargetsMap [ t . Arn ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												st . LastUpdate  =  UTCNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												st . ResyncStatus  =  ResyncCanceled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												m . TargetsMap [ t . Arn ]  =  st 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												m . LastUpdate  =  UTCNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											globalReplicationPool . resyncer . statusMap [ bucket ]  =  m 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											globalReplicationPool . resyncer . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rs . Status  =  ResyncCanceled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rs . LastUpdate  =  UTCNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  saveSiteResyncMetadata ( ctx ,  rs ,  objAPI ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 23:05:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  globalReplicationPool . resyncer . resyncCancelCh  <-  struct { } { } : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-14 23:16:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalSiteResyncMetrics . updateState ( rs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res . Status  =  rs . Status . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									siteResyncMetaFormat     =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									siteResyncMetaVersionV1  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									siteResyncMetaVersion    =  siteResyncMetaVersionV1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									siteResyncSaveInterval   =  10  *  time . Second 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newSiteResyncStatus ( dID  string ,  buckets  [ ] BucketInfo )  SiteResyncStatus  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									now  :=  UTCNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  SiteResyncStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Version :         siteResyncMetaVersion , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Status :          ResyncStarted , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DeplID :          dID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										TotBuckets :      len ( buckets ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketStatuses :  make ( map [ string ] ResyncStatusType ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  bi  :=  range  buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . BucketStatuses [ bi . Name ]  =  ResyncPending 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . ResyncID  =  mustGetUUID ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . StartTime  =  now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . LastUpdate  =  now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// load site resync metadata from disk
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  loadSiteResyncMetadata ( ctx  context . Context ,  objAPI  ObjectLayer ,  dID  string )  ( rs  SiteResyncStatus ,  e  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data ,  err  :=  readConfig ( GlobalContext ,  objAPI ,  getSRResyncFilePath ( dID ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rs ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( data )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Seems to be empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rs ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( data )  <=  4  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rs ,  fmt . Errorf ( "site resync: no data" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Read resync meta header
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  binary . LittleEndian . Uint16 ( data [ 0 : 2 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  siteResyncMetaFormat : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rs ,  fmt . Errorf ( "resyncMeta: unknown format: %d" ,  binary . LittleEndian . Uint16 ( data [ 0 : 2 ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  binary . LittleEndian . Uint16 ( data [ 2 : 4 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  siteResyncMetaVersion : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rs ,  fmt . Errorf ( "resyncMeta: unknown version: %d" ,  binary . LittleEndian . Uint16 ( data [ 2 : 4 ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// OK, parse data.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  =  rs . UnmarshalMsg ( data [ 4 : ] ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rs ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  rs . Version  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  siteResyncMetaVersionV1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rs ,  fmt . Errorf ( "unexpected resync meta version: %d" ,  rs . Version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rs ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// save resync status of peer to resync/depl-id.meta
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  saveSiteResyncMetadata ( ctx  context . Context ,  ss  SiteResyncStatus ,  objectAPI  ObjectLayer )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data  :=  make ( [ ] byte ,  4 ,  ss . Msgsize ( ) + 4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initialize the resync meta header.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									binary . LittleEndian . PutUint16 ( data [ 0 : 2 ] ,  siteResyncMetaFormat ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									binary . LittleEndian . PutUint16 ( data [ 2 : 4 ] ,  siteResyncMetaVersion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf ,  err  :=  ss . MarshalMsg ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  saveConfig ( ctx ,  objectAPI ,  getSRResyncFilePath ( ss . DeplID ) ,  buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getSRResyncFilePath ( dID  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  pathJoin ( siteResyncPrefix ,  dID + ".meta" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}