admin: Add ServerInfo API() (#3743)

master
Anis Elleuch 8 years ago committed by Harshavardhana
parent fb39c7c26b
commit 7f86a21317
  1. 92
      cmd/admin-handlers.go
  2. 3
      cmd/admin-router.go
  3. 17
      cmd/event-notifier.go
  4. 6
      cmd/server-startup-msg.go
  5. 119
      pkg/madmin/info-commands.go
  6. 45
      pkg/madmin/service-commands.go

@ -188,6 +188,98 @@ func (adminAPI adminAPIHandlers) ServiceCredentialsHandler(w http.ResponseWriter
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }
// ServerProperties holds some server information such as, version, region
// uptime, etc..
type ServerProperties struct {
Uptime time.Duration `json:"uptime"`
Version string `json:"version"`
CommitID string `json:"commitID"`
Region string `json:"region"`
SQSARN []string `json:"sqsARN"`
}
// ServerConnStats holds transferred bytes from/to the server
type ServerConnStats struct {
TotalInputBytes uint64 `json:"transferred"`
TotalOutputBytes uint64 `json:"received"`
Throughput uint64 `json:"throughput,omitempty"`
}
// ServerInfo holds the information that will be returned by ServerInfo API
type ServerInfo struct {
StorageInfo StorageInfo `json:"storage"`
ConnStats ServerConnStats `json:"network"`
Properties ServerProperties `json:"server"`
}
// ServerInfoHandler - GET /?server-info
// ----------
// Get server information
func (adminAPI adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Request) {
// Authenticate request
adminAPIErr := checkRequestAuthType(r, "", "", "")
if adminAPIErr != ErrNone {
writeErrorResponse(w, adminAPIErr, r.URL)
return
}
// Build storage info
objLayer := newObjectLayerFn()
if objLayer == nil {
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
return
}
storage := objLayer.StorageInfo()
// Build list of enabled ARNs queues
var arns []string
for queueArn := range globalEventNotifier.GetAllExternalTargets() {
arns = append(arns, queueArn)
}
// Fetch uptimes from all peers. This may fail to due to lack
// of read-quorum availability.
uptime, err := getPeerUptimes(globalAdminPeers)
if err != nil {
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
errorIf(err, "Unable to get uptime from majority of servers.")
return
}
// Build server properties information
properties := ServerProperties{
Version: Version,
CommitID: CommitID,
Region: serverConfig.GetRegion(),
SQSARN: arns,
Uptime: uptime,
}
// Build network info
connStats := ServerConnStats{
TotalInputBytes: globalConnStats.getTotalInputBytes(),
TotalOutputBytes: globalConnStats.getTotalOutputBytes(),
}
// Build the whole returned information
info := ServerInfo{
StorageInfo: storage,
ConnStats: connStats,
Properties: properties,
}
// Marshal API response
jsonBytes, err := json.Marshal(info)
if err != nil {
writeErrorResponse(w, ErrInternalError, r.URL)
errorIf(err, "Failed to marshal storage info into json.")
return
}
// Reply with storage information (across nodes in a
// distributed setup) as json.
writeSuccessResponseJSON(w, jsonBytes)
}
// validateLockQueryParams - Validates query params for list/clear locks management APIs. // validateLockQueryParams - Validates query params for list/clear locks management APIs.
func validateLockQueryParams(vars url.Values) (string, string, time.Duration, APIErrorCode) { func validateLockQueryParams(vars url.Values) (string, string, time.Duration, APIErrorCode) {
bucket := vars.Get(string(mgmtBucket)) bucket := vars.Get(string(mgmtBucket))

@ -39,6 +39,9 @@ func registerAdminRouter(mux *router.Router) {
// Service update credentials // Service update credentials
adminRouter.Methods("POST").Queries("service", "").Headers(minioAdminOpHeader, "set-credentials").HandlerFunc(adminAPI.ServiceCredentialsHandler) adminRouter.Methods("POST").Queries("service", "").Headers(minioAdminOpHeader, "set-credentials").HandlerFunc(adminAPI.ServiceCredentialsHandler)
// Info operations
adminRouter.Methods("GET").Queries("info", "").HandlerFunc(adminAPI.ServerInfoHandler)
/// Lock operations /// Lock operations
// List Locks // List Locks

@ -162,9 +162,22 @@ func newNotificationEvent(event eventData) NotificationEvent {
return nEvent return nEvent
} }
// Fetch the external target. No locking needed here since this map is // Fetch all external targets. This returns a copy of the current map of
// never written after initial startup. // external notification targets.
func (en eventNotifier) GetAllExternalTargets() map[string]*logrus.Logger {
en.external.rwMutex.RLock()
defer en.external.rwMutex.RUnlock()
targetsCopy := make(map[string]*logrus.Logger)
for k, v := range en.external.targets {
targetsCopy[k] = v
}
return targetsCopy
}
// Fetch the external target.
func (en eventNotifier) GetExternalTarget(queueARN string) *logrus.Logger { func (en eventNotifier) GetExternalTarget(queueARN string) *logrus.Logger {
en.external.rwMutex.RLock()
defer en.external.rwMutex.RUnlock()
return en.external.targets[queueARN] return en.external.targets[queueARN]
} }

@ -101,10 +101,12 @@ func printEventNotifiers() {
return return
} }
arnMsg := colorBlue("SQS ARNs: ") arnMsg := colorBlue("SQS ARNs: ")
if len(globalEventNotifier.external.targets) == 0 { // Get all configured external notification targets
externalTargets := globalEventNotifier.GetAllExternalTargets()
if len(externalTargets) == 0 {
arnMsg += colorBold(fmt.Sprintf(getFormatStr(len("<none>"), 1), "<none>")) arnMsg += colorBold(fmt.Sprintf(getFormatStr(len("<none>"), 1), "<none>"))
} }
for queueArn := range globalEventNotifier.external.targets { for queueArn := range externalTargets {
arnMsg += colorBold(fmt.Sprintf(getFormatStr(len(queueArn), 1), queueArn)) arnMsg += colorBold(fmt.Sprintf(getFormatStr(len(queueArn), 1), queueArn))
} }
console.Println(arnMsg) console.Println(arnMsg)

@ -0,0 +1,119 @@
/*
* Minio Cloud Storage, (C) 2017 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package madmin
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"time"
)
// BackendType - represents different backend types.
type BackendType int
// Enum for different backend types.
const (
Unknown BackendType = iota
// Filesystem backend.
FS
// Multi disk Erasure (single, distributed) backend.
Erasure
// Add your own backend.
)
// StorageInfo - represents total capacity of underlying storage.
type StorageInfo struct {
// Total disk space.
Total int64
// Free available disk space.
Free int64
// Backend type.
Backend struct {
// Represents various backend types, currently on FS and Erasure.
Type BackendType
// Following fields are only meaningful if BackendType is Erasure.
OnlineDisks int // Online disks during server startup.
OfflineDisks int // Offline disks during server startup.
ReadQuorum int // Minimum disks required for successful read operations.
WriteQuorum int // Minimum disks required for successful write operations.
}
}
// ServerProperties holds some of the server's information such as uptime,
// version, region, ..
type ServerProperties struct {
Uptime time.Duration `json:"uptime"`
Version string `json:"version"`
CommitID string `json:"commitID"`
Region string `json:"region"`
SQSARN []string `json:"sqsARN"`
}
// ServerConnStats holds network information
type ServerConnStats struct {
TotalInputBytes uint64 `json:"transferred"`
TotalOutputBytes uint64 `json:"received"`
}
// ServerInfo holds the whole server information that will be
// returned by ServerInfo API.
type ServerInfo struct {
StorageInfo StorageInfo `json:"storage"`
ConnStats ServerConnStats `json:"network"`
Properties ServerProperties `json:"server"`
}
// ServerInfo - Connect to a minio server and call Server Info Management API
// to fetch server's information represented by ServerInfo structure
func (adm *AdminClient) ServerInfo() (ServerInfo, error) {
// Prepare web service request
reqData := requestData{}
reqData.queryValues = make(url.Values)
reqData.queryValues.Set("info", "")
reqData.customHeaders = make(http.Header)
resp, err := adm.executeMethod("GET", reqData)
defer closeResponse(resp)
if err != nil {
return ServerInfo{}, err
}
// Check response http status code
if resp.StatusCode != http.StatusOK {
return ServerInfo{}, httpRespToErrorResponse(resp)
}
// Unmarshal the server's json response
var info ServerInfo
respBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ServerInfo{}, err
}
err = json.Unmarshal(respBytes, &info)
if err != nil {
return ServerInfo{}, err
}
return info, nil
}

@ -1,5 +1,5 @@
/* /*
* Minio Cloud Storage, (C) 2016 Minio, Inc. * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -28,50 +28,9 @@ import (
"time" "time"
) )
// BackendType - represents different backend types.
type BackendType int
// Enum for different backend types.
const (
Unknown BackendType = iota
// Filesystem backend.
FS
// Multi disk Erasure (single, distributed) backend.
Erasure
// Add your own backend.
)
// StorageInfo - represents total capacity of underlying storage.
type StorageInfo struct {
// Total disk space.
Total int64
// Free available disk space.
Free int64
// Backend type.
Backend struct {
// Represents various backend types, currently on FS and Erasure.
Type BackendType
// Following fields are only meaningful if BackendType is Erasure.
OnlineDisks int // Online disks during server startup.
OfflineDisks int // Offline disks during server startup.
ReadQuorum int // Minimum disks required for successful read operations.
WriteQuorum int // Minimum disks required for successful write operations.
}
}
// ServerVersion - server version
type ServerVersion struct {
Version string `json:"version"`
CommitID string `json:"commitID"`
}
// ServiceStatusMetadata - contains the response of service status API // ServiceStatusMetadata - contains the response of service status API
type ServiceStatusMetadata struct { type ServiceStatusMetadata struct {
StorageInfo StorageInfo `json:"storageInfo"` Uptime time.Duration `json:"uptime"`
ServerVersion ServerVersion `json:"serverVersion"`
Uptime time.Duration `json:"uptime"`
} }
// ServiceStatus - Connect to a minio server and call Service Status Management API // ServiceStatus - Connect to a minio server and call Service Status Management API

Loading…
Cancel
Save