Skip to content

Commit 2cf755f

Browse files
authored
Implement CRD migration (#2610)
1 parent d990bf9 commit 2cf755f

File tree

2 files changed

+98
-16
lines changed

2 files changed

+98
-16
lines changed

cmd/main.go

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
// +kubebuilder:scaffold:imports
2929
"github.com/spf13/pflag"
3030

31+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3132
"k8s.io/apimachinery/pkg/runtime"
3233
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
3334
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
@@ -39,9 +40,11 @@ import (
3940
ctrl "sigs.k8s.io/controller-runtime"
4041
"sigs.k8s.io/controller-runtime/pkg/cache"
4142
"sigs.k8s.io/controller-runtime/pkg/client"
43+
"sigs.k8s.io/controller-runtime/pkg/controller"
4244
"sigs.k8s.io/controller-runtime/pkg/webhook"
4345

4446
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
47+
"sigs.k8s.io/cluster-api/controllers/crdmigrator"
4548
"sigs.k8s.io/cluster-api/util/flags"
4649

4750
powervsinfrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/powervs/v1beta2"
@@ -60,19 +63,21 @@ import (
6063
)
6164

6265
var (
63-
watchNamespace string
64-
enableLeaderElection bool
65-
healthAddr string
66-
syncPeriod time.Duration
67-
managerOptions = flags.ManagerOptions{}
68-
logOptions = logs.NewOptions()
69-
webhookPort int
70-
webhookCertDir string
71-
watchFilterValue string
72-
disableHTTP2 bool
73-
7466
scheme = runtime.NewScheme()
7567
setupLog = ctrl.Log.WithName("setup")
68+
69+
// flags.
70+
watchNamespace string
71+
enableLeaderElection bool
72+
healthAddr string
73+
syncPeriod time.Duration
74+
managerOptions = flags.ManagerOptions{}
75+
logOptions = logs.NewOptions()
76+
webhookPort int
77+
webhookCertDir string
78+
watchFilterValue string
79+
disableHTTP2 bool
80+
skipCRDMigrationPhases []string
7681
)
7782

7883
func init() {
@@ -84,10 +89,13 @@ func init() {
8489
utilruntime.Must(vpcinfrav1beta1.AddToScheme(scheme))
8590
utilruntime.Must(vpcinfrav1.AddToScheme(scheme))
8691
utilruntime.Must(clusterv1.AddToScheme(scheme))
92+
utilruntime.Must(apiextensionsv1.AddToScheme(scheme))
8793
// +kubebuilder:scaffold:scheme
8894
}
8995

9096
func initFlags(fs *pflag.FlagSet) {
97+
logsv1.AddFlags(logOptions, fs)
98+
9199
fs.BoolVar(
92100
&enableLeaderElection,
93101
"leader-elect",
@@ -136,15 +144,26 @@ func initFlags(fs *pflag.FlagSet) {
136144
"The webhook server port the manager will listen on.",
137145
)
138146

139-
fs.StringVar(&webhookCertDir, "webhook-cert-dir", "/tmp/k8s-webhook-server/serving-certs/",
147+
fs.StringVar(&webhookCertDir,
148+
"webhook-cert-dir",
149+
"/tmp/k8s-webhook-server/serving-certs/",
140150
"The webhook certificate directory, where the server should find the TLS certificate and key.")
141151

142-
fs.StringVar(&watchFilterValue, "watch-filter", "",
152+
fs.StringVar(&watchFilterValue,
153+
"watch-filter",
154+
"",
143155
fmt.Sprintf("Label value that the controller watches to reconcile cluster-api objects. Label key is always %s. If unspecified, the controller watches for all cluster-api objects.", clusterv1.WatchLabel))
144-
fs.BoolVar(&disableHTTP2, "disable-http2", true, "http/2 should be disabled due to its vulnerabilities. More specifically, disabling http/2 will"+
145-
" prevent from being vulnerable to the HTTP/2 Stream Cancellation and Rapid Reset CVEs.")
146156

147-
logsv1.AddFlags(logOptions, fs)
157+
fs.BoolVar(&disableHTTP2,
158+
"disable-http2",
159+
true,
160+
"http/2 should be disabled due to its vulnerabilities. More specifically, disabling http/2 will prevent from being vulnerable to the HTTP/2 Stream Cancellation and Rapid Reset CVEs.")
161+
162+
fs.StringSliceVar(&skipCRDMigrationPhases,
163+
"skip-crd-migration-phases",
164+
[]string{},
165+
"List of CRD migration phases to skip. Valid values are: StorageVersionMigration, CleanupManagedFields.")
166+
148167
flags.AddManagerOptions(fs, &managerOptions)
149168
}
150169

@@ -166,6 +185,11 @@ func validateFlags() error {
166185
// Add RBAC for the authorized diagnostics endpoint.
167186
// +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create
168187
// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create
188+
// ADD CRD RBAC for CRD Migrator.
189+
// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch
190+
// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions;customresourcedefinitions/status,verbs=update;patch,resourceNames=ibmpowervsclusters.infrastructure.cluster.x-k8s.io;ibmpowervsclustertemplates.infrastructure.cluster.x-k8s.io;ibmpowervsmachines.infrastructure.cluster.x-k8s.io;ibmpowervsmachinetemplates.infrastructure.cluster.x-k8s.io;ibmpowervsimages.infrastructure.cluster.x-k8s.io
191+
// ADD CR RBAC for CRD Migrator.
192+
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=ibmpowervsclustertemplates,verbs=get;list;watch;patch;update
169193

170194
func main() {
171195
initFlags(pflag.CommandLine)
@@ -268,6 +292,32 @@ func main() {
268292
}
269293

270294
func setupReconcilers(ctx context.Context, mgr ctrl.Manager, serviceEndpoint []endpoints.ServiceEndpoint) {
295+
// Note: The kubebuilder RBAC markers above has to be kept in sync
296+
// with the CRDs that should be migrated by this provider.
297+
crdMigratorConfig := map[client.Object]crdmigrator.ByObjectConfig{
298+
&powervsinfrav1.IBMPowerVSCluster{}: {UseCache: true, UseStatusForStorageVersionMigration: true},
299+
&powervsinfrav1.IBMPowerVSClusterTemplate{}: {UseCache: false},
300+
&powervsinfrav1.IBMPowerVSMachine{}: {UseCache: true, UseStatusForStorageVersionMigration: true},
301+
&powervsinfrav1.IBMPowerVSMachineTemplate{}: {UseCache: false},
302+
&powervsinfrav1.IBMPowerVSImage{}: {UseCache: true, UseStatusForStorageVersionMigration: true},
303+
}
304+
305+
crdMigratorSkipPhases := []crdmigrator.Phase{}
306+
for _, p := range skipCRDMigrationPhases {
307+
crdMigratorSkipPhases = append(crdMigratorSkipPhases, crdmigrator.Phase(p))
308+
}
309+
if err := (&crdmigrator.CRDMigrator{
310+
Client: mgr.GetClient(),
311+
APIReader: mgr.GetAPIReader(),
312+
SkipCRDMigrationPhases: crdMigratorSkipPhases,
313+
Config: crdMigratorConfig,
314+
// The CRDMigrator is run with only concurrency 1 to ensure we don't overwhelm the apiserver by patching a
315+
// lot of CRs concurrently.
316+
}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: 1}); err != nil {
317+
setupLog.Error(err, "Unable to create controller", "controller", "CRDMigrator")
318+
os.Exit(1)
319+
}
320+
271321
if err := (&controllers.IBMVPCClusterReconciler{
272322
Client: mgr.GetClient(),
273323
Log: ctrl.Log.WithName("controllers").WithName("IBMVPCCluster"),

config/rbac/role.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,28 @@ rules:
2323
- get
2424
- list
2525
- watch
26+
- apiGroups:
27+
- apiextensions.k8s.io
28+
resources:
29+
- customresourcedefinitions
30+
verbs:
31+
- get
32+
- list
33+
- watch
34+
- apiGroups:
35+
- apiextensions.k8s.io
36+
resourceNames:
37+
- ibmpowervsclusters.infrastructure.cluster.x-k8s.io
38+
- ibmpowervsclustertemplates.infrastructure.cluster.x-k8s.io
39+
- ibmpowervsimages.infrastructure.cluster.x-k8s.io
40+
- ibmpowervsmachines.infrastructure.cluster.x-k8s.io
41+
- ibmpowervsmachinetemplates.infrastructure.cluster.x-k8s.io
42+
resources:
43+
- customresourcedefinitions
44+
- customresourcedefinitions/status
45+
verbs:
46+
- patch
47+
- update
2648
- apiGroups:
2749
- authentication.k8s.io
2850
resources:
@@ -76,6 +98,16 @@ rules:
7698
- get
7799
- patch
78100
- update
101+
- apiGroups:
102+
- infrastructure.cluster.x-k8s.io
103+
resources:
104+
- ibmpowervsclustertemplates
105+
verbs:
106+
- get
107+
- list
108+
- patch
109+
- update
110+
- watch
79111
- apiGroups:
80112
- infrastructure.cluster.x-k8s.io
81113
resources:

0 commit comments

Comments
 (0)