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