From f815f1d182857fa150313de3812a97e1c3f83d8c Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 14:21:17 -0800 Subject: [PATCH 01/11] add ARC flag, update UTs Signed-off-by: Arvind Thirumurugan --- cmd/crdinstaller/main.go | 12 +++++++---- cmd/crdinstaller/utils/util.go | 9 +++++++- cmd/crdinstaller/utils/util_test.go | 32 ++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/cmd/crdinstaller/main.go b/cmd/crdinstaller/main.go index ba945f981..be3058819 100644 --- a/cmd/crdinstaller/main.go +++ b/cmd/crdinstaller/main.go @@ -22,7 +22,10 @@ import ( "go.goms.io/fleet/cmd/crdinstaller/utils" ) -var mode = flag.String("mode", "", "Mode to run in: 'hub' or 'member' (required)") +var ( + mode = flag.String("mode", "", "Mode to run in: 'hub' or 'member' (required)") + isArcInstallation = flag.Bool("arcInstallation", false, "Enable ARC AKS installation mode") +) func main() { klog.InitFlags(nil) @@ -34,6 +37,7 @@ func main() { } klog.Infof("Starting CRD installer in %s mode", *mode) + klog.Infof("ARC installation mode: %v", *isArcInstallation) // Print all flags for debugging. flag.VisitAll(func(f *flag.Flag) { @@ -66,7 +70,7 @@ func main() { // Install CRDs from the fixed location. const crdPath = "/workspace/config/crd/bases" - if err := installCRDs(ctx, client, crdPath, *mode); err != nil { + if err := installCRDs(ctx, client, crdPath, *mode, *isArcInstallation); err != nil { klog.Fatalf("Failed to install CRDs: %v", err) } @@ -74,7 +78,7 @@ func main() { } // installCRDs installs the CRDs from the specified directory based on the mode. -func installCRDs(ctx context.Context, client client.Client, crdPath, mode string) error { +func installCRDs(ctx context.Context, client client.Client, crdPath, mode string, isArcInstallation bool) error { // List of CRDs to install based on mode. crdsToInstall, err := utils.CollectCRDs(crdPath, mode, client.Scheme()) if err != nil { @@ -89,7 +93,7 @@ func installCRDs(ctx context.Context, client client.Client, crdPath, mode string // Install each CRD. for i := range crdsToInstall { - if err := utils.InstallCRD(ctx, client, &crdsToInstall[i]); err != nil { + if err := utils.InstallCRD(ctx, client, &crdsToInstall[i], isArcInstallation); err != nil { return err } } diff --git a/cmd/crdinstaller/utils/util.go b/cmd/crdinstaller/utils/util.go index 2ff94dc22..862e0d146 100644 --- a/cmd/crdinstaller/utils/util.go +++ b/cmd/crdinstaller/utils/util.go @@ -24,6 +24,8 @@ import ( ) const ( + // ArcInstallationKey is the key used to indicate if the installation is for ARC AKS cluster. + ArcInstallationKey = "crd-installer.azurefleet.io/arcinstallation" // CRDInstallerLabelKey is the label key used to indicate that a CRD is managed by the installer. CRDInstallerLabelKey = "crd-installer.azurefleet.io/managed" // AzureManagedLabelKey is the label key used to indicate that a CRD is managed by an azure resource. @@ -42,7 +44,7 @@ var ( ) // InstallCRD creates/updates a Custom Resource Definition (CRD) from the provided CRD object. -func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1.CustomResourceDefinition) error { +func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1.CustomResourceDefinition, isArcInstallation bool) error { klog.V(2).Infof("Installing CRD: %s", crd.Name) existingCRD := apiextensionsv1.CustomResourceDefinition{ @@ -59,6 +61,11 @@ func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1. if existingCRD.Labels == nil { existingCRD.Labels = make(map[string]string) } + if isArcInstallation { + // For ARC AKS installation, we want to add an additional label to indicate this is an ARC managed cluster, + // needed for clean up of CRD by kube-addon-manager. + existingCRD.Labels[ArcInstallationKey] = "true" + } // Ensure the label for management by the installer is set. existingCRD.Labels[CRDInstallerLabelKey] = "true" // Also set the Azure managed label to indicate this is managed by Fleet, diff --git a/cmd/crdinstaller/utils/util_test.go b/cmd/crdinstaller/utils/util_test.go index 22f474b7d..4eb23fec8 100644 --- a/cmd/crdinstaller/utils/util_test.go +++ b/cmd/crdinstaller/utils/util_test.go @@ -155,21 +155,29 @@ func TestInstallCRD(t *testing.T) { } tests := []struct { - name string - crd *apiextensionsv1.CustomResourceDefinition - wantError bool + name string + crd *apiextensionsv1.CustomResourceDefinition + isArcInstallation bool + wantError bool }{ { - name: "successful CRD installation", - crd: testCRD, - wantError: false, + name: "successful CRD installation without ARC", + crd: testCRD, + isArcInstallation: false, + wantError: false, + }, + { + name: "successful CRD installation with ARC", + crd: testCRD, + isArcInstallation: true, + wantError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build() - err := InstallCRD(context.Background(), fakeClient, tt.crd) + err := InstallCRD(context.Background(), fakeClient, tt.crd, tt.isArcInstallation) if tt.wantError { if err == nil { @@ -198,6 +206,16 @@ func TestInstallCRD(t *testing.T) { t.Errorf("Expected CRD label %s to be %q, got %q", AzureManagedLabelKey, FleetLabelValue, installedCRD.Labels[AzureManagedLabelKey]) } + if tt.isArcInstallation { + if installedCRD.Labels[ArcInstallationKey] != "true" { + t.Errorf("Expected CRD label %s to be 'true', got %q", ArcInstallationKey, installedCRD.Labels[ArcInstallationKey]) + } + } else { + if _, exists := installedCRD.Labels[ArcInstallationKey]; exists { + t.Errorf("Expected CRD label %s to not exist for non-ARC installation", ArcInstallationKey) + } + } + if diff := cmp.Diff(tt.crd.Spec, installedCRD.Spec); diff != "" { t.Errorf("CRD spec mismatch (-want +got):\n%s", diff) } From fee6431cd25d0982ef3468c4757fb1f28c29133f Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 14:27:31 -0800 Subject: [PATCH 02/11] fix IT Signed-off-by: Arvind Thirumurugan --- test/crdinstaller/crd_installer_integration_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/crdinstaller/crd_installer_integration_test.go b/test/crdinstaller/crd_installer_integration_test.go index 7aee4a5d0..61594d7de 100644 --- a/test/crdinstaller/crd_installer_integration_test.go +++ b/test/crdinstaller/crd_installer_integration_test.go @@ -36,7 +36,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { It("should create original CRD", func() { crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd)).To(Succeed()) + Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) }) It("should verify original CRD installation", func() { @@ -61,7 +61,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { It("should update the CRD with new field in spec with crdinstaller label", func() { crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd)).To(Succeed()) + Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) }) It("should verify updated CRD", func() { From 72dabffbcb6f1ff6927eb765ab2bba40592ba823 Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 14:39:07 -0800 Subject: [PATCH 03/11] update IT Signed-off-by: Arvind Thirumurugan --- .../crd_installer_integration_test.go | 154 +++++++++++++----- 1 file changed, 113 insertions(+), 41 deletions(-) diff --git a/test/crdinstaller/crd_installer_integration_test.go b/test/crdinstaller/crd_installer_integration_test.go index 61594d7de..a2b0fdc8a 100644 --- a/test/crdinstaller/crd_installer_integration_test.go +++ b/test/crdinstaller/crd_installer_integration_test.go @@ -13,9 +13,11 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" cmdCRDInstaller "go.goms.io/fleet/cmd/crdinstaller/utils" + "go.goms.io/fleet/pkg/utils" ) const ( @@ -33,53 +35,111 @@ const ( // It ensures that the installer can create a CRD, update it with new fields, and handle ownership label correctly. // The original CRD has 4 properties, and the updated CRD has a new property to simulate CRD upgrade. var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { - It("should create original CRD", func() { - crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) - Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) - }) + Context("without ARC installation mode", func() { + AfterAll(func() { + deleteCRD(crdName) + }) - It("should verify original CRD installation", func() { - ensureCRDExistsWithLabels(map[string]string{ - cmdCRDInstaller.CRDInstallerLabelKey: "true", - cmdCRDInstaller.AzureManagedLabelKey: cmdCRDInstaller.FleetLabelValue, + It("should create original CRD", func() { + crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) + Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) + Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) }) - crd := &apiextensionsv1.CustomResourceDefinition{} - Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crdName}, crd)).NotTo(HaveOccurred(), "CRD %s should be installed", crdName) - spec := fetchSpecJSONSchemaProperties(crd) - // Original CRD should have 4 properties defined in spec. - Expect(len(spec.Properties)).Should(Equal(4), "CRD %s should have 4 properties defined in spec", crdName) - Expect(spec.Properties["bar"].Type).Should(Equal("string"), "CRD %s should have 'bar' property of type string defined in properties", crdName) - _, ok := spec.Properties["newField"] - Expect(ok).To(BeFalse(), "CRD %s should not have 'newField' property defined in properties", crdName) - }) - It("update the CRD to add a random label", func() { - updateCRDLabels(crdName, map[string]string{randomLabelKey: "true"}) - }) + It("should verify original CRD installation", func() { + ensureCRDExistsWithLabels(map[string]string{ + cmdCRDInstaller.CRDInstallerLabelKey: "true", + cmdCRDInstaller.AzureManagedLabelKey: cmdCRDInstaller.FleetLabelValue, + }) + crd := &apiextensionsv1.CustomResourceDefinition{} + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crdName}, crd)).NotTo(HaveOccurred(), "CRD %s should be installed", crdName) + spec := fetchSpecJSONSchemaProperties(crd) + // Original CRD should have 4 properties defined in spec. + Expect(len(spec.Properties)).Should(Equal(4), "CRD %s should have 4 properties defined in spec", crdName) + Expect(spec.Properties["bar"].Type).Should(Equal("string"), "CRD %s should have 'bar' property of type string defined in properties", crdName) + _, ok := spec.Properties["newField"] + Expect(ok).To(BeFalse(), "CRD %s should not have 'newField' property defined in properties", crdName) + }) - It("should update the CRD with new field in spec with crdinstaller label", func() { - crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) - Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) + It("update the CRD to add a random label", func() { + updateCRDLabels(crdName, map[string]string{randomLabelKey: "true"}) + }) + + It("should update the CRD with new field in spec with crdinstaller label", func() { + crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) + Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) + Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) + }) + + It("should verify updated CRD", func() { + // ensure we don't overwrite the random label. + ensureCRDExistsWithLabels(map[string]string{ + randomLabelKey: "true", + cmdCRDInstaller.CRDInstallerLabelKey: "true", + cmdCRDInstaller.AzureManagedLabelKey: cmdCRDInstaller.FleetLabelValue, + }) + crd := &apiextensionsv1.CustomResourceDefinition{} + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crdName}, crd)).NotTo(HaveOccurred(), "CRD %s should be installed", crdName) + spec := fetchSpecJSONSchemaProperties(crd) + // Updated CRD should have 5 properties defined in spec. + Expect(len(spec.Properties)).Should(Equal(5), "CRD %s should have 5 properties defined in spec", crdName) + Expect(spec.Properties["bar"].Type).Should(Equal("string"), "CRD %s should have 'bar' property of type string defined in properties", crdName) + _, ok := spec.Properties["newField"] + Expect(ok).To(BeTrue(), "CRD %s should have 'newField' property defined in properties", crdName) + Expect(spec.Properties["newField"].Type).Should(Equal("string"), "CRD %s should have 'newField' property of type string defined in properties", crdName) + }) }) - It("should verify updated CRD", func() { - // ensure we don't overwrite the random label. - ensureCRDExistsWithLabels(map[string]string{ - randomLabelKey: "true", - cmdCRDInstaller.CRDInstallerLabelKey: "true", - cmdCRDInstaller.AzureManagedLabelKey: cmdCRDInstaller.FleetLabelValue, + Context("with ARC installation mode", func() { + AfterAll(func() { + deleteCRD(crdName) + }) + + It("should create CRD with ARC installation mode", func() { + crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) + Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) + Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true)).To(Succeed()) + }) + + It("should verify CRD has ARC installation label", func() { + ensureCRDExistsWithLabels(map[string]string{ + cmdCRDInstaller.CRDInstallerLabelKey: "true", + cmdCRDInstaller.AzureManagedLabelKey: cmdCRDInstaller.FleetLabelValue, + cmdCRDInstaller.ArcInstallationKey: "true", + }) + crd := &apiextensionsv1.CustomResourceDefinition{} + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crdName}, crd)).NotTo(HaveOccurred(), "CRD %s should be installed", crdName) + spec := fetchSpecJSONSchemaProperties(crd) + // Original CRD should have 4 properties defined in spec. + Expect(len(spec.Properties)).Should(Equal(4), "CRD %s should have 4 properties defined in spec", crdName) + }) + + It("update the CRD to add a random label", func() { + updateCRDLabels(crdName, map[string]string{randomLabelKey: "true"}) + }) + + It("should update the CRD with new field in spec while preserving ARC label", func() { + crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) + Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) + Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true)).To(Succeed()) + }) + + It("should verify updated CRD has all labels including ARC", func() { + // ensure we don't overwrite the random label and ARC label is preserved. + ensureCRDExistsWithLabels(map[string]string{ + randomLabelKey: "true", + cmdCRDInstaller.CRDInstallerLabelKey: "true", + cmdCRDInstaller.AzureManagedLabelKey: cmdCRDInstaller.FleetLabelValue, + cmdCRDInstaller.ArcInstallationKey: "true", + }) + crd := &apiextensionsv1.CustomResourceDefinition{} + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crdName}, crd)).NotTo(HaveOccurred(), "CRD %s should be installed", crdName) + spec := fetchSpecJSONSchemaProperties(crd) + // Updated CRD should have 5 properties defined in spec. + Expect(len(spec.Properties)).Should(Equal(5), "CRD %s should have 5 properties defined in spec", crdName) + _, ok := spec.Properties["newField"] + Expect(ok).To(BeTrue(), "CRD %s should have 'newField' property defined in properties", crdName) }) - crd := &apiextensionsv1.CustomResourceDefinition{} - Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crdName}, crd)).NotTo(HaveOccurred(), "CRD %s should be installed", crdName) - spec := fetchSpecJSONSchemaProperties(crd) - // Updated CRD should have 5 properties defined in spec. - Expect(len(spec.Properties)).Should(Equal(5), "CRD %s should have 5 properties defined in spec", crdName) - Expect(spec.Properties["bar"].Type).Should(Equal("string"), "CRD %s should have 'bar' property of type string defined in properties", crdName) - _, ok := spec.Properties["newField"] - Expect(ok).To(BeTrue(), "CRD %s should have 'newField' property defined in properties", crdName) - Expect(spec.Properties["newField"].Type).Should(Equal("string"), "CRD %s should have 'newField' property of type string defined in properties", crdName) }) }) @@ -115,5 +175,17 @@ func ensureCRDExistsWithLabels(wantLabels map[string]string) { return fmt.Errorf("crd labels mismatch (-want, +got) :\n%s", diff) } return nil - }, eventuallyDuration, eventuallyInterval).ShouldNot(HaveOccurred(), "CRD %s should exist with labels %v", crdName) + }, eventuallyDuration, eventuallyInterval).ShouldNot(HaveOccurred(), "CRD %s should exist with labels %v", crdName, wantLabels) +} + +func deleteCRD(crdName string) { + crd := &apiextensionsv1.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: crdName, + }, + } + Expect(k8sClient.Delete(ctx, crd)).Should(SatisfyAny(Succeed(), utils.NotFoundMatcher{})) + Eventually(func() error { + return k8sClient.Get(ctx, types.NamespacedName{Name: crdName}, crd) + }, eventuallyDuration, eventuallyInterval).Should(utils.NotFoundMatcher{}, "CRD %s should be deleted", crdName) } From 32cfc1429b7ae9f5db67211920e789c42ffdb79f Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 14:43:18 -0800 Subject: [PATCH 04/11] add flag to member-agent-arc chart Signed-off-by: Arvind Thirumurugan --- charts/member-agent-arc/templates/deployment.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/charts/member-agent-arc/templates/deployment.yaml b/charts/member-agent-arc/templates/deployment.yaml index 195dc29ba..1cddda7e5 100644 --- a/charts/member-agent-arc/templates/deployment.yaml +++ b/charts/member-agent-arc/templates/deployment.yaml @@ -22,6 +22,7 @@ spec: image: "{{ .Values.crdinstaller.repository }}:{{ .Values.crdinstaller.tag }}" args: - --mode=member + - --arcInstallation=true - --v={{ .Values.crdinstaller.logVerbosity }} securityContext: capabilities: From 0cee6146e2a61e1d380e62f8342ee3e491bb5afc Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 14:58:59 -0800 Subject: [PATCH 05/11] make reviewable Signed-off-by: Arvind Thirumurugan --- cmd/crdinstaller/utils/util.go | 8 ++++++-- go.mod | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cmd/crdinstaller/utils/util.go b/cmd/crdinstaller/utils/util.go index 862e0d146..565997e05 100644 --- a/cmd/crdinstaller/utils/util.go +++ b/cmd/crdinstaller/utils/util.go @@ -34,6 +34,10 @@ const ( FleetLabelValue = "fleet" ) +const ( + trueLabelValue = "true" +) + var ( multiclusterCRD = map[string]bool{ "multicluster.x-k8s.io_clusterprofiles.yaml": true, @@ -64,10 +68,10 @@ func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1. if isArcInstallation { // For ARC AKS installation, we want to add an additional label to indicate this is an ARC managed cluster, // needed for clean up of CRD by kube-addon-manager. - existingCRD.Labels[ArcInstallationKey] = "true" + existingCRD.Labels[ArcInstallationKey] = trueLabelValue } // Ensure the label for management by the installer is set. - existingCRD.Labels[CRDInstallerLabelKey] = "true" + existingCRD.Labels[CRDInstallerLabelKey] = trueLabelValue // Also set the Azure managed label to indicate this is managed by Fleet, // needed for clean up of CRD by kube-addon-manager. existingCRD.Labels[AzureManagedLabelKey] = FleetLabelValue diff --git a/go.mod b/go.mod index c8524cc40..77c698443 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.5.20 sigs.k8s.io/cluster-inventory-api v0.0.0-20251028164203-2e3fabb46733 sigs.k8s.io/controller-runtime v0.22.4 + sigs.k8s.io/yaml v1.6.0 ) require ( @@ -134,7 +135,6 @@ require ( sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect - sigs.k8s.io/yaml v1.6.0 // indirect ) replace ( From 83ef9929561f470547bf481f465a4d718645ea27 Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 15:07:10 -0800 Subject: [PATCH 06/11] minor IT refactor Signed-off-by: Arvind Thirumurugan --- .../crd_installer_integration_test.go | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/crdinstaller/crd_installer_integration_test.go b/test/crdinstaller/crd_installer_integration_test.go index a2b0fdc8a..56660f5e7 100644 --- a/test/crdinstaller/crd_installer_integration_test.go +++ b/test/crdinstaller/crd_installer_integration_test.go @@ -35,15 +35,17 @@ const ( // It ensures that the installer can create a CRD, update it with new fields, and handle ownership label correctly. // The original CRD has 4 properties, and the updated CRD has a new property to simulate CRD upgrade. var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { - Context("without ARC installation mode", func() { - AfterAll(func() { - deleteCRD(crdName) - }) + AfterEach(OncePerOrdered, func() { + deleteCRD(crdName) + }) + Context("without ARC installation mode", func() { It("should create original CRD", func() { crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) + Eventually(func() error { + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false) + }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) It("should verify original CRD installation", func() { @@ -68,7 +70,9 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { It("should update the CRD with new field in spec with crdinstaller label", func() { crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false)).To(Succeed()) + Eventually(func() error { + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false) + }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) It("should verify updated CRD", func() { @@ -91,14 +95,12 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { }) Context("with ARC installation mode", func() { - AfterAll(func() { - deleteCRD(crdName) - }) - It("should create CRD with ARC installation mode", func() { crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true)).To(Succeed()) + Eventually(func() error { + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true) + }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) It("should verify CRD has ARC installation label", func() { @@ -121,7 +123,9 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { It("should update the CRD with new field in spec while preserving ARC label", func() { crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) - Expect(cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true)).To(Succeed()) + Eventually(func() error { + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true) + }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) It("should verify updated CRD has all labels including ARC", func() { From 581f6f6389b7198f020d5eb6da6f7ebf9e4d526a Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 15:38:34 -0800 Subject: [PATCH 07/11] address comment Signed-off-by: Arvind Thirumurugan --- cmd/crdinstaller/utils/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/crdinstaller/utils/util.go b/cmd/crdinstaller/utils/util.go index 565997e05..604410f0e 100644 --- a/cmd/crdinstaller/utils/util.go +++ b/cmd/crdinstaller/utils/util.go @@ -25,7 +25,7 @@ import ( const ( // ArcInstallationKey is the key used to indicate if the installation is for ARC AKS cluster. - ArcInstallationKey = "crd-installer.azurefleet.io/arcinstallation" + ArcInstallationKey = "crd-installer.azurefleet.io/arc" // CRDInstallerLabelKey is the label key used to indicate that a CRD is managed by the installer. CRDInstallerLabelKey = "crd-installer.azurefleet.io/managed" // AzureManagedLabelKey is the label key used to indicate that a CRD is managed by an azure resource. From ea74c0fcf97ce276566246cb430a71a39eb8ed38 Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 18:33:09 -0800 Subject: [PATCH 08/11] address comment Signed-off-by: Arvind Thirumurugan --- .../templates/deployment.yaml | 3 +- cmd/crdinstaller/main.go | 14 ++++------ cmd/crdinstaller/utils/util.go | 6 ++-- cmd/crdinstaller/utils/util_test.go | 28 +++++++++---------- .../crd_installer_integration_test.go | 8 +++--- 5 files changed, 28 insertions(+), 31 deletions(-) diff --git a/charts/member-agent-arc/templates/deployment.yaml b/charts/member-agent-arc/templates/deployment.yaml index 1cddda7e5..30f8ef5ff 100644 --- a/charts/member-agent-arc/templates/deployment.yaml +++ b/charts/member-agent-arc/templates/deployment.yaml @@ -21,8 +21,7 @@ spec: imagePullPolicy: IfNotPresent image: "{{ .Values.crdinstaller.repository }}:{{ .Values.crdinstaller.tag }}" args: - - --mode=member - - --arcInstallation=true + - --mode=arcMember - --v={{ .Values.crdinstaller.logVerbosity }} securityContext: capabilities: diff --git a/cmd/crdinstaller/main.go b/cmd/crdinstaller/main.go index be3058819..29fcd78bc 100644 --- a/cmd/crdinstaller/main.go +++ b/cmd/crdinstaller/main.go @@ -23,8 +23,7 @@ import ( ) var ( - mode = flag.String("mode", "", "Mode to run in: 'hub' or 'member' (required)") - isArcInstallation = flag.Bool("arcInstallation", false, "Enable ARC AKS installation mode") + mode = flag.String("mode", "", "Mode to run in: 'hub', 'member', 'arcMember', (required)") ) func main() { @@ -32,12 +31,11 @@ func main() { flag.Parse() // Validate required flags. - if *mode != "hub" && *mode != "member" { - klog.Fatal("--mode flag must be either 'hub' or 'member'") + if *mode != "hub" && *mode != "member" && *mode != "arcMember" { + klog.Fatal("--mode flag must be either 'hub' or 'member' or ''arcMember'") } klog.Infof("Starting CRD installer in %s mode", *mode) - klog.Infof("ARC installation mode: %v", *isArcInstallation) // Print all flags for debugging. flag.VisitAll(func(f *flag.Flag) { @@ -70,7 +68,7 @@ func main() { // Install CRDs from the fixed location. const crdPath = "/workspace/config/crd/bases" - if err := installCRDs(ctx, client, crdPath, *mode, *isArcInstallation); err != nil { + if err := installCRDs(ctx, client, crdPath, *mode); err != nil { klog.Fatalf("Failed to install CRDs: %v", err) } @@ -78,7 +76,7 @@ func main() { } // installCRDs installs the CRDs from the specified directory based on the mode. -func installCRDs(ctx context.Context, client client.Client, crdPath, mode string, isArcInstallation bool) error { +func installCRDs(ctx context.Context, client client.Client, crdPath, mode string) error { // List of CRDs to install based on mode. crdsToInstall, err := utils.CollectCRDs(crdPath, mode, client.Scheme()) if err != nil { @@ -93,7 +91,7 @@ func installCRDs(ctx context.Context, client client.Client, crdPath, mode string // Install each CRD. for i := range crdsToInstall { - if err := utils.InstallCRD(ctx, client, &crdsToInstall[i], isArcInstallation); err != nil { + if err := utils.InstallCRD(ctx, client, &crdsToInstall[i], mode); err != nil { return err } } diff --git a/cmd/crdinstaller/utils/util.go b/cmd/crdinstaller/utils/util.go index 604410f0e..001c17718 100644 --- a/cmd/crdinstaller/utils/util.go +++ b/cmd/crdinstaller/utils/util.go @@ -48,7 +48,7 @@ var ( ) // InstallCRD creates/updates a Custom Resource Definition (CRD) from the provided CRD object. -func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1.CustomResourceDefinition, isArcInstallation bool) error { +func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1.CustomResourceDefinition, mode string) error { klog.V(2).Infof("Installing CRD: %s", crd.Name) existingCRD := apiextensionsv1.CustomResourceDefinition{ @@ -65,7 +65,7 @@ func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1. if existingCRD.Labels == nil { existingCRD.Labels = make(map[string]string) } - if isArcInstallation { + if mode == "arcMember" { // For ARC AKS installation, we want to add an additional label to indicate this is an ARC managed cluster, // needed for clean up of CRD by kube-addon-manager. existingCRD.Labels[ArcInstallationKey] = trueLabelValue @@ -117,7 +117,7 @@ func CollectCRDs(crdDirectoryPath, mode string, scheme *runtime.Scheme) ([]apiex // Process based on mode. crdFileName := filepath.Base(crdpath) - if mode == "member" { + if mode == "member" || mode == "arcMember" { if memberCRD[crdFileName] { crd, err := GetCRDFromPath(crdpath, scheme) if err != nil { diff --git a/cmd/crdinstaller/utils/util_test.go b/cmd/crdinstaller/utils/util_test.go index 4eb23fec8..61f7460f8 100644 --- a/cmd/crdinstaller/utils/util_test.go +++ b/cmd/crdinstaller/utils/util_test.go @@ -155,29 +155,29 @@ func TestInstallCRD(t *testing.T) { } tests := []struct { - name string - crd *apiextensionsv1.CustomResourceDefinition - isArcInstallation bool - wantError bool + name string + crd *apiextensionsv1.CustomResourceDefinition + mode string + wantError bool }{ { - name: "successful CRD installation without ARC", - crd: testCRD, - isArcInstallation: false, - wantError: false, + name: "successful CRD installation with member mode", + crd: testCRD, + mode: "member", + wantError: false, }, { - name: "successful CRD installation with ARC", - crd: testCRD, - isArcInstallation: true, - wantError: false, + name: "successful CRD installation with arcMember mode", + crd: testCRD, + mode: "arcMember", + wantError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build() - err := InstallCRD(context.Background(), fakeClient, tt.crd, tt.isArcInstallation) + err := InstallCRD(context.Background(), fakeClient, tt.crd, tt.mode) if tt.wantError { if err == nil { @@ -206,7 +206,7 @@ func TestInstallCRD(t *testing.T) { t.Errorf("Expected CRD label %s to be %q, got %q", AzureManagedLabelKey, FleetLabelValue, installedCRD.Labels[AzureManagedLabelKey]) } - if tt.isArcInstallation { + if tt.mode == "arcMember" { if installedCRD.Labels[ArcInstallationKey] != "true" { t.Errorf("Expected CRD label %s to be 'true', got %q", ArcInstallationKey, installedCRD.Labels[ArcInstallationKey]) } diff --git a/test/crdinstaller/crd_installer_integration_test.go b/test/crdinstaller/crd_installer_integration_test.go index 56660f5e7..5879a68ff 100644 --- a/test/crdinstaller/crd_installer_integration_test.go +++ b/test/crdinstaller/crd_installer_integration_test.go @@ -44,7 +44,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false) + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "member") }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) @@ -71,7 +71,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, false) + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "member") }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) @@ -99,7 +99,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true) + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "arcMember") }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) @@ -124,7 +124,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, true) + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "arcMember") }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) From e45d430400026350000060cb886be4ddd8907e9f Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 18:36:09 -0800 Subject: [PATCH 09/11] minor refactor Signed-off-by: Arvind Thirumurugan --- cmd/crdinstaller/utils/util.go | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/cmd/crdinstaller/utils/util.go b/cmd/crdinstaller/utils/util.go index 001c17718..ae2339a95 100644 --- a/cmd/crdinstaller/utils/util.go +++ b/cmd/crdinstaller/utils/util.go @@ -117,7 +117,8 @@ func CollectCRDs(crdDirectoryPath, mode string, scheme *runtime.Scheme) ([]apiex // Process based on mode. crdFileName := filepath.Base(crdpath) - if mode == "member" || mode == "arcMember" { + switch mode { + case "member", "arcMember": if memberCRD[crdFileName] { crd, err := GetCRDFromPath(crdpath, scheme) if err != nil { @@ -125,25 +126,16 @@ func CollectCRDs(crdDirectoryPath, mode string, scheme *runtime.Scheme) ([]apiex } crdsToInstall = append(crdsToInstall, *crd) } - // Skip CRDs that are not in the memberCRD map. - return nil - } - - crd, err := GetCRDFromPath(crdpath, scheme) - if err != nil { - return err - } - - // For hub mode, only collect CRDs whose group has substring kubernetes-fleet.io. - if mode == "hub" { + case "hub": + crd, err := GetCRDFromPath(crdpath, scheme) + if err != nil { + return err + } // special case for multicluster external CRD in hub cluster. if multiclusterCRD[crdFileName] { crdsToInstall = append(crdsToInstall, *crd) - return nil - } - group := crd.Spec.Group - // Check if the group contains "kubernetes-fleet.io" substring. - if strings.Contains(group, "kubernetes-fleet.io") && !memberCRD[crdFileName] { + } else if strings.Contains(crd.Spec.Group, "kubernetes-fleet.io") && !memberCRD[crdFileName] { + // For hub mode, only collect CRDs whose group has substring kubernetes-fleet.io. crdsToInstall = append(crdsToInstall, *crd) } } From f0cf7de92e4678138a3e6ed7b2808df757d0fe5d Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 18:43:14 -0800 Subject: [PATCH 10/11] minor refactor Signed-off-by: Arvind Thirumurugan --- cmd/crdinstaller/utils/util.go | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/cmd/crdinstaller/utils/util.go b/cmd/crdinstaller/utils/util.go index ae2339a95..e5ab87531 100644 --- a/cmd/crdinstaller/utils/util.go +++ b/cmd/crdinstaller/utils/util.go @@ -117,27 +117,22 @@ func CollectCRDs(crdDirectoryPath, mode string, scheme *runtime.Scheme) ([]apiex // Process based on mode. crdFileName := filepath.Base(crdpath) + var shouldInstall bool switch mode { case "member", "arcMember": - if memberCRD[crdFileName] { - crd, err := GetCRDFromPath(crdpath, scheme) - if err != nil { - return err - } - crdsToInstall = append(crdsToInstall, *crd) - } + shouldInstall = memberCRD[crdFileName] case "hub": + // Install multicluster CRD or CRDs with kubernetes-fleet.io in the filename (excluding member-only CRDs). + // CRD filenames follow the pattern _.yaml, so we can check the filename. + shouldInstall = multiclusterCRD[crdFileName] || (strings.Contains(crdFileName, "kubernetes-fleet.io") && !memberCRD[crdFileName]) + } + + if shouldInstall { crd, err := GetCRDFromPath(crdpath, scheme) if err != nil { return err } - // special case for multicluster external CRD in hub cluster. - if multiclusterCRD[crdFileName] { - crdsToInstall = append(crdsToInstall, *crd) - } else if strings.Contains(crd.Spec.Group, "kubernetes-fleet.io") && !memberCRD[crdFileName] { - // For hub mode, only collect CRDs whose group has substring kubernetes-fleet.io. - crdsToInstall = append(crdsToInstall, *crd) - } + crdsToInstall = append(crdsToInstall, *crd) } return nil From 3384aa9cc06d5ff338e0e9578b499f7512b3d8da Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Thu, 5 Feb 2026 23:26:20 -0800 Subject: [PATCH 11/11] lint fix Signed-off-by: Arvind Thirumurugan --- cmd/crdinstaller/main.go | 4 ++-- cmd/crdinstaller/utils/util.go | 16 +++++++++++++--- cmd/crdinstaller/utils/util_test.go | 10 +++++----- .../crd_installer_integration_test.go | 8 ++++---- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/cmd/crdinstaller/main.go b/cmd/crdinstaller/main.go index 29fcd78bc..1f6639fb4 100644 --- a/cmd/crdinstaller/main.go +++ b/cmd/crdinstaller/main.go @@ -31,8 +31,8 @@ func main() { flag.Parse() // Validate required flags. - if *mode != "hub" && *mode != "member" && *mode != "arcMember" { - klog.Fatal("--mode flag must be either 'hub' or 'member' or ''arcMember'") + if *mode != utils.ModeHub && *mode != utils.ModeMember && *mode != utils.ModeArcMember { + klog.Fatal("--mode flag must be either 'hub' or 'member' or 'arcMember'") } klog.Infof("Starting CRD installer in %s mode", *mode) diff --git a/cmd/crdinstaller/utils/util.go b/cmd/crdinstaller/utils/util.go index e5ab87531..6601c59ad 100644 --- a/cmd/crdinstaller/utils/util.go +++ b/cmd/crdinstaller/utils/util.go @@ -38,6 +38,16 @@ const ( trueLabelValue = "true" ) +// Mode constants for CRD installer. +const ( + // ModeHub installs hub cluster CRDs. + ModeHub = "hub" + // ModeMember installs member cluster CRDs. + ModeMember = "member" + // ModeArcMember installs member cluster CRDs with ARC labels. + ModeArcMember = "arcMember" +) + var ( multiclusterCRD = map[string]bool{ "multicluster.x-k8s.io_clusterprofiles.yaml": true, @@ -65,7 +75,7 @@ func InstallCRD(ctx context.Context, client client.Client, crd *apiextensionsv1. if existingCRD.Labels == nil { existingCRD.Labels = make(map[string]string) } - if mode == "arcMember" { + if mode == ModeArcMember { // For ARC AKS installation, we want to add an additional label to indicate this is an ARC managed cluster, // needed for clean up of CRD by kube-addon-manager. existingCRD.Labels[ArcInstallationKey] = trueLabelValue @@ -119,9 +129,9 @@ func CollectCRDs(crdDirectoryPath, mode string, scheme *runtime.Scheme) ([]apiex var shouldInstall bool switch mode { - case "member", "arcMember": + case ModeMember, ModeArcMember: shouldInstall = memberCRD[crdFileName] - case "hub": + case ModeHub: // Install multicluster CRD or CRDs with kubernetes-fleet.io in the filename (excluding member-only CRDs). // CRD filenames follow the pattern _.yaml, so we can check the filename. shouldInstall = multiclusterCRD[crdFileName] || (strings.Contains(crdFileName, "kubernetes-fleet.io") && !memberCRD[crdFileName]) diff --git a/cmd/crdinstaller/utils/util_test.go b/cmd/crdinstaller/utils/util_test.go index 61f7460f8..bb67ee577 100644 --- a/cmd/crdinstaller/utils/util_test.go +++ b/cmd/crdinstaller/utils/util_test.go @@ -56,7 +56,7 @@ func runTest(t *testing.T, crdPath string) { }{ { name: "hub mode v1beta1 with actual directory", - mode: "hub", + mode: ModeHub, wantedCRDNames: []string{ "memberclusters.cluster.kubernetes-fleet.io", "internalmemberclusters.cluster.kubernetes-fleet.io", @@ -90,7 +90,7 @@ func runTest(t *testing.T, crdPath string) { }, { name: "member mode v1beta1 with actual directory", - mode: "member", + mode: ModeMember, wantedCRDNames: []string{ "appliedworks.placement.kubernetes-fleet.io", }, @@ -163,13 +163,13 @@ func TestInstallCRD(t *testing.T) { { name: "successful CRD installation with member mode", crd: testCRD, - mode: "member", + mode: ModeMember, wantError: false, }, { name: "successful CRD installation with arcMember mode", crd: testCRD, - mode: "arcMember", + mode: ModeArcMember, wantError: false, }, } @@ -206,7 +206,7 @@ func TestInstallCRD(t *testing.T) { t.Errorf("Expected CRD label %s to be %q, got %q", AzureManagedLabelKey, FleetLabelValue, installedCRD.Labels[AzureManagedLabelKey]) } - if tt.mode == "arcMember" { + if tt.mode == ModeArcMember { if installedCRD.Labels[ArcInstallationKey] != "true" { t.Errorf("Expected CRD label %s to be 'true', got %q", ArcInstallationKey, installedCRD.Labels[ArcInstallationKey]) } diff --git a/test/crdinstaller/crd_installer_integration_test.go b/test/crdinstaller/crd_installer_integration_test.go index 5879a68ff..cbc4daebd 100644 --- a/test/crdinstaller/crd_installer_integration_test.go +++ b/test/crdinstaller/crd_installer_integration_test.go @@ -44,7 +44,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "member") + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, cmdCRDInstaller.ModeMember) }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) @@ -71,7 +71,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "member") + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, cmdCRDInstaller.ModeMember) }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) @@ -99,7 +99,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(originalCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", originalCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "arcMember") + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, cmdCRDInstaller.ModeArcMember) }, eventuallyDuration, eventuallyInterval).Should(Succeed()) }) @@ -124,7 +124,7 @@ var _ = Describe("Test CRD Installer, Create and Update CRD", Ordered, func() { crd, err := cmdCRDInstaller.GetCRDFromPath(updatedCRDPath, scheme) Expect(err).NotTo(HaveOccurred(), "should get CRD from path %s", updatedCRDPath) Eventually(func() error { - return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, "arcMember") + return cmdCRDInstaller.InstallCRD(ctx, k8sClient, crd, cmdCRDInstaller.ModeArcMember) }, eventuallyDuration, eventuallyInterval).Should(Succeed()) })