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