package internal import ( "context" "fmt" "strings" log "github.com/sirupsen/logrus" v1 "k8s.io/api/coordination/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) func generateClient() (kubernetes.Clientset, error) { log.WithFields(log.Fields{ "Caller": "generateClient", }).Info("Generating k8s client") config, err := rest.InClusterConfig() if err != nil { return kubernetes.Clientset{}, fmt.Errorf("Could not generate in cluster config: %s", err.Error()) } clientset, err := kubernetes.NewForConfig(config) if err != nil { return kubernetes.Clientset{}, fmt.Errorf("Could not generate clientset: %s", err.Error()) } return *clientset, nil } func LabelNode(nodeName string, leaseName string, cfg *Config) error { client, err := generateClient() if err != nil { return fmt.Errorf("Could not generate client: %s", err.Error()) } log.WithFields(log.Fields{ "Caller": "LabelNode", }).Info(fmt.Sprintf("Trying to label node %s", nodeName)) node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) if err != nil { return fmt.Errorf("Could not find Kubernetes node: %s", err.Error()) } if node.Labels == nil { node.Labels = make(map[string]string) } node.Labels[cfg.CiliumLabel] = "true" node.Labels["cilium.uploadfilter24.eu/lease"] = leaseName _, err = client.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{}) if err != nil { return fmt.Errorf("Could not update node label: %s", err.Error()) } log.WithFields(log.Fields{ "Caller": "LabelNode", }).Info(fmt.Sprintf("Node %s labeled with %s=%s\n", nodeName, cfg.CiliumLabel, "true")) return nil } func RemoveLabelFromNode(nodeName string) error { client, err := generateClient() if err != nil { return fmt.Errorf("Could not generate client: %s", err.Error()) } log.WithFields(log.Fields{ "Caller": "LabelNode", }).Info(fmt.Sprintf("Removing Label from node %s", nodeName)) labelKey := "metallb-speaker" node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) if err != nil { panic(err.Error()) } delete(node.Labels, labelKey) _, err = client.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{}) if err != nil { panic(err.Error()) } fmt.Printf("Label %s removed from node %s\n", labelKey, nodeName) return nil } // func GetCiliumL2Leases() ([]v1.Lease, error) { // client, err := generateClient() // if err != nil { // log.WithFields(log.Fields{"Caller": "GetCiliumL2Leases"}).Errorf("Could not generate client: %s", err.Error()) // return nil, err // } // leases, err := client.CoordinationV1().Leases("kube-system").List(context.TODO(), metav1.ListOptions{}) // if err != nil { // log.WithFields(log.Fields{"Caller": "GetCiliumL2Leases"}).Errorf("Could not list leases: %s", err.Error()) // return nil, err // } // ciliumLeases := []v1.Lease{} // for _, l := range leases.Items { // if strings.HasPrefix(l.Name, "cilium-l2announce") { // log.WithFields(log.Fields{ // "Caller": "GetCiliumL2Leases", // "Lease": l.Name, // }).Info("Found Cilium L2 lease") // // Pretty-print a couple of fields for debugging // if l.Spec.HolderIdentity != nil { // log.WithFields(log.Fields{"HolderIdentity": *l.Spec.HolderIdentity}).Debug("HolderIdentity") // } // ciliumLeases = append(ciliumLeases, l) // } // } // return ciliumLeases, nil // } func GetNodeNameFromLease(lease v1.Lease) (string, error) { if lease.Spec.HolderIdentity == nil { return "", fmt.Errorf("Lease %s has no HolderIdentity", lease.Name) } holderIdentity := *lease.Spec.HolderIdentity parts := strings.Split(holderIdentity, "-") if len(parts) < 3 { return "", fmt.Errorf("Unexpected HolderIdentity format: %s", holderIdentity) } nodeName := strings.Join(parts[2:], "-") return nodeName, nil }