-
Notifications
You must be signed in to change notification settings - Fork 4.7k
/
tolerations.go
93 lines (85 loc) · 3.46 KB
/
tolerations.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
package operators
import (
"context"
"fmt"
"strings"
. "github.com/onsi/ginkgo"
exutil "github.com/openshift/origin/test/extended/util"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
e2e "k8s.io/kubernetes/test/e2e/framework"
)
var _ = Describe("[sig-arch] Managed cluster should", func() {
oc := exutil.NewCLIWithoutNamespace("operators")
It("ensure control plane operators do not make themselves unevictable", func() {
// iterate over the references to find valid images
pods, err := oc.KubeFramework().ClientSet.CoreV1().Pods("").List(context.Background(), metav1.ListOptions{})
if err != nil {
e2e.Failf("unable to list pods: %v", err)
}
// list of pods that use images not in the release payload
invalidPodTolerations := sets.NewString()
// a pod in a namespace that begins with kube-* or openshift-* must come from our release payload
// TODO components in openshift-operators may not come from our payload, may want to weaken restriction
namespacePrefixes := sets.NewString("kube-", "openshift-")
excludedNamespaces := sets.NewString("openshift-kube-apiserver", "openshift-kube-controller-manager", "openshift-kube-scheduler", "openshift-etcd", "openshift-openstack-infra", "openshift-ovirt-infra")
// exclude these pods from checks
whitelistPods := sets.NewString("network-operator", "dns-operator", "olm-operators", "gcp-routes-controller", "ovnkube-master", "must-gather")
for _, pod := range pods.Items {
// exclude non-control plane namespaces
if !hasPrefixSet(pod.Namespace, namespacePrefixes) {
continue
}
// exclude static pod managed namespaces
if excludedNamespaces.Has(pod.Namespace) {
continue
}
if hasPrefixSet(pod.Name, whitelistPods) {
continue
}
// exclude pods started by DaemonSets
if ownedByDaemonSet(pod) {
continue
}
for _, toleration := range pod.Spec.Tolerations {
if toleration.Operator == v1.TolerationOpExists && toleration.Effect == v1.TaintEffectNoExecute {
if toleration.Key == "" {
invalidPodTolerations.Insert(fmt.Sprintf("%s/%s tolerates all taints", pod.Namespace, pod.Name))
}
if toleration.Key == v1.TaintNodeUnreachable || toleration.Key == v1.TaintNodeNotReady {
if toleration.TolerationSeconds == nil {
invalidPodTolerations.Insert(fmt.Sprintf("%s/%s tolerates %s with no tolerationSeconds", pod.Namespace, pod.Name, toleration.Key))
}
/* TODO enable this once we can get tolerationSeconds explicity defined in every component */
/*if *toleration.TolerationSeconds == 300 {
invalidPodTolerations.Insert(fmt.Sprintf("%s/%s tolerates %s with default tolerationSeconds", pod.Namespace, pod.Name, toleration.Key))
}*/
}
}
}
}
// log for debugging output before we ultimately fail
//e2e.Logf("Pods found with invalid tolerations: %s", strings.Join(invalidPodTolerations.List(), "\n"))
numInvalidPodTolerations := len(invalidPodTolerations)
if numInvalidPodTolerations > 0 {
e2e.Failf("\n%d pods found with invalid tolerations:\n%s", numInvalidPodTolerations, strings.Join(invalidPodTolerations.List(), "\n"))
}
})
})
func hasPrefixSet(name string, set sets.String) bool {
for _, prefix := range set.List() {
if strings.HasPrefix(name, prefix) {
return true
}
}
return false
}
func ownedByDaemonSet(pod v1.Pod) bool {
for _, ownerRef := range pod.OwnerReferences {
if ownerRef.Kind == "DaemonSet" {
return true
}
}
return false
}