github.com/minio/madmin-go/v2@v2.2.1/tier-config.go (about) 1 // 2 // Copyright (c) 2015-2022 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 "encoding/json" 24 "errors" 25 "log" 26 ) 27 28 //go:generate msgp -file $GOFILE 29 30 // TierConfigVer refers to the current tier config version 31 const TierConfigVer = "v1" 32 33 // TierType enumerates different remote tier backends. 34 type TierType int 35 36 const ( 37 // Unsupported refers to remote tier backend that is not supported in this version 38 Unsupported TierType = iota 39 // S3 refers to AWS S3 compatible backend 40 S3 41 // Azure refers to Azure Blob Storage 42 Azure 43 // GCS refers to Google Cloud Storage 44 GCS 45 // MinIO refers to MinIO object storage backend 46 MinIO 47 ) 48 49 // String returns the name of tt's remote tier backend. 50 func (tt TierType) String() string { 51 switch tt { 52 case S3: 53 return "s3" 54 case Azure: 55 return "azure" 56 case GCS: 57 return "gcs" 58 case MinIO: 59 return "minio" 60 } 61 return "unsupported" 62 } 63 64 // MarshalJSON returns the canonical json representation of tt. 65 func (tt TierType) MarshalJSON() ([]byte, error) { 66 typ := tt.String() 67 return json.Marshal(typ) 68 } 69 70 // UnmarshalJSON parses the provided tier type string, failing unmarshal 71 // if data contains invalid tier type. 72 func (tt *TierType) UnmarshalJSON(data []byte) error { 73 var s string 74 err := json.Unmarshal(data, &s) 75 if err != nil { 76 return err 77 } 78 79 newtt, err := NewTierType(s) 80 if err != nil { 81 return err 82 } 83 *tt = newtt 84 return nil 85 } 86 87 // NewTierType creates TierType if scType is a valid tier type string, otherwise 88 // returns an error. 89 func NewTierType(scType string) (TierType, error) { 90 switch scType { 91 case S3.String(): 92 return S3, nil 93 case Azure.String(): 94 return Azure, nil 95 case GCS.String(): 96 return GCS, nil 97 case MinIO.String(): 98 return MinIO, nil 99 } 100 101 return Unsupported, ErrTierTypeUnsupported 102 } 103 104 // TierConfig represents the different remote tier backend configurations 105 // supported. The specific backend is identified by the Type field. It has a 106 // Version field to allow for backwards-compatible extension in the future. 107 type TierConfig struct { 108 Version string 109 Type TierType `json:",omitempty"` 110 Name string `json:",omitempty"` 111 S3 *TierS3 `json:",omitempty"` 112 Azure *TierAzure `json:",omitempty"` 113 GCS *TierGCS `json:",omitempty"` 114 MinIO *TierMinIO `json:",omitempty"` 115 } 116 117 var ( 118 // ErrTierNameEmpty "remote tier name empty" 119 ErrTierNameEmpty = errors.New("remote tier name empty") 120 // ErrTierInvalidConfig "invalid tier config" 121 ErrTierInvalidConfig = errors.New("invalid tier config") 122 // ErrTierInvalidConfigVersion "invalid tier config version" 123 ErrTierInvalidConfigVersion = errors.New("invalid tier config version") 124 // ErrTierTypeUnsupported "unsupported tier type" 125 ErrTierTypeUnsupported = errors.New("unsupported tier type") 126 ) 127 128 // Clone returns a copy of TierConfig with secret key/credentials redacted. 129 func (cfg *TierConfig) Clone() TierConfig { 130 var ( 131 s3 TierS3 132 az TierAzure 133 gcs TierGCS 134 m TierMinIO 135 ) 136 switch cfg.Type { 137 case S3: 138 s3 = *cfg.S3 139 s3.SecretKey = "REDACTED" 140 case Azure: 141 az = *cfg.Azure 142 az.AccountKey = "REDACTED" 143 case GCS: 144 gcs = *cfg.GCS 145 gcs.Creds = "REDACTED" 146 case MinIO: 147 m = *cfg.MinIO 148 m.SecretKey = "REDACTED" 149 } 150 return TierConfig{ 151 Version: cfg.Version, 152 Type: cfg.Type, 153 Name: cfg.Name, 154 S3: &s3, 155 Azure: &az, 156 GCS: &gcs, 157 MinIO: &m, 158 } 159 } 160 161 // UnmarshalJSON unmarshals json value to ensure that Type field is filled in 162 // correspondence with the tier config supplied. 163 // See TestUnmarshalTierConfig for an example json. 164 func (cfg *TierConfig) UnmarshalJSON(b []byte) error { 165 type tierConfig TierConfig 166 var m tierConfig 167 err := json.Unmarshal(b, &m) 168 if err != nil { 169 return err 170 } 171 172 switch m.Version { 173 case TierConfigVer: 174 default: 175 return ErrTierInvalidConfigVersion 176 } 177 178 switch m.Type { 179 case S3: 180 if m.S3 == nil { 181 return ErrTierInvalidConfig 182 } 183 case Azure: 184 if m.Azure == nil { 185 return ErrTierInvalidConfig 186 } 187 case GCS: 188 if m.GCS == nil { 189 return ErrTierInvalidConfig 190 } 191 case MinIO: 192 if m.MinIO == nil { 193 return ErrTierInvalidConfig 194 } 195 } 196 197 if m.Name == "" { 198 return ErrTierNameEmpty 199 } 200 201 *cfg = TierConfig(m) 202 return nil 203 } 204 205 // Endpoint returns the remote tier backend endpoint. 206 func (cfg *TierConfig) Endpoint() string { 207 switch cfg.Type { 208 case S3: 209 return cfg.S3.Endpoint 210 case Azure: 211 return cfg.Azure.Endpoint 212 case GCS: 213 return cfg.GCS.Endpoint 214 case MinIO: 215 return cfg.MinIO.Endpoint 216 } 217 log.Printf("unexpected tier type %s", cfg.Type) 218 return "" 219 } 220 221 // Bucket returns the remote tier backend bucket. 222 func (cfg *TierConfig) Bucket() string { 223 switch cfg.Type { 224 case S3: 225 return cfg.S3.Bucket 226 case Azure: 227 return cfg.Azure.Bucket 228 case GCS: 229 return cfg.GCS.Bucket 230 case MinIO: 231 return cfg.MinIO.Bucket 232 } 233 log.Printf("unexpected tier type %s", cfg.Type) 234 return "" 235 } 236 237 // Prefix returns the remote tier backend prefix. 238 func (cfg *TierConfig) Prefix() string { 239 switch cfg.Type { 240 case S3: 241 return cfg.S3.Prefix 242 case Azure: 243 return cfg.Azure.Prefix 244 case GCS: 245 return cfg.GCS.Prefix 246 case MinIO: 247 return cfg.MinIO.Prefix 248 } 249 log.Printf("unexpected tier type %s", cfg.Type) 250 return "" 251 } 252 253 // Region returns the remote tier backend region. 254 func (cfg *TierConfig) Region() string { 255 switch cfg.Type { 256 case S3: 257 return cfg.S3.Region 258 case Azure: 259 return cfg.Azure.Region 260 case GCS: 261 return cfg.GCS.Region 262 case MinIO: 263 return cfg.MinIO.Region 264 } 265 log.Printf("unexpected tier type %s", cfg.Type) 266 return "" 267 }