package node import ( "context" "fmt" "os" "strings" "k8s.io/client-go/tools/clientcmd" "k8s.io/klog/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubernetes "k8s.io/client-go/kubernetes" ) func ApplyLocalNodeMetadataIfPossible(ctx context.Context, nctx *NodeContext) error { spec := nctx.Config.Spec if len(spec.NodeAnnotations) == 0 && len(spec.NodeLabels) == 0 { return nil // nothing to do } nodeName := strings.TrimSpace(spec.NodeName) if nodeName == "" { return fmt.Errorf("spec.nodeName is required") } // Prefer admin kubeconfig (control-plane) kubeconfig := adminKubeconfigPath if _, err := os.Stat(kubeconfig); err != nil { klog.V(2).Infof("admin kubeconfig not found, skipping node metadata apply") return nil } restConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { return fmt.Errorf("build kubeconfig: %w", err) } client, err := kubernetes.NewForConfig(restConfig) if err != nil { return fmt.Errorf("create kubernetes client: %w", err) } node, err := client.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) if err != nil { return fmt.Errorf("get node %q: %w", nodeName, err) } if node.Labels == nil { node.Labels = make(map[string]string) } if node.Annotations == nil { node.Annotations = make(map[string]string) } // Apply labels for k, v := range spec.NodeLabels { node.Labels[k] = v } // Apply annotations for k, v := range spec.NodeAnnotations { node.Annotations[k] = v } _, err = client.CoreV1().Nodes().Update(ctx, node, metav1.UpdateOptions{}) if err != nil { return fmt.Errorf("update node metadata: %w", err) } klog.Infof("applied labels/annotations to node %q", nodeName) return nil }