2018-10-16 18:40:34 +01:00
|
|
|
// Copyright (C) 2018 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package audit
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
2018-12-04 18:47:58 +00:00
|
|
|
"storj.io/storj/pkg/pb"
|
|
|
|
"storj.io/storj/pkg/statdb"
|
|
|
|
statsproto "storj.io/storj/pkg/statdb/proto"
|
2018-11-29 18:39:27 +00:00
|
|
|
"storj.io/storj/pkg/storj"
|
2018-10-16 18:40:34 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type reporter interface {
|
2018-12-04 18:47:58 +00:00
|
|
|
RecordAudits(ctx context.Context, failedNodes []*pb.Node) (err error)
|
2018-10-16 18:40:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Reporter records audit reports in statdb and implements the reporter interface
|
|
|
|
type Reporter struct {
|
2018-12-04 18:47:58 +00:00
|
|
|
statdb *statdb.StatDB
|
2018-10-16 18:40:34 +01:00
|
|
|
maxRetries int
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewReporter instantiates a reporter
|
2018-11-07 01:16:43 +00:00
|
|
|
func NewReporter(ctx context.Context, statDBPort string, maxRetries int, apiKey string) (reporter *Reporter, err error) {
|
2018-12-04 18:47:58 +00:00
|
|
|
sdb := statdb.LoadFromContext(ctx)
|
2018-10-16 18:40:34 +01:00
|
|
|
|
2018-12-04 18:47:58 +00:00
|
|
|
return &Reporter{statdb: sdb, maxRetries: maxRetries}, nil
|
2018-10-16 18:40:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// RecordAudits saves failed audit details to statdb
|
2018-12-04 18:47:58 +00:00
|
|
|
func (reporter *Reporter) RecordAudits(ctx context.Context, nodes []*pb.Node) (err error) {
|
2018-10-16 18:40:34 +01:00
|
|
|
retries := 0
|
|
|
|
for len(nodes) > 0 && retries < reporter.maxRetries {
|
2018-12-04 18:47:58 +00:00
|
|
|
res, err := reporter.statdb.UpdateBatch(ctx, &statsproto.UpdateBatchRequest{
|
|
|
|
NodeList: nodes,
|
|
|
|
})
|
2018-10-16 18:40:34 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-12-04 18:47:58 +00:00
|
|
|
nodes = res.GetFailedNodes()
|
2018-10-16 18:40:34 +01:00
|
|
|
retries++
|
|
|
|
}
|
|
|
|
if retries >= reporter.maxRetries && len(nodes) > 0 {
|
|
|
|
return Error.New("some nodes who failed the audit also failed to be updated in statdb")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-12-04 18:47:58 +00:00
|
|
|
func setAuditFailStatus(ctx context.Context, failedNodes storj.NodeIDList) (failStatusNodes []*pb.Node) {
|
2018-10-16 18:40:34 +01:00
|
|
|
for i := range failedNodes {
|
2018-12-04 18:47:58 +00:00
|
|
|
setNode := &pb.Node{
|
2018-11-29 18:39:27 +00:00
|
|
|
Id: failedNodes[i],
|
2018-10-16 18:40:34 +01:00
|
|
|
AuditSuccess: false,
|
|
|
|
IsUp: true,
|
|
|
|
UpdateAuditSuccess: true,
|
|
|
|
UpdateUptime: true,
|
|
|
|
}
|
|
|
|
failStatusNodes = append(failStatusNodes, setNode)
|
|
|
|
}
|
|
|
|
return failStatusNodes
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: offline nodes should maybe be marked as failing the audit in the future
|
2018-12-04 18:47:58 +00:00
|
|
|
func setOfflineStatus(ctx context.Context, offlineNodeIDs storj.NodeIDList) (offlineStatusNodes []*pb.Node) {
|
2018-10-16 18:40:34 +01:00
|
|
|
for i := range offlineNodeIDs {
|
2018-12-04 18:47:58 +00:00
|
|
|
setNode := &pb.Node{
|
2018-11-29 18:39:27 +00:00
|
|
|
Id: offlineNodeIDs[i],
|
2018-10-16 18:40:34 +01:00
|
|
|
IsUp: false,
|
|
|
|
UpdateUptime: true,
|
|
|
|
}
|
|
|
|
offlineStatusNodes = append(offlineStatusNodes, setNode)
|
|
|
|
}
|
|
|
|
return offlineStatusNodes
|
|
|
|
}
|
|
|
|
|
2018-12-04 18:47:58 +00:00
|
|
|
func setSuccessStatus(ctx context.Context, offlineNodeIDs storj.NodeIDList) (successStatusNodes []*pb.Node) {
|
2018-10-16 18:40:34 +01:00
|
|
|
for i := range offlineNodeIDs {
|
2018-12-04 18:47:58 +00:00
|
|
|
setNode := &pb.Node{
|
2018-11-29 18:39:27 +00:00
|
|
|
Id: offlineNodeIDs[i],
|
2018-10-16 18:40:34 +01:00
|
|
|
AuditSuccess: true,
|
|
|
|
IsUp: true,
|
|
|
|
UpdateAuditSuccess: true,
|
|
|
|
UpdateUptime: true,
|
|
|
|
}
|
|
|
|
successStatusNodes = append(successStatusNodes, setNode)
|
|
|
|
}
|
|
|
|
return successStatusNodes
|
|
|
|
}
|