diff --git a/cmd/agent/app/agent.go b/cmd/agent/app/agent.go index 02cb087af..a09af57ee 100644 --- a/cmd/agent/app/agent.go +++ b/cmd/agent/app/agent.go @@ -263,7 +263,14 @@ func registerWithControlPlaneAPIServer(controlPlaneRestConfig, clusterRestConfig return err } - clusterObj, err := generateClusterInControllerPlane(controlPlaneRestConfig, opts) + impersonatorSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: opts.ClusterNamespace, + Name: names.GenerateImpersonationSecretName(opts.ClusterName), + }, + } + + clusterObj, err := generateClusterInControllerPlane(controlPlaneRestConfig, opts, *impersonatorSecret) if err != nil { return err } @@ -273,33 +280,28 @@ func registerWithControlPlaneAPIServer(controlPlaneRestConfig, clusterRestConfig return err } + impersonatorSecret.OwnerReferences = []metav1.OwnerReference{ + *metav1.NewControllerRef(clusterObj, clusterv1alpha1.SchemeGroupVersion.WithKind("Cluster"))} + impersonatorSecret.Data = map[string][]byte{ + clusterv1alpha1.SecretTokenKey: clusterImpersonatorSecret.Data[clusterv1alpha1.SecretTokenKey]} // create secret to store impersonation info in control plane - impersonationSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: opts.ClusterNamespace, - Name: names.GenerateImpersonationSecretName(opts.ClusterName), - OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(clusterObj, clusterv1alpha1.SchemeGroupVersion.WithKind("Cluster")), - }, - }, - Data: map[string][]byte{ - clusterv1alpha1.SecretCADataKey: clusterImpersonatorSecret.Data["ca.crt"], - clusterv1alpha1.SecretTokenKey: clusterImpersonatorSecret.Data[clusterv1alpha1.SecretTokenKey], - }, - } - _, err = util.CreateSecret(controlPlaneKubeClient, impersonationSecret) + _, err = util.CreateSecret(controlPlaneKubeClient, impersonatorSecret) if err != nil { return fmt.Errorf("failed to create impersonator secret in control plane. error: %v", err) } return nil } -func generateClusterInControllerPlane(controlPlaneRestConfig *restclient.Config, opts *options.Options) (*clusterv1alpha1.Cluster, error) { +func generateClusterInControllerPlane(controlPlaneRestConfig *restclient.Config, opts *options.Options, impersonatorSecret corev1.Secret) (*clusterv1alpha1.Cluster, error) { clusterObj := &clusterv1alpha1.Cluster{} clusterObj.Name = opts.ClusterName clusterObj.Spec.SyncMode = clusterv1alpha1.Pull clusterObj.Spec.APIEndpoint = opts.ClusterAPIEndpoint clusterObj.Spec.ProxyURL = opts.ProxyServerAddress + clusterObj.Spec.ImpersonatorSecretRef = &clusterv1alpha1.LocalSecretReference{ + Namespace: impersonatorSecret.Namespace, + Name: impersonatorSecret.Name, + } controlPlaneKarmadaClient := karmadaclientset.NewForConfigOrDie(controlPlaneRestConfig) cluster, err := util.CreateOrUpdateClusterObject(controlPlaneKarmadaClient, clusterObj) diff --git a/pkg/controllers/unifiedauth/ensure_impersonation_secret.go b/pkg/controllers/unifiedauth/ensure_impersonation_secret.go index ad7b67732..f3eb6902a 100644 --- a/pkg/controllers/unifiedauth/ensure_impersonation_secret.go +++ b/pkg/controllers/unifiedauth/ensure_impersonation_secret.go @@ -10,6 +10,7 @@ import ( "k8s.io/klog/v2" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" + karmadaclientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" "github.com/karmada-io/karmada/pkg/util" "github.com/karmada-io/karmada/pkg/util/names" ) @@ -18,8 +19,6 @@ import ( // This logic is used only in the upgrade scenario of the current version // and can be deleted in the next version. func (c *Controller) ensureImpersonationSecret() { - controlPlaneKubeClient := kubeclient.NewForConfigOrDie(c.ControllerPlaneConfig) - clusterList := &clusterv1alpha1.ClusterList{} if err := c.Client.List(context.TODO(), clusterList); err != nil { klog.Errorf("Failed to list clusterList, error: %v", err) @@ -30,14 +29,17 @@ func (c *Controller) ensureImpersonationSecret() { if cluster.Spec.SyncMode == clusterv1alpha1.Pull { continue } - err := c.ensureImpersonationSecretForCluster(controlPlaneKubeClient, &clusterList.Items[index]) + err := c.ensureImpersonationSecretForCluster(&clusterList.Items[index]) if err != nil { klog.Errorf("Failed to ensure impersonation secret exist for cluster %s", cluster.Name) } } } -func (c *Controller) ensureImpersonationSecretForCluster(karmadaKubeClient kubeclient.Interface, cluster *clusterv1alpha1.Cluster) error { +func (c *Controller) ensureImpersonationSecretForCluster(cluster *clusterv1alpha1.Cluster) error { + controlPlaneKubeClient := kubeclient.NewForConfigOrDie(c.ControllerPlaneConfig) + controlPlaneKarmadaClient := karmadaclientset.NewForConfigOrDie(c.ControllerPlaneConfig) + klog.V(4).Infof("Create impersonation secret for cluster %s", cluster.Name) // create a ClusterClient for the given member cluster clusterClient, err := c.ClusterClientSetFunc(cluster.Name, c.Client, nil) @@ -63,7 +65,7 @@ func (c *Controller) ensureImpersonationSecretForCluster(karmadaKubeClient kubec } // create secret to store impersonation info in control plane - impersonationSecret := &corev1.Secret{ + impersonatorSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: clusterNamespace, Name: names.GenerateImpersonationSecretName(cluster.Name), @@ -72,16 +74,26 @@ func (c *Controller) ensureImpersonationSecretForCluster(karmadaKubeClient kubec }, }, Data: map[string][]byte{ - clusterv1alpha1.SecretCADataKey: clusterImpersonatorSecret.Data["ca.crt"], - clusterv1alpha1.SecretTokenKey: clusterImpersonatorSecret.Data[clusterv1alpha1.SecretTokenKey], + clusterv1alpha1.SecretTokenKey: clusterImpersonatorSecret.Data[clusterv1alpha1.SecretTokenKey], }, } - _, err = util.CreateSecret(karmadaKubeClient, impersonationSecret) + _, err = util.CreateSecret(controlPlaneKubeClient, impersonatorSecret) if err != nil { return fmt.Errorf("failed to create impersonator secret in control plane. error: %v", err) } + if cluster.Spec.ImpersonatorSecretRef == nil { + cluster.Spec.ImpersonatorSecretRef = &clusterv1alpha1.LocalSecretReference{ + Namespace: impersonatorSecret.Namespace, + Name: impersonatorSecret.Name, + } + _, err = util.CreateOrUpdateClusterObject(controlPlaneKarmadaClient, cluster) + if err != nil { + return err + } + } + return nil } diff --git a/pkg/karmadactl/join.go b/pkg/karmadactl/join.go index 618fa36f3..47f7b6218 100644 --- a/pkg/karmadactl/join.go +++ b/pkg/karmadactl/join.go @@ -174,7 +174,7 @@ func JoinCluster(controlPlaneRestConfig, clusterConfig *rest.Config, opts Comman return err } - clusterSecret, impersonationSecret, err := obtainCredentialsFromMemberCluster(clusterKubeClient, opts.ClusterNamespace, opts.ClusterName, opts.DryRun) + clusterSecret, impersonatorSecret, err := obtainCredentialsFromMemberCluster(clusterKubeClient, opts.ClusterNamespace, opts.ClusterName, opts.DryRun) if err != nil { return err } @@ -183,7 +183,7 @@ func JoinCluster(controlPlaneRestConfig, clusterConfig *rest.Config, opts Comman return nil } - err = registerClusterInControllerPlane(opts, controlPlaneRestConfig, clusterConfig, controlPlaneKubeClient, clusterSecret, impersonationSecret) + err = registerClusterInControllerPlane(opts, controlPlaneRestConfig, clusterConfig, controlPlaneKubeClient, clusterSecret, impersonatorSecret) if err != nil { return err } @@ -269,23 +269,22 @@ func registerClusterInControllerPlane(opts CommandJoinOption, controlPlaneRestCo } // create secret to store impersonation info in control plane - impersonationSecret := &corev1.Secret{ + impersonatorSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: opts.ClusterNamespace, Name: names.GenerateImpersonationSecretName(opts.ClusterName), }, Data: map[string][]byte{ - clusterv1alpha1.SecretCADataKey: clusterImpersonatorSecret.Data["ca.crt"], - clusterv1alpha1.SecretTokenKey: clusterImpersonatorSecret.Data[clusterv1alpha1.SecretTokenKey], + clusterv1alpha1.SecretTokenKey: clusterImpersonatorSecret.Data[clusterv1alpha1.SecretTokenKey], }, } - impersonationSecret, err = util.CreateSecret(controlPlaneKubeClient, impersonationSecret) + impersonatorSecret, err = util.CreateSecret(controlPlaneKubeClient, impersonatorSecret) if err != nil { return fmt.Errorf("failed to create impersonator secret in control plane. error: %v", err) } - cluster, err := generateClusterInControllerPlane(controlPlaneRestConfig, clusterConfig, opts, *secret) + cluster, err := generateClusterInControllerPlane(controlPlaneRestConfig, clusterConfig, opts, *secret, *impersonatorSecret) if err != nil { return err } @@ -304,15 +303,15 @@ func registerClusterInControllerPlane(opts CommandJoinOption, controlPlaneRestCo return fmt.Errorf("failed to patch secret %s/%s, error: %v", secret.Namespace, secret.Name, err) } - err = util.PatchSecret(controlPlaneKubeClient, impersonationSecret.Namespace, impersonationSecret.Name, types.MergePatchType, patchSecretBody) + err = util.PatchSecret(controlPlaneKubeClient, impersonatorSecret.Namespace, impersonatorSecret.Name, types.MergePatchType, patchSecretBody) if err != nil { - return fmt.Errorf("failed to patch impersonator secret %s/%s, error: %v", impersonationSecret.Namespace, impersonationSecret.Name, err) + return fmt.Errorf("failed to patch impersonator secret %s/%s, error: %v", impersonatorSecret.Namespace, impersonatorSecret.Name, err) } return nil } -func generateClusterInControllerPlane(controlPlaneConfig, clusterConfig *rest.Config, opts CommandJoinOption, secret corev1.Secret) (*clusterv1alpha1.Cluster, error) { +func generateClusterInControllerPlane(controlPlaneConfig, clusterConfig *rest.Config, opts CommandJoinOption, secret, impersonatorSecret corev1.Secret) (*clusterv1alpha1.Cluster, error) { clusterObj := &clusterv1alpha1.Cluster{} clusterObj.Name = opts.ClusterName clusterObj.Spec.SyncMode = clusterv1alpha1.Push @@ -321,6 +320,10 @@ func generateClusterInControllerPlane(controlPlaneConfig, clusterConfig *rest.Co Namespace: secret.Namespace, Name: secret.Name, } + clusterObj.Spec.ImpersonatorSecretRef = &clusterv1alpha1.LocalSecretReference{ + Namespace: impersonatorSecret.Namespace, + Name: impersonatorSecret.Name, + } if opts.ClusterProvider != "" { clusterObj.Spec.Provider = opts.ClusterProvider diff --git a/pkg/registry/cluster/storage/proxy.go b/pkg/registry/cluster/storage/proxy.go index e49303d78..ffc3176d1 100644 --- a/pkg/registry/cluster/storage/proxy.go +++ b/pkg/registry/cluster/storage/proxy.go @@ -18,7 +18,6 @@ import ( clusterapis "github.com/karmada-io/karmada/pkg/apis/cluster" karmadaclientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" - "github.com/karmada-io/karmada/pkg/util/names" ) // ProxyREST implements the proxy subresource for a Cluster. @@ -71,9 +70,17 @@ func (r *ProxyREST) Connect(ctx context.Context, id string, options runtime.Obje } func (r *ProxyREST) getImpersonateToken(clusterName string) (string, error) { - // TODO: add impersonation secretRef to Cluster api to indicate impersonation secret. - secret, err := r.kubeClient.CoreV1().Secrets(names.NamespaceKarmadaCluster).Get(context.TODO(), - names.GenerateImpersonationSecretName(clusterName), metav1.GetOptions{}) + cluster, err := r.karmadaClient.ClusterV1alpha1().Clusters().Get(context.TODO(), clusterName, metav1.GetOptions{}) + if err != nil { + return "", err + } + + if cluster.Spec.ImpersonatorSecretRef == nil { + return "", fmt.Errorf("the impersonatorSecretRef of cluster %s is nil", clusterName) + } + + secret, err := r.kubeClient.CoreV1().Secrets(cluster.Spec.ImpersonatorSecretRef.Namespace).Get(context.TODO(), + cluster.Spec.ImpersonatorSecretRef.Name, metav1.GetOptions{}) if err != nil { return "", err }