func (f *featureGate) Set(value string) error {
	f.enabled = make(map[string]bool)
	for _, s := range strings.Split(value, ",") {
		if len(s) == 0 {
			continue
		}
		arr := strings.SplitN(s, "=", 2)
		k := strings.TrimSpace(arr[0])
		_, ok := f.known[k]
		if !ok {
			return fmt.Errorf("unrecognized key: %s", k)
		}
		if len(arr) != 2 {
			return fmt.Errorf("missing bool value for %s", k)
		}
		v := strings.TrimSpace(arr[1])
		boolValue, err := strconv.ParseBool(v)
		if err != nil {
			return fmt.Errorf("invalid value of %s: %s, err: %v", k, v, err)
		}
		f.enabled[k] = boolValue
		if fn, found := f.special[k]; found {
			fn(f, boolValue)
		}
	}
	glog.Infof("feature gates: %v", f.enabled)
	return nil
}
Set, String, and Type implement pflag.Value
Set Parses a string of the form // "key1=value1,key2=value2,..." into a
map[string]bool of known keys or returns an error.
package config
import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"github.com/golang/glog"
	"github.com/spf13/pflag"
)
const (
	flagName = "feature-gates"
	allAlphaGate              = "AllAlpha"
	externalTrafficLocalOnly  = "AllowExtTrafficLocalEndpoints"
	appArmor                  = "AppArmor"
	dynamicKubeletConfig      = "DynamicKubeletConfig"
	dynamicVolumeProvisioning = "DynamicVolumeProvisioning"
)
var (
	knownFeatures = map[string]featureSpec{
		allAlphaGate:              {false, alpha},
		externalTrafficLocalOnly:  {false, alpha},
		appArmor:                  {true, beta},
		dynamicKubeletConfig:      {false, alpha},
		dynamicVolumeProvisioning: {true, alpha},
	}
	specialFeatures = map[string]func(f *featureGate, val bool){
		allAlphaGate: setUnsetAlphaGates,
	}
	DefaultFeatureGate = &featureGate{
		known:   knownFeatures,
		special: specialFeatures,
	}
)
type featureSpec struct {
	enabled    bool
	prerelease prerelease
}
type prerelease string
const (
	alpha = prerelease("ALPHA")
	beta  = prerelease("BETA")
	ga    = prerelease("")
)
type FeatureGate interface {
	AddFlag(fs *pflag.FlagSet)
	AppArmor() bool
	ExternalTrafficLocalOnly() bool
	DynamicVolumeProvisioning() bool
	DynamicKubeletConfig() bool
}
type featureGate struct {
	known   map[string]featureSpec
	special map[string]func(*featureGate, bool)
	enabled map[string]bool
}
func setUnsetAlphaGates(f *featureGate, val bool) {
	for k, v := range f.known {
		if v.prerelease == alpha {
			if _, found := f.enabled[k]; !found {
				f.enabled[k] = val
			}
		}
	}
}