mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
add HA gate and minVersion validation
This commit is contained in:
parent
f01bfd4580
commit
0ff425db4f
@ -231,6 +231,10 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := features.ValidateVersion(features.InitFeatureGates, cfg.FeatureGates, cfg.KubernetesVersion); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("[init] Using Kubernetes version: %s\n", cfg.KubernetesVersion)
|
fmt.Printf("[init] Using Kubernetes version: %s\n", cfg.KubernetesVersion)
|
||||||
fmt.Printf("[init] Using Authorization modes: %v\n", cfg.AuthorizationModes)
|
fmt.Printf("[init] Using Authorization modes: %v\n", cfg.AuthorizationModes)
|
||||||
|
|
||||||
|
@ -10,7 +10,10 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["features.go"],
|
srcs = ["features.go"],
|
||||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/features",
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/features",
|
||||||
deps = ["//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library"],
|
deps = [
|
||||||
|
"//pkg/util/version:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -23,21 +23,61 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
"k8s.io/kubernetes/pkg/util/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// HighAvailability is alpha in v1.9
|
||||||
|
HighAvailability = "HighAvailability"
|
||||||
|
|
||||||
// SelfHosting is beta in v1.8
|
// SelfHosting is beta in v1.8
|
||||||
SelfHosting utilfeature.Feature = "SelfHosting"
|
SelfHosting = "SelfHosting"
|
||||||
|
|
||||||
// StoreCertsInSecrets is alpha in v1.8
|
// StoreCertsInSecrets is alpha in v1.8
|
||||||
StoreCertsInSecrets utilfeature.Feature = "StoreCertsInSecrets"
|
StoreCertsInSecrets = "StoreCertsInSecrets"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var v190 = version.MustParseSemantic("v1.9.0")
|
||||||
|
|
||||||
|
// InitFeatureGates are the default feature gates for the init command
|
||||||
|
var InitFeatureGates = FeatureList{
|
||||||
|
SelfHosting: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
|
||||||
|
StoreCertsInSecrets: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
|
||||||
|
HighAvailability: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}, MinimumVersion: v190},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feature represents a feature being gated
|
||||||
|
type Feature struct {
|
||||||
|
utilfeature.FeatureSpec
|
||||||
|
MinimumVersion *version.Version
|
||||||
|
}
|
||||||
|
|
||||||
// FeatureList represents a list of feature gates
|
// FeatureList represents a list of feature gates
|
||||||
type FeatureList map[utilfeature.Feature]utilfeature.FeatureSpec
|
type FeatureList map[string]Feature
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
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",
|
||||||
|
requestedVersion, k, minVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Enabled indicates whether a feature name has been enabled
|
// Enabled indicates whether a feature name has been enabled
|
||||||
func Enabled(featureList map[string]bool, featureName utilfeature.Feature) bool {
|
func Enabled(featureList map[string]bool, featureName string) bool {
|
||||||
return featureList[string(featureName)]
|
return featureList[string(featureName)]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +101,6 @@ func Keys(featureList FeatureList) []string {
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitFeatureGates are the default feature gates for the init command
|
|
||||||
var InitFeatureGates = FeatureList{
|
|
||||||
SelfHosting: {Default: false, PreRelease: utilfeature.Alpha},
|
|
||||||
StoreCertsInSecrets: {Default: false, PreRelease: utilfeature.Alpha},
|
|
||||||
}
|
|
||||||
|
|
||||||
// KnownFeatures returns a slice of strings describing the FeatureList features.
|
// KnownFeatures returns a slice of strings describing the FeatureList features.
|
||||||
func KnownFeatures(f *FeatureList) []string {
|
func KnownFeatures(f *FeatureList) []string {
|
||||||
var known []string
|
var known []string
|
||||||
|
@ -25,9 +25,9 @@ import (
|
|||||||
|
|
||||||
func TestKnownFeatures(t *testing.T) {
|
func TestKnownFeatures(t *testing.T) {
|
||||||
var someFeatures = FeatureList{
|
var someFeatures = FeatureList{
|
||||||
"feature2": {Default: true, PreRelease: utilfeature.Alpha},
|
"feature2": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Alpha}},
|
||||||
"feature1": {Default: false, PreRelease: utilfeature.Beta},
|
"feature1": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
|
||||||
"feature3": {Default: false, PreRelease: utilfeature.GA},
|
"feature3": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.GA}},
|
||||||
}
|
}
|
||||||
|
|
||||||
r := KnownFeatures(&someFeatures)
|
r := KnownFeatures(&someFeatures)
|
||||||
@ -55,8 +55,8 @@ func TestKnownFeatures(t *testing.T) {
|
|||||||
|
|
||||||
func TestNewFeatureGate(t *testing.T) {
|
func TestNewFeatureGate(t *testing.T) {
|
||||||
var someFeatures = FeatureList{
|
var someFeatures = FeatureList{
|
||||||
"feature1": {Default: false, PreRelease: utilfeature.Beta},
|
"feature1": {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
|
||||||
"feature2": {Default: true, PreRelease: utilfeature.Alpha},
|
"feature2": {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Alpha}},
|
||||||
}
|
}
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
@ -117,3 +117,42 @@ 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}, MinimumVersion: v190},
|
||||||
|
}
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
requestedVersion string
|
||||||
|
requestedFeatures map[string]bool
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{ //no min version
|
||||||
|
requestedFeatures: map[string]bool{"feature1": true},
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{ //min version but correct value given
|
||||||
|
requestedFeatures: map[string]bool{"feature2": true},
|
||||||
|
requestedVersion: "v1.9.0",
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{ //min version and incorrect value given
|
||||||
|
requestedFeatures: map[string]bool{"feature2": true},
|
||||||
|
requestedVersion: "v1.8.2",
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
err := ValidateVersion(someFeatures, test.requestedFeatures, test.requestedVersion)
|
||||||
|
if !test.expectedError && err != nil {
|
||||||
|
t.Errorf("ValidateVersion failed when not expected: %v", err)
|
||||||
|
continue
|
||||||
|
} else if test.expectedError && err == nil {
|
||||||
|
t.Error("ValidateVersion didn't failed when expected")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user