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  }