mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-09-29 12:42:24 +08:00
878 lines
22 KiB
Go
878 lines
22 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"reflect"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
corev1 "k8s.io/api/core/v1"
|
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/fields"
|
|
"k8s.io/apimachinery/pkg/util/wait"
|
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/rest"
|
|
"k8s.io/client-go/util/retry"
|
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
|
|
|
pkgconfig "github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
|
)
|
|
|
|
var (
|
|
namespace string
|
|
clientset *kubernetes.Clientset
|
|
restconfig *rest.Config
|
|
)
|
|
|
|
const (
|
|
local = `{"status": "Reviews is healthy on local pc"}`
|
|
local8080 = `{"status": "Reviews is healthy on local pc 8080"}`
|
|
remote = `{"status": "Reviews is healthy"}`
|
|
)
|
|
|
|
func TestFunctions(t *testing.T) {
|
|
// 1) test connect
|
|
t.Run("init", Init)
|
|
t.Run("kubevpnConnect", kubevpnConnect)
|
|
t.Run("commonTest", commonTest)
|
|
t.Run("checkConnectStatus", checkConnectStatus)
|
|
|
|
// 2) test proxy mode
|
|
t.Run("kubevpnProxy", kubevpnProxy)
|
|
t.Run("commonTest", commonTest)
|
|
t.Run("testUDP", testUDP)
|
|
t.Run("proxyServiceReviewsServiceIP", proxyServiceReviewsServiceIP)
|
|
t.Run("proxyServiceReviewsPodIP", proxyServiceReviewsPodIP)
|
|
t.Run("checkProxyStatus", checkProxyStatus)
|
|
|
|
// 3) test proxy mode with service mesh
|
|
t.Run("kubevpnLeave", kubevpnLeave)
|
|
t.Run("kubevpnProxyWithServiceMesh", kubevpnProxyWithServiceMesh)
|
|
t.Run("commonTest", commonTest)
|
|
t.Run("serviceMeshReviewsServiceIP", serviceMeshReviewsServiceIP)
|
|
t.Run("serviceMeshReviewsPodIP", serviceMeshReviewsPodIP)
|
|
t.Run("checkProxyWithServiceMeshStatus", checkProxyWithServiceMeshStatus)
|
|
|
|
// 4) test proxy mode with service mesh and gvisor
|
|
t.Run("kubevpnLeave", kubevpnLeave)
|
|
t.Run("kubevpnUninstall", kubevpnUninstall)
|
|
t.Run("kubevpnProxyWithServiceMeshAndGvisorMode", kubevpnProxyWithServiceMeshAndGvisorMode)
|
|
t.Run("commonTest", commonTest)
|
|
t.Run("serviceMeshReviewsServiceIP", serviceMeshReviewsServiceIP)
|
|
t.Run("checkProxyWithServiceMeshAndGvisorStatus", checkProxyWithServiceMeshAndGvisorStatus)
|
|
t.Run("kubevpnLeaveService", kubevpnLeaveService)
|
|
t.Run("kubevpnQuit", kubevpnQuit)
|
|
|
|
// 5) install centrally in ns test -- connect mode
|
|
t.Run("centerKubevpnUninstall", kubevpnUninstall)
|
|
t.Run("centerKubevpnInstallInNsKubevpn", kubevpnConnectToNsKubevpn)
|
|
t.Run("centerKubevpnConnect", kubevpnConnect)
|
|
t.Run("checkServiceShouldNotInNsDefault", checkServiceShouldNotInNsDefault)
|
|
t.Run("centerCheckConnectStatus", centerCheckConnectStatus)
|
|
t.Run("centerCommonTest", commonTest)
|
|
|
|
// 6) install centrally in ns test -- proxy mode
|
|
t.Run("centerKubevpnProxy", kubevpnProxy)
|
|
t.Run("checkServiceShouldNotInNsDefault", checkServiceShouldNotInNsDefault)
|
|
t.Run("centerCommonTest", commonTest)
|
|
t.Run("centerTestUDP", testUDP)
|
|
t.Run("centerProxyServiceReviewsServiceIP", proxyServiceReviewsServiceIP)
|
|
t.Run("centerProxyServiceReviewsPodIP", proxyServiceReviewsPodIP)
|
|
t.Run("centerCheckProxyStatus", centerCheckProxyStatus)
|
|
|
|
// 7) install centrally in ns test -- proxy mode with service mesh
|
|
t.Run("kubevpnLeave", kubevpnLeave)
|
|
t.Run("kubevpnProxyWithServiceMesh", kubevpnProxyWithServiceMesh)
|
|
t.Run("checkServiceShouldNotInNsDefault", checkServiceShouldNotInNsDefault)
|
|
t.Run("commonTest", commonTest)
|
|
t.Run("serviceMeshReviewsServiceIP", serviceMeshReviewsServiceIP)
|
|
t.Run("serviceMeshReviewsPodIP", serviceMeshReviewsPodIP)
|
|
t.Run("centerCheckProxyWithServiceMeshStatus", centerCheckProxyWithServiceMeshStatus)
|
|
|
|
// 8) install centrally in ns test -- proxy mode with service mesh and gvisor
|
|
t.Run("kubevpnQuit", kubevpnQuit)
|
|
t.Run("kubevpnProxyWithServiceMeshAndGvisorModePortMap", kubevpnProxyWithServiceMeshAndGvisorModePortMap)
|
|
t.Run("checkServiceShouldNotInNsDefault", checkServiceShouldNotInNsDefault)
|
|
t.Run("commonTest", commonTest)
|
|
t.Run("serviceMeshReviewsServiceIPPortMap", serviceMeshReviewsServiceIPPortMap)
|
|
t.Run("kubevpnLeave", kubevpnLeave)
|
|
t.Run("centerCheckProxyWithServiceMeshAndGvisorStatus", centerCheckProxyWithServiceMeshAndGvisorStatus)
|
|
t.Run("kubevpnLeaveService", kubevpnLeaveService)
|
|
t.Run("kubevpnQuit", kubevpnQuit)
|
|
}
|
|
|
|
func commonTest(t *testing.T) {
|
|
// 1) test domain access
|
|
t.Run("kubevpnStatus", kubevpnStatus)
|
|
t.Run("pingPodIP", pingPodIP)
|
|
t.Run("healthCheckPodDetails", healthCheckPodDetails)
|
|
t.Run("healthCheckServiceDetails", healthCheckServiceDetails)
|
|
t.Run("shortDomainDetails", shortDomainDetails)
|
|
t.Run("fullDomainDetails", fullDomainDetails)
|
|
}
|
|
|
|
func pingPodIP(t *testing.T) {
|
|
list, err := clientset.CoreV1().Pods(namespace).List(context.Background(), v1.ListOptions{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var wg = &sync.WaitGroup{}
|
|
for _, item := range list.Items {
|
|
if item.Status.Phase != corev1.PodRunning {
|
|
continue
|
|
}
|
|
if item.DeletionTimestamp != nil {
|
|
continue
|
|
}
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
for i := 0; i < 60; i++ {
|
|
cmd := exec.Command("ping", "-c", "1", item.Status.PodIP)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err = cmd.Run()
|
|
if err == nil && cmd.ProcessState.Success() {
|
|
return
|
|
}
|
|
}
|
|
t.Errorf("Failed to ping IP: %s of pod: %s", item.Status.PodIP, item.Name)
|
|
kubectl(t)
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
}
|
|
|
|
func healthCheckPodDetails(t *testing.T) {
|
|
var app = "details"
|
|
ip, err := getPodIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
|
healthChecker(t, endpoint, nil, "")
|
|
}
|
|
|
|
func healthChecker(t *testing.T, endpoint string, header map[string]string, keyword string) {
|
|
req, err := http.NewRequest("GET", endpoint, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for k, v := range header {
|
|
req.Header.Add(k, v)
|
|
}
|
|
|
|
err = retry.OnError(
|
|
wait.Backoff{Duration: time.Second, Factor: 1, Jitter: 0, Steps: 120},
|
|
func(err error) bool { return err != nil },
|
|
func() error {
|
|
var resp *http.Response
|
|
resp, err = (&http.Client{Timeout: time.Second * 5}).Do(req)
|
|
if err != nil {
|
|
t.Logf("failed to do health check endpoint: %s: %v", endpoint, err)
|
|
return err
|
|
}
|
|
if resp.StatusCode != 200 {
|
|
if resp.Body != nil {
|
|
defer resp.Body.Close()
|
|
all, _ := io.ReadAll(resp.Body)
|
|
return fmt.Errorf("status code is %s, conetent: %v", resp.Status, string(all))
|
|
}
|
|
return fmt.Errorf("status code is %s", resp.Status)
|
|
}
|
|
defer resp.Body.Close()
|
|
if keyword != "" {
|
|
content, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if string(content) != keyword {
|
|
return fmt.Errorf("response=%s, want: %s", string(content), keyword)
|
|
}
|
|
return nil
|
|
}
|
|
return nil
|
|
},
|
|
)
|
|
if err != nil {
|
|
kubectl(t)
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func healthCheckServiceDetails(t *testing.T) {
|
|
var app = "details"
|
|
ip, err := getServiceIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
|
healthChecker(t, endpoint, nil, "")
|
|
}
|
|
|
|
func shortDomainDetails(t *testing.T) {
|
|
var app = "details"
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", app, 9080)
|
|
healthChecker(t, endpoint, nil, "")
|
|
}
|
|
|
|
func fullDomainDetails(t *testing.T) {
|
|
var app = "details"
|
|
domains := []string{
|
|
fmt.Sprintf("%s.%s.svc.cluster.local", app, namespace),
|
|
fmt.Sprintf("%s.%s.svc", app, namespace),
|
|
fmt.Sprintf("%s.%s", app, namespace),
|
|
}
|
|
|
|
for _, domain := range domains {
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", domain, 9080)
|
|
healthChecker(t, endpoint, nil, "")
|
|
}
|
|
}
|
|
|
|
func serviceMeshReviewsPodIP(t *testing.T) {
|
|
app := "reviews"
|
|
ip, err := getPodIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
|
healthChecker(t, endpoint, nil, remote)
|
|
healthChecker(t, endpoint, map[string]string{"env": "test"}, local)
|
|
}
|
|
|
|
func serviceMeshReviewsServiceIP(t *testing.T) {
|
|
app := "reviews"
|
|
ip, err := getServiceIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
|
healthChecker(t, endpoint, nil, remote)
|
|
healthChecker(t, endpoint, map[string]string{"env": "test"}, local)
|
|
}
|
|
|
|
func serviceMeshReviewsServiceIPPortMap(t *testing.T) {
|
|
app := "reviews"
|
|
ip, err := getServiceIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
|
healthChecker(t, endpoint, nil, remote)
|
|
healthChecker(t, endpoint, map[string]string{"env": "test"}, local8080)
|
|
}
|
|
|
|
func getServiceIP(app string) (string, error) {
|
|
serviceList, err := clientset.CoreV1().Services(namespace).List(context.Background(), v1.ListOptions{
|
|
LabelSelector: fields.OneTermEqualSelector("app", app).String(),
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var ip string
|
|
for _, item := range serviceList.Items {
|
|
ip = item.Spec.ClusterIP
|
|
if ip != "" {
|
|
return ip, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("failed to found service ip for service %s", app)
|
|
}
|
|
|
|
func proxyServiceReviewsPodIP(t *testing.T) {
|
|
app := "reviews"
|
|
ip, err := getPodIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
|
healthChecker(t, endpoint, nil, local)
|
|
healthChecker(t, endpoint, map[string]string{"env": "test"}, local)
|
|
}
|
|
|
|
func getPodIP(app string) (string, error) {
|
|
list, err := clientset.CoreV1().Pods(namespace).List(context.Background(), v1.ListOptions{
|
|
LabelSelector: fields.OneTermEqualSelector("app", app).String(),
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
for _, pod := range list.Items {
|
|
if pod.DeletionTimestamp == nil &&
|
|
pod.Status.Phase == corev1.PodRunning && pod.Status.PodIP != "" {
|
|
return pod.Status.PodIP, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("failed to found pod ip for service %s", app)
|
|
}
|
|
|
|
func proxyServiceReviewsServiceIP(t *testing.T) {
|
|
app := "reviews"
|
|
ip, err := getServiceIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
endpoint := fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
|
healthChecker(t, endpoint, nil, local)
|
|
healthChecker(t, endpoint, map[string]string{"env": "test"}, local)
|
|
}
|
|
|
|
func testUDP(t *testing.T) {
|
|
app := "reviews"
|
|
port, err := util.GetAvailableUDPPortOrDie()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
go udpServer(t, port)
|
|
|
|
var ip string
|
|
err = retry.OnError(
|
|
wait.Backoff{Duration: time.Second, Factor: 2, Jitter: 0.2, Steps: 5},
|
|
func(err error) bool {
|
|
return err != nil
|
|
},
|
|
func() error {
|
|
ip, err = getPodIP(app)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Logf("Dail udp to IP: %s", ip)
|
|
return udpClient(t, ip, port)
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Failed to access pod IP: %s, port: %v", ip, port)
|
|
}
|
|
}
|
|
|
|
func udpClient(t *testing.T, ip string, port int) error {
|
|
udpConn, err := net.DialUDP("udp4", nil, &net.UDPAddr{
|
|
IP: net.ParseIP(ip),
|
|
Port: port,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer udpConn.Close()
|
|
|
|
err = udpConn.SetDeadline(time.Now().Add(time.Second * 30))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
sendData := []byte("hello server!")
|
|
_, err = udpConn.Write(sendData)
|
|
if err != nil {
|
|
t.Logf("Failed to send udp packet: %v", err)
|
|
return err
|
|
}
|
|
|
|
data := make([]byte, 4096)
|
|
read, remoteAddr, err := udpConn.ReadFromUDP(data)
|
|
if err != nil {
|
|
t.Logf("Failed to read udp packet: %v", err)
|
|
return err
|
|
}
|
|
t.Logf("read data from %v: %v", remoteAddr, string(data[:read]))
|
|
return nil
|
|
}
|
|
|
|
func udpServer(t *testing.T, port int) {
|
|
// 创建监听
|
|
udpConn, err := net.ListenUDP("udp4", &net.UDPAddr{
|
|
IP: net.IPv4(0, 0, 0, 0),
|
|
Port: port,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
defer udpConn.Close()
|
|
|
|
data := make([]byte, 4096)
|
|
for {
|
|
read, remoteAddr, err := udpConn.ReadFromUDP(data[:])
|
|
if err != nil {
|
|
t.Logf("failed to read udp data from %v: %v", remoteAddr, err)
|
|
continue
|
|
}
|
|
t.Logf("read data from %v: %v", remoteAddr, string(data[:read]))
|
|
|
|
sendData := []byte("hello client!")
|
|
_, err = udpConn.WriteToUDP(sendData, remoteAddr)
|
|
if err != nil {
|
|
t.Logf("failed to send udp data to %v: %v", remoteAddr, err)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func kubevpnConnect(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "connect", "--debug")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnConnectToNsKubevpn(t *testing.T) {
|
|
_, err := clientset.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{
|
|
ObjectMeta: v1.ObjectMeta{
|
|
Name: "kubevpn",
|
|
},
|
|
}, v1.CreateOptions{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cmdConnect := exec.Command("kubevpn", "connect", "--namespace", "kubevpn", "--debug")
|
|
cmdQuit := exec.Command("kubevpn", "quit")
|
|
for _, cmd := range []*exec.Cmd{cmdConnect, cmdQuit} {
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func kubevpnProxy(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "proxy", "deployments/reviews", "--debug")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnProxyWithServiceMesh(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "proxy", "deployments/reviews", "--headers", "env=test", "--debug")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnProxyWithServiceMeshAndGvisorMode(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "proxy", "svc/reviews", "--headers", "env=test", "--netstack", "gvisor", "--debug")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnProxyWithServiceMeshAndGvisorModePortMap(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "proxy", "svc/reviews", "--headers", "env=test", "--netstack", "gvisor", "--debug", "--portmap", "9080:8080")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnLeave(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "leave", "deployments/reviews")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnLeaveService(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "leave", "services/reviews")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func checkConnectStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: namespace,
|
|
Status: "connected",
|
|
ProxyList: nil,
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(statuses, expect) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
func centerCheckConnectStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: "default",
|
|
Status: "connected",
|
|
ProxyList: nil,
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(statuses, expect) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
|
|
type status struct {
|
|
ID int32
|
|
Mode string
|
|
Namespace string
|
|
Status string
|
|
ProxyList []*proxy
|
|
}
|
|
type proxy struct {
|
|
Namespace string
|
|
Workload string
|
|
RuleList []*rule
|
|
}
|
|
type rule struct {
|
|
Headers map[string]string
|
|
CurrentDevice bool
|
|
PortMap map[int32]int32
|
|
}
|
|
|
|
func checkProxyStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: namespace,
|
|
Status: "connected",
|
|
ProxyList: []*proxy{{
|
|
Namespace: namespace,
|
|
Workload: "deployments.apps/reviews",
|
|
RuleList: []*rule{{
|
|
Headers: nil,
|
|
CurrentDevice: true,
|
|
PortMap: map[int32]int32{9080: 9080},
|
|
}},
|
|
}},
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(statuses, expect) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
|
|
func centerCheckProxyStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: "default",
|
|
Status: "connected",
|
|
ProxyList: []*proxy{{
|
|
Namespace: "default",
|
|
Workload: "deployments.apps/reviews",
|
|
RuleList: []*rule{{
|
|
Headers: nil,
|
|
CurrentDevice: true,
|
|
PortMap: map[int32]int32{9080: 9080},
|
|
}},
|
|
}},
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(statuses, expect) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
|
|
func checkProxyWithServiceMeshStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: namespace,
|
|
Status: "connected",
|
|
ProxyList: []*proxy{{
|
|
Namespace: namespace,
|
|
Workload: "deployments.apps/reviews",
|
|
RuleList: []*rule{{
|
|
Headers: map[string]string{"env": "test"},
|
|
CurrentDevice: true,
|
|
PortMap: map[int32]int32{9080: 9080},
|
|
}},
|
|
}},
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(statuses, expect) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
|
|
func centerCheckProxyWithServiceMeshStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: "default",
|
|
Status: "connected",
|
|
ProxyList: []*proxy{{
|
|
Namespace: "default",
|
|
Workload: "deployments.apps/reviews",
|
|
RuleList: []*rule{{
|
|
Headers: map[string]string{"env": "test"},
|
|
CurrentDevice: true,
|
|
PortMap: map[int32]int32{9080: 9080},
|
|
}},
|
|
}},
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(statuses, expect) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
|
|
func checkProxyWithServiceMeshAndGvisorStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: namespace,
|
|
Status: "connected",
|
|
ProxyList: []*proxy{{
|
|
Namespace: namespace,
|
|
Workload: "services/reviews",
|
|
RuleList: []*rule{{
|
|
Headers: map[string]string{"env": "test"},
|
|
CurrentDevice: true,
|
|
PortMap: map[int32]int32{9080: 9080},
|
|
}},
|
|
}},
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
opt := cmp.FilterPath(func(p cmp.Path) bool {
|
|
vx := p.Last().String()
|
|
if vx == `["Headers"]` {
|
|
return true
|
|
}
|
|
return false
|
|
}, cmp.Ignore())
|
|
if !cmp.Equal(statuses, expect, opt) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
|
|
func centerCheckProxyWithServiceMeshAndGvisorStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expect := []*status{{
|
|
ID: 0,
|
|
Mode: "full",
|
|
Namespace: "default",
|
|
Status: "connected",
|
|
ProxyList: []*proxy{{
|
|
Namespace: "default",
|
|
Workload: "services/reviews",
|
|
RuleList: []*rule{{
|
|
Headers: map[string]string{"env": "test"},
|
|
CurrentDevice: true,
|
|
PortMap: map[int32]int32{9080: 8080},
|
|
}},
|
|
}},
|
|
}}
|
|
|
|
var statuses []*status
|
|
if err = json.Unmarshal(output, &statuses); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
opt := cmp.FilterPath(func(p cmp.Path) bool {
|
|
vx := p.Last().String()
|
|
if vx == `["Headers"]` {
|
|
return true
|
|
}
|
|
return false
|
|
}, cmp.Ignore())
|
|
if !cmp.Equal(statuses, expect, opt) {
|
|
marshal, _ := json.Marshal(expect)
|
|
t.Fatalf("expect: %s, but was: %s", string(marshal), string(output))
|
|
}
|
|
}
|
|
|
|
func kubevpnUninstall(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "uninstall", "kubevpn")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnStatus(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "status")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubevpnQuit(t *testing.T) {
|
|
cmd := exec.Command("kubevpn", "quit")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func checkServiceShouldNotInNsDefault(t *testing.T) {
|
|
_, err := clientset.CoreV1().Services(namespace).Get(context.Background(), pkgconfig.ConfigMapPodTrafficManager, v1.GetOptions{})
|
|
if !k8serrors.IsNotFound(err) {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func kubectl(t *testing.T) {
|
|
cmdGetPod := exec.Command("kubectl", "get", "pods", "-o", "wide")
|
|
cmdDescribePod := exec.Command("kubectl", "describe", "pods")
|
|
cmdGetSvc := exec.Command("kubectl", "get", "services", "-o", "wide")
|
|
cmdDescribeSvc := exec.Command("kubectl", "describe", "services")
|
|
for _, cmd := range []*exec.Cmd{cmdGetPod, cmdDescribePod, cmdGetSvc, cmdDescribeSvc} {
|
|
t.Logf("exec: %v", cmd.Args)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func Init(t *testing.T) {
|
|
var err error
|
|
|
|
configFlags := genericclioptions.NewConfigFlags(true)
|
|
f := cmdutil.NewFactory(cmdutil.NewMatchVersionFlags(configFlags))
|
|
|
|
if restconfig, err = f.ToRESTConfig(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if clientset, err = kubernetes.NewForConfig(restconfig); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if namespace, _, err = f.ToRawKubeConfigLoader().Namespace(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
go startupHttpServer(t, "9080", local)
|
|
go startupHttpServer(t, "8080", local8080)
|
|
}
|
|
|
|
func startupHttpServer(t *testing.T, port, str string) {
|
|
var health = func(w http.ResponseWriter, r *http.Request) {
|
|
_, _ = w.Write([]byte(str))
|
|
}
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/", health)
|
|
mux.HandleFunc("/health", health)
|
|
t.Logf("Start listening http port %s ...", port)
|
|
err := http.ListenAndServe(":"+port, mux)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|