diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 55e39c0e..602b8d67 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -24,6 +24,17 @@ rules: - patch - update - watch +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + - customresourcedefinitions/status + verbs: + - get + - list + - patch + - update + - watch - apiGroups: - authentication.k8s.io resources: @@ -80,6 +91,7 @@ rules: - cloudstackaffinitygroups/status - cloudstackisolatednetworks/status - cloudstackmachines/status + - cloudstackmachinestatecheckers/status - cloudstackmachinetemplates/status verbs: - get @@ -95,6 +107,17 @@ rules: - get - patch - update +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - cloudstackclustertemplates + - cloudstackmachinestatecheckers + verbs: + - get + - list + - patch + - update + - watch - apiGroups: - infrastructure.cluster.x-k8s.io resources: diff --git a/go.mod b/go.mod index f781ae64..8452abdb 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( golang.org/x/text v0.28.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.33.3 + k8s.io/apiextensions-apiserver v0.33.3 k8s.io/apimachinery v0.33.3 k8s.io/client-go v0.33.3 k8s.io/component-base v0.33.3 @@ -95,7 +96,6 @@ require ( google.golang.org/protobuf v1.36.6 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - k8s.io/apiextensions-apiserver v0.33.3 // indirect k8s.io/apiserver v0.33.3 // indirect k8s.io/cluster-bootstrap v0.33.3 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect diff --git a/main.go b/main.go index 1266befd..93ef0bf6 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,7 @@ import ( "github.com/spf13/pflag" corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -37,6 +38,7 @@ import ( logsv1 "k8s.io/component-base/logs/api/v1" "k8s.io/klog/v2" clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" + "sigs.k8s.io/cluster-api/controllers/crdmigrator" "sigs.k8s.io/cluster-api/controllers/remote" "sigs.k8s.io/cluster-api/feature" "sigs.k8s.io/cluster-api/util/flags" @@ -61,6 +63,7 @@ var ( ) func init() { + utilruntime.Must(apiextensionsv1.AddToScheme(scheme)) utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(clusterv1.AddToScheme(scheme)) utilruntime.Must(infrav1beta1.AddToScheme(scheme)) @@ -90,6 +93,7 @@ var ( managerOptions = flags.ManagerOptions{} logOptions = logs.NewOptions() showVersion bool + skipCRDMigrationPhases []string cloudStackClusterConcurrency int cloudStackMachineConcurrency int @@ -180,6 +184,9 @@ func initFlags(fs *pflag.FlagSet) { fs.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.") + fs.StringArrayVar(&skipCRDMigrationPhases, "skip-crd-migration-phases", []string{}, + "List of CRD migration phases to skip. Valid values are: StorageVersionMigration, CleanupManagedFields.") + fs.BoolVar(&showVersion, "version", false, "Show current version and exit.") flags.AddManagerOptions(fs, &managerOptions) @@ -190,6 +197,11 @@ func initFlags(fs *pflag.FlagSet) { // Add RBAC for the authorized diagnostics endpoint. // +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create // +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create +// Setup CRD migrator +// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch;update;patch +// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions/status,verbs=get;list;watch;update;patch +// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=cloudstackclusters;cloudstackmachines;cloudstackmachinetemplates;cloudstackclustertemplates;cloudstackfailuredomains;cloudstackisolatednetworks;cloudstackaffinitygroups;cloudstackmachinestatecheckers,verbs=get;list;watch;patch;update +// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=cloudstackclusters/status;cloudstackmachines/status;cloudstackmachinetemplates/status;cloudstackfailuredomains/status;cloudstackisolatednetworks/status;cloudstackaffinitygroups/status;cloudstackmachinestatecheckers/status,verbs=get;patch;update func main() { initFlags(pflag.CommandLine) @@ -308,6 +320,55 @@ func setupChecks(mgr ctrl.Manager) { func setupReconcilers(ctx context.Context, mgr manager.Manager) { scopeFactory := scope.NewClientScopeFactory(10) + + crdMigratorConfig := map[client.Object]crdmigrator.ByObjectConfig{ + &infrav1.CloudStackCluster{}: { + UseCache: true, + UseStatusForStorageVersionMigration: true, + }, + &infrav1.CloudStackMachine{}: { + UseCache: true, + UseStatusForStorageVersionMigration: true, + }, + &infrav1.CloudStackMachineTemplate{}: { + UseCache: true, + UseStatusForStorageVersionMigration: true, + }, + &infrav1.CloudStackClusterTemplate{}: { + UseCache: true, + UseStatusForStorageVersionMigration: false, + }, + &infrav1.CloudStackFailureDomain{}: { + UseCache: true, + UseStatusForStorageVersionMigration: true, + }, + &infrav1.CloudStackIsolatedNetwork{}: { + UseCache: true, + UseStatusForStorageVersionMigration: true, + }, + &infrav1.CloudStackAffinityGroup{}: { + UseCache: true, + UseStatusForStorageVersionMigration: true, + }, + &infrav1.CloudStackMachineStateChecker{}: { + UseCache: true, + UseStatusForStorageVersionMigration: true, + }, + } + crdMigratorSkipPhases := []crdmigrator.Phase{} + for _, p := range skipCRDMigrationPhases { + crdMigratorSkipPhases = append(crdMigratorSkipPhases, crdmigrator.Phase(p)) + } + if err := (&crdmigrator.CRDMigrator{ + Client: mgr.GetClient(), + APIReader: mgr.GetAPIReader(), + SkipCRDMigrationPhases: crdMigratorSkipPhases, + Config: crdMigratorConfig, + }).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: 1}); err != nil { + setupLog.Error(err, "unable to setup CRD migrator") + os.Exit(1) + } + if err := (&controllers.CloudStackClusterReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), diff --git a/metadata.yaml b/metadata.yaml index 5f4e11ce..a48fd594 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -6,6 +6,12 @@ apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3 kind: Metadata releaseSeries: + - major: 0 + minor: 12 + contract: v1beta1 + - major: 0 + minor: 11 + contract: v1beta1 - major: 0 minor: 10 contract: v1beta1 diff --git a/tilt-provider.json b/tilt-provider.json index 46ac7e04..32bf7603 100644 --- a/tilt-provider.json +++ b/tilt-provider.json @@ -10,7 +10,7 @@ "go.sum", "api", "cmd", - "controllers", + "internal", "pkg" ] }