|
| 1 | +// |
| 2 | +// Copyright (c) 2015-2025 MinIO, Inc. |
| 3 | +// |
| 4 | +// This file is part of MinIO Object Storage stack |
| 5 | +// |
| 6 | +// This program is free software: you can redistribute it and/or modify |
| 7 | +// it under the terms of the GNU Affero General Public License as |
| 8 | +// published by the Free Software Foundation, either version 3 of the |
| 9 | +// License, or (at your option) any later version. |
| 10 | +// |
| 11 | +// This program is distributed in the hope that it will be useful, |
| 12 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | +// GNU Affero General Public License for more details. |
| 15 | +// |
| 16 | +// You should have received a copy of the GNU Affero General Public License |
| 17 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | +// |
| 19 | + |
| 20 | +package madmin |
| 21 | + |
| 22 | +import ( |
| 23 | + "fmt" |
| 24 | + "net/url" |
| 25 | + "time" |
| 26 | +) |
| 27 | + |
| 28 | +//msgp:clearomitted |
| 29 | +//msgp:tag json |
| 30 | +//go:generate msgp |
| 31 | + |
| 32 | +// BucketTargets represents a slice of bucket targets by type and endpoint |
| 33 | +type BucketTargets struct { |
| 34 | + Targets []BucketTarget `json:"targets"` |
| 35 | +} |
| 36 | + |
| 37 | +// Empty returns true if struct is empty. |
| 38 | +func (t BucketTargets) Empty() bool { |
| 39 | + if len(t.Targets) == 0 { |
| 40 | + return true |
| 41 | + } |
| 42 | + empty := true |
| 43 | + for _, t := range t.Targets { |
| 44 | + if !t.Empty() { |
| 45 | + return false |
| 46 | + } |
| 47 | + } |
| 48 | + return empty |
| 49 | +} |
| 50 | + |
| 51 | +// ServiceType represents service type |
| 52 | +type ServiceType string |
| 53 | + |
| 54 | +const ( |
| 55 | + // ReplicationService specifies replication service |
| 56 | + ReplicationService ServiceType = "replication" |
| 57 | +) |
| 58 | + |
| 59 | +// IsValid returns true if ARN type represents replication |
| 60 | +func (t ServiceType) IsValid() bool { |
| 61 | + return t == ReplicationService |
| 62 | +} |
| 63 | + |
| 64 | +// BucketTarget represents the target bucket and site association. |
| 65 | +type BucketTarget struct { |
| 66 | + SourceBucket string `json:"sourcebucket"` |
| 67 | + Endpoint string `json:"endpoint"` |
| 68 | + Credentials *Credentials `json:"credentials"` |
| 69 | + TargetBucket string `json:"targetbucket"` |
| 70 | + Secure bool `json:"secure"` |
| 71 | + Path string `json:"path,omitempty"` |
| 72 | + API string `json:"api,omitempty"` |
| 73 | + Arn string `json:"arn,omitempty"` |
| 74 | + Type ServiceType `json:"type"` |
| 75 | + Region string `json:"region,omitempty"` |
| 76 | + BandwidthLimit int64 `json:"bandwidthlimit,omitempty"` |
| 77 | + ReplicationSync bool `json:"replicationSync"` |
| 78 | + StorageClass string `json:"storageclass,omitempty"` |
| 79 | + HealthCheckDuration time.Duration `json:"healthCheckDuration,omitempty"` |
| 80 | + DisableProxy bool `json:"disableProxy"` |
| 81 | + ResetBeforeDate time.Time `json:"resetBeforeDate,omitempty"` |
| 82 | + ResetID string `json:"resetID,omitempty"` |
| 83 | + TotalDowntime time.Duration `json:"totalDowntime"` |
| 84 | + LastOnline time.Time `json:"lastOnline"` |
| 85 | + Online bool `json:"isOnline"` |
| 86 | + Latency LatencyStat `json:"latency"` |
| 87 | + DeploymentID string `json:"deploymentID,omitempty"` |
| 88 | + Edge bool `json:"edge"` // target is recipient of edge traffic |
| 89 | + EdgeSyncBeforeExpiry bool `json:"edgeSyncBeforeExpiry"` // must replicate to edge before expiry |
| 90 | + OfflineCount int64 `json:"offlineCount"` |
| 91 | +} |
| 92 | + |
| 93 | +// Credentials holds access and secret keys. |
| 94 | +type Credentials struct { |
| 95 | + AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"` |
| 96 | + SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"` |
| 97 | + SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"` |
| 98 | + Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"` |
| 99 | +} |
| 100 | + |
| 101 | +// Clone returns shallow clone of BucketTarget without secret key in credentials |
| 102 | +func (t *BucketTarget) Clone() BucketTarget { |
| 103 | + return BucketTarget{ |
| 104 | + SourceBucket: t.SourceBucket, |
| 105 | + Endpoint: t.Endpoint, |
| 106 | + TargetBucket: t.TargetBucket, |
| 107 | + Credentials: &Credentials{AccessKey: t.Credentials.AccessKey}, |
| 108 | + Secure: t.Secure, |
| 109 | + Path: t.Path, |
| 110 | + API: t.API, |
| 111 | + Arn: t.Arn, |
| 112 | + Type: t.Type, |
| 113 | + Region: t.Region, |
| 114 | + BandwidthLimit: t.BandwidthLimit, |
| 115 | + ReplicationSync: t.ReplicationSync, |
| 116 | + StorageClass: t.StorageClass, // target storage class |
| 117 | + HealthCheckDuration: t.HealthCheckDuration, |
| 118 | + DisableProxy: t.DisableProxy, |
| 119 | + ResetBeforeDate: t.ResetBeforeDate, |
| 120 | + ResetID: t.ResetID, |
| 121 | + TotalDowntime: t.TotalDowntime, |
| 122 | + LastOnline: t.LastOnline, |
| 123 | + Online: t.Online, |
| 124 | + Latency: t.Latency, |
| 125 | + DeploymentID: t.DeploymentID, |
| 126 | + Edge: t.Edge, |
| 127 | + EdgeSyncBeforeExpiry: t.EdgeSyncBeforeExpiry, |
| 128 | + OfflineCount: t.OfflineCount, |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +// URL returns target url |
| 133 | +func (t BucketTarget) URL() *url.URL { |
| 134 | + scheme := "http" |
| 135 | + if t.Secure { |
| 136 | + scheme = "https" |
| 137 | + } |
| 138 | + return &url.URL{ |
| 139 | + Scheme: scheme, |
| 140 | + Host: t.Endpoint, |
| 141 | + } |
| 142 | +} |
| 143 | + |
| 144 | +// Empty returns true if struct is empty. |
| 145 | +func (t BucketTarget) Empty() bool { |
| 146 | + return t.String() == "" || t.Credentials == nil |
| 147 | +} |
| 148 | + |
| 149 | +func (t *BucketTarget) String() string { |
| 150 | + return fmt.Sprintf("%s %s", t.Endpoint, t.TargetBucket) |
| 151 | +} |
0 commit comments