...
1 package internal
2
3 import (
4 "errors"
5 "fmt"
6 "strings"
7
8 "net/http"
9
10 "edge-infra.dev/pkg/k8s/runtime/conditions"
11
12 "github.com/go-logr/logr"
13 )
14
15
16
17
18
19
20
21 const (
22 maxIterations = 100
23 errThreshold = 95
24 )
25
26
27
28 var knownUnrecoverableErrs = []string{
29 "no matching credentials were found",
30 }
31
32 type livenessStatus struct {
33 err error
34 objName string
35 }
36
37
38
39
40
41
42
43
44
45
46
47
48
49 type LivenessChecker struct {
50 statuses []livenessStatus
51 logger logr.Logger
52 currIteration int
53 }
54
55
56
57 func New(l logr.Logger) *LivenessChecker {
58 return &LivenessChecker{
59 statuses: make([]livenessStatus, maxIterations),
60 logger: l,
61 }
62 }
63
64
65
66 func (lc *LivenessChecker) AddStatus(obj conditions.Setter, err error) {
67 if err != nil && strings.Contains(strings.ToLower(err.Error()), "go-containerregistry") {
68 for _, errSubstr := range knownUnrecoverableErrs {
69 if strings.Contains(errSubstr, err.Error()) {
70 unrecoverableErrMsg := fmt.Sprintf("found unrecoverable error: %s", err)
71 lc.logger.Error(err, unrecoverableErrMsg)
72 }
73 }
74 }
75
76 ls := livenessStatus{
77 err: err,
78 objName: obj.GetName(),
79 }
80
81 lc.statuses[lc.currIteration%maxIterations] = ls
82
83 lc.currIteration++
84 }
85
86
87
88 func (lc *LivenessChecker) Status() error {
89 errCount := 0
90 var err error
91 for _, status := range lc.statuses {
92 if status.err != nil {
93 errCount++
94 }
95 if errCount == errThreshold {
96 err = status.err
97
98 lc.logger.Error(err, "unrecoverable error in lumperctl liveness")
99 return err
100 }
101 }
102
103 return nil
104 }
105
106
107
108 func (lc *LivenessChecker) Check(req *http.Request) error {
109 if req.Method != http.MethodGet {
110 return errors.New("please use http GET for liveness status")
111 }
112
113 return lc.Status()
114 }
115
View as plain text