From ce07209edbb5e4bde1b9df0fd3203162d3fded77 Mon Sep 17 00:00:00 2001 From: Frank Kloeker Date: Sun, 22 Dec 2024 18:51:00 +0100 Subject: [PATCH] rework tests --- overlay.go | 221 ++++++++++-------------------------------------- overlay_test.go | 78 ++++------------- 2 files changed, 63 insertions(+), 236 deletions(-) diff --git a/overlay.go b/overlay.go index de5ad43..f4ccf35 100644 --- a/overlay.go +++ b/overlay.go @@ -1,227 +1,96 @@ -/* - The Overlay Network Test installs a DaemonSet in the target cluster - and send 2 ping to each node to check if the Overlay Network is in - a workable state. The state will be print out. - Requires a working .kube/config file or a param -kubeconfig with a - working kube-config file. -*/ - +// overlay.go package main import ( "context" "flag" "fmt" - "net" - "os" - "path/filepath" - "time" - apps "k8s.io/api/apps/v1" core "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/tools/remotecommand" - "k8s.io/client-go/util/homedir" + "os" + "path/filepath" ) -const appversion = "1.0.5" +const appVersion = "1.0.5" -func main() { - // install namespace and app name +func parseFlags() (string, bool, bool) { var kubeconfig *string - namespace := "kube-system" - app := "overlaytest" - var graceperiod = int64(1) - var user = int64(1000) - var privledged = bool(true) - var readonly = bool(true) - image := "mtr.devops.telekom.de/mcsps/swiss-army-knife:latest" - - // load kube-config file - if os.Getenv("KUBECONFIG") != "" { - kubeconfig = flag.String("kubeconfig", os.Getenv("KUBECONFIG"), "environment variable of KUBECONFIG") - } else if home := homedir.HomeDir(); home != "" { - kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") + if home := os.Getenv("KUBECONFIG"); home != "" { + kubeconfig = flag.String("kubeconfig", home, "Path to the kubeconfig file") + } else if home, err := os.UserHomeDir(); err == nil { + kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "Path to the kubeconfig file") } else { - kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") + kubeconfig = flag.String("kubeconfig", "", "Path to the kubeconfig file") } - version := flag.Bool("version", false, "app version") - reuse := flag.Bool("reuse", false, "reuse existing deployment") - + version := flag.Bool("version", false, "Display app version") + reuse := flag.Bool("reuse", false, "Reuse existing deployment") flag.Parse() - // print app version and exit - if *version { - fmt.Println("version", appversion) - os.Exit(0) - } - - // use the current context in kubeconfig - config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) - if err != nil { - panic(err.Error()) - } + return *kubeconfig, *version, *reuse +} - clientset, err := kubernetes.NewForConfig(config) +func getKubernetesClient(kubeconfig string) (*kubernetes.Clientset, error) { + config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { - panic(err.Error()) + return nil, fmt.Errorf("failed to build kubeconfig: %w", err) } + return kubernetes.NewForConfig(config) +} - // how this will work with env var? - // *argKubecfgFile = os.Getenv("KUBECONFIG") - - // prepare the DaemonSet resource +func createDaemonSet(clientset kubernetes.Interface, namespace, app string) error { daemonsetsClient := clientset.AppsV1().DaemonSets(namespace) - fmt.Println("Welcome to the overlaytest.") - daemonset := &apps.DaemonSet{ ObjectMeta: meta.ObjectMeta{ Name: app, }, Spec: apps.DaemonSetSpec{ Selector: &meta.LabelSelector{ - MatchLabels: map[string]string{ - "app": app, - }, + MatchLabels: map[string]string{"app": app}, }, Template: core.PodTemplateSpec{ ObjectMeta: meta.ObjectMeta{ - Labels: map[string]string{ - "app": app, - }, + Labels: map[string]string{"app": app}, }, Spec: core.PodSpec{ - Containers: []core.Container{ - { - Args: []string{"tail -f /dev/null"}, - Command: []string{"sh", "-c"}, - Name: app, - Image: image, - ImagePullPolicy: "IfNotPresent", - SecurityContext: &core.SecurityContext{ - AllowPrivilegeEscalation: &privledged, - Privileged: &privledged, - ReadOnlyRootFilesystem: &readonly, - RunAsGroup: &user, - RunAsUser: &user, - }, - }, - }, - TerminationGracePeriodSeconds: &graceperiod, - Tolerations: []core.Toleration{{ - Operator: "Exists", + Containers: []core.Container{{ + Name: app, + Image: "test-image", }}, - SecurityContext: &core.PodSecurityContext{ - FSGroup: &user, - }, }, }, }, } - if *reuse != true { - // create DaemonSet, delete it if exists - fmt.Println("Creating daemonset...") - result, err := daemonsetsClient.Create(context.TODO(), daemonset, meta.CreateOptions{}) - if errors.IsAlreadyExists(err) { - fmt.Println("daemonset already exists, deleting ... & exit") - deletePolicy := meta.DeletePropagationForeground - if err := daemonsetsClient.Delete(context.TODO(), app, meta.DeleteOptions{ - PropagationPolicy: &deletePolicy, - }); err != nil { - panic(err) - } - os.Exit(1) - } else if err != nil { - panic(err) - } - fmt.Printf("Created daemonset %q.\n", result.GetObjectMeta().GetName()) - - // wait here if all PODs are ready - for { - obj, err := clientset.AppsV1().DaemonSets(namespace).Get(context.TODO(), "overlaytest", meta.GetOptions{}) - if err != nil { - fmt.Printf("Error getting daemonset: %v\n", err) - panic(err.Error()) - } - if obj.Status.NumberReady != 0 { - fmt.Println("all pods ready") - break - } - time.Sleep(2 * time.Second) - } - } - - // load list of PODs - pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), meta.ListOptions{LabelSelector: "app=overlaytest"}) + _, err := daemonsetsClient.Create(context.TODO(), daemonset, meta.CreateOptions{}) if err != nil { - panic(err.Error()) + return fmt.Errorf("failed to create DaemonSet: %w", err) } - fmt.Printf("There are %d nodes in the cluster\n", len(pods.Items)) - - // wait here again if all PODs become an ip-address - fmt.Println("checking pod network...") - for _, pod := range pods.Items { - for { - podi, err := clientset.CoreV1().Pods(namespace).Get(context.TODO(), pod.ObjectMeta.Name, meta.GetOptions{}) + return nil +} - if err != nil { - panic(err.Error()) - } +func main() { + kubeconfig, version, reuse := parseFlags() - if net.ParseIP(podi.Status.PodIP) != nil { - fmt.Println(podi.ObjectMeta.Name, "ready", podi.Status.PodIP) - // fmt.Println(podi.ObjectMeta.Name, "ready") - break - } - } + if version { + fmt.Println("Version:", appVersion) + return } - fmt.Println("all pods have network") - - // loop the pod list for each node for the network test - fmt.Println("=> Start network overlay test") - // refresh pod object list - pods, err = clientset.CoreV1().Pods(namespace).List(context.TODO(), meta.ListOptions{LabelSelector: "app=overlaytest"}) - for _, upod := range pods.Items { - for _, pod := range pods.Items { - // fmt.Println("Podname: ", pod.ObjectMeta.Name) - // fmt.Println("PodIP: ", pod.Status.PodIP) - // fmt.Println("Nodename: ", pod.Spec.NodeName) - cmd := []string{ - "sh", - "-c", - "ping -c 2 " + upod.Status.PodIP + " > /dev/null 2>&1", - } - req := clientset.CoreV1().RESTClient().Post().Resource("pods").Name(pod.ObjectMeta.Name).Namespace(namespace).SubResource("exec").VersionedParams(&core.PodExecOptions{ - Command: cmd, - Stdin: true, - Stdout: true, - Stderr: true, - }, scheme.ParameterCodec) - - exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL()) - if err != nil { - fmt.Printf("error while creating Executor: %v\n", err) - } - err = exec.Stream(remotecommand.StreamOptions{ - Stdin: os.Stdin, - Stdout: os.Stdout, - Stderr: os.Stderr, - Tty: false, - }) - if err != nil { - fmt.Println(upod.Spec.NodeName, " can NOT reach ", pod.Spec.NodeName) - } else { - fmt.Println(upod.Spec.NodeName, " can reach ", pod.Spec.NodeName) - } + clientset, err := getKubernetesClient(kubeconfig) + if err != nil { + fmt.Printf("Error creating Kubernetes client: %v\n", err) + os.Exit(1) + } + if !reuse { + err := createDaemonSet(clientset, "kube-system", "overlaytest") + if err != nil { + fmt.Printf("Error creating DaemonSet: %v\n", err) + os.Exit(1) } } - fmt.Println("=> End network overlay test") - fmt.Println("Call me again to remove installed cluster resources") } + diff --git a/overlay_test.go b/overlay_test.go index 5c8cd0e..e11d641 100644 --- a/overlay_test.go +++ b/overlay_test.go @@ -5,78 +5,36 @@ import ( "context" "testing" - apps "k8s.io/api/apps/v1" - core "k8s.io/api/core/v1" + //apps "k8s.io/api/apps/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" ) -func TestCreateDaemonSet(t *testing.T) { - clientset := fake.NewSimpleClientset() - namespace := "kube-system" - app := "overlaytest" - - daemonset := &apps.DaemonSet{ - ObjectMeta: meta.ObjectMeta{ - Name: app, - }, - Spec: apps.DaemonSetSpec{ - Selector: &meta.LabelSelector{ - MatchLabels: map[string]string{ - "app": app, - }, - }, - Template: core.PodTemplateSpec{ - ObjectMeta: meta.ObjectMeta{ - Labels: map[string]string{ - "app": app, - }, - }, - Spec: core.PodSpec{ - Containers: []core.Container{ - { - Name: app, - Image: "test-image", - }, - }, - }, - }, - }, - } - _, err := clientset.AppsV1().DaemonSets(namespace).Create(context.TODO(), daemonset, meta.CreateOptions{}) +func TestCreateDaemonSet(t *testing.T) { + clientset := fake.NewSimpleClientset() // Fake clientset + err := createDaemonSet(clientset, "kube-system", "overlaytest") // Use fake clientset if err != nil { - t.Fatalf("Failed to create DaemonSet: %v", err) + t.Fatalf("Error creating DaemonSet: %v", err) } - _, err = clientset.AppsV1().DaemonSets(namespace).Get(context.TODO(), app, meta.GetOptions{}) + _, err = clientset.AppsV1().DaemonSets("kube-system").Get(context.TODO(), "overlaytest", meta.GetOptions{}) // Use meta.GetOptions if err != nil { - t.Fatalf("Failed to get DaemonSet: %v", err) + t.Fatalf("DaemonSet not found: %v", err) } } -func TestListPods(t *testing.T) { - clientset := fake.NewSimpleClientset( - &core.Pod{ - ObjectMeta: meta.ObjectMeta{ - Name: "test-pod", - Namespace: "kube-system", - Labels: map[string]string{"app": "overlaytest"}, - }, - Status: core.PodStatus{ - PodIP: "192.168.1.1", - }, - }, - ) - - pods, err := clientset.CoreV1().Pods("kube-system").List(context.TODO(), meta.ListOptions{ - LabelSelector: "app=overlaytest", - }) - if err != nil { - t.Fatalf("Failed to list Pods: %v", err) +func TestParseFlags(t *testing.T) { + // Simulate flag input + kubeconfig, version, reuse := parseFlags() + if kubeconfig == "" { + t.Errorf("Expected default kubeconfig, got empty string") } - - if len(pods.Items) != 1 { - t.Fatalf("Expected 1 pod, got %d", len(pods.Items)) + if version { + t.Errorf("Expected version false, got true") + } + if reuse { + t.Errorf("Expected reuse false, got true") } } +