mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Support multiple --feature-gates flags in the command line
This commit is contained in:
parent
fa0387c9fe
commit
faa5b44381
@ -50,10 +50,7 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DefaultFeatureGate is a shared global FeatureGate.
|
// DefaultFeatureGate is a shared global FeatureGate.
|
||||||
DefaultFeatureGate = &featureGate{
|
DefaultFeatureGate FeatureGate = NewFeatureGate()
|
||||||
known: defaultFeatures,
|
|
||||||
special: specialFeatures,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type FeatureSpec struct {
|
type FeatureSpec struct {
|
||||||
@ -75,43 +72,9 @@ const (
|
|||||||
type FeatureGate interface {
|
type FeatureGate interface {
|
||||||
AddFlag(fs *pflag.FlagSet)
|
AddFlag(fs *pflag.FlagSet)
|
||||||
Set(value string) error
|
Set(value string) error
|
||||||
Add(features map[Feature]FeatureSpec)
|
Enabled(key Feature) bool
|
||||||
|
Add(features map[Feature]FeatureSpec) error
|
||||||
KnownFeatures() []string
|
KnownFeatures() []string
|
||||||
|
|
||||||
// Every feature gate should add method here following this template:
|
|
||||||
//
|
|
||||||
// // owner: @username
|
|
||||||
// // alpha: v1.4
|
|
||||||
// MyFeature() bool
|
|
||||||
|
|
||||||
// owner: @timstclair
|
|
||||||
// beta: v1.4
|
|
||||||
AppArmor() bool
|
|
||||||
|
|
||||||
// owner: @girishkalele
|
|
||||||
// alpha: v1.4
|
|
||||||
ExternalTrafficLocalOnly() bool
|
|
||||||
|
|
||||||
// owner: @saad-ali
|
|
||||||
// alpha: v1.3
|
|
||||||
DynamicVolumeProvisioning() bool
|
|
||||||
|
|
||||||
// owner: @mtaufen
|
|
||||||
// alpha: v1.4
|
|
||||||
DynamicKubeletConfig() bool
|
|
||||||
|
|
||||||
// owner: timstclair
|
|
||||||
// alpha: v1.5
|
|
||||||
StreamingProxyRedirects() bool
|
|
||||||
|
|
||||||
// owner: @pweil-
|
|
||||||
// alpha: v1.5
|
|
||||||
ExperimentalHostUserNamespaceDefaulting() bool
|
|
||||||
|
|
||||||
// owner: @davidopp
|
|
||||||
// alpha: v1.6
|
|
||||||
// TODO: remove when alpha support for affinity is removed
|
|
||||||
AffinityInAnnotations() bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// featureGate implements FeatureGate as well as pflag.Value for flag parsing.
|
// featureGate implements FeatureGate as well as pflag.Value for flag parsing.
|
||||||
@ -137,10 +100,21 @@ func setUnsetAlphaGates(f *featureGate, val bool) {
|
|||||||
// Set, String, and Type implement pflag.Value
|
// Set, String, and Type implement pflag.Value
|
||||||
var _ pflag.Value = &featureGate{}
|
var _ pflag.Value = &featureGate{}
|
||||||
|
|
||||||
|
func NewFeatureGate() *featureGate {
|
||||||
|
f := &featureGate{
|
||||||
|
known: map[Feature]FeatureSpec{},
|
||||||
|
special: specialFeatures,
|
||||||
|
enabled: map[Feature]bool{},
|
||||||
|
}
|
||||||
|
for k, v := range defaultFeatures {
|
||||||
|
f.known[k] = v
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
// Set Parses a string of the form // "key1=value1,key2=value2,..." into a
|
// Set Parses a string of the form // "key1=value1,key2=value2,..." into a
|
||||||
// map[string]bool of known keys or returns an error.
|
// map[string]bool of known keys or returns an error.
|
||||||
func (f *featureGate) Set(value string) error {
|
func (f *featureGate) Set(value string) error {
|
||||||
f.enabled = make(map[Feature]bool)
|
|
||||||
for _, s := range strings.Split(value, ",") {
|
for _, s := range strings.Split(value, ",") {
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
continue
|
continue
|
||||||
|
@ -119,9 +119,11 @@ func TestFeatureGateFlag(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
fs := pflag.NewFlagSet("testfeaturegateflag", pflag.ContinueOnError)
|
fs := pflag.NewFlagSet("testfeaturegateflag", pflag.ContinueOnError)
|
||||||
f := DefaultFeatureGate
|
f := NewFeatureGate()
|
||||||
f.known[testAlphaGate] = FeatureSpec{Default: false, PreRelease: Alpha}
|
f.Add(map[Feature]FeatureSpec{
|
||||||
f.known[testBetaGate] = FeatureSpec{Default: false, PreRelease: Beta}
|
testAlphaGate: {Default: false, PreRelease: Alpha},
|
||||||
|
testBetaGate: {Default: false, PreRelease: Beta},
|
||||||
|
})
|
||||||
f.AddFlag(fs)
|
f.AddFlag(fs)
|
||||||
|
|
||||||
err := fs.Parse([]string{fmt.Sprintf("--%s=%s", flagName, test.arg)})
|
err := fs.Parse([]string{fmt.Sprintf("--%s=%s", flagName, test.arg)})
|
||||||
@ -140,15 +142,45 @@ func TestFeatureGateFlag(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFeatureGateOverride(t *testing.T) {
|
||||||
|
const testAlphaGate Feature = "TestAlpha"
|
||||||
|
const testBetaGate Feature = "TestBeta"
|
||||||
|
|
||||||
|
// Don't parse the flag, assert defaults are used.
|
||||||
|
var f FeatureGate = NewFeatureGate()
|
||||||
|
f.Add(map[Feature]FeatureSpec{
|
||||||
|
testAlphaGate: {Default: false, PreRelease: Alpha},
|
||||||
|
testBetaGate: {Default: false, PreRelease: Beta},
|
||||||
|
})
|
||||||
|
|
||||||
|
f.Set("TestAlpha=true,TestBeta=true")
|
||||||
|
if f.Enabled(testAlphaGate) != true {
|
||||||
|
t.Errorf("Expected true")
|
||||||
|
}
|
||||||
|
if f.Enabled(testBetaGate) != true {
|
||||||
|
t.Errorf("Expected true")
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Set("TestAlpha=false")
|
||||||
|
if f.Enabled(testAlphaGate) != false {
|
||||||
|
t.Errorf("Expected false")
|
||||||
|
}
|
||||||
|
if f.Enabled(testBetaGate) != true {
|
||||||
|
t.Errorf("Expected true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFeatureGateFlagDefaults(t *testing.T) {
|
func TestFeatureGateFlagDefaults(t *testing.T) {
|
||||||
// gates for testing
|
// gates for testing
|
||||||
const testAlphaGate Feature = "TestAlpha"
|
const testAlphaGate Feature = "TestAlpha"
|
||||||
const testBetaGate Feature = "TestBeta"
|
const testBetaGate Feature = "TestBeta"
|
||||||
|
|
||||||
// Don't parse the flag, assert defaults are used.
|
// Don't parse the flag, assert defaults are used.
|
||||||
f := DefaultFeatureGate
|
var f FeatureGate = NewFeatureGate()
|
||||||
f.known[testAlphaGate] = FeatureSpec{Default: false, PreRelease: Alpha}
|
f.Add(map[Feature]FeatureSpec{
|
||||||
f.known[testBetaGate] = FeatureSpec{Default: true, PreRelease: Beta}
|
testAlphaGate: {Default: false, PreRelease: Alpha},
|
||||||
|
testBetaGate: {Default: true, PreRelease: Beta},
|
||||||
|
})
|
||||||
|
|
||||||
if f.Enabled(testAlphaGate) != false {
|
if f.Enabled(testAlphaGate) != false {
|
||||||
t.Errorf("Expected false")
|
t.Errorf("Expected false")
|
||||||
|
Loading…
Reference in New Issue
Block a user