Skip to content

Commit

Permalink
added custom unmarshalling for timestamp and changed the scope to osd
Browse files Browse the repository at this point in the history
  • Loading branch information
shutstart committed Dec 17, 2024
1 parent 3173d30 commit 9c73a94
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 79 deletions.
77 changes: 14 additions & 63 deletions pkg/api/status_api_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package api
import (
"context"
"encoding/json"
"time"

pb "github.com/clyso/ceph-api/api/gen/grpc/go"
"github.com/clyso/ceph-api/pkg/rados"
Expand Down Expand Up @@ -79,7 +78,7 @@ func (s *statusAPI) GetCephMonDump(ctx context.Context, req *emptypb.Empty) (*pb
}

func (s *statusAPI) GetCephOsdDump(ctx context.Context, body *emptypb.Empty) (*pb.GetCephOsdDumpResponse, error) {
if err := user.HasPermissions(ctx, user.ScopeMonitor, user.PermRead); err != nil {
if err := user.HasPermissions(ctx, user.ScopeOsd, user.PermRead); err != nil {
return nil, err
}

Expand All @@ -94,44 +93,19 @@ func (s *statusAPI) GetCephOsdDump(ctx context.Context, body *emptypb.Empty) (*p
return nil, err
}

modifiedGoParsedTimestamp, err := parseCustomTimestamp(osdDump.Modified)
if err != nil {
return nil, err
}
modifiedTimestamp := timestamppb.New(modifiedGoParsedTimestamp)

createdGoParsedTimestamp, err := parseCustomTimestamp(osdDump.Created)
if err != nil {
return nil, err
}
createdTimestamp := timestamppb.New(createdGoParsedTimestamp)

lastUpChangeGoParsedTimestamp, err := parseCustomTimestamp(osdDump.LastUpChange)
if err != nil {
return nil, err
}
lastUpChange := timestamppb.New(lastUpChangeGoParsedTimestamp)
response := convertToPbGetCephOsdDumpResponse(osdDump)

lastInChangeGoParsedTimestamp, err := parseCustomTimestamp(osdDump.LastInChange)
if err != nil {
return nil, err
}
lastInChange := timestamppb.New(lastInChangeGoParsedTimestamp)
return response, nil
}

func convertToPbGetCephOsdDumpResponse(osdDump types.CephOsdDumpResponse) *pb.GetCephOsdDumpResponse {
// Convert pools
var osdDumpPools []*pb.OsdDumpPool
for _, pool := range osdDump.Pools {
createTimePbGoParsed, err := parseCustomTimestamp(pool.CreateTime)
if err != nil {
return nil, err
}

createTimePb := timestamppb.New(createTimePbGoParsed)

osdDumpPools = append(osdDumpPools, &pb.OsdDumpPool{
Pool: pool.Pool,
PoolName: pool.PoolName,
CreateTime: createTimePb,
CreateTime: pool.CreateTime.Timestamp,
Flags: pool.Flags,
FlagsNames: pool.FlagsNames,
Type: pool.Type,
Expand Down Expand Up @@ -195,42 +169,30 @@ func (s *statusAPI) GetCephOsdDump(ctx context.Context, body *emptypb.Empty) (*p

blocklistPb := make(map[string]*timestamppb.Timestamp, len(osdDump.Blocklist))
for ip, t := range osdDump.Blocklist {
goParsedTime, err := parseCustomTimestamp(t)
if err != nil {
return nil, err
}
blocklistPb[ip] = timestamppb.New(goParsedTime)
blocklistPb[ip] = t.Timestamp
}

var osdXInfo []*pb.OsdDumpOsdXInfo
for _, osdX := range osdDump.OsdXinfo {
downStamp, err := parseCustomTimestamp(osdX.DownStamp)
if err != nil {
return nil, err
}
lastPurgedSnapsScrub, err := parseCustomTimestamp(osdX.LastPurgedSnapsScrub)
if err != nil {
return nil, err
}
osdXInfo = append(osdXInfo, &pb.OsdDumpOsdXInfo{
Osd: osdX.Osd,
DownStamp: timestamppb.New(downStamp),
DownStamp: osdX.DownStamp.Timestamp,
LaggyProbability: osdX.LaggyProbability,
LaggyInterval: osdX.LaggyInterval,
Features: osdX.Features,
OldWeight: osdX.OldWeight,
LastPurgedSnapsScrub: timestamppb.New(lastPurgedSnapsScrub),
LastPurgedSnapsScrub: osdX.LastPurgedSnapsScrub.Timestamp,
DeadEpoch: osdX.DeadEpoch,
})
}

response := pb.GetCephOsdDumpResponse{
return &pb.GetCephOsdDumpResponse{
Epoch: osdDump.Epoch,
Fsid: osdDump.Fsid,
Modified: modifiedTimestamp,
Created: createdTimestamp,
LastUpChange: lastUpChange,
LastInChange: lastInChange,
Modified: osdDump.Modified.Timestamp,
Created: osdDump.Created.Timestamp,
LastUpChange: osdDump.LastUpChange.Timestamp,
LastInChange: osdDump.LastInChange.Timestamp,
Flags: osdDump.Flags,
FlagsNum: osdDump.FlagsNum,
FlagsSet: osdDump.FlagsSet,
Expand Down Expand Up @@ -268,15 +230,4 @@ func (s *statusAPI) GetCephOsdDump(ctx context.Context, body *emptypb.Empty) (*p
DeviceClassFlags: osdDump.DeviceClassFlags,
StretchMode: osdDump.StretchMode,
}

return &response, nil
}

func parseCustomTimestamp(timestamp string) (time.Time, error) {
const customTimeLayout = "2006-01-02T15:04:05.000000-0700"
if timestamp == "0.000000" || timestamp == "" {
// Return the zero time for Go, indicating an unset or invalid time.
return time.Time{}, nil
}
return time.Parse(customTimeLayout, timestamp)
}
57 changes: 43 additions & 14 deletions pkg/types/status.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package types

import (
"strings"
"time"

pb "github.com/clyso/ceph-api/api/gen/grpc/go"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
)

type CephMonDumpResponse struct {
Expand All @@ -27,10 +29,10 @@ type CephMonDumpResponse struct {
type CephOsdDumpResponse struct {
Epoch int32 `json:"epoch,omitempty"`
Fsid string `json:"fsid"`
Created string `json:"created"`
Modified string `json:"modified,omitempty"`
LastUpChange string `json:"last_up_change,omitempty"`
LastInChange string `json:"last_in_change,omitempty"`
Created CephTimestamp `json:"created"`
Modified CephTimestamp `json:"modified,omitempty"`
LastUpChange CephTimestamp `json:"last_up_change,omitempty"`
LastInChange CephTimestamp `json:"last_in_change,omitempty"`
Flags string `json:"flags,omitempty"`
FlagsNum int32 `json:"flags_num,omitempty"`
FlagsSet []string `json:"flags_set,omitempty"`
Expand All @@ -53,7 +55,7 @@ type CephOsdDumpResponse struct {
PgUpmapPrimaries []*structpb.Value `json:"pg_upmap_primaries,omitempty"`
PgTemp []*structpb.Value `json:"pg_temp,omitempty"`
PrimaryTemp []*structpb.Value `json:"primary_temp,omitempty"`
Blocklist map[string]string `json:"blocklist,omitempty"`
Blocklist map[string]CephTimestamp `json:"blocklist,omitempty"`
RangeBlocklist *structpb.Struct `json:"range_blocklist,omitempty"`
ErasureCodeProfiles map[string]*pb.OsdDumpErasureCodeProfile `json:"erasure_code_profiles,omitempty"`
RemovedSnapsQueue []*structpb.Value `json:"removed_snaps_queue,omitempty"`
Expand All @@ -67,7 +69,7 @@ type CephOsdDumpResponse struct {
type OsdDumpPool struct {
Pool int32 `json:"pool,omitempty"`
PoolName string `json:"pool_name,omitempty"`
CreateTime string `json:"create_time"`
CreateTime CephTimestamp `json:"create_time"`
Flags int64 `json:"flags,omitempty"`
FlagsNames string `json:"flags_names,omitempty"`
Type int32 `json:"type,omitempty"`
Expand Down Expand Up @@ -129,12 +131,39 @@ type OsdDumpPool struct {
}

type OsdDumpOsdXInfo struct {
Osd int32 `json:"osd,omitempty"`
DownStamp string `json:"down_stamp,omitempty"`
LaggyProbability float64 `json:"laggy_probability,omitempty"`
LaggyInterval float64 `json:"laggy_interval,omitempty"`
Features uint64 `json:"features,omitempty"`
OldWeight float64 `json:"old_weight,omitempty"`
LastPurgedSnapsScrub string `json:"last_purged_snaps_scrub,omitempty"`
DeadEpoch int32 `json:"dead_epoch,omitempty"`
Osd int32 `json:"osd,omitempty"`
DownStamp CephTimestamp `json:"down_stamp,omitempty"`
LaggyProbability float64 `json:"laggy_probability,omitempty"`
LaggyInterval float64 `json:"laggy_interval,omitempty"`
Features uint64 `json:"features,omitempty"`
OldWeight float64 `json:"old_weight,omitempty"`
LastPurgedSnapsScrub CephTimestamp `json:"last_purged_snaps_scrub,omitempty"`
DeadEpoch int32 `json:"dead_epoch,omitempty"`
}

type CephTimestamp struct {
*timestamppb.Timestamp
}

const customTimeLayout = "2006-01-02T15:04:05.000000-0700"

// custom unmashal function for CephTimestamp
func (ct *CephTimestamp) UnmarshalJSON(data []byte) error {
// data is a JSON string (e.g., "\"2023-05-01T12:34:56.000000-0700\"")

// First, trim surrounding quotes.
s := strings.Trim(string(data), `"`)

// Handle the "0.000000" or empty-string case
if s == "0.000000" || s == "" {
ct.Timestamp = timestamppb.New(time.Time{})
return nil
}

parsed, err := time.Parse(customTimeLayout, s)
if err != nil {
return err
}
ct.Timestamp = timestamppb.New(parsed)
return nil
}
2 changes: 0 additions & 2 deletions test/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ func Test_GetCephMonDump(t *testing.T) {
r.NotNil(res)

// Validate required fields in CephMonDumpResponse
r.NotEmpty(res.Epoch, "Epoch should not be empty")
r.NotEmpty(res.Fsid, "Fsid should not be empty")
r.NotEmpty(res.Modified, "Modified timestamp should not be empty")
r.NotEmpty(res.Created, "Created timestamp should not be empty")
Expand Down Expand Up @@ -79,7 +78,6 @@ func Test_GetCephOsdDump(t *testing.T) {
r.NotNil(res, "Response should not be nil")

// Top-level validations
r.NotEmpty(res.Epoch, "Epoch should not be empty")
r.NotEmpty(res.Fsid, "Fsid should not be empty")
r.NotNil(res.Created, "Created timestamp should not be nil")
r.NotNil(res.Modified, "Modified timestamp should not be nil")
Expand Down

0 comments on commit 9c73a94

Please sign in to comment.