Fix DefaultTolerationSeconds admission plugin. It was using

versioned object whereas admission plugins operate on internal objects.
This commit is contained in:
Avesh Agarwal
2017-03-08 16:22:39 -05:00
parent 7b4bec038c
commit 9f533de80d
5 changed files with 244 additions and 101 deletions

View File

@@ -15,7 +15,6 @@ go_test(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apiserver/pkg/admission",
],
@@ -26,8 +25,8 @@ go_library(
srcs = ["admission.go"],
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//vendor:github.com/golang/glog",
"//pkg/api:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apiserver/pkg/admission",
],

View File

@@ -21,11 +21,10 @@ import (
"fmt"
"io"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api"
)
var (
@@ -62,28 +61,32 @@ func NewDefaultTolerationSeconds() admission.Interface {
}
func (p *plugin) Admit(attributes admission.Attributes) (err error) {
if attributes.GetResource().GroupResource() != v1.Resource("pods") {
if attributes.GetResource().GroupResource() != api.Resource("pods") {
return nil
}
pod, ok := attributes.GetObject().(*v1.Pod)
if !ok {
glog.Errorf("expected pod but got %s", attributes.GetKind().Kind)
if len(attributes.GetSubresource()) > 0 {
// only run the checks below on pods proper and not subresources
return nil
}
pod, ok := attributes.GetObject().(*api.Pod)
if !ok {
return errors.NewBadRequest(fmt.Sprintf("expected *api.Pod but got %T", attributes.GetObject()))
}
tolerations := pod.Spec.Tolerations
toleratesNodeNotReady := false
toleratesNodeUnreachable := false
for _, toleration := range tolerations {
if (toleration.Key == metav1.TaintNodeNotReady || len(toleration.Key) == 0) &&
(toleration.Effect == v1.TaintEffectNoExecute || len(toleration.Effect) == 0) {
(toleration.Effect == api.TaintEffectNoExecute || len(toleration.Effect) == 0) {
toleratesNodeNotReady = true
}
if (toleration.Key == metav1.TaintNodeUnreachable || len(toleration.Key) == 0) &&
(toleration.Effect == v1.TaintEffectNoExecute || len(toleration.Effect) == 0) {
(toleration.Effect == api.TaintEffectNoExecute || len(toleration.Effect) == 0) {
toleratesNodeUnreachable = true
}
}
@@ -94,10 +97,10 @@ func (p *plugin) Admit(attributes admission.Attributes) (err error) {
}
if !toleratesNodeNotReady {
_, err := v1.AddOrUpdateTolerationInPod(pod, &v1.Toleration{
_, err := api.AddOrUpdateTolerationInPod(pod, &api.Toleration{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: defaultNotReadyTolerationSeconds,
})
if err != nil {
@@ -107,10 +110,10 @@ func (p *plugin) Admit(attributes admission.Attributes) (err error) {
}
if !toleratesNodeUnreachable {
_, err := v1.AddOrUpdateTolerationInPod(pod, &v1.Toleration{
_, err := api.AddOrUpdateTolerationInPod(pod, &api.Toleration{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: defaultUnreachableTolerationSeconds,
})
if err != nil {

View File

@@ -22,7 +22,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
)
func TestForgivenessAdmission(t *testing.T) {
@@ -35,27 +34,27 @@ func TestForgivenessAdmission(t *testing.T) {
handler := NewDefaultTolerationSeconds()
tests := []struct {
description string
requestedPod v1.Pod
expectedPod v1.Pod
requestedPod api.Pod
expectedPod api.Pod
}{
{
description: "pod has no tolerations, expect add tolerations for `notread:NoExecute` and `unreachable:NoExecute`",
requestedPod: v1.Pod{
Spec: v1.PodSpec{},
requestedPod: api.Pod{
Spec: api.PodSpec{},
},
expectedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
expectedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: &defaultTolerationSeconds,
},
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: &defaultTolerationSeconds,
},
},
@@ -64,39 +63,39 @@ func TestForgivenessAdmission(t *testing.T) {
},
{
description: "pod has tolerations, but none is for taint `notread:NoExecute` or `unreachable:NoExecute`, expect add tolerations for `notread:NoExecute` and `unreachable:NoExecute`",
requestedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
requestedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: "foo",
Operator: v1.TolerationOpEqual,
Operator: api.TolerationOpEqual,
Value: "bar",
Effect: v1.TaintEffectNoSchedule,
Effect: api.TaintEffectNoSchedule,
TolerationSeconds: genTolerationSeconds(700),
},
},
},
},
expectedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
expectedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: "foo",
Operator: v1.TolerationOpEqual,
Operator: api.TolerationOpEqual,
Value: "bar",
Effect: v1.TaintEffectNoSchedule,
Effect: api.TaintEffectNoSchedule,
TolerationSeconds: genTolerationSeconds(700),
},
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: &defaultTolerationSeconds,
},
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: &defaultTolerationSeconds,
},
},
@@ -105,31 +104,31 @@ func TestForgivenessAdmission(t *testing.T) {
},
{
description: "pod specified a toleration for taint `notReady:NoExecute`, expect add toleration for `unreachable:NoExecute`",
requestedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
requestedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
},
},
},
expectedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
expectedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: &defaultTolerationSeconds,
},
},
@@ -138,31 +137,31 @@ func TestForgivenessAdmission(t *testing.T) {
},
{
description: "pod specified a toleration for taint `unreachable:NoExecute`, expect add toleration for `notReady:NoExecute`",
requestedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
requestedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
},
},
},
expectedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
expectedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: &defaultTolerationSeconds,
},
},
@@ -171,37 +170,37 @@ func TestForgivenessAdmission(t *testing.T) {
},
{
description: "pod specified tolerations for both `notread:NoExecute` and `unreachable:NoExecute`, expect no change",
requestedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
requestedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
},
},
},
expectedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
expectedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(700),
},
},
@@ -210,29 +209,29 @@ func TestForgivenessAdmission(t *testing.T) {
},
{
description: "pod specified toleration for taint `unreachable`, expect add toleration for `notReady:NoExecute`",
requestedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
requestedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Operator: api.TolerationOpExists,
TolerationSeconds: genTolerationSeconds(700),
},
},
},
},
expectedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
expectedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Key: metav1.TaintNodeUnreachable,
Operator: v1.TolerationOpExists,
Operator: api.TolerationOpExists,
TolerationSeconds: genTolerationSeconds(700),
},
{
Key: metav1.TaintNodeNotReady,
Operator: v1.TolerationOpExists,
Effect: v1.TaintEffectNoExecute,
Operator: api.TolerationOpExists,
Effect: api.TaintEffectNoExecute,
TolerationSeconds: genTolerationSeconds(300),
},
},
@@ -241,18 +240,18 @@ func TestForgivenessAdmission(t *testing.T) {
},
{
description: "pod has wildcard toleration for all kind of taints, expect no change",
requestedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
{Operator: v1.TolerationOpExists, TolerationSeconds: genTolerationSeconds(700)},
requestedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{Operator: api.TolerationOpExists, TolerationSeconds: genTolerationSeconds(700)},
},
},
},
expectedPod: v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
expectedPod: api.Pod{
Spec: api.PodSpec{
Tolerations: []api.Toleration{
{
Operator: v1.TolerationOpExists,
Operator: api.TolerationOpExists,
TolerationSeconds: genTolerationSeconds(700),
},
},
@@ -262,7 +261,7 @@ func TestForgivenessAdmission(t *testing.T) {
}
for _, test := range tests {
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", v1.Resource("pods").WithVersion("version"), "", "ignored", nil))
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
if err != nil {
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
}