diff --git a/cmd/agent/app/agent.go b/cmd/agent/app/agent.go index e993638a8..4fd6d2be6 100644 --- a/cmd/agent/app/agent.go +++ b/cmd/agent/app/agent.go @@ -133,6 +133,13 @@ func run(ctx context.Context, karmadaConfig karmadactl.KarmadaConfig, opts *opti ControlPlaneConfig: controlPlaneRestConfig, ClusterConfig: clusterConfig, } + + id, err := util.ObtainClusterID(clusterKubeClient) + if err != nil { + return err + } + registerOption.ClusterID = id + clusterSecret, impersonatorSecret, err := util.ObtainCredentialsFromMemberCluster(clusterKubeClient, registerOption) if err != nil { return err @@ -325,6 +332,7 @@ func generateClusterInControllerPlane(opts util.ClusterRegisterOption) (*cluster cluster.Spec.SyncMode = clusterv1alpha1.Pull cluster.Spec.APIEndpoint = opts.ClusterAPIEndpoint cluster.Spec.ProxyURL = opts.ProxyServerAddress + cluster.Spec.ID = opts.ClusterID if opts.ClusterProvider != "" { cluster.Spec.Provider = opts.ClusterProvider } diff --git a/pkg/controllers/cluster/cluster_controller.go b/pkg/controllers/cluster/cluster_controller.go index d6b54937b..560eda47b 100644 --- a/pkg/controllers/cluster/cluster_controller.go +++ b/pkg/controllers/cluster/cluster_controller.go @@ -165,6 +165,18 @@ func (c *Controller) Reconcile(ctx context.Context, req controllerruntime.Reques // Start starts an asynchronous loop that monitors the status of cluster. func (c *Controller) Start(ctx context.Context) error { + // starts a goroutine to collect existed clusters' ID for upgrade scenario + // And can be removed in next version + klog.Infof("Starting collect ID of already existed clusters") + go func() { + err := c.collectIDForClusterObjectIfNeeded(ctx) + if err != nil { + klog.Errorf("Error collecting clusters' ID: %v", err) + } + + klog.Infof("Finishing collect ID of already existed clusters") + }() + klog.Infof("Starting cluster health monitor") defer klog.Infof("Shutting cluster health monitor") @@ -563,3 +575,44 @@ func (c *Controller) taintClusterByCondition(ctx context.Context, cluster *clust return nil } + +func (c *Controller) collectIDForClusterObjectIfNeeded(ctx context.Context) (err error) { + clusterList := &clusterv1alpha1.ClusterList{} + if err := c.Client.List(ctx, clusterList); err != nil { + return err + } + + clusters := clusterList.Items + var errs []error + + for i := range clusters { + cluster := &clusters[i] + if cluster.Spec.ID != "" { + continue + } + + if cluster.Spec.SyncMode == clusterv1alpha1.Pull { + continue + } + + clusterClient, err := util.NewClusterClientSet(cluster.Name, c.Client, nil) + if err != nil { + errs = append(errs, err) + continue + } + + id, err := util.ObtainClusterID(clusterClient.KubeClient) + if err != nil { + errs = append(errs, err) + continue + } + cluster.Spec.ID = id + + err = c.Client.Update(ctx, cluster) + if err != nil { + errs = append(errs, err) + continue + } + } + return utilerrors.NewAggregate(errs) +} diff --git a/pkg/karmadactl/join.go b/pkg/karmadactl/join.go index 6b9cb2bfa..7a6aa5486 100644 --- a/pkg/karmadactl/join.go +++ b/pkg/karmadactl/join.go @@ -175,6 +175,12 @@ func JoinCluster(controlPlaneRestConfig, clusterConfig *rest.Config, opts Comman ClusterConfig: clusterConfig, } + id, err := util.ObtainClusterID(clusterKubeClient) + if err != nil { + return err + } + registerOption.ClusterID = id + clusterSecret, impersonatorSecret, err := util.ObtainCredentialsFromMemberCluster(clusterKubeClient, registerOption) if err != nil { return err @@ -199,6 +205,7 @@ func generateClusterInControllerPlane(opts util.ClusterRegisterOption) (*cluster clusterObj.Name = opts.ClusterName clusterObj.Spec.SyncMode = clusterv1alpha1.Push clusterObj.Spec.APIEndpoint = opts.ClusterConfig.Host + clusterObj.Spec.ID = opts.ClusterID clusterObj.Spec.SecretRef = &clusterv1alpha1.LocalSecretReference{ Namespace: opts.Secret.Namespace, Name: opts.Secret.Name, diff --git a/pkg/util/cluster.go b/pkg/util/cluster.go index 26a07bd00..5d88d0e4d 100644 --- a/pkg/util/cluster.go +++ b/pkg/util/cluster.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/client" @@ -45,6 +46,7 @@ type ClusterRegisterOption struct { ClusterConfig *rest.Config Secret corev1.Secret ImpersonatorSecret corev1.Secret + ClusterID string } // IsKubeCredentialsEnabled represents whether report secret @@ -169,3 +171,12 @@ func updateCluster(controlPlaneClient karmadaclientset.Interface, cluster *clust return newCluster, nil } + +// ObtainClusterID returns the cluster ID property with clusterKubeClient +func ObtainClusterID(clusterKubeClient *kubernetes.Clientset) (string, error) { + ns, err := clusterKubeClient.CoreV1().Namespaces().Get(context.TODO(), metav1.NamespaceSystem, metav1.GetOptions{}) + if err != nil { + return "", err + } + return string(ns.UID), nil +}