2016-11-05 17:09:05 -07:00
|
|
|
/*
|
|
|
|
|
Copyright 2016 The Rook Authors. All rights reserved.
|
|
|
|
|
|
|
|
|
|
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.
|
2017-03-10 19:00:27 -08:00
|
|
|
|
|
|
|
|
Some of the code below came from https://github.com/digitalocean/ceph_exporter
|
|
|
|
|
which has the same license.
|
2016-11-05 17:09:05 -07:00
|
|
|
*/
|
2016-10-27 11:11:54 -07:00
|
|
|
package client
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
"github.com/rook/rook/pkg/clusterd"
|
2016-10-27 11:11:54 -07:00
|
|
|
"github.com/rook/rook/pkg/model"
|
|
|
|
|
)
|
|
|
|
|
|
2017-03-10 19:00:27 -08:00
|
|
|
const (
|
|
|
|
|
// CephHealthOK denotes the status of ceph cluster when healthy.
|
|
|
|
|
CephHealthOK = "HEALTH_OK"
|
|
|
|
|
|
|
|
|
|
// CephHealthWarn denotes the status of ceph cluster when unhealthy but recovering.
|
|
|
|
|
CephHealthWarn = "HEALTH_WARN"
|
|
|
|
|
|
|
|
|
|
// CephHealthErr denotes the status of ceph cluster when unhealthy but usually needs
|
|
|
|
|
// manual intervention.
|
|
|
|
|
CephHealthErr = "HEALTH_ERR"
|
|
|
|
|
)
|
|
|
|
|
|
2016-10-27 11:11:54 -07:00
|
|
|
type CephStatus struct {
|
|
|
|
|
Health HealthStatus `json:"health"`
|
|
|
|
|
FSID string `json:"fsid"`
|
|
|
|
|
ElectionEpoch int `json:"election_epoch"`
|
|
|
|
|
Quorum []int `json:"quorum"`
|
|
|
|
|
QuorumNames []string `json:"quorum_names"`
|
|
|
|
|
MonMap MonMap `json:"monmap"`
|
|
|
|
|
OsdMap struct {
|
|
|
|
|
OsdMap OsdMap `json:"osdmap"`
|
|
|
|
|
} `json:"osdmap"`
|
2017-06-13 12:33:08 -07:00
|
|
|
PgMap PgMap `json:"pgmap"`
|
|
|
|
|
MgrMap MgrMap `json:"mgrmap"`
|
2016-10-27 11:11:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type HealthStatus struct {
|
2017-08-01 20:43:15 -07:00
|
|
|
Status string `json:"status"`
|
|
|
|
|
Checks map[string]CheckMessage `json:"checks"`
|
2016-10-27 11:11:54 -07:00
|
|
|
}
|
|
|
|
|
|
2017-08-01 20:43:15 -07:00
|
|
|
type CheckMessage struct {
|
2016-10-27 11:11:54 -07:00
|
|
|
Severity string `json:"severity"`
|
2017-08-11 15:50:40 -07:00
|
|
|
Summary struct {
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
} `json:"summary"`
|
2016-10-27 11:11:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type MonMap struct {
|
|
|
|
|
Epoch int `json:"epoch"`
|
|
|
|
|
FSID string `json:"fsid"`
|
|
|
|
|
CreatedTime string `json:"created"`
|
|
|
|
|
ModifiedTime string `json:"modified"`
|
|
|
|
|
Mons []MonMapEntry `json:"mons"`
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-13 12:33:08 -07:00
|
|
|
type MgrMap struct {
|
|
|
|
|
Epoch int `json:"epoch"`
|
|
|
|
|
ActiveGID int `json:"active_gid"`
|
|
|
|
|
ActiveName string `json:"active_name"`
|
|
|
|
|
ActiveAddr string `json:"active_addr"`
|
|
|
|
|
Available bool `json:"available"`
|
|
|
|
|
Standbys []MgrStandby `json:"standbys"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type MgrStandby struct {
|
|
|
|
|
GID int `json:"gid"`
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 11:11:54 -07:00
|
|
|
type OsdMap struct {
|
|
|
|
|
Epoch int `json:"epoch"`
|
|
|
|
|
NumOsd int `json:"num_osds"`
|
|
|
|
|
NumUpOsd int `json:"num_up_osds"`
|
|
|
|
|
NumInOsd int `json:"num_in_osds"`
|
|
|
|
|
Full bool `json:"full"`
|
|
|
|
|
NearFull bool `json:"nearfull"`
|
|
|
|
|
NumRemappedPgs int `json:"num_remapped_pgs"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PgMap struct {
|
2017-08-11 15:50:40 -07:00
|
|
|
PgsByState []PgStateEntry `json:"pgs_by_state"`
|
|
|
|
|
Version int `json:"version"`
|
|
|
|
|
NumPgs int `json:"num_pgs"`
|
|
|
|
|
DataBytes uint64 `json:"data_bytes"`
|
|
|
|
|
UsedBytes uint64 `json:"bytes_used"`
|
|
|
|
|
AvailableBytes uint64 `json:"bytes_avail"`
|
|
|
|
|
TotalBytes uint64 `json:"bytes_total"`
|
|
|
|
|
ReadBps uint64 `json:"read_bytes_sec"`
|
|
|
|
|
WriteBps uint64 `json:"write_bytes_sec"`
|
|
|
|
|
ReadOps uint64 `json:"read_op_per_sec"`
|
|
|
|
|
WriteOps uint64 `json:"write_op_per_sec"`
|
|
|
|
|
RecoveryBps uint64 `json:"recovering_bytes_per_sec"`
|
|
|
|
|
RecoveryObjectsPerSec uint64 `json:"recovering_objects_per_sec"`
|
|
|
|
|
RecoveryKeysPerSec uint64 `json:"recovering_keys_per_sec"`
|
|
|
|
|
CacheFlushBps uint64 `json:"flush_bytes_sec"`
|
|
|
|
|
CacheEvictBps uint64 `json:"evict_bytes_sec"`
|
|
|
|
|
CachePromoteBps uint64 `json:"promote_op_per_sec"`
|
2016-10-27 11:11:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PgStateEntry struct {
|
|
|
|
|
StateName string `json:"state_name"`
|
|
|
|
|
Count int `json:"count"`
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
func Status(context *clusterd.Context, clusterName string) (CephStatus, error) {
|
2017-06-13 12:33:08 -07:00
|
|
|
args := []string{"status"}
|
2017-06-02 13:44:54 -07:00
|
|
|
buf, err := ExecuteCephCommand(context, clusterName, args)
|
2016-10-27 11:11:54 -07:00
|
|
|
if err != nil {
|
|
|
|
|
return CephStatus{}, fmt.Errorf("failed to get status: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var status CephStatus
|
|
|
|
|
if err := json.Unmarshal(buf, &status); err != nil {
|
|
|
|
|
return CephStatus{}, fmt.Errorf("failed to unmarshal status response: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return status, nil
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-02 13:44:54 -07:00
|
|
|
func StatusPlain(context *clusterd.Context, clusterName string) ([]byte, error) {
|
|
|
|
|
args := []string{"status"}
|
|
|
|
|
buf, err := ExecuteCephCommandPlain(context, clusterName, args)
|
2017-03-10 19:00:27 -08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to get status: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf, nil
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 11:11:54 -07:00
|
|
|
func HealthToModelHealthStatus(cephHealth string) model.HealthStatus {
|
|
|
|
|
switch cephHealth {
|
2017-03-10 19:00:27 -08:00
|
|
|
case CephHealthOK:
|
2016-10-27 11:11:54 -07:00
|
|
|
return model.HealthOK
|
2017-03-10 19:00:27 -08:00
|
|
|
case CephHealthWarn:
|
2016-10-27 11:11:54 -07:00
|
|
|
return model.HealthWarning
|
2017-03-10 19:00:27 -08:00
|
|
|
case CephHealthErr:
|
2016-10-27 11:11:54 -07:00
|
|
|
return model.HealthError
|
|
|
|
|
default:
|
|
|
|
|
return model.HealthUnknown
|
|
|
|
|
}
|
|
|
|
|
}
|