diff --git a/pkg/addonmanager/controllers/registration/controller.go b/pkg/addonmanager/controllers/registration/controller.go index ac0f07dde..f1888e3ec 100644 --- a/pkg/addonmanager/controllers/registration/controller.go +++ b/pkg/addonmanager/controllers/registration/controller.go @@ -156,6 +156,16 @@ func (c *addonRegistrationController) sync(ctx context.Context, syncCtx factory. managedClusterAddonCopy.Status.Namespace = managedClusterAddonCopy.Spec.InstallNamespace } + if registrationOption.AgentInstallNamespace != nil { + ns := registrationOption.AgentInstallNamespace(managedClusterAddonCopy) + if len(ns) > 0 { + managedClusterAddonCopy.Status.Namespace = ns + } else { + klog.Infof("Namespace for addon %s/%s returned by agent install namespace func is empty", + managedClusterAddonCopy.Namespace, managedClusterAddonCopy.Name) + } + } + meta.SetStatusCondition(&managedClusterAddonCopy.Status.Conditions, metav1.Condition{ Type: addonapiv1alpha1.ManagedClusterAddOnRegistrationApplied, Status: metav1.ConditionTrue, diff --git a/pkg/addonmanager/controllers/registration/controller_test.go b/pkg/addonmanager/controllers/registration/controller_test.go index e53b8d3c4..38126700a 100644 --- a/pkg/addonmanager/controllers/registration/controller_test.go +++ b/pkg/addonmanager/controllers/registration/controller_test.go @@ -23,9 +23,10 @@ import ( ) type testAgent struct { - name string - namespace string - registrations []addonapiv1alpha1.RegistrationConfig + name string + namespace string + registrations []addonapiv1alpha1.RegistrationConfig + agentInstallNamespace func(addon *addonapiv1alpha1.ManagedClusterAddOn) string } func (t *testAgent) Manifests(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) ([]runtime.Object, error) { @@ -38,7 +39,7 @@ func (t *testAgent) GetAgentAddonOptions() agent.AgentAddonOptions { AddonName: t.name, } } - return agent.AgentAddonOptions{ + agentOption := agent.AgentAddonOptions{ AddonName: t.name, Registration: &agent.RegistrationOption{ CSRConfigurations: func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig { @@ -50,6 +51,11 @@ func (t *testAgent) GetAgentAddonOptions() agent.AgentAddonOptions { Namespace: t.namespace, }, } + + if t.agentInstallNamespace != nil { + agentOption.Registration.AgentInstallNamespace = t.agentInstallNamespace + } + return agentOption } func TestReconcile(t *testing.T) { @@ -176,6 +182,39 @@ func TestReconcile(t *testing.T) { }, }}, }, + { + name: "with registrations and override namespace by agentInstallNamespace", + cluster: []runtime.Object{addontesting.NewManagedCluster("cluster1")}, + addon: []runtime.Object{ + func() *addonapiv1alpha1.ManagedClusterAddOn { + addon := addontesting.NewAddon("test", "cluster1", metav1.OwnerReference{ + Kind: "ClusterManagementAddOn", + Name: "test", + }) + addon.Spec.InstallNamespace = "default2" + return addon + }(), + }, + validateAddonActions: func(t *testing.T, actions []clienttesting.Action) { + addontesting.AssertActions(t, actions, "patch") + actual := actions[0].(clienttesting.PatchActionImpl).Patch + addOn := &addonapiv1alpha1.ManagedClusterAddOn{} + err := json.Unmarshal(actual, addOn) + if err != nil { + t.Fatal(err) + } + if addOn.Status.Registrations[0].SignerName != "test" { + t.Errorf("Registration config is not updated") + } + if addOn.Status.Namespace != "default3" { + t.Errorf("Namespace in status is not correct") + } + }, + testaddon: &testAgent{name: "test", namespace: "default", + registrations: []addonapiv1alpha1.RegistrationConfig{{SignerName: "test"}}, + agentInstallNamespace: func(addon *addonapiv1alpha1.ManagedClusterAddOn) string { return "default3" }, + }, + }, } for _, c := range cases { diff --git a/pkg/agent/inteface.go b/pkg/agent/inteface.go index cdc412d9e..32514684f 100644 --- a/pkg/agent/inteface.go +++ b/pkg/agent/inteface.go @@ -110,8 +110,16 @@ type RegistrationOption struct { // Namespace is the namespace where registraiton credential will be put on the managed cluster. It // will be overridden by installNamespace on ManagedClusterAddon spec if set + // Deprecated: use AgentInstallNamespace instead Namespace string + // AgentInstallNamespace returns the namespace where registration credential will be put on the managed cluster. + // It will override the installNamespace on ManagedClusterAddon spec if set and the returned value is not empty. + // Note: Set this very carefully. If this is set, the addon agent must be deployed in the same namespace, which + // means when implementing Manifests function in AgentAddon interface, the namespace of the addon agent manifest + // must be set to the same value returned by this function. + AgentInstallNamespace func(addon *addonapiv1alpha1.ManagedClusterAddOn) string + // CSRApproveCheck checks whether the addon agent registration should be approved by the hub. // Addon hub controller can implement this func to auto-approve all the CSRs. A better CSR check is // recommended to include (1) the validity of requester's requesting identity and (2) the other request