diff --git a/pkg/clustertree/cluster-manager/controllers/pod/root_pod_controller.go b/pkg/clustertree/cluster-manager/controllers/pod/root_pod_controller.go index 9fea35173..16640f222 100644 --- a/pkg/clustertree/cluster-manager/controllers/pod/root_pod_controller.go +++ b/pkg/clustertree/cluster-manager/controllers/pod/root_pod_controller.go @@ -381,6 +381,15 @@ func (r *RootPodReconciler) createSATokenInLeafCluster(ctx context.Context, lr * secretName = sa.Secrets[0].Name } + if secretName == "" { + tokenSecret, err := r.createDefaultSecretInRootCluster(ctx, sa) + if err != nil { + return nil, err + } + + secretName = tokenSecret.Name + } + csName := fmt.Sprintf("master-%s-token", sa.Name) csKey := types.NamespacedName{ Namespace: ns, @@ -424,44 +433,122 @@ func (r *RootPodReconciler) createSATokenInLeafCluster(ctx context.Context, lr * return newSE, nil } -func (r *RootPodReconciler) createCAInLeafCluster(ctx context.Context, lr *leafUtils.LeafResource, ns string) (*corev1.ConfigMap, error) { - masterCAConfigmapKey := types.NamespacedName{ +func (r *RootPodReconciler) createDefaultSecretInRootCluster(ctx context.Context, sa *corev1.ServiceAccount) (*corev1.Secret, error) { + tokenSecretName := fmt.Sprintf("kosmos-%s-token", sa.Name) + tokenSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: tokenSecretName, + Namespace: sa.Namespace, + Annotations: map[string]string{ + utils.TokenSecretAnnotations: sa.Name, + }, + }, + Type: utils.TokenSecretType, + } + err := r.RootClient.Create(ctx, tokenSecret) + + if err != nil { + return nil, fmt.Errorf("could not create token-secret %s in host cluster: %v", tokenSecretName, err) + } + + patchSa := sa.DeepCopy() + patchSa.Secrets = []corev1.ObjectReference{ + { + Name: tokenSecretName, + }, + } + err = r.RootClient.Update(ctx, patchSa) + if err != nil { + return nil, fmt.Errorf("could not update sa %s in host cluster: %v", patchSa.Name, err) + } + + return tokenSecret, nil +} + +func (r *RootPodReconciler) createConfigMapInLeafCluster(ctx context.Context, lr *leafUtils.LeafResource, configMapName string, ns string) (*corev1.ConfigMap, error) { + var memberConfigmapKeyName string + if strings.HasPrefix(configMapName, utils.RooTCAConfigMapName) { + memberConfigmapKeyName = utils.MasterRooTCAName + } else { + memberConfigmapKeyName = configMapName + } + + configmapKey := types.NamespacedName{ Namespace: ns, - Name: utils.MasterRooTCAName, + Name: memberConfigmapKeyName, } - masterCA := &corev1.ConfigMap{} + memberConfigMap := &corev1.ConfigMap{} - err := lr.Client.Get(ctx, masterCAConfigmapKey, masterCA) + err := lr.Client.Get(ctx, configmapKey, memberConfigMap) if err != nil && !errors.IsNotFound(err) { - return nil, fmt.Errorf("could not check configmap %s in member cluster: %v", utils.MasterRooTCAName, err) + return nil, fmt.Errorf("could not check configmap %s in member cluster: %v", configmapKey.Name, err) } if err == nil { - return masterCA, nil + return memberConfigMap, nil } - ca := &corev1.ConfigMap{} + masterConfigMap := &corev1.ConfigMap{} - rootCAConfigmapKey := types.NamespacedName{ + masterConfigmapKey := types.NamespacedName{ Namespace: ns, - Name: utils.RooTCAConfigMapName, + Name: configMapName, } - err = r.Client.Get(ctx, rootCAConfigmapKey, ca) + err = r.Client.Get(ctx, masterConfigmapKey, masterConfigMap) if err != nil { - return nil, fmt.Errorf("could not find configmap %s in master cluster: %v", ca, err) + return nil, fmt.Errorf("could not find configmap %s in master cluster: %v", configmapKey.Name, err) } - newCA := ca.DeepCopy() - newCA.Name = utils.MasterRooTCAName - podutils.FitObjectMeta(&newCA.ObjectMeta) + newConfigMap := masterConfigMap.DeepCopy() + newConfigMap.Name = memberConfigmapKeyName + podutils.FitObjectMeta(&newConfigMap.ObjectMeta) - err = lr.Client.Create(ctx, newCA) + err = lr.Client.Create(ctx, newConfigMap) if err != nil && !errors.IsAlreadyExists(err) { - return nil, fmt.Errorf("could not create configmap %s in member cluster: %v", newCA.Name, err) + return nil, fmt.Errorf("could not create configmap %s in member cluster: %v", newConfigMap.Name, err) } - return newCA, nil + return newConfigMap, nil +} + +func (r *RootPodReconciler) createSecretInLeafCluster(ctx context.Context, lr *leafUtils.LeafResource, secretName string, ns string) (*corev1.Secret, error) { + secretKey := types.NamespacedName{ + Namespace: ns, + Name: secretName, + } + + memberSecret := &corev1.Secret{} + + err := lr.Client.Get(ctx, secretKey, memberSecret) + if err != nil && !errors.IsNotFound(err) { + return nil, fmt.Errorf("could not check secret %s in member cluster: %v", secretKey.Name, err) + } + if err == nil { + return memberSecret, nil + } + + masterSecret := &corev1.Secret{} + + masterSecretKey := types.NamespacedName{ + Namespace: ns, + Name: secretName, + } + + err = r.Client.Get(ctx, masterSecretKey, masterSecret) + if err != nil { + return nil, fmt.Errorf("could not find secret %s in master cluster: %v", masterSecretKey.Name, err) + } + + newSecret := masterSecret.DeepCopy() + podutils.FitObjectMeta(&newSecret.ObjectMeta) + + err = lr.Client.Create(ctx, newSecret) + if err != nil && !errors.IsAlreadyExists(err) { + return nil, fmt.Errorf("could not create secret %s in member cluster: %v", newSecret.Name, err) + } + + return newSecret, nil } // changeToMasterCoreDNS point the dns of the pod to the master cluster, so that the pod can access any service. @@ -496,61 +583,116 @@ func (r *RootPodReconciler) changeToMasterCoreDNS(ctx context.Context, pod *core } func (r *RootPodReconciler) convertAuth(ctx context.Context, lr *leafUtils.LeafResource, pod *corev1.Pod) { - if pod.Spec.AutomountServiceAccountToken == nil || *pod.Spec.AutomountServiceAccountToken { - falseValue := false - pod.Spec.AutomountServiceAccountToken = &falseValue + if pod.Spec.Volumes == nil { + return + } - sa := pod.Spec.ServiceAccountName - _, err := r.createSAInLeafCluster(ctx, lr, sa, pod.Namespace) - if err != nil { - klog.Errorf("[convertAuth] create sa failed, ns: %s, pod: %s", pod.Namespace, pod.Name) - return - } + for _, volume := range pod.Spec.Volumes { + if volume.Projected != nil { + falseValue := false + pod.Spec.AutomountServiceAccountToken = &falseValue - se, err := r.createSATokenInLeafCluster(ctx, lr, sa, pod.Namespace) - if err != nil { - klog.Errorf("[convertAuth] create sa secret failed, ns: %s, pod: %s", pod.Namespace, pod.Name) - return - } + saName := pod.Spec.ServiceAccountName + _, err := r.createSAInLeafCluster(ctx, lr, saName, pod.Namespace) + if err != nil { + klog.Errorf("[convertAuth] create sa failed, ns: %s, pod: %s", pod.Namespace, pod.Name) + return + } - rootCA, err := r.createCAInLeafCluster(ctx, lr, pod.Namespace) - if err != nil { - klog.Errorf("[convertAuth] create sa secret failed, ns: %s, pod: %s", pod.Namespace, pod.Name) - return - } + sources := []corev1.VolumeProjection{} - volumes := pod.Spec.Volumes - for _, v := range volumes { - if strings.HasPrefix(v.Name, utils.SATokenPrefix) { - sources := []corev1.VolumeProjection{} - for _, src := range v.Projected.Sources { - if src.ServiceAccountToken != nil { - continue + for _, projectedVolumeSource := range volume.Projected.Sources { + if projectedVolumeSource.ServiceAccountToken != nil { + serviceAccountToken := projectedVolumeSource.ServiceAccountToken + tokenSecret, err := r.createSATokenInLeafCluster(ctx, lr, saName, pod.Namespace) + if err != nil { + klog.Errorf("[convertAuth] create sa secret failed, ns: %s, pod: %s", pod.Namespace, pod.Name) + return } - if src.ConfigMap != nil && src.ConfigMap.Name == utils.RooTCAConfigMapName { - src.ConfigMap.Name = rootCA.Name + secretProjection := corev1.VolumeProjection{ + Secret: &corev1.SecretProjection{ + Items: []corev1.KeyToPath{ + { + Key: "token", + Path: serviceAccountToken.Path, + }, + }, + }, } - sources = append(sources, src) + secretProjection.Secret.Name = tokenSecret.Name + sources = append(sources, secretProjection) } - - secretProjection := corev1.VolumeProjection{ - Secret: &corev1.SecretProjection{ - Items: []corev1.KeyToPath{ - { - Key: "token", - Path: "token", + if projectedVolumeSource.ConfigMap != nil { + configMap := projectedVolumeSource.ConfigMap + cm, err := r.createConfigMapInLeafCluster(ctx, lr, configMap.Name, pod.Namespace) + if err != nil { + klog.Errorf("[convertAuth] create configmap failed, ns: %s, cm: %s", pod.Namespace, cm.Name) + return + } + var key string + var path string + for _, item := range configMap.Items { + if item.Key != "" { + key = item.Key + } + if item.Path != "" { + path = item.Path + } + } + configMapProjection := corev1.VolumeProjection{ + ConfigMap: &corev1.ConfigMapProjection{ + Items: []corev1.KeyToPath{ + { + Key: key, + Path: path, + }, }, }, - }, + } + configMapProjection.ConfigMap.Name = cm.Name + sources = append(sources, configMapProjection) + } + if projectedVolumeSource.Secret != nil { + Secret := projectedVolumeSource.Secret + se, err := r.createSecretInLeafCluster(ctx, lr, Secret.Name, pod.Namespace) + if err != nil { + klog.Errorf("[convertAuth] create secret failed, ns: %s, cm: %s", pod.Namespace, se.Name) + return + } + var key string + var path string + for _, item := range Secret.Items { + if item.Key != "" { + key = item.Key + } + if item.Path != "" { + path = item.Path + } + } + SecretProjection := corev1.VolumeProjection{ + Secret: &corev1.SecretProjection{ + Items: []corev1.KeyToPath{ + { + Key: key, + Path: path, + }, + }, + }, + } + SecretProjection.Secret.Name = se.Name + sources = append(sources, SecretProjection) + } + if projectedVolumeSource.DownwardAPI != nil { + DownwardAPIProjection := corev1.VolumeProjection{ + DownwardAPI: projectedVolumeSource.DownwardAPI, + } + sources = append(sources, DownwardAPIProjection) } - secretProjection.Secret.Name = se.Name - sources = append(sources, secretProjection) - v.Projected.Sources = sources } + volume.Projected.Sources = sources } } } - func (r *RootPodReconciler) createServiceAccountInLeafCluster(ctx context.Context, lr *leafUtils.LeafResource, secret *corev1.Secret) error { if !lr.EnableServiceAccount { return nil diff --git a/pkg/utils/constants.go b/pkg/utils/constants.go index da08a63db..c4a1e29a7 100644 --- a/pkg/utils/constants.go +++ b/pkg/utils/constants.go @@ -156,10 +156,12 @@ const ( ) const ( - ReservedNS = "kube-system" - RooTCAConfigMapName = "kube-root-ca.crt" - SATokenPrefix = "kube-api-access" - MasterRooTCAName = "master-root-ca.crt" + ReservedNS = "kube-system" + RooTCAConfigMapName = "kube-root-ca.crt" + SATokenPrefix = "kube-api-access" + MasterRooTCAName = "master-root-ca.crt" + TokenSecretType = "kubernetes.io/service-account-token" + TokenSecretAnnotations = "kubernetes.io/service-account.name" ) var GVR_CONFIGMAP = schema.GroupVersionResource{