-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
error_helpers.go
97 lines (83 loc) · 3.73 KB
/
error_helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2019 Authors of Cilium
//
// 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 k8s
import (
"strings"
"time"
"github.com/cilium/cilium/pkg/lock"
)
var (
// k8sErrMsgMU guards additions and removals to k8sErrMsg, which stores a
// time after which a repeat error message can be printed
k8sErrMsgMU lock.Mutex
k8sErrMsg = map[string]time.Time{}
)
const k8sErrLogTimeout = time.Minute
// k8sErrorUpdateCheckUnmuteTime returns a boolean indicating whether we should
// log errmsg or not. It manages once-per-k8sErrLogTimeout entry in k8sErrMsg.
// When errmsg is new or more than k8sErrLogTimeout has passed since the last
// invocation that returned true, it returns true.
func k8sErrorUpdateCheckUnmuteTime(errstr string, now time.Time) bool {
k8sErrMsgMU.Lock()
defer k8sErrMsgMU.Unlock()
if unmuteDeadline, ok := k8sErrMsg[errstr]; !ok || now.After(unmuteDeadline) {
k8sErrMsg[errstr] = now.Add(k8sErrLogTimeout)
return true
}
return false
}
// K8sErrorHandler handles the error messages in a non verbose way by omitting
// repeated instances of the same error message for a timeout defined with
// k8sErrLogTimeout.
func K8sErrorHandler(e error) {
if e == nil {
return
}
// We rate-limit certain categories of error message. These are matched
// below, with a default behaviour to print everything else without
// rate-limiting.
// Note: We also have side-effects in some of the special cases.
now := time.Now()
errstr := e.Error()
switch {
// This can occur when cilium comes up before the k8s API server, and keeps
// trying to connect.
case strings.Contains(errstr, "connection refused"):
if k8sErrorUpdateCheckUnmuteTime(errstr, now) {
log.WithError(e).Error("k8sError")
}
// k8s does not allow us to watch both ThirdPartyResource and
// CustomResourceDefinition. This would occur when a user mixes these within
// the k8s cluster, and might occur when upgrading from versions of cilium
// that used ThirdPartyResource to define CiliumNetworkPolicy.
case strings.Contains(errstr, "Failed to list *v2.CiliumNetworkPolicy: the server could not find the requested resource"):
if k8sErrorUpdateCheckUnmuteTime(errstr, now) {
log.WithError(e).Error("No Cilium Network Policy CRD defined in the cluster, please set `--skip-crd-creation=false` to avoid seeing this error.")
}
// fromCIDR and toCIDR used to expect an "ip" subfield (so, they were a YAML
// map with one field) but common usage and expectation would simply list the
// CIDR ranges and IPs desired as a YAML list. In these cases we would see
// this decode error. We have since changed the definition to be a simple
// list of strings.
case strings.Contains(errstr, "Unable to decode an event from the watch stream: unable to decode watch event"),
strings.Contains(errstr, "Failed to list *v1.CiliumNetworkPolicy: only encoded map or array can be decoded into a struct"),
strings.Contains(errstr, "Failed to list *v2.CiliumNetworkPolicy: only encoded map or array can be decoded into a struct"),
strings.Contains(errstr, "Failed to list *v2.CiliumNetworkPolicy: v2.CiliumNetworkPolicyList:"):
if k8sErrorUpdateCheckUnmuteTime(errstr, now) {
log.WithError(e).Error("Unable to decode k8s watch event")
}
default:
log.WithError(e).Error("k8sError")
}
}