Fresh dep ensure

This commit is contained in:
Mike Cronce
2018-11-26 13:23:56 -05:00
parent 93cb8a04d7
commit 407478ab9a
9016 changed files with 551394 additions and 279685 deletions

View File

@ -11,8 +11,9 @@ go_library(
srcs = ["features.go"],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/features",
deps = [
"//pkg/util/version:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
@ -33,5 +34,8 @@ go_test(
name = "go_default_test",
srcs = ["features_test.go"],
embed = [":go_default_library"],
deps = ["//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library"],
deps = [
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
],
)

View File

@ -22,65 +22,53 @@ import (
"strconv"
"strings"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/version"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/util/version"
)
const (
// HighAvailability is alpha in v1.9
HighAvailability = "HighAvailability"
// CoreDNS is GA in v1.11
CoreDNS = "CoreDNS"
// SelfHosting is alpha in v1.8 and v1.9
SelfHosting = "SelfHosting"
// StoreCertsInSecrets is alpha in v1.8 and v1.9
StoreCertsInSecrets = "StoreCertsInSecrets"
// DynamicKubeletConfig is alpha in v1.9
// DynamicKubeletConfig is beta in v1.11
DynamicKubeletConfig = "DynamicKubeletConfig"
// Auditing is beta in 1.8
Auditing = "Auditing"
)
var coreDNSMessage = "featureGates:CoreDNS has been removed in v1.13\n" +
"\tUse kubeadm-config to select which DNS addon to install."
// InitFeatureGates are the default feature gates for the init command
var InitFeatureGates = FeatureList{
SelfHosting: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
StoreCertsInSecrets: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
// We don't want to advertise this feature gate exists in v1.9 to avoid confusion as it is not yet working
HighAvailability: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}, HiddenInHelpText: true},
CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.GA}},
DynamicKubeletConfig: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
Auditing: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Deprecated}, HiddenInHelpText: true, DeprecationMessage: coreDNSMessage},
}
// Feature represents a feature being gated
type Feature struct {
utilfeature.FeatureSpec
MinimumVersion *version.Version
HiddenInHelpText bool
MinimumVersion *version.Version
HiddenInHelpText bool
DeprecationMessage string
}
// FeatureList represents a list of feature gates
type FeatureList map[string]Feature
// ValidateVersion ensures that a feature gate list is compatible with the chosen kubernetes version
// ValidateVersion ensures that a feature gate list is compatible with the chosen Kubernetes version
func ValidateVersion(allFeatures FeatureList, requestedFeatures map[string]bool, requestedVersion string) error {
if requestedVersion == "" {
return nil
}
parsedExpVersion, err := version.ParseSemantic(requestedVersion)
if err != nil {
return fmt.Errorf("Error parsing version %s: %v", requestedVersion, err)
return errors.Wrapf(err, "error parsing version %s", requestedVersion)
}
for k := range requestedFeatures {
if minVersion := allFeatures[k].MinimumVersion; minVersion != nil {
if !parsedExpVersion.AtLeast(minVersion) {
return fmt.Errorf(
"the requested kubernetes version (%s) is incompatible with the %s feature gate, which needs %s as a minimum",
return errors.Errorf(
"the requested Kubernetes version (%s) is incompatible with the %s feature gate, which needs %s as a minimum",
requestedVersion, k, minVersion)
}
}
@ -99,9 +87,9 @@ func Enabled(featureList map[string]bool, featureName string) bool {
// Supports indicates whether a feature name is supported on the given
// feature set
func Supports(featureList FeatureList, featureName string) bool {
for k := range featureList {
for k, v := range featureList {
if featureName == string(k) {
return true
return v.PreRelease != utilfeature.Deprecated
}
}
return false
@ -145,39 +133,50 @@ func NewFeatureGate(f *FeatureList, value string) (map[string]bool, error) {
arr := strings.SplitN(s, "=", 2)
if len(arr) != 2 {
return nil, fmt.Errorf("missing bool value for feature-gate key:%s", s)
return nil, errors.Errorf("missing bool value for feature-gate key:%s", s)
}
k := strings.TrimSpace(arr[0])
v := strings.TrimSpace(arr[1])
if !Supports(*f, k) {
return nil, fmt.Errorf("unrecognized feature-gate key: %s", k)
featureSpec, ok := (*f)[k]
if !ok {
return nil, errors.Errorf("unrecognized feature-gate key: %s", k)
}
if featureSpec.PreRelease == utilfeature.Deprecated {
return nil, errors.Errorf("feature-gate key is deprecated: %s", k)
}
boolValue, err := strconv.ParseBool(v)
if err != nil {
return nil, fmt.Errorf("invalid value %v for feature-gate key: %s, use true|false instead", v, k)
return nil, errors.Errorf("invalid value %v for feature-gate key: %s, use true|false instead", v, k)
}
featureGate[k] = boolValue
}
ResolveFeatureGateDependencies(featureGate)
return featureGate, nil
}
// ResolveFeatureGateDependencies resolve dependencies between feature gates
func ResolveFeatureGateDependencies(featureGate map[string]bool) {
// CheckDeprecatedFlags takes a list of existing feature gate flags and validates against the current feature flag set.
// It used during upgrades for ensuring consistency of feature gates used in an existing cluster, that might
// be created with a previous version of kubeadm, with the set of features currently supported by kubeadm
func CheckDeprecatedFlags(f *FeatureList, features map[string]bool) map[string]string {
deprecatedMsg := map[string]string{}
for k := range features {
featureSpec, ok := (*f)[k]
if !ok {
// This case should never happen, it is implemented only as a sentinel
// for removal of flags executed when flags are still in use (always before deprecate, then after one cycle remove)
deprecatedMsg[k] = fmt.Sprintf("Unknown feature gate flag: %s", k)
}
// if StoreCertsInSecrets enabled, SelfHosting should enabled
if Enabled(featureGate, StoreCertsInSecrets) {
featureGate[SelfHosting] = true
if featureSpec.PreRelease == utilfeature.Deprecated {
if _, ok := deprecatedMsg[k]; !ok {
deprecatedMsg[k] = featureSpec.DeprecationMessage
}
}
}
// if HighAvailability enabled, both StoreCertsInSecrets and SelfHosting should enabled
if Enabled(featureGate, HighAvailability) && !Enabled(featureGate, StoreCertsInSecrets) {
featureGate[SelfHosting] = true
featureGate[StoreCertsInSecrets] = true
}
return deprecatedMsg
}

View File

@ -20,14 +20,18 @@ import (
"reflect"
"testing"
"k8s.io/apimachinery/pkg/util/version"
utilfeature "k8s.io/apiserver/pkg/util/feature"
)
var TestMinVersion = version.MustParseSemantic("v1.12.0-alpha.1")
func TestKnownFeatures(t *testing.T) {
var someFeatures = FeatureList{
"feature2": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Alpha}},
"feature1": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
"feature3": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.GA}},
"hidden": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.GA}, HiddenInHelpText: true},
}
r := KnownFeatures(&someFeatures)
@ -55,8 +59,9 @@ func TestKnownFeatures(t *testing.T) {
func TestNewFeatureGate(t *testing.T) {
var someFeatures = FeatureList{
"feature1": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
"feature2": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Alpha}},
"feature1": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
"feature2": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Alpha}},
"deprecated": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Deprecated}},
}
var tests = []struct {
@ -88,6 +93,10 @@ func TestNewFeatureGate(t *testing.T) {
value: "feature1=true,unknownFeature=false",
expectedError: true,
},
{ //deprecated feature-gate key
value: "deprecated=true",
expectedError: true,
},
{ //one feature
value: "feature1=true",
expectedError: false,
@ -121,7 +130,7 @@ func TestNewFeatureGate(t *testing.T) {
func TestValidateVersion(t *testing.T) {
var someFeatures = FeatureList{
"feature1": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
"feature2": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Alpha}},
"feature2": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Alpha}, MinimumVersion: TestMinVersion},
}
var tests = []struct {
@ -133,10 +142,16 @@ func TestValidateVersion(t *testing.T) {
requestedFeatures: map[string]bool{"feature1": true},
expectedError: false,
},
{ //no min version
{ //min version but correct value given
requestedFeatures: map[string]bool{"feature2": true},
requestedVersion: "v1.12.0",
expectedError: false,
},
{ //min version and incorrect value given
requestedFeatures: map[string]bool{"feature2": true},
requestedVersion: "v1.11.2",
expectedError: true,
},
}
for _, test := range tests {
@ -151,39 +166,6 @@ func TestValidateVersion(t *testing.T) {
}
}
func TestResolveFeatureGateDependencies(t *testing.T) {
var tests = []struct {
inputFeatures map[string]bool
expectedFeatures map[string]bool
}{
{ // no flags
inputFeatures: map[string]bool{},
expectedFeatures: map[string]bool{},
},
{ // others flags
inputFeatures: map[string]bool{CoreDNS: false},
expectedFeatures: map[string]bool{CoreDNS: false},
},
{ // just StoreCertsInSecrets flags
inputFeatures: map[string]bool{StoreCertsInSecrets: true},
expectedFeatures: map[string]bool{StoreCertsInSecrets: true, SelfHosting: true},
},
{ // just HighAvailability flags
inputFeatures: map[string]bool{HighAvailability: true},
expectedFeatures: map[string]bool{HighAvailability: true, StoreCertsInSecrets: true, SelfHosting: true},
},
}
for _, test := range tests {
ResolveFeatureGateDependencies(test.inputFeatures)
if !reflect.DeepEqual(test.inputFeatures, test.expectedFeatures) {
t.Errorf("ResolveFeatureGateDependencies failed, expected: %v, got: %v", test.inputFeatures, test.expectedFeatures)
}
}
}
// TestEnabledDefaults tests that Enabled returns the default values for
// each feature gate when no feature gates are specified.
func TestEnabledDefaults(t *testing.T) {
@ -196,3 +178,32 @@ func TestEnabledDefaults(t *testing.T) {
}
}
}
func TestCheckDeprecatedFlags(t *testing.T) {
dummyMessage := "dummy message"
var someFeatures = FeatureList{
"feature1": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
"deprecated": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Deprecated}, DeprecationMessage: dummyMessage},
}
var tests = []struct {
features map[string]bool
expectedMsg map[string]string
}{
{ // feature deprecated
features: map[string]bool{"deprecated": true},
expectedMsg: map[string]string{"deprecated": dummyMessage},
},
{ // valid feature
features: map[string]bool{"feature1": true},
expectedMsg: map[string]string{},
},
}
for _, test := range tests {
msg := CheckDeprecatedFlags(&someFeatures, test.features)
if !reflect.DeepEqual(test.expectedMsg, msg) {
t.Error("CheckDeprecatedFlags didn't returned expected message")
}
}
}