migrate --register-with-taints to KubeletConfiguration

This commit is contained in:
caozhiyuan
2021-10-04 09:17:10 +08:00
parent c84da4e3e6
commit bad4faf1b9
23 changed files with 260 additions and 149 deletions

View File

@@ -21,11 +21,10 @@ import (
"fmt"
"strings"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/core/helper"
)
@@ -88,51 +87,6 @@ func validateTaintEffect(effect v1.TaintEffect) error {
return nil
}
// NewTaintsVar wraps []api.Taint in a struct that implements flag.Value to allow taints to be
// bound to command line flags.
func NewTaintsVar(ptr *[]api.Taint) taintsVar {
return taintsVar{
ptr: ptr,
}
}
type taintsVar struct {
ptr *[]api.Taint
}
func (t taintsVar) Set(s string) error {
if len(s) == 0 {
*t.ptr = nil
return nil
}
sts := strings.Split(s, ",")
var taints []api.Taint
for _, st := range sts {
taint, err := parseTaint(st)
if err != nil {
return err
}
taints = append(taints, api.Taint{Key: taint.Key, Value: taint.Value, Effect: api.TaintEffect(taint.Effect)})
}
*t.ptr = taints
return nil
}
func (t taintsVar) String() string {
if len(*t.ptr) == 0 {
return ""
}
var taints []string
for _, taint := range *t.ptr {
taints = append(taints, fmt.Sprintf("%s=%s:%s", taint.Key, taint.Value, taint.Effect))
}
return strings.Join(taints, ",")
}
func (t taintsVar) Type() string {
return "[]api.Taint"
}
// ParseTaints takes a spec which is an array and creates slices for new taints to be added, taints to be deleted.
// It also validates the spec. For example, the form `<key>` may be used to remove a taint, but not to add one.
func ParseTaints(spec []string) ([]v1.Taint, []v1.Taint, error) {
@@ -350,3 +304,23 @@ func TaintSetFilter(taints []v1.Taint, fn func(*v1.Taint) bool) []v1.Taint {
return res
}
// CheckTaintValidation checks if the given taint is valid.
// Returns error if the given taint is invalid.
func CheckTaintValidation(taint v1.Taint) error {
if errs := validation.IsQualifiedName(taint.Key); len(errs) > 0 {
return fmt.Errorf("invalid taint key: %s", strings.Join(errs, "; "))
}
if taint.Value != "" {
if errs := validation.IsValidLabelValue(taint.Value); len(errs) > 0 {
return fmt.Errorf("invalid taint value: %s", strings.Join(errs, "; "))
}
}
if taint.Effect != "" {
if err := validateTaintEffect(taint.Effect); err != nil {
return err
}
}
return nil
}

View File

@@ -21,71 +21,9 @@ import (
"strings"
"testing"
"k8s.io/api/core/v1"
api "k8s.io/kubernetes/pkg/apis/core"
"github.com/spf13/pflag"
v1 "k8s.io/api/core/v1"
)
func TestTaintsVar(t *testing.T) {
cases := []struct {
f string
err bool
t []api.Taint
}{
{
f: "",
t: []api.Taint(nil),
},
{
f: "--t=foo=bar:NoSchedule",
t: []api.Taint{{Key: "foo", Value: "bar", Effect: "NoSchedule"}},
},
{
f: "--t=baz:NoSchedule",
t: []api.Taint{{Key: "baz", Value: "", Effect: "NoSchedule"}},
},
{
f: "--t=foo=bar:NoSchedule,baz:NoSchedule,bing=bang:PreferNoSchedule,qux=:NoSchedule",
t: []api.Taint{
{Key: "foo", Value: "bar", Effect: api.TaintEffectNoSchedule},
{Key: "baz", Value: "", Effect: "NoSchedule"},
{Key: "bing", Value: "bang", Effect: api.TaintEffectPreferNoSchedule},
{Key: "qux", Value: "", Effect: "NoSchedule"},
},
},
{
f: "--t=dedicated-for=user1:NoExecute,baz:NoSchedule,foo-bar=:NoSchedule",
t: []api.Taint{
{Key: "dedicated-for", Value: "user1", Effect: "NoExecute"},
{Key: "baz", Value: "", Effect: "NoSchedule"},
{Key: "foo-bar", Value: "", Effect: "NoSchedule"},
},
},
}
for i, c := range cases {
args := append([]string{"test"}, strings.Fields(c.f)...)
cli := pflag.NewFlagSet("test", pflag.ContinueOnError)
var taints []api.Taint
cli.Var(NewTaintsVar(&taints), "t", "bar")
err := cli.Parse(args)
if err == nil && c.err {
t.Errorf("[%v] expected error", i)
continue
}
if err != nil && !c.err {
t.Errorf("[%v] unexpected error: %v", i, err)
continue
}
if !reflect.DeepEqual(c.t, taints) {
t.Errorf("[%v] unexpected taints:\n\texpected:\n\t\t%#v\n\tgot:\n\t\t%#v", i, c.t, taints)
}
}
}
func TestAddOrUpdateTaint(t *testing.T) {
node := &v1.Node{}
@@ -757,3 +695,50 @@ func TestParseTaints(t *testing.T) {
}
}
}
func TestValidateTaint(t *testing.T) {
cases := []struct {
name string
taintsToCheck v1.Taint
expectedErr bool
}{
{
name: "taint invalid key",
taintsToCheck: v1.Taint{Key: "", Value: "bar_1", Effect: v1.TaintEffectNoExecute},
expectedErr: true,
},
{
name: "taint invalid value",
taintsToCheck: v1.Taint{Key: "foo_1", Value: strings.Repeat("a", 64), Effect: v1.TaintEffectNoExecute},
expectedErr: true,
},
{
name: "taint invalid effect",
taintsToCheck: v1.Taint{Key: "foo_2", Value: "bar_2", Effect: "no_such_effect"},
expectedErr: true,
},
{
name: "valid taint",
taintsToCheck: v1.Taint{Key: "foo_3", Value: "bar_3", Effect: v1.TaintEffectNoExecute},
expectedErr: false,
},
{
name: "valid taint",
taintsToCheck: v1.Taint{Key: "foo_4", Effect: v1.TaintEffectNoExecute},
expectedErr: false,
},
{
name: "valid taint",
taintsToCheck: v1.Taint{Key: "foo_5", Value: "bar_5"},
expectedErr: false,
},
}
for _, c := range cases {
err := CheckTaintValidation(c.taintsToCheck)
if c.expectedErr && err == nil {
t.Errorf("[%s] expected error for spec %+v, but got nothing", c.name, c.taintsToCheck)
}
}
}