mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #39851 from liggitt/taint-versioned
Automatic merge from submit-queue Use versioned Taint/Toleration/AvoidPods objects when marshalling fixes #39847 `kubectl taint`, the kubelet's `--register-with-taints` option, and several Taint/Toleration/AllowPod annotation helpers were marshaling/unmarshaling using internal structs
This commit is contained in:
		@@ -16,6 +16,7 @@ go_library(
 | 
			
		||||
        "doc.go",
 | 
			
		||||
        "field_constants.go",
 | 
			
		||||
        "helpers.go",
 | 
			
		||||
        "json.go",
 | 
			
		||||
        "mapper.go",
 | 
			
		||||
        "meta.go",
 | 
			
		||||
        "ref.go",
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,6 @@ package api
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/md5"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
@@ -486,32 +485,6 @@ const (
 | 
			
		||||
	UnsafeSysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/unsafe-sysctls"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
 | 
			
		||||
// and converts it to the []Toleration type in api.
 | 
			
		||||
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) {
 | 
			
		||||
	var tolerations []Toleration
 | 
			
		||||
	if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" {
 | 
			
		||||
		err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return tolerations, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return tolerations, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
 | 
			
		||||
// and converts it to the []Taint type in api.
 | 
			
		||||
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) {
 | 
			
		||||
	var taints []Taint
 | 
			
		||||
	if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" {
 | 
			
		||||
		err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return []Taint{}, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return taints, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TolerationToleratesTaint checks if the toleration tolerates the taint.
 | 
			
		||||
func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool {
 | 
			
		||||
	if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
 | 
			
		||||
@@ -557,17 +530,6 @@ func (t *Taint) ToString() string {
 | 
			
		||||
	return fmt.Sprintf("%v=%v:%v", t.Key, t.Value, t.Effect)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (AvoidPods, error) {
 | 
			
		||||
	var avoidPods AvoidPods
 | 
			
		||||
	if len(annotations) > 0 && annotations[PreferAvoidPodsAnnotationKey] != "" {
 | 
			
		||||
		err := json.Unmarshal([]byte(annotations[PreferAvoidPodsAnnotationKey]), &avoidPods)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return avoidPods, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return avoidPods, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
 | 
			
		||||
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
 | 
			
		||||
// SysctlsFromPodAnnotation.
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,6 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/labels"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/resource"
 | 
			
		||||
)
 | 
			
		||||
@@ -342,102 +341,6 @@ func TestMatchTaint(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetAvoidPodsFromNode(t *testing.T) {
 | 
			
		||||
	controllerFlag := true
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		node        *Node
 | 
			
		||||
		expectValue AvoidPods
 | 
			
		||||
		expectErr   bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			node:        &Node{},
 | 
			
		||||
			expectValue: AvoidPods{},
 | 
			
		||||
			expectErr:   false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			node: &Node{
 | 
			
		||||
				ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
					Annotations: map[string]string{
 | 
			
		||||
						PreferAvoidPodsAnnotationKey: `
 | 
			
		||||
							{
 | 
			
		||||
							    "preferAvoidPods": [
 | 
			
		||||
							        {
 | 
			
		||||
							            "podSignature": {
 | 
			
		||||
							                "podController": {
 | 
			
		||||
						                            "apiVersion": "v1",
 | 
			
		||||
						                            "kind": "ReplicationController",
 | 
			
		||||
						                            "name": "foo",
 | 
			
		||||
						                            "uid": "abcdef123456",
 | 
			
		||||
						                            "controller": true
 | 
			
		||||
							                }
 | 
			
		||||
							            },
 | 
			
		||||
							            "reason": "some reason",
 | 
			
		||||
							            "message": "some message"
 | 
			
		||||
							        }
 | 
			
		||||
							    ]
 | 
			
		||||
							}`,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectValue: AvoidPods{
 | 
			
		||||
				PreferAvoidPods: []PreferAvoidPodsEntry{
 | 
			
		||||
					{
 | 
			
		||||
						PodSignature: PodSignature{
 | 
			
		||||
							PodController: &metav1.OwnerReference{
 | 
			
		||||
								APIVersion: "v1",
 | 
			
		||||
								Kind:       "ReplicationController",
 | 
			
		||||
								Name:       "foo",
 | 
			
		||||
								UID:        "abcdef123456",
 | 
			
		||||
								Controller: &controllerFlag,
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
						Reason:  "some reason",
 | 
			
		||||
						Message: "some message",
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			node: &Node{
 | 
			
		||||
				// Missing end symbol of "podController" and "podSignature"
 | 
			
		||||
				ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
					Annotations: map[string]string{
 | 
			
		||||
						PreferAvoidPodsAnnotationKey: `
 | 
			
		||||
							{
 | 
			
		||||
							    "preferAvoidPods": [
 | 
			
		||||
							        {
 | 
			
		||||
							            "podSignature": {
 | 
			
		||||
							                "podController": {
 | 
			
		||||
							                    "kind": "ReplicationController",
 | 
			
		||||
							                    "apiVersion": "v1"
 | 
			
		||||
							            "reason": "some reason",
 | 
			
		||||
							            "message": "some message"
 | 
			
		||||
							        }
 | 
			
		||||
							    ]
 | 
			
		||||
							}`,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectValue: AvoidPods{},
 | 
			
		||||
			expectErr:   true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, tc := range testCases {
 | 
			
		||||
		v, err := GetAvoidPodsFromNodeAnnotations(tc.node.Annotations)
 | 
			
		||||
		if err == nil && tc.expectErr {
 | 
			
		||||
			t.Errorf("[%v]expected error but got none.", i)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil && !tc.expectErr {
 | 
			
		||||
			t.Errorf("[%v]did not expect error but got: %v", i, err)
 | 
			
		||||
		}
 | 
			
		||||
		if !reflect.DeepEqual(tc.expectValue, v) {
 | 
			
		||||
			t.Errorf("[%v]expect value %v but got %v with %v", i, tc.expectValue, v, v.PreferAvoidPods[0].PodSignature.PodController.Controller)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSysctlsFromPodAnnotation(t *testing.T) {
 | 
			
		||||
	type Test struct {
 | 
			
		||||
		annotation  string
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								pkg/api/json.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								pkg/api/json.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2017 The Kubernetes Authors.
 | 
			
		||||
 | 
			
		||||
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 api
 | 
			
		||||
 | 
			
		||||
import "encoding/json"
 | 
			
		||||
 | 
			
		||||
// This file implements json marshaling/unmarshaling interfaces on objects that are currently marshaled into annotations
 | 
			
		||||
// to prevent anyone from marshaling these internal structs.
 | 
			
		||||
 | 
			
		||||
var _ = json.Marshaler(Taint{})
 | 
			
		||||
var _ = json.Unmarshaler(&Taint{})
 | 
			
		||||
 | 
			
		||||
func (Taint) MarshalJSON() ([]byte, error) { panic("do not marshal internal struct") }
 | 
			
		||||
func (*Taint) UnmarshalJSON([]byte) error  { panic("do not unmarshal to internal struct") }
 | 
			
		||||
 | 
			
		||||
var _ = json.Marshaler(Toleration{})
 | 
			
		||||
var _ = json.Unmarshaler(&Toleration{})
 | 
			
		||||
 | 
			
		||||
func (Toleration) MarshalJSON() ([]byte, error) { panic("do not marshal internal struct") }
 | 
			
		||||
func (*Toleration) UnmarshalJSON([]byte) error  { panic("do not unmarshal to internal struct") }
 | 
			
		||||
 | 
			
		||||
var _ = json.Marshaler(&AvoidPods{})
 | 
			
		||||
var _ = json.Unmarshaler(&AvoidPods{})
 | 
			
		||||
 | 
			
		||||
func (AvoidPods) MarshalJSON() ([]byte, error) { panic("do not marshal internal struct") }
 | 
			
		||||
func (*AvoidPods) UnmarshalJSON([]byte) error  { panic("do not unmarshal to internal struct") }
 | 
			
		||||
@@ -23,6 +23,7 @@ go_library(
 | 
			
		||||
        "//pkg/api/resource:go_default_library",
 | 
			
		||||
        "//pkg/api/service:go_default_library",
 | 
			
		||||
        "//pkg/api/util:go_default_library",
 | 
			
		||||
        "//pkg/api/v1:go_default_library",
 | 
			
		||||
        "//pkg/api/validation/genericvalidation:go_default_library",
 | 
			
		||||
        "//pkg/apis/storage/util:go_default_library",
 | 
			
		||||
        "//pkg/capabilities:go_default_library",
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@ import (
 | 
			
		||||
	utilpod "k8s.io/kubernetes/pkg/api/pod"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/resource"
 | 
			
		||||
	apiservice "k8s.io/kubernetes/pkg/api/service"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/validation/genericvalidation"
 | 
			
		||||
	storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/capabilities"
 | 
			
		||||
@@ -1846,11 +1847,16 @@ func ValidateNodeSelector(nodeSelector *api.NodeSelector, fldPath *field.Path) f
 | 
			
		||||
func ValidateAvoidPodsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
 | 
			
		||||
	allErrs := field.ErrorList{}
 | 
			
		||||
 | 
			
		||||
	avoids, err := api.GetAvoidPodsFromNodeAnnotations(annotations)
 | 
			
		||||
	v1Avoids, err := v1.GetAvoidPodsFromNodeAnnotations(annotations)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		allErrs = append(allErrs, field.Invalid(fldPath.Child("AvoidPods"), api.PreferAvoidPodsAnnotationKey, err.Error()))
 | 
			
		||||
		return allErrs
 | 
			
		||||
	}
 | 
			
		||||
	var avoids api.AvoidPods
 | 
			
		||||
	if err := v1.Convert_v1_AvoidPods_To_api_AvoidPods(&v1Avoids, &avoids, nil); err != nil {
 | 
			
		||||
		allErrs = append(allErrs, field.Invalid(fldPath.Child("AvoidPods"), api.PreferAvoidPodsAnnotationKey, err.Error()))
 | 
			
		||||
		return allErrs
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(avoids.PreferAvoidPods) != 0 {
 | 
			
		||||
		for i, pa := range avoids.PreferAvoidPods {
 | 
			
		||||
@@ -1976,11 +1982,18 @@ func validatePodAffinity(podAffinity *api.PodAffinity, fldPath *field.Path) fiel
 | 
			
		||||
func ValidateTolerationsInPodAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
 | 
			
		||||
	allErrs := field.ErrorList{}
 | 
			
		||||
 | 
			
		||||
	tolerations, err := api.GetTolerationsFromPodAnnotations(annotations)
 | 
			
		||||
	v1Tolerations, err := v1.GetTolerationsFromPodAnnotations(annotations)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		allErrs = append(allErrs, field.Invalid(fldPath, api.TolerationsAnnotationKey, err.Error()))
 | 
			
		||||
		return allErrs
 | 
			
		||||
	}
 | 
			
		||||
	tolerations := make([]api.Toleration, len(v1Tolerations))
 | 
			
		||||
	for i := range v1Tolerations {
 | 
			
		||||
		if err := v1.Convert_v1_Toleration_To_api_Toleration(&v1Tolerations[i], &tolerations[i], nil); err != nil {
 | 
			
		||||
			allErrs = append(allErrs, field.Invalid(fldPath, api.TolerationsAnnotationKey, err.Error()))
 | 
			
		||||
			return allErrs
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(tolerations) > 0 {
 | 
			
		||||
		allErrs = append(allErrs, validateTolerations(tolerations, fldPath.Child(api.TolerationsAnnotationKey))...)
 | 
			
		||||
	}
 | 
			
		||||
@@ -2676,11 +2689,18 @@ func validateTaints(taints []api.Taint, fldPath *field.Path) field.ErrorList {
 | 
			
		||||
func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
 | 
			
		||||
	allErrs := field.ErrorList{}
 | 
			
		||||
 | 
			
		||||
	taints, err := api.GetTaintsFromNodeAnnotations(annotations)
 | 
			
		||||
	v1Taints, err := v1.GetTaintsFromNodeAnnotations(annotations)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		allErrs = append(allErrs, field.Invalid(fldPath, api.TaintsAnnotationKey, err.Error()))
 | 
			
		||||
		return allErrs
 | 
			
		||||
	}
 | 
			
		||||
	taints := make([]api.Taint, len(v1Taints))
 | 
			
		||||
	for i := range v1Taints {
 | 
			
		||||
		if err := v1.Convert_v1_Taint_To_api_Taint(&v1Taints[i], &taints[i], nil); err != nil {
 | 
			
		||||
			allErrs = append(allErrs, field.Invalid(fldPath, api.TaintsAnnotationKey, err.Error()))
 | 
			
		||||
			return allErrs
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(taints) > 0 {
 | 
			
		||||
		allErrs = append(allErrs, validateTaints(taints, fldPath.Child(api.TaintsAnnotationKey))...)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ import (
 | 
			
		||||
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/validation"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/kubectl"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
 | 
			
		||||
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
 | 
			
		||||
@@ -44,8 +44,8 @@ import (
 | 
			
		||||
// TaintOptions have the data required to perform the taint operation
 | 
			
		||||
type TaintOptions struct {
 | 
			
		||||
	resources      []string
 | 
			
		||||
	taintsToAdd    []api.Taint
 | 
			
		||||
	taintsToRemove []api.Taint
 | 
			
		||||
	taintsToAdd    []v1.Taint
 | 
			
		||||
	taintsToRemove []v1.Taint
 | 
			
		||||
	builder        *resource.Builder
 | 
			
		||||
	selector       string
 | 
			
		||||
	overwrite      bool
 | 
			
		||||
@@ -112,8 +112,8 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func deleteTaint(taints []api.Taint, taintToDelete api.Taint) ([]api.Taint, error) {
 | 
			
		||||
	newTaints := []api.Taint{}
 | 
			
		||||
func deleteTaint(taints []v1.Taint, taintToDelete v1.Taint) ([]v1.Taint, error) {
 | 
			
		||||
	newTaints := []v1.Taint{}
 | 
			
		||||
	found := false
 | 
			
		||||
	for _, taint := range taints {
 | 
			
		||||
		if taint.Key == taintToDelete.Key &&
 | 
			
		||||
@@ -132,14 +132,14 @@ func deleteTaint(taints []api.Taint, taintToDelete api.Taint) ([]api.Taint, erro
 | 
			
		||||
 | 
			
		||||
// reorganizeTaints returns the updated set of taints, taking into account old taints that were not updated,
 | 
			
		||||
// old taints that were updated, old taints that were deleted, and new taints.
 | 
			
		||||
func reorganizeTaints(accessor metav1.Object, overwrite bool, taintsToAdd []api.Taint, taintsToRemove []api.Taint) ([]api.Taint, error) {
 | 
			
		||||
	newTaints := append([]api.Taint{}, taintsToAdd...)
 | 
			
		||||
func reorganizeTaints(accessor metav1.Object, overwrite bool, taintsToAdd []v1.Taint, taintsToRemove []v1.Taint) ([]v1.Taint, error) {
 | 
			
		||||
	newTaints := append([]v1.Taint{}, taintsToAdd...)
 | 
			
		||||
 | 
			
		||||
	var oldTaints []api.Taint
 | 
			
		||||
	var oldTaints []v1.Taint
 | 
			
		||||
	var err error
 | 
			
		||||
	annotations := accessor.GetAnnotations()
 | 
			
		||||
	if annotations != nil {
 | 
			
		||||
		if oldTaints, err = api.GetTaintsFromNodeAnnotations(annotations); err != nil {
 | 
			
		||||
		if oldTaints, err = v1.GetTaintsFromNodeAnnotations(annotations); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -168,9 +168,9 @@ func reorganizeTaints(accessor metav1.Object, overwrite bool, taintsToAdd []api.
 | 
			
		||||
	return newTaints, utilerrors.NewAggregate(allErrs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseTaints(spec []string) ([]api.Taint, []api.Taint, error) {
 | 
			
		||||
	var taints, taintsToRemove []api.Taint
 | 
			
		||||
	uniqueTaints := map[api.TaintEffect]sets.String{}
 | 
			
		||||
func parseTaints(spec []string) ([]v1.Taint, []v1.Taint, error) {
 | 
			
		||||
	var taints, taintsToRemove []v1.Taint
 | 
			
		||||
	uniqueTaints := map[v1.TaintEffect]sets.String{}
 | 
			
		||||
 | 
			
		||||
	for _, taintSpec := range spec {
 | 
			
		||||
		if strings.Index(taintSpec, "=") != -1 && strings.Index(taintSpec, ":") != -1 {
 | 
			
		||||
@@ -191,13 +191,13 @@ func parseTaints(spec []string) ([]api.Taint, []api.Taint, error) {
 | 
			
		||||
			taints = append(taints, newTaint)
 | 
			
		||||
		} else if strings.HasSuffix(taintSpec, "-") {
 | 
			
		||||
			taintKey := taintSpec[:len(taintSpec)-1]
 | 
			
		||||
			var effect api.TaintEffect
 | 
			
		||||
			var effect v1.TaintEffect
 | 
			
		||||
			if strings.Index(taintKey, ":") != -1 {
 | 
			
		||||
				parts := strings.Split(taintKey, ":")
 | 
			
		||||
				taintKey = parts[0]
 | 
			
		||||
				effect = api.TaintEffect(parts[1])
 | 
			
		||||
				effect = v1.TaintEffect(parts[1])
 | 
			
		||||
			}
 | 
			
		||||
			taintsToRemove = append(taintsToRemove, api.Taint{Key: taintKey, Effect: effect})
 | 
			
		||||
			taintsToRemove = append(taintsToRemove, v1.Taint{Key: taintKey, Effect: effect})
 | 
			
		||||
		} else {
 | 
			
		||||
			return nil, nil, fmt.Errorf("unknown taint spec: %v", taintSpec)
 | 
			
		||||
		}
 | 
			
		||||
@@ -363,14 +363,14 @@ func (o TaintOptions) RunTaint() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// validateNoTaintOverwrites validates that when overwrite is false, to-be-updated taints don't exist in the node taint list (yet)
 | 
			
		||||
func validateNoTaintOverwrites(accessor metav1.Object, taints []api.Taint) error {
 | 
			
		||||
func validateNoTaintOverwrites(accessor metav1.Object, taints []v1.Taint) error {
 | 
			
		||||
	annotations := accessor.GetAnnotations()
 | 
			
		||||
	if annotations == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	allErrs := []error{}
 | 
			
		||||
	oldTaints, err := api.GetTaintsFromNodeAnnotations(annotations)
 | 
			
		||||
	oldTaints, err := v1.GetTaintsFromNodeAnnotations(annotations)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		allErrs = append(allErrs, err)
 | 
			
		||||
		return utilerrors.NewAggregate(allErrs)
 | 
			
		||||
@@ -412,7 +412,7 @@ func (o TaintOptions) updateTaints(obj runtime.Object) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	annotations[api.TaintsAnnotationKey] = string(taintsData)
 | 
			
		||||
	annotations[v1.TaintsAnnotationKey] = string(taintsData)
 | 
			
		||||
	accessor.SetAnnotations(annotations)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/strategicpatch"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func generateNodeAndTaintedNode(oldTaints []api.Taint, newTaints []api.Taint) (*api.Node, *api.Node) {
 | 
			
		||||
func generateNodeAndTaintedNode(oldTaints []v1.Taint, newTaints []v1.Taint) (*api.Node, *api.Node) {
 | 
			
		||||
	var taintedNode *api.Node
 | 
			
		||||
 | 
			
		||||
	oldTaintsData, _ := json.Marshal(oldTaints)
 | 
			
		||||
@@ -45,7 +45,7 @@ func generateNodeAndTaintedNode(oldTaints []api.Taint, newTaints []api.Taint) (*
 | 
			
		||||
			Name:              "node-name",
 | 
			
		||||
			CreationTimestamp: metav1.Time{Time: time.Now()},
 | 
			
		||||
			Annotations: map[string]string{
 | 
			
		||||
				api.TaintsAnnotationKey: string(oldTaintsData),
 | 
			
		||||
				v1.TaintsAnnotationKey: string(oldTaintsData),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		Spec: api.NodeSpec{
 | 
			
		||||
@@ -59,18 +59,18 @@ func generateNodeAndTaintedNode(oldTaints []api.Taint, newTaints []api.Taint) (*
 | 
			
		||||
	// A copy of the same node, but tainted.
 | 
			
		||||
	taintedNode = clone.(*api.Node)
 | 
			
		||||
	taintedNode.Annotations = map[string]string{
 | 
			
		||||
		api.TaintsAnnotationKey: string(newTaintsData),
 | 
			
		||||
		v1.TaintsAnnotationKey: string(newTaintsData),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node, taintedNode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AnnotationsHaveEqualTaints(annotationA map[string]string, annotationB map[string]string) bool {
 | 
			
		||||
	taintsA, err := api.GetTaintsFromNodeAnnotations(annotationA)
 | 
			
		||||
	taintsA, err := v1.GetTaintsFromNodeAnnotations(annotationA)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	taintsB, err := api.GetTaintsFromNodeAnnotations(annotationB)
 | 
			
		||||
	taintsB, err := v1.GetTaintsFromNodeAnnotations(annotationB)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
@@ -97,8 +97,8 @@ func AnnotationsHaveEqualTaints(annotationA map[string]string, annotationB map[s
 | 
			
		||||
func TestTaint(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		description string
 | 
			
		||||
		oldTaints   []api.Taint
 | 
			
		||||
		newTaints   []api.Taint
 | 
			
		||||
		oldTaints   []v1.Taint
 | 
			
		||||
		newTaints   []v1.Taint
 | 
			
		||||
		args        []string
 | 
			
		||||
		expectFatal bool
 | 
			
		||||
		expectTaint bool
 | 
			
		||||
@@ -106,7 +106,7 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
		// success cases
 | 
			
		||||
		{
 | 
			
		||||
			description: "taints a node with effect NoSchedule",
 | 
			
		||||
			newTaints: []api.Taint{{
 | 
			
		||||
			newTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "foo",
 | 
			
		||||
				Value:  "bar",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
@@ -117,7 +117,7 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description: "taints a node with effect PreferNoSchedule",
 | 
			
		||||
			newTaints: []api.Taint{{
 | 
			
		||||
			newTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "foo",
 | 
			
		||||
				Value:  "bar",
 | 
			
		||||
				Effect: "PreferNoSchedule",
 | 
			
		||||
@@ -128,12 +128,12 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description: "update an existing taint on the node, change the value from bar to barz",
 | 
			
		||||
			oldTaints: []api.Taint{{
 | 
			
		||||
			oldTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "foo",
 | 
			
		||||
				Value:  "bar",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
			}},
 | 
			
		||||
			newTaints: []api.Taint{{
 | 
			
		||||
			newTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "foo",
 | 
			
		||||
				Value:  "barz",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
@@ -144,7 +144,7 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description: "taints a node with two taints",
 | 
			
		||||
			newTaints: []api.Taint{{
 | 
			
		||||
			newTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "dedicated",
 | 
			
		||||
				Value:  "namespaceA",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
@@ -159,7 +159,7 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description: "node has two taints with the same key but different effect, remove one of them by indicating exact key and effect",
 | 
			
		||||
			oldTaints: []api.Taint{{
 | 
			
		||||
			oldTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "dedicated",
 | 
			
		||||
				Value:  "namespaceA",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
@@ -168,7 +168,7 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
				Value:  "namespaceA",
 | 
			
		||||
				Effect: "PreferNoSchedule",
 | 
			
		||||
			}},
 | 
			
		||||
			newTaints: []api.Taint{{
 | 
			
		||||
			newTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "dedicated",
 | 
			
		||||
				Value:  "namespaceA",
 | 
			
		||||
				Effect: "PreferNoSchedule",
 | 
			
		||||
@@ -179,7 +179,7 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description: "node has two taints with the same key but different effect, remove all of them with wildcard",
 | 
			
		||||
			oldTaints: []api.Taint{{
 | 
			
		||||
			oldTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "dedicated",
 | 
			
		||||
				Value:  "namespaceA",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
@@ -188,14 +188,14 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
				Value:  "namespaceA",
 | 
			
		||||
				Effect: "PreferNoSchedule",
 | 
			
		||||
			}},
 | 
			
		||||
			newTaints:   []api.Taint{},
 | 
			
		||||
			newTaints:   []v1.Taint{},
 | 
			
		||||
			args:        []string{"node", "node-name", "dedicated-"},
 | 
			
		||||
			expectFatal: false,
 | 
			
		||||
			expectTaint: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description: "node has two taints, update one of them and remove the other",
 | 
			
		||||
			oldTaints: []api.Taint{{
 | 
			
		||||
			oldTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "dedicated",
 | 
			
		||||
				Value:  "namespaceA",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
@@ -204,7 +204,7 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
				Value:  "bar",
 | 
			
		||||
				Effect: "PreferNoSchedule",
 | 
			
		||||
			}},
 | 
			
		||||
			newTaints: []api.Taint{{
 | 
			
		||||
			newTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "foo",
 | 
			
		||||
				Value:  "barz",
 | 
			
		||||
				Effect: "PreferNoSchedule",
 | 
			
		||||
@@ -235,12 +235,12 @@ func TestTaint(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description: "can't update existing taint on the node, since 'overwrite' flag is not set",
 | 
			
		||||
			oldTaints: []api.Taint{{
 | 
			
		||||
			oldTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "foo",
 | 
			
		||||
				Value:  "bar",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
			}},
 | 
			
		||||
			newTaints: []api.Taint{{
 | 
			
		||||
			newTaints: []v1.Taint{{
 | 
			
		||||
				Key:    "foo",
 | 
			
		||||
				Value:  "bar",
 | 
			
		||||
				Effect: "NoSchedule",
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@ import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/events"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/resource"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/apps"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/autoscaling"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/batch"
 | 
			
		||||
@@ -2748,9 +2749,15 @@ func printLabelsMultilineWithIndent(w *PrefixWriter, initialIndent, title, inner
 | 
			
		||||
 | 
			
		||||
// printTaintsMultiline prints multiple taints with a proper alignment.
 | 
			
		||||
func printTaintsInAnnotationMultiline(w *PrefixWriter, title string, annotations map[string]string) {
 | 
			
		||||
	taints, err := api.GetTaintsFromNodeAnnotations(annotations)
 | 
			
		||||
	v1Taints, err := v1.GetTaintsFromNodeAnnotations(annotations)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		taints = []api.Taint{}
 | 
			
		||||
		v1Taints = []v1.Taint{}
 | 
			
		||||
	}
 | 
			
		||||
	taints := make([]api.Taint, len(v1Taints))
 | 
			
		||||
	for i := range v1Taints {
 | 
			
		||||
		if err := v1.Convert_v1_Taint_To_api_Taint(&v1Taints[i], &taints[i], nil); err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	printTaintsMultilineWithIndent(w, "", title, "\t", taints)
 | 
			
		||||
}
 | 
			
		||||
@@ -2787,9 +2794,15 @@ func printTaintsMultilineWithIndent(w *PrefixWriter, initialIndent, title, inner
 | 
			
		||||
 | 
			
		||||
// printTolerationsMultiline prints multiple tolerations with a proper alignment.
 | 
			
		||||
func printTolerationsInAnnotationMultiline(w *PrefixWriter, title string, annotations map[string]string) {
 | 
			
		||||
	tolerations, err := api.GetTolerationsFromPodAnnotations(annotations)
 | 
			
		||||
	v1Tolerations, err := v1.GetTolerationsFromPodAnnotations(annotations)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		tolerations = []api.Toleration{}
 | 
			
		||||
		v1Tolerations = []v1.Toleration{}
 | 
			
		||||
	}
 | 
			
		||||
	tolerations := make([]api.Toleration, len(v1Tolerations))
 | 
			
		||||
	for i := range v1Tolerations {
 | 
			
		||||
		if err := v1.Convert_v1_Toleration_To_api_Toleration(&v1Tolerations[i], &tolerations[i], nil); err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	printTolerationsMultilineWithIndent(w, "", title, "\t", tolerations)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ func TestDescribePod(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
func TestDescribePodTolerations(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	podTolerations := []api.Toleration{{Key: "key1", Value: "value1"},
 | 
			
		||||
	podTolerations := []v1.Toleration{{Key: "key1", Value: "value1"},
 | 
			
		||||
		{Key: "key2", Value: "value2"}}
 | 
			
		||||
	pt, _ := json.Marshal(podTolerations)
 | 
			
		||||
	fake := fake.NewSimpleClientset(&api.Pod{
 | 
			
		||||
@@ -77,7 +77,7 @@ func TestDescribePodTolerations(t *testing.T) {
 | 
			
		||||
			Name:      "bar",
 | 
			
		||||
			Namespace: "foo",
 | 
			
		||||
			Annotations: map[string]string{
 | 
			
		||||
				api.TolerationsAnnotationKey: string(pt),
 | 
			
		||||
				v1.TolerationsAnnotationKey: string(pt),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
 
 | 
			
		||||
@@ -204,7 +204,13 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
 | 
			
		||||
	}
 | 
			
		||||
	if len(kl.kubeletConfiguration.RegisterWithTaints) > 0 {
 | 
			
		||||
		annotations := make(map[string]string)
 | 
			
		||||
		b, err := json.Marshal(kl.kubeletConfiguration.RegisterWithTaints)
 | 
			
		||||
		taints := make([]v1.Taint, len(kl.kubeletConfiguration.RegisterWithTaints))
 | 
			
		||||
		for i := range kl.kubeletConfiguration.RegisterWithTaints {
 | 
			
		||||
			if err := v1.Convert_api_Taint_To_v1_Taint(&kl.kubeletConfiguration.RegisterWithTaints[i], &taints[i], nil); err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		b, err := json.Marshal(taints)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ go_library(
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//pkg/api:go_default_library",
 | 
			
		||||
        "//pkg/api/v1:go_default_library",
 | 
			
		||||
        "//vendor:k8s.io/apimachinery/pkg/util/validation",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -23,11 +23,12 @@ import (
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/validation"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ParseTaint parses a taint from a string. Taint must be off the format '<key>=<value>:<effect>'.
 | 
			
		||||
func ParseTaint(st string) (api.Taint, error) {
 | 
			
		||||
	var taint api.Taint
 | 
			
		||||
func ParseTaint(st string) (v1.Taint, error) {
 | 
			
		||||
	var taint v1.Taint
 | 
			
		||||
	parts := strings.Split(st, "=")
 | 
			
		||||
	if len(parts) != 2 || len(parts[1]) == 0 || len(validation.IsQualifiedName(parts[0])) > 0 {
 | 
			
		||||
		return taint, fmt.Errorf("invalid taint spec: %v", st)
 | 
			
		||||
@@ -35,14 +36,14 @@ func ParseTaint(st string) (api.Taint, error) {
 | 
			
		||||
 | 
			
		||||
	parts2 := strings.Split(parts[1], ":")
 | 
			
		||||
 | 
			
		||||
	effect := api.TaintEffect(parts2[1])
 | 
			
		||||
	effect := v1.TaintEffect(parts2[1])
 | 
			
		||||
 | 
			
		||||
	errs := validation.IsValidLabelValue(parts2[0])
 | 
			
		||||
	if len(parts2) != 2 || len(errs) != 0 {
 | 
			
		||||
		return taint, fmt.Errorf("invalid taint spec: %v, %s", st, strings.Join(errs, "; "))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if effect != api.TaintEffectNoSchedule && effect != api.TaintEffectPreferNoSchedule {
 | 
			
		||||
	if effect != v1.TaintEffectNoSchedule && effect != v1.TaintEffectPreferNoSchedule {
 | 
			
		||||
		return taint, fmt.Errorf("invalid taint spec: %v, unsupported taint effect", st)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -73,7 +74,7 @@ func (t taintsVar) Set(s string) error {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		taints = append(taints, taint)
 | 
			
		||||
		taints = append(taints, api.Taint{Key: taint.Key, Value: taint.Value, Effect: api.TaintEffect(taint.Effect)})
 | 
			
		||||
	}
 | 
			
		||||
	*t.ptr = taints
 | 
			
		||||
	return nil
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user