github.com/minio/madmin-go@v1.7.5/replication-api.go (about)

     1  //
     2  // MinIO Object Storage (c) 2022 MinIO, Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //      http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package madmin
    18  
    19  import (
    20  	"context"
    21  	"encoding/json"
    22  	"net/http"
    23  	"net/url"
    24  	"time"
    25  )
    26  
    27  // ReplDiffOpts holds options for `mc replicate diff` command
    28  type ReplDiffOpts struct {
    29  	ARN     string
    30  	Verbose bool
    31  	Prefix  string
    32  }
    33  
    34  // TgtDiffInfo returns status of unreplicated objects
    35  // for the target ARN
    36  type TgtDiffInfo struct {
    37  	ReplicationStatus       string `json:"rStatus,omitempty"`  // target replication status
    38  	DeleteReplicationStatus string `json:"drStatus,omitempty"` // target delete replication status
    39  }
    40  
    41  // DiffInfo represents relevant replication status and last attempt to replicate
    42  // for the replication targets configured for the bucket
    43  type DiffInfo struct {
    44  	Object                  string                 `json:"object"`
    45  	VersionID               string                 `json:"versionId"`
    46  	Targets                 map[string]TgtDiffInfo `json:"targets,omitempty"`
    47  	Err                     error                  `json:"error,omitempty"`
    48  	ReplicationStatus       string                 `json:"rStatus,omitempty"` // overall replication status
    49  	DeleteReplicationStatus string                 `json:"dStatus,omitempty"` // overall replication status of version delete
    50  	ReplicationTimestamp    time.Time              `json:"replTimestamp,omitempty"`
    51  	LastModified            time.Time              `json:"lastModified,omitempty"`
    52  	IsDeleteMarker          bool                   `json:"deletemarker"`
    53  }
    54  
    55  // BucketReplicationDiff - gets diff for non-replicated entries.
    56  func (adm *AdminClient) BucketReplicationDiff(ctx context.Context, bucketName string, opts ReplDiffOpts) <-chan DiffInfo {
    57  	diffCh := make(chan DiffInfo)
    58  
    59  	// start a routine to start reading line by line.
    60  	go func(diffCh chan<- DiffInfo) {
    61  		defer close(diffCh)
    62  		queryValues := url.Values{}
    63  		queryValues.Set("bucket", bucketName)
    64  
    65  		if opts.Verbose {
    66  			queryValues.Set("verbose", "true")
    67  		}
    68  		if opts.ARN != "" {
    69  			queryValues.Set("arn", opts.ARN)
    70  		}
    71  		if opts.Prefix != "" {
    72  			queryValues.Set("prefix", opts.Prefix)
    73  		}
    74  
    75  		reqData := requestData{
    76  			relPath:     adminAPIPrefix + "/replication/diff",
    77  			queryValues: queryValues,
    78  		}
    79  
    80  		// Execute PUT on /minio/admin/v3/diff to set quota for a bucket.
    81  		resp, err := adm.executeMethod(ctx, http.MethodPost, reqData)
    82  		if err != nil {
    83  			diffCh <- DiffInfo{Err: err}
    84  			return
    85  		}
    86  		defer closeResponse(resp)
    87  
    88  		if resp.StatusCode != http.StatusOK {
    89  			diffCh <- DiffInfo{Err: httpRespToErrorResponse(resp)}
    90  			return
    91  		}
    92  
    93  		dec := json.NewDecoder(resp.Body)
    94  		for {
    95  			var di DiffInfo
    96  			if err = dec.Decode(&di); err != nil {
    97  				break
    98  			}
    99  			select {
   100  			case <-ctx.Done():
   101  				return
   102  			case diffCh <- di:
   103  			}
   104  		}
   105  	}(diffCh)
   106  	// Returns the diff channel, for caller to start reading from.
   107  	return diffCh
   108  }