Skip to content

Commit

Permalink
rework tests
Browse files Browse the repository at this point in the history
  • Loading branch information
eumel8 committed Dec 22, 2024
1 parent eb2255c commit ce07209
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 236 deletions.
221 changes: 45 additions & 176 deletions overlay.go
Original file line number Diff line number Diff line change
@@ -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")
}

78 changes: 18 additions & 60 deletions overlay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}

0 comments on commit ce07209

Please sign in to comment.