mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 02:43:36 +00:00
vendor files
This commit is contained in:
38
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/BUILD
generated
vendored
Normal file
38
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/BUILD
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_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",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["features_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/features",
|
||||
library = ":go_default_library",
|
||||
deps = ["//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library"],
|
||||
)
|
178
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features.go
generated
vendored
Normal file
178
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features.go
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
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 features
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
const (
|
||||
// HighAvailability is alpha in v1.9
|
||||
HighAvailability = "HighAvailability"
|
||||
|
||||
// CoreDNS is alpha in v1.9
|
||||
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 = "DynamicKubeletConfig"
|
||||
)
|
||||
|
||||
var v190 = version.MustParseSemantic("v1.9.0-alpha.1")
|
||||
|
||||
// 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}, MinimumVersion: v190, HiddenInHelpText: true},
|
||||
CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}, MinimumVersion: v190},
|
||||
DynamicKubeletConfig: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}, MinimumVersion: v190},
|
||||
}
|
||||
|
||||
// Feature represents a feature being gated
|
||||
type Feature struct {
|
||||
utilfeature.FeatureSpec
|
||||
MinimumVersion *version.Version
|
||||
HiddenInHelpText bool
|
||||
}
|
||||
|
||||
// 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
|
||||
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
|
||||
func Enabled(featureList map[string]bool, featureName string) bool {
|
||||
return featureList[string(featureName)]
|
||||
}
|
||||
|
||||
// Supports indicates whether a feature name is supported on the given
|
||||
// feature set
|
||||
func Supports(featureList FeatureList, featureName string) bool {
|
||||
for k := range featureList {
|
||||
if featureName == string(k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Keys returns a slice of feature names for a given feature set
|
||||
func Keys(featureList FeatureList) []string {
|
||||
var list []string
|
||||
for k := range featureList {
|
||||
list = append(list, string(k))
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// KnownFeatures returns a slice of strings describing the FeatureList features.
|
||||
func KnownFeatures(f *FeatureList) []string {
|
||||
var known []string
|
||||
for k, v := range *f {
|
||||
if v.HiddenInHelpText {
|
||||
continue
|
||||
}
|
||||
|
||||
pre := ""
|
||||
if v.PreRelease != utilfeature.GA {
|
||||
pre = fmt.Sprintf("%s - ", v.PreRelease)
|
||||
}
|
||||
known = append(known, fmt.Sprintf("%s=true|false (%sdefault=%t)", k, pre, v.Default))
|
||||
}
|
||||
sort.Strings(known)
|
||||
return known
|
||||
}
|
||||
|
||||
// NewFeatureGate parses a string of the form "key1=value1,key2=value2,..." into a
|
||||
// map[string]bool of known keys or returns an error.
|
||||
func NewFeatureGate(f *FeatureList, value string) (map[string]bool, error) {
|
||||
featureGate := map[string]bool{}
|
||||
for _, s := range strings.Split(value, ",") {
|
||||
if len(s) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
arr := strings.SplitN(s, "=", 2)
|
||||
if len(arr) != 2 {
|
||||
return nil, fmt.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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
featureGate[k] = boolValue
|
||||
}
|
||||
|
||||
ResolveFeatureGateDependencies(featureGate)
|
||||
|
||||
return featureGate, nil
|
||||
}
|
||||
|
||||
// ResolveFeatureGateDependencies resolve dependencies between feature gates
|
||||
func ResolveFeatureGateDependencies(featureGate map[string]bool) {
|
||||
|
||||
// if StoreCertsInSecrets enabled, SelfHosting should enabled
|
||||
if Enabled(featureGate, StoreCertsInSecrets) {
|
||||
featureGate[SelfHosting] = true
|
||||
}
|
||||
|
||||
// if HighAvailability enabled, both StoreCertsInSecrets and SelfHosting should enabled
|
||||
if Enabled(featureGate, HighAvailability) && !Enabled(featureGate, StoreCertsInSecrets) {
|
||||
featureGate[SelfHosting] = true
|
||||
featureGate[StoreCertsInSecrets] = true
|
||||
}
|
||||
}
|
191
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features_test.go
generated
vendored
Normal file
191
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features_test.go
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
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 features
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
)
|
||||
|
||||
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}},
|
||||
}
|
||||
|
||||
r := KnownFeatures(&someFeatures)
|
||||
|
||||
if len(r) != 3 {
|
||||
t.Errorf("KnownFeatures returned %d values, expected 3", len(r))
|
||||
}
|
||||
|
||||
// check the first value is feature1 (the list should be sorted); prerelease and default should be present
|
||||
f1 := "feature1=true|false (BETA - default=false)"
|
||||
if r[0] != f1 {
|
||||
t.Errorf("KnownFeatures returned %s values, expected %s", r[0], f1)
|
||||
}
|
||||
// check the second value is feature2; prerelease and default should be present
|
||||
f2 := "feature2=true|false (ALPHA - default=true)"
|
||||
if r[1] != f2 {
|
||||
t.Errorf("KnownFeatures returned %s values, expected %s", r[1], f2)
|
||||
}
|
||||
// check the second value is feature3; prerelease should not shown fo GA features; default should be present
|
||||
f3 := "feature3=true|false (default=false)"
|
||||
if r[2] != f3 {
|
||||
t.Errorf("KnownFeatures returned %s values, expected %s", r[2], f3)
|
||||
}
|
||||
}
|
||||
|
||||
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}},
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
value string
|
||||
expectedError bool
|
||||
expectedFeaturesGate map[string]bool
|
||||
}{
|
||||
{ //invalid value (missing =)
|
||||
value: "invalidValue",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //invalid value (missing =)
|
||||
value: "feature1=true,invalidValue",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //invalid value (not a boolean)
|
||||
value: "feature1=notABoolean",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //invalid value (not a boolean)
|
||||
value: "feature1=true,feature2=notABoolean",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //unrecognized feature-gate key
|
||||
value: "unknownFeature=false",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //unrecognized feature-gate key
|
||||
value: "feature1=true,unknownFeature=false",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //one feature
|
||||
value: "feature1=true",
|
||||
expectedError: false,
|
||||
expectedFeaturesGate: map[string]bool{"feature1": true},
|
||||
},
|
||||
{ //two features
|
||||
value: "feature1=true,feature2=false",
|
||||
expectedError: false,
|
||||
expectedFeaturesGate: map[string]bool{"feature1": true, "feature2": false},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
r, err := NewFeatureGate(&someFeatures, test.value)
|
||||
|
||||
if !test.expectedError && err != nil {
|
||||
t.Errorf("NewFeatureGate failed when not expected: %v", err)
|
||||
continue
|
||||
} else if test.expectedError && err == nil {
|
||||
t.Error("NewFeatureGate didn't failed when expected")
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(r, test.expectedFeaturesGate) {
|
||||
t.Errorf("NewFeatureGate returned a unexpected value")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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{"SupportIPVSProxyMode": true},
|
||||
expectedFeatures: map[string]bool{"SupportIPVSProxyMode": true},
|
||||
},
|
||||
{ // 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)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user