Repository: etcd-io/etcd
File: server/embed/config.go (Go)

Code before:
	}

	copySecurityDetails := func(tls *transport.TLSInfo, ysc *securityConfig) {
		tls.CertFile = ysc.CertFile
		tls.KeyFile = ysc.KeyFile
		tls.ClientCertFile = ysc.ClientCertFile
		tls.ClientKeyFile = ysc.ClientKeyFile
		tls.ClientCertAuth = ysc.CertAuth
		tls.TrustedCAFile = ysc.TrustedCAFile
		tls.AllowedCNs = ysc.AllowedCNs
		tls.AllowedHostnames = ysc.AllowedHostnames
	}
	copySecurityDetails(&cfg.ClientTLSInfo, &cfg.ClientSecurityJSON)
	copySecurityDetails(&cfg.PeerTLSInfo, &cfg.PeerSecurityJSON)
	cfg.ClientAutoTLS = cfg.ClientSecurityJSON.AutoTLS
	cfg.PeerAutoTLS = cfg.PeerSecurityJSON.AutoTLS
	if cfg.SelfSignedCertValidity == 0 {
		cfg.SelfSignedCertValidity = 1
	}
	return cfg.Validate()
}

// SetFeatureGatesFromExperimentalFlags sets the feature gate values if the feature gate is not explicitly set
// while their corresponding experimental flags are explicitly set, for all the features in ExperimentalFlagToFeatureMap.
// TODO: remove after all experimental flags are deprecated.
func SetFeatureGatesFromExperimentalFlags(fg featuregate.FeatureGate, getExperimentalFlagVal func(string) *bool, featureGatesFlagName, featureGatesVal string) error {
	m := make(map[featuregate.Feature]bool)
	// verify that the feature gate and its experimental flag are not both set at the same time.
	for expFlagName, featureName := range features.ExperimentalFlagToFeatureMap {
		flagVal := getExperimentalFlagVal(expFlagName)
		if flagVal == nil {
			continue
		}
		if strings.Contains(featureGatesVal, string(featureName)) {
			return fmt.Errorf("cannot specify both flags: --%s=%v and --%s=%s=%v at the same time, please just use --%s=%s=%v",
				expFlagName, *flagVal, featureGatesFlagName, featureName, fg.Enabled(featureName), featureGatesFlagName, featureName, fg.Enabled(featureName))
		}
		m[featureName] = *flagVal
	}

	// filter out unknown features for fg, because we could use SetFeatureGatesFromExperimentalFlags both for
	// server and cluster level feature gates.
	allFeatures := fg.(featuregate.MutableFeatureGate).GetAll()
	mFiltered := make(map[string]bool)
	for k, v := range m {
		if _, ok := allFeatures[k]; ok {
			mFiltered[string(k)] = v
		}
	}
	return fg.(featuregate.MutableFeatureGate).SetFromMap(mFiltered)
}

Review comment (suggestion):
You should be able to read `embed.ServerFeatureGateFlagName` directly.
```suggestion
func SetFeatureGatesFromExperimentalFlags(fg featuregate.FeatureGate, getExperimentalFlagVal func(string) *bool, featureGatesVal string) error {
```

Code after:
	}

	copySecurityDetails := func(tls *transport.TLSInfo, ysc *securityConfig) {
		tls.CertFile = ysc.CertFile
		tls.KeyFile = ysc.KeyFile
		tls.ClientCertFile = ysc.ClientCertFile
		tls.ClientKeyFile = ysc.ClientKeyFile
		tls.ClientCertAuth = ysc.CertAuth
		tls.TrustedCAFile = ysc.TrustedCAFile
		tls.AllowedCNs = ysc.AllowedCNs
		tls.AllowedHostnames = ysc.AllowedHostnames
	}
	copySecurityDetails(&cfg.ClientTLSInfo, &cfg.ClientSecurityJSON)
	copySecurityDetails(&cfg.PeerTLSInfo, &cfg.PeerSecurityJSON)
	cfg.ClientAutoTLS = cfg.ClientSecurityJSON.AutoTLS
	cfg.PeerAutoTLS = cfg.PeerSecurityJSON.AutoTLS
	if cfg.SelfSignedCertValidity == 0 {
		cfg.SelfSignedCertValidity = 1
	}
	return cfg.Validate()
}

// SetFeatureGatesFromExperimentalFlags sets the feature gate values if the feature gate is not explicitly set
// while their corresponding experimental flags are explicitly set, for all the features in ExperimentalFlagToFeatureMap.
// TODO: remove after all experimental flags are deprecated.
func SetFeatureGatesFromExperimentalFlags(fg featuregate.FeatureGate, getExperimentalFlagVal func(string) *bool, featureGatesVal string) error {
	m := make(map[featuregate.Feature]bool)
	// verify that the feature gate and its experimental flag are not both set at the same time.
	for expFlagName, featureName := range features.ExperimentalFlagToFeatureMap {
		flagVal := getExperimentalFlagVal(expFlagName)
		if flagVal == nil {
			continue
		}
		if strings.Contains(featureGatesVal, string(featureName)) {
			return fmt.Errorf("cannot specify both flags: --%s=%v and --%s=%s=%v at the same time, please just use --%s=%s=%v",
				expFlagName, *flagVal, ServerFeatureGateFlagName, featureName, fg.Enabled(featureName), ServerFeatureGateFlagName, featureName, fg.Enabled(featureName))
		}
		m[featureName] = *flagVal
	}

	// filter out unknown features for fg, because we could use SetFeatureGatesFromExperimentalFlags both for
	// server and cluster level feature gates.
	allFeatures := fg.(featuregate.MutableFeatureGate).GetAll()
	mFiltered := make(map[string]bool)
	for k, v := range m {
		if _, ok := allFeatures[k]; ok {
			mFiltered[string(k)] = v
		}
	}
	return fg.(featuregate.MutableFeatureGate).SetFromMap(mFiltered)
}