Skip to content

Commit 873422d

Browse files
authored
Merge pull request #2359 from sedefsavas/featuregate
✨Adding feature-gate flag for experimental features (and migrating from go flags to pflags)
2 parents ddb58eb + c8bb750 commit 873422d

File tree

5 files changed

+104
-14
lines changed

5 files changed

+104
-14
lines changed

features/features.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package features
18+
19+
import (
20+
"k8s.io/apimachinery/pkg/util/runtime"
21+
"k8s.io/component-base/featuregate"
22+
23+
utilfeature "sigs.k8s.io/cluster-api/util/featuregate"
24+
)
25+
26+
const (
27+
// Every feature gate should add method here following this template:
28+
//
29+
// // owner: @username
30+
// // alpha: v1.X
31+
// MyFeature featuregate.Feature = "MyFeature"
32+
)
33+
34+
func init() {
35+
runtime.Must(utilfeature.DefaultMutableFeatureGate.Add(defaultClusterAPIFeatureGates))
36+
}
37+
38+
// defaultClusterAPIFeatureGates consists of all known cluster-api-specific feature keys.
39+
// To add a new feature, define a key for it above and add it here.
40+
var defaultClusterAPIFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
41+
// Every feature should be initiated here:
42+
// MyFeature: {Default: false, PreRelease: featuregate.Alpha},
43+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require (
2222
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
2323
github.com/prometheus/procfs v0.0.5 // indirect
2424
github.com/spf13/cobra v0.0.5
25+
github.com/spf13/pflag v1.0.5
2526
github.com/spf13/viper v1.3.2
2627
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738
2728
go.uber.org/atomic v1.4.0 // indirect
@@ -39,6 +40,7 @@ require (
3940
k8s.io/apiserver v0.17.2
4041
k8s.io/client-go v0.17.2
4142
k8s.io/cluster-bootstrap v0.0.0-20190516232516-d7d78ab2cfe7
43+
k8s.io/component-base v0.17.2
4244
k8s.io/klog v1.0.0
4345
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f
4446
sigs.k8s.io/controller-runtime v0.5.0

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI=
498498
k8s.io/cluster-bootstrap v0.0.0-20190516232516-d7d78ab2cfe7 h1:5wvjieVoU4oovHlkeD256q2M2YYi2P01zk6wxSR2zk0=
499499
k8s.io/cluster-bootstrap v0.0.0-20190516232516-d7d78ab2cfe7/go.mod h1:iBSm2nwo3OaiuW8VDvc3ySDXK5SKfUrxwPvBloKG7zg=
500500
k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
501+
k8s.io/component-base v0.17.2 h1:0XHf+cerTvL9I5Xwn9v+0jmqzGAZI7zNydv4tL6Cw6A=
501502
k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs=
502503
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
503504
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=

main.go

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@ import (
2222
"os"
2323
"time"
2424

25+
"github.com/spf13/pflag"
2526
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2627
"k8s.io/apimachinery/pkg/runtime"
2728
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
2829
"k8s.io/client-go/rest"
2930
"k8s.io/klog"
3031
"k8s.io/klog/klogr"
32+
_ "sigs.k8s.io/cluster-api/features"
33+
"sigs.k8s.io/cluster-api/util/featuregate"
3134
ctrl "sigs.k8s.io/controller-runtime"
3235
"sigs.k8s.io/controller-runtime/pkg/cache"
3336
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -69,44 +72,52 @@ func init() {
6972
// +kubebuilder:scaffold:scheme
7073
}
7174

72-
func main() {
73-
flag.StringVar(&metricsAddr, "metrics-addr", ":8080",
75+
// InitFlags initializes the flags.
76+
func InitFlags(fs *pflag.FlagSet) {
77+
fs.StringVar(&metricsAddr, "metrics-addr", ":8080",
7478
"The address the metric endpoint binds to.")
7579

76-
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
80+
fs.BoolVar(&enableLeaderElection, "enable-leader-election", false,
7781
"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
7882

79-
flag.StringVar(&watchNamespace, "namespace", "",
83+
fs.StringVar(&watchNamespace, "namespace", "",
8084
"Namespace that the controller watches to reconcile cluster-api objects. If unspecified, the controller watches for cluster-api objects across all namespaces.")
8185

82-
flag.StringVar(&profilerAddress, "profiler-address", "",
86+
fs.StringVar(&profilerAddress, "profiler-address", "",
8387
"Bind address to expose the pprof profiler (e.g. localhost:6060)")
8488

85-
flag.IntVar(&clusterConcurrency, "cluster-concurrency", 10,
89+
fs.IntVar(&clusterConcurrency, "cluster-concurrency", 10,
8690
"Number of clusters to process simultaneously")
8791

88-
flag.IntVar(&machineConcurrency, "machine-concurrency", 10,
92+
fs.IntVar(&machineConcurrency, "machine-concurrency", 10,
8993
"Number of machines to process simultaneously")
9094

91-
flag.IntVar(&machineSetConcurrency, "machineset-concurrency", 10,
95+
fs.IntVar(&machineSetConcurrency, "machineset-concurrency", 10,
9296
"Number of machine sets to process simultaneously")
9397

94-
flag.IntVar(&machineDeploymentConcurrency, "machinedeployment-concurrency", 10,
98+
fs.IntVar(&machineDeploymentConcurrency, "machinedeployment-concurrency", 10,
9599
"Number of machine deployments to process simultaneously")
96100

97-
flag.IntVar(&machinePoolConcurrency, "machinepool-concurrency", 10,
101+
fs.IntVar(&machinePoolConcurrency, "machinepool-concurrency", 10,
98102
"Number of machine pools to process simultaneously")
99103

100-
flag.DurationVar(&syncPeriod, "sync-period", 10*time.Minute,
104+
fs.DurationVar(&syncPeriod, "sync-period", 10*time.Minute,
101105
"The minimum interval at which watched resources are reconciled (e.g. 15m)")
102106

103-
flag.IntVar(&webhookPort, "webhook-port", 0,
107+
fs.IntVar(&webhookPort, "webhook-port", 0,
104108
"Webhook Server port, disabled by default. When enabled, the manager will only work as webhook server, no reconcilers are installed.")
105109

106-
flag.StringVar(&healthAddr, "health-addr", ":9440",
110+
fs.StringVar(&healthAddr, "health-addr", ":9440",
107111
"The address the health endpoint binds to.")
108112

109-
flag.Parse()
113+
// Add --feature-gates flag
114+
featuregate.DefaultMutableFeatureGate.AddFlag(fs)
115+
}
116+
117+
func main() {
118+
InitFlags(pflag.CommandLine)
119+
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
120+
pflag.Parse()
110121

111122
ctrl.SetLogger(klogr.New())
112123

util/featuregate/featuregate.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package featuregate
18+
19+
import (
20+
"k8s.io/component-base/featuregate"
21+
)
22+
23+
var (
24+
// DefaultMutableFeatureGate is a mutable version of DefaultFeatureGate.
25+
// Only top-level commands/options setup and the k8s.io/component-base/featuregate/testing package should make use of this.
26+
// Tests that need to modify featuregate gates for the duration of their test should use:
27+
// defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.<FeatureName>, <value>)()
28+
DefaultMutableFeatureGate featuregate.MutableFeatureGate = featuregate.NewFeatureGate()
29+
30+
// DefaultFeatureGate is a shared global FeatureGate.
31+
// Top-level commands/options setup that needs to modify this featuregate gate should use DefaultMutableFeatureGate.
32+
DefaultFeatureGate featuregate.FeatureGate = DefaultMutableFeatureGate
33+
)

0 commit comments

Comments
 (0)