github.com/minio/madmin-go@v1.7.5/info-commands.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 "context" 21 "encoding/json" 22 "net/http" 23 "time" 24 ) 25 26 // BackendType - represents different backend types. 27 type BackendType int 28 29 // Enum for different backend types. 30 const ( 31 Unknown BackendType = iota 32 // Filesystem backend. 33 FS 34 // Multi disk Erasure (single, distributed) backend. 35 Erasure 36 // Gateway to other storage 37 Gateway 38 39 // Add your own backend. 40 ) 41 42 // ItemState - represents the status of any item in offline,init,online state 43 type ItemState string 44 45 const ( 46 47 // ItemOffline indicates that the item is offline 48 ItemOffline = ItemState("offline") 49 // ItemInitializing indicates that the item is still in initialization phase 50 ItemInitializing = ItemState("initializing") 51 // ItemOnline indicates that the item is online 52 ItemOnline = ItemState("online") 53 ) 54 55 // StorageInfo - represents total capacity of underlying storage. 56 type StorageInfo struct { 57 Disks []Disk 58 59 // Backend type. 60 Backend BackendInfo 61 } 62 63 // BackendInfo - contains info of the underlying backend 64 type BackendInfo struct { 65 // Represents various backend types, currently on FS, Erasure and Gateway 66 Type BackendType 67 68 // Following fields are only meaningful if BackendType is Gateway. 69 GatewayOnline bool 70 71 // Following fields are only meaningful if BackendType is Erasure. 72 OnlineDisks BackendDisks // Online disks during server startup. 73 OfflineDisks BackendDisks // Offline disks during server startup. 74 75 // Following fields are only meaningful if BackendType is Erasure. 76 StandardSCData []int // Data disks for currently configured Standard storage class. 77 StandardSCParity int // Parity disks for currently configured Standard storage class. 78 RRSCData []int // Data disks for currently configured Reduced Redundancy storage class. 79 RRSCParity int // Parity disks for currently configured Reduced Redundancy storage class. 80 81 // Adds number of erasure sets and drives per set. 82 TotalSets []int // Each index value corresponds to per pool 83 DrivesPerSet []int // Each index value corresponds to per pool 84 } 85 86 // BackendDisks - represents the map of endpoint-disks. 87 type BackendDisks map[string]int 88 89 // Sum - Return the sum of the disks in the endpoint-disk map. 90 func (d1 BackendDisks) Sum() (sum int) { 91 for _, count := range d1 { 92 sum += count 93 } 94 return sum 95 } 96 97 // Merge - Reduces two endpoint-disk maps. 98 func (d1 BackendDisks) Merge(d2 BackendDisks) BackendDisks { 99 if len(d2) == 0 { 100 d2 = make(BackendDisks) 101 } 102 merged := make(BackendDisks) 103 for i1, v1 := range d1 { 104 if v2, ok := d2[i1]; ok { 105 merged[i1] = v2 + v1 106 continue 107 } 108 merged[i1] = v1 109 } 110 return merged 111 } 112 113 // StorageInfo - Connect to a minio server and call Storage Info Management API 114 // to fetch server's information represented by StorageInfo structure 115 func (adm *AdminClient) StorageInfo(ctx context.Context) (StorageInfo, error) { 116 resp, err := adm.executeMethod(ctx, http.MethodGet, requestData{relPath: adminAPIPrefix + "/storageinfo"}) 117 defer closeResponse(resp) 118 if err != nil { 119 return StorageInfo{}, err 120 } 121 122 // Check response http status code 123 if resp.StatusCode != http.StatusOK { 124 return StorageInfo{}, httpRespToErrorResponse(resp) 125 } 126 127 // Unmarshal the server's json response 128 var storageInfo StorageInfo 129 if err = json.NewDecoder(resp.Body).Decode(&storageInfo); err != nil { 130 return StorageInfo{}, err 131 } 132 133 return storageInfo, nil 134 } 135 136 // BucketUsageInfo - bucket usage info provides 137 // - total size of the bucket 138 // - total objects in a bucket 139 // - object size histogram per bucket 140 type BucketUsageInfo struct { 141 Size uint64 `json:"size"` 142 ReplicationPendingSize uint64 `json:"objectsPendingReplicationTotalSize"` 143 ReplicationFailedSize uint64 `json:"objectsFailedReplicationTotalSize"` 144 ReplicatedSize uint64 `json:"objectsReplicatedTotalSize"` 145 ReplicaSize uint64 `json:"objectReplicaTotalSize"` 146 ReplicationPendingCount uint64 `json:"objectsPendingReplicationCount"` 147 ReplicationFailedCount uint64 `json:"objectsFailedReplicationCount"` 148 149 VersionsCount uint64 `json:"versionsCount"` 150 ObjectsCount uint64 `json:"objectsCount"` 151 ObjectSizesHistogram map[string]uint64 `json:"objectsSizesHistogram"` 152 } 153 154 // DataUsageInfo represents data usage stats of the underlying Object API 155 type DataUsageInfo struct { 156 // LastUpdate is the timestamp of when the data usage info was last updated. 157 // This does not indicate a full scan. 158 LastUpdate time.Time `json:"lastUpdate"` 159 160 // Objects total count across all buckets 161 ObjectsTotalCount uint64 `json:"objectsCount"` 162 163 // Objects total size across all buckets 164 ObjectsTotalSize uint64 `json:"objectsTotalSize"` 165 166 // Total Size for objects that have not yet been replicated 167 ReplicationPendingSize uint64 `json:"objectsPendingReplicationTotalSize"` 168 169 // Total size for objects that have witness one or more failures and will be retried 170 ReplicationFailedSize uint64 `json:"objectsFailedReplicationTotalSize"` 171 172 // Total size for objects that have been replicated to destination 173 ReplicatedSize uint64 `json:"objectsReplicatedTotalSize"` 174 175 // Total size for objects that are replicas 176 ReplicaSize uint64 `json:"objectsReplicaTotalSize"` 177 178 // Total number of objects pending replication 179 ReplicationPendingCount uint64 `json:"objectsPendingReplicationCount"` 180 181 // Total number of objects that failed replication 182 ReplicationFailedCount uint64 `json:"objectsFailedReplicationCount"` 183 184 // Total number of buckets in this cluster 185 BucketsCount uint64 `json:"bucketsCount"` 186 187 // Buckets usage info provides following information across all buckets 188 // - total size of the bucket 189 // - total objects in a bucket 190 // - object size histogram per bucket 191 BucketsUsage map[string]BucketUsageInfo `json:"bucketsUsageInfo"` 192 193 // TierStats holds per-tier stats like bytes tiered, etc. 194 TierStats map[string]TierStats `json:"tierStats"` 195 196 // Deprecated kept here for backward compatibility reasons. 197 BucketSizes map[string]uint64 `json:"bucketsSizes"` 198 } 199 200 // DataUsageInfo - returns data usage of the current object API 201 func (adm *AdminClient) DataUsageInfo(ctx context.Context) (DataUsageInfo, error) { 202 resp, err := adm.executeMethod(ctx, http.MethodGet, requestData{relPath: adminAPIPrefix + "/datausageinfo"}) 203 defer closeResponse(resp) 204 if err != nil { 205 return DataUsageInfo{}, err 206 } 207 208 // Check response http status code 209 if resp.StatusCode != http.StatusOK { 210 return DataUsageInfo{}, httpRespToErrorResponse(resp) 211 } 212 213 // Unmarshal the server's json response 214 var dataUsageInfo DataUsageInfo 215 if err = json.NewDecoder(resp.Body).Decode(&dataUsageInfo); err != nil { 216 return DataUsageInfo{}, err 217 } 218 219 return dataUsageInfo, nil 220 } 221 222 // InfoMessage container to hold server admin related information. 223 type InfoMessage struct { 224 Mode string `json:"mode,omitempty"` 225 Domain []string `json:"domain,omitempty"` 226 Region string `json:"region,omitempty"` 227 SQSARN []string `json:"sqsARN,omitempty"` 228 DeploymentID string `json:"deploymentID,omitempty"` 229 Buckets Buckets `json:"buckets,omitempty"` 230 Objects Objects `json:"objects,omitempty"` 231 Versions Versions `json:"versions,omitempty"` 232 Usage Usage `json:"usage,omitempty"` 233 Services Services `json:"services,omitempty"` 234 Backend interface{} `json:"backend,omitempty"` 235 Servers []ServerProperties `json:"servers,omitempty"` 236 } 237 238 func (info InfoMessage) BackendType() BackendType { 239 // MinIO server type default 240 backendType := Unknown 241 242 // Set the type of MinIO server ("FS", "Erasure", "Unknown") 243 switch v := info.Backend.(type) { 244 case FSBackend: 245 backendType = FS 246 case ErasureBackend: 247 backendType = Erasure 248 case map[string]interface{}: 249 vt, ok := v["backendType"] 250 if ok { 251 backendTypeS, _ := vt.(string) 252 switch backendTypeS { 253 case "Erasure": 254 backendType = Erasure 255 } 256 } 257 } 258 return backendType 259 } 260 261 func (info InfoMessage) StandardParity() int { 262 switch info.BackendType() { 263 case Erasure: 264 switch v := info.Backend.(type) { 265 case ErasureBackend: 266 return v.StandardSCParity 267 case map[string]interface{}: 268 scParity, ok := v["standardSCParity"].(float64) 269 if ok { 270 return int(scParity) 271 } 272 } 273 } 274 return -1 275 } 276 277 // Services contains different services information 278 type Services struct { 279 KMS KMS `json:"kms,omitempty"` 280 LDAP LDAP `json:"ldap,omitempty"` 281 Logger []Logger `json:"logger,omitempty"` 282 Audit []Audit `json:"audit,omitempty"` 283 Notifications []map[string][]TargetIDStatus `json:"notifications,omitempty"` 284 } 285 286 // Buckets contains the number of buckets 287 type Buckets struct { 288 Count uint64 `json:"count"` 289 Error string `json:"error,omitempty"` 290 } 291 292 // Objects contains the number of objects 293 type Objects struct { 294 Count uint64 `json:"count"` 295 Error string `json:"error,omitempty"` 296 } 297 298 // Versions contains the number of versions 299 type Versions struct { 300 Count uint64 `json:"count"` 301 Error string `json:"error,omitempty"` 302 } 303 304 // Usage contains the total size used 305 type Usage struct { 306 Size uint64 `json:"size"` 307 Error string `json:"error,omitempty"` 308 } 309 310 // TierStats contains per-tier statistics like total size, number of 311 // objects/versions transitioned, etc. 312 type TierStats struct { 313 TotalSize uint64 `json:"totalSize"` 314 NumVersions int `json:"numVersions"` 315 NumObjects int `json:"numObjects"` 316 } 317 318 // KMS contains KMS status information 319 type KMS struct { 320 Status string `json:"status,omitempty"` 321 Encrypt string `json:"encrypt,omitempty"` 322 Decrypt string `json:"decrypt,omitempty"` 323 } 324 325 // LDAP contains ldap status 326 type LDAP struct { 327 Status string `json:"status,omitempty"` 328 } 329 330 // Status of endpoint 331 type Status struct { 332 Status string `json:"status,omitempty"` 333 } 334 335 // Audit contains audit logger status 336 type Audit map[string]Status 337 338 // Logger contains logger status 339 type Logger map[string]Status 340 341 // TargetIDStatus containsid and status 342 type TargetIDStatus map[string]Status 343 344 // backendType - indicates the type of backend storage 345 type backendType string 346 347 const ( 348 // FsType - Backend is FS Type 349 FsType = backendType("FS") 350 // ErasureType - Backend is Erasure type 351 ErasureType = backendType("Erasure") 352 ) 353 354 // FSBackend contains specific FS storage information 355 type FSBackend struct { 356 Type backendType `json:"backendType,omitempty"` 357 } 358 359 // ErasureBackend contains specific erasure storage information 360 type ErasureBackend struct { 361 Type backendType `json:"backendType,omitempty"` 362 OnlineDisks int `json:"onlineDisks,omitempty"` 363 OfflineDisks int `json:"offlineDisks,omitempty"` 364 // Parity disks for currently configured Standard storage class. 365 StandardSCParity int `json:"standardSCParity,omitempty"` 366 // Parity disks for currently configured Reduced Redundancy storage class. 367 RRSCParity int `json:"rrSCParity,omitempty"` 368 } 369 370 // ServerProperties holds server information 371 type ServerProperties struct { 372 State string `json:"state,omitempty"` 373 Endpoint string `json:"endpoint,omitempty"` 374 Scheme string `json:"scheme,omitempty"` 375 Uptime int64 `json:"uptime,omitempty"` 376 Version string `json:"version,omitempty"` 377 CommitID string `json:"commitID,omitempty"` 378 Network map[string]string `json:"network,omitempty"` 379 Disks []Disk `json:"drives,omitempty"` 380 PoolNumber int `json:"poolNumber,omitempty"` 381 MemStats MemStats `json:"mem_stats"` 382 GoMaxProcs int `json:"go_max_procs,omitempty"` 383 NumCPU int `json:"num_cpu,omitempty"` 384 RuntimeVersion string `json:"runtime_version,omitempty"` 385 GCStats *GCStats `json:"gc_stats,omitempty"` 386 MinioEnvVars map[string]string `json:"minio_env_vars,omitempty"` 387 } 388 389 // DiskMetrics has the information about XL Storage APIs 390 // the number of calls of each API and the moving average of 391 // the duration, in nanosecond, of each API. 392 type DiskMetrics struct { 393 LastMinute map[string]TimedAction `json:"lastMinute,omitempty"` 394 APICalls map[string]uint64 `json:"apiCalls,omitempty"` 395 396 // Deprecated: Use LastMinute instead. Not populated from servers after July 2022. 397 APILatencies map[string]interface{} `json:"apiLatencies,omitempty"` 398 } 399 400 // Disk holds Disk information 401 type Disk struct { 402 Endpoint string `json:"endpoint,omitempty"` 403 RootDisk bool `json:"rootDisk,omitempty"` 404 DrivePath string `json:"path,omitempty"` 405 Healing bool `json:"healing,omitempty"` 406 Scanning bool `json:"scanning,omitempty"` 407 State string `json:"state,omitempty"` 408 UUID string `json:"uuid,omitempty"` 409 Major uint32 `json:"major"` 410 Minor uint32 `json:"minor"` 411 Model string `json:"model,omitempty"` 412 TotalSpace uint64 `json:"totalspace,omitempty"` 413 UsedSpace uint64 `json:"usedspace,omitempty"` 414 AvailableSpace uint64 `json:"availspace,omitempty"` 415 ReadThroughput float64 `json:"readthroughput,omitempty"` 416 WriteThroughPut float64 `json:"writethroughput,omitempty"` 417 ReadLatency float64 `json:"readlatency,omitempty"` 418 WriteLatency float64 `json:"writelatency,omitempty"` 419 Utilization float64 `json:"utilization,omitempty"` 420 Metrics *DiskMetrics `json:"metrics,omitempty"` 421 HealInfo *HealingDisk `json:"heal_info,omitempty"` 422 FreeInodes uint64 `json:"free_inodes,omitempty"` 423 424 // Indexes, will be -1 until assigned a set. 425 PoolIndex int `json:"pool_index"` 426 SetIndex int `json:"set_index"` 427 DiskIndex int `json:"disk_index"` 428 } 429 430 // ServerInfo - Connect to a minio server and call Server Admin Info Management API 431 // to fetch server's information represented by infoMessage structure 432 func (adm *AdminClient) ServerInfo(ctx context.Context) (InfoMessage, error) { 433 resp, err := adm.executeMethod(ctx, 434 http.MethodGet, 435 requestData{relPath: adminAPIPrefix + "/info"}, 436 ) 437 defer closeResponse(resp) 438 if err != nil { 439 return InfoMessage{}, err 440 } 441 442 // Check response http status code 443 if resp.StatusCode != http.StatusOK { 444 return InfoMessage{}, httpRespToErrorResponse(resp) 445 } 446 447 // Unmarshal the server's json response 448 var message InfoMessage 449 if err = json.NewDecoder(resp.Body).Decode(&message); err != nil { 450 return InfoMessage{}, err 451 } 452 453 return message, nil 454 }