...
1
16
17 package defaulttolerationseconds
18
19 import (
20 "context"
21 "flag"
22 "fmt"
23 "io"
24
25 v1 "k8s.io/api/core/v1"
26 "k8s.io/apimachinery/pkg/api/errors"
27 "k8s.io/apiserver/pkg/admission"
28 api "k8s.io/kubernetes/pkg/apis/core"
29 )
30
31
32 const PluginName = "DefaultTolerationSeconds"
33
34 var (
35 defaultNotReadyTolerationSeconds = flag.Int64("default-not-ready-toleration-seconds", 300,
36 "Indicates the tolerationSeconds of the toleration for notReady:NoExecute"+
37 " that is added by default to every pod that does not already have such a toleration.")
38
39 defaultUnreachableTolerationSeconds = flag.Int64("default-unreachable-toleration-seconds", 300,
40 "Indicates the tolerationSeconds of the toleration for unreachable:NoExecute"+
41 " that is added by default to every pod that does not already have such a toleration.")
42
43 notReadyToleration = api.Toleration{
44 Key: v1.TaintNodeNotReady,
45 Operator: api.TolerationOpExists,
46 Effect: api.TaintEffectNoExecute,
47 TolerationSeconds: defaultNotReadyTolerationSeconds,
48 }
49
50 unreachableToleration = api.Toleration{
51 Key: v1.TaintNodeUnreachable,
52 Operator: api.TolerationOpExists,
53 Effect: api.TaintEffectNoExecute,
54 TolerationSeconds: defaultUnreachableTolerationSeconds,
55 }
56 )
57
58
59 func Register(plugins *admission.Plugins) {
60 plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
61 return NewDefaultTolerationSeconds(), nil
62 })
63 }
64
65
66
67
68
69
70
71 type Plugin struct {
72 *admission.Handler
73 }
74
75 var _ admission.MutationInterface = &Plugin{}
76
77
78 func NewDefaultTolerationSeconds() *Plugin {
79 return &Plugin{
80 Handler: admission.NewHandler(admission.Create, admission.Update),
81 }
82 }
83
84
85 func (p *Plugin) Admit(ctx context.Context, attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
86 if attributes.GetResource().GroupResource() != api.Resource("pods") {
87 return nil
88 }
89
90 if len(attributes.GetSubresource()) > 0 {
91
92 return nil
93 }
94
95 pod, ok := attributes.GetObject().(*api.Pod)
96 if !ok {
97 return errors.NewBadRequest(fmt.Sprintf("expected *api.Pod but got %T", attributes.GetObject()))
98 }
99
100 tolerations := pod.Spec.Tolerations
101
102 toleratesNodeNotReady := false
103 toleratesNodeUnreachable := false
104 for _, toleration := range tolerations {
105 if (toleration.Key == v1.TaintNodeNotReady || len(toleration.Key) == 0) &&
106 (toleration.Effect == api.TaintEffectNoExecute || len(toleration.Effect) == 0) {
107 toleratesNodeNotReady = true
108 }
109
110 if (toleration.Key == v1.TaintNodeUnreachable || len(toleration.Key) == 0) &&
111 (toleration.Effect == api.TaintEffectNoExecute || len(toleration.Effect) == 0) {
112 toleratesNodeUnreachable = true
113 }
114 }
115
116 if !toleratesNodeNotReady {
117 pod.Spec.Tolerations = append(pod.Spec.Tolerations, notReadyToleration)
118 }
119
120 if !toleratesNodeUnreachable {
121 pod.Spec.Tolerations = append(pod.Spec.Tolerations, unreachableToleration)
122 }
123
124 return nil
125 }
126
View as plain text