Merge pull request #42648 from sttts/sttts-multiple-feature-gate-calls

Automatic merge from submit-queue (batch tested with PRs 42637, 42648)

Support multiple --feature-gates flags in the command line

Fixes the issue in https://github.com/kubernetes/kubernetes/pull/42647.

Before this change the whole set of gates was replaced with new values. Now values are overridden one by one.
pull/6/head
Kubernetes Submit Queue 2017-03-07 12:14:18 -08:00 committed by GitHub
commit 7593a9f555
2 changed files with 53 additions and 47 deletions

View File

@ -50,10 +50,7 @@ var (
}
// DefaultFeatureGate is a shared global FeatureGate.
DefaultFeatureGate = &featureGate{
known: defaultFeatures,
special: specialFeatures,
}
DefaultFeatureGate FeatureGate = NewFeatureGate()
)
type FeatureSpec struct {
@ -75,43 +72,9 @@ const (
type FeatureGate interface {
AddFlag(fs *pflag.FlagSet)
Set(value string) error
Add(features map[Feature]FeatureSpec)
Enabled(key Feature) bool
Add(features map[Feature]FeatureSpec) error
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.
@ -137,10 +100,21 @@ func setUnsetAlphaGates(f *featureGate, val bool) {
// Set, String, and Type implement pflag.Value
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
// map[string]bool of known keys or returns an error.
func (f *featureGate) Set(value string) error {
f.enabled = make(map[Feature]bool)
for _, s := range strings.Split(value, ",") {
if len(s) == 0 {
continue

View File

@ -119,9 +119,11 @@ func TestFeatureGateFlag(t *testing.T) {
}
for i, test := range tests {
fs := pflag.NewFlagSet("testfeaturegateflag", pflag.ContinueOnError)
f := DefaultFeatureGate
f.known[testAlphaGate] = FeatureSpec{Default: false, PreRelease: Alpha}
f.known[testBetaGate] = FeatureSpec{Default: false, PreRelease: Beta}
f := NewFeatureGate()
f.Add(map[Feature]FeatureSpec{
testAlphaGate: {Default: false, PreRelease: Alpha},
testBetaGate: {Default: false, PreRelease: Beta},
})
f.AddFlag(fs)
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) {
// gates for testing
const testAlphaGate Feature = "TestAlpha"
const testBetaGate Feature = "TestBeta"
// Don't parse the flag, assert defaults are used.
f := DefaultFeatureGate
f.known[testAlphaGate] = FeatureSpec{Default: false, PreRelease: Alpha}
f.known[testBetaGate] = FeatureSpec{Default: true, PreRelease: Beta}
var f FeatureGate = NewFeatureGate()
f.Add(map[Feature]FeatureSpec{
testAlphaGate: {Default: false, PreRelease: Alpha},
testBetaGate: {Default: true, PreRelease: Beta},
})
if f.Enabled(testAlphaGate) != false {
t.Errorf("Expected false")