From 62aacec7bb21854e26cf619e49a9a0e533e5c10f Mon Sep 17 00:00:00 2001
From: cheliequan <liequanche@126.com>
Date: 星期一, 22 五月 2023 14:17:19 +0800
Subject: [PATCH] 创建、删除和测试函数在一个文件中

---
 src/main/main.go |  523 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 523 insertions(+), 0 deletions(-)

diff --git a/src/main/main.go b/src/main/main.go
new file mode 100644
index 0000000..006d1a5
--- /dev/null
+++ b/src/main/main.go
@@ -0,0 +1,523 @@
+package main
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"log"
+	"math/rand"
+	"os"
+	"path/filepath"
+	"time"
+
+	appsv1 "k8s.io/api/apps/v1"
+	apiv1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/intstr"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/tools/clientcmd"
+)
+
+var (
+	replicas      int32 = 3
+	port          int32 = 9081
+	usedNodePorts       = make(map[int32]bool)
+	namespaces          = []string{"guangsheng", "geruimi", "tongsheng"}
+)
+
+func main() {
+	createCmd := flag.NewFlagSet("create", flag.ExitOnError)
+	deleteCmd := flag.NewFlagSet("delete", flag.ExitOnError)
+	testCmd := flag.NewFlagSet("test", flag.ExitOnError)
+
+	createNamespace := createCmd.String("ns", "", "Namespace name")
+	createDeployment := createCmd.String("deployment", "", "Deployment name")
+	createService := createCmd.String("service", "", "Service name")
+
+	deleteNamespace := deleteCmd.String("ns", "", "Namespace name")
+	deleteDeployment := deleteCmd.String("deployment", "", "Deployment name")
+	deleteService := deleteCmd.String("service", "", "Service name")
+
+	if len(os.Args) < 2 {
+		fmt.Println("create/delete/test command is required")
+		os.Exit(1)
+	}
+
+	switch os.Args[1] {
+	case "create":
+		createCmd.Parse(os.Args[2:])
+	case "delete":
+		deleteCmd.Parse(os.Args[2:])
+	case "test":
+		testCmd.Parse(os.Args[2:])
+	default:
+		flag.PrintDefaults()
+		os.Exit(1)
+	}
+
+	// 閰嶇疆 Kubernetes 闆嗙兢鐨� kubeconfig 璺緞
+	kubeconfig := flag.String("kubeconfig", filepath.Join(homeDir(), ".kube", "config"), "kubeconfig file")
+	flag.Parse()
+
+	// 鍒涘缓 Kubernetes 瀹㈡埛绔�
+	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
+	if err != nil {
+		panic(err.Error())
+	}
+
+	clientset, err := kubernetes.NewForConfig(config)
+	if err != nil {
+		panic(err.Error())
+	}
+
+	// 鎵ц create 鍛戒护
+	if createCmd.Parsed() {
+		if *createNamespace == "" || *createDeployment == "" || *createService == "" {
+			fmt.Println("Namespace, Deployment, and Service names are required")
+			createCmd.PrintDefaults()
+			os.Exit(1)
+		}
+
+		err := CreateDeploymentAndService(clientset, *createNamespace, *createDeployment, *createService)
+		if err != nil {
+			panic(err)
+		}
+
+		nodeport, err := GetServiceNodePort(clientset, *createNamespace, *createService)
+		if err != nil {
+			panic(err)
+		}
+
+		log.Printf("Service NodePort: %d\n", nodeport)
+	}
+
+	// 鎵ц delete 鍛戒护
+	if deleteCmd.Parsed() {
+		if *deleteNamespace == "" || *deleteDeployment == "" || *deleteService == "" {
+			fmt.Println("Namespace, Deployment, and Service names are required")
+			deleteCmd.PrintDefaults()
+			os.Exit(1)
+		}
+
+		err := DeleteResources(clientset, *deleteNamespace, *deleteDeployment, *deleteService)
+		if err != nil {
+			panic(err)
+		}
+
+		fmt.Println("Resources deleted.")
+	}
+
+	// 鎵ц鍒涘缓鍜屽垹闄ゆ祴璇�
+	if testCmd.Parsed() {
+		fmt.Println("\033[97;40mRunning create and delete tests...\033[0m")
+
+		// 鍒涘缓娴嬭瘯
+		fmt.Println("\033[97;40m--- Create Test ---\033[0m")
+		for _, ns := range namespaces {
+			deploymentName := ns
+			serviceName := ns
+			err := CreateDeploymentAndService(clientset, ns, deploymentName, serviceName)
+			if err != nil {
+				log.Printf("\033[97;41mFailed to create resources in namespace %s: %v\033[0m\n", ns, err)
+			} else {
+				nodeport, err := GetServiceNodePort(clientset, ns, ns)
+				if err != nil {
+					panic(err)
+				}
+
+				log.Printf("Service NodePort: %d\n", nodeport)
+				log.Printf("\033[97;42mSuccessfully created resources in namespace %s\033[0m\n", ns)
+			}
+		}
+
+		// 寤惰繜 1000 绉掑悗鍒犻櫎鍒涘缓鐨勮祫婧�
+		time.Sleep(1000 * time.Second)
+
+		// 鍒犻櫎娴嬭瘯
+		fmt.Println("\033[97;40m--- Delete Test ---\033[0m")
+
+		// 鍒犻櫎澶氫釜 Namespace 涓嬬殑鐩稿悓鍚嶇О鐨� Deployment 鍜� Service
+		for _, ns := range namespaces {
+			err = DeleteResources(clientset, ns, ns, ns)
+			if err != nil {
+				panic(err)
+			}
+		}
+
+		fmt.Println("Resources deleted.")
+	}
+
+}
+
+// CheckAndDeleteResources 妫�娴嬪苟鍒犻櫎鎸囧畾鐨� Namespace銆丏eployment 鍜� Service
+func CheckAndDeleteResources(clientset *kubernetes.Clientset, namespace, deploymentName, serviceName string) error {
+	fmt.Println("\033[1;37;40mChecking and deleting resources in Namespace:", namespace, "\033[0m")
+
+	// 妫�鏌ュ苟鍒犻櫎 Deployment
+	err := deleteDeploymentIfExists(clientset, namespace, deploymentName)
+	if err != nil {
+		return err
+	}
+
+	// 妫�鏌ュ苟鍒犻櫎 Service
+	err = deleteServiceIfExists(clientset, namespace, serviceName)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// deleteDeploymentIfExists 妫�鏌ュ苟鍒犻櫎鎸囧畾鐨� Deployment锛堝鏋滃瓨鍦級
+func deleteDeploymentIfExists(clientset *kubernetes.Clientset, namespace, deploymentName string) error {
+	fmt.Println("\033[1;37;40mChecking and deleting Deployment:", deploymentName, "\033[0m")
+
+	err := clientset.AppsV1().Deployments(namespace).Delete(context.TODO(), deploymentName, metav1.DeleteOptions{})
+	if err != nil {
+		if errors.IsNotFound(err) {
+			fmt.Printf("Deployment %s not found in Namespace %s\n", deploymentName, namespace)
+		} else {
+			return fmt.Errorf("failed to delete Deployment: %v", err)
+		}
+	} else {
+		fmt.Printf("Deployment %s deleted from Namespace %s\n", deploymentName, namespace)
+	}
+
+	return nil
+}
+
+// deleteServiceIfExists 妫�鏌ュ苟鍒犻櫎鎸囧畾鐨� Service锛堝鏋滃瓨鍦級
+func deleteServiceIfExists(clientset *kubernetes.Clientset, namespace, serviceName string) error {
+	fmt.Println("\033[1;37;40mChecking and deleting Service:", serviceName, "\033[0m")
+
+	err := clientset.CoreV1().Services(namespace).Delete(context.TODO(), serviceName, metav1.DeleteOptions{})
+	if err != nil {
+		if errors.IsNotFound(err) {
+			fmt.Printf("Service %s not found in Namespace %s\n", serviceName, namespace)
+		} else {
+			return fmt.Errorf("failed to delete Service: %v", err)
+		}
+	} else {
+		fmt.Printf("Service %s deleted from Namespace %s\n", serviceName, namespace)
+	}
+
+	return nil
+}
+
+func CreateDeploymentAndService(clientset *kubernetes.Clientset, namespace, deploymentName, serviceName string) error {
+	fmt.Println("\033[1;37;40mCreating resources in Namespace:", namespace, "\033[0m")
+
+	// 妫�娴嬪苟鍒犻櫎宸插瓨鍦ㄧ殑 Deployment 鍜� Service
+	err := CheckAndDeleteResources(clientset, namespace, deploymentName, serviceName)
+	if err != nil {
+		return err
+	}
+
+	// 鍒涘缓 Namespace
+	err = createNamespace(clientset, namespace)
+	if err != nil {
+		return err
+	}
+
+	// 鍒涘缓 Deployment
+	err = createDeployment(clientset, namespace, deploymentName)
+	if err != nil {
+		return err
+	}
+
+	// 鍒涘缓 Service
+	err = createService(clientset, namespace, serviceName)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// createNamespace 鍒涘缓鎸囧畾鐨� Namespace
+func createNamespace(clientset *kubernetes.Clientset, namespace string) error {
+	log.Printf("Creating Namespace: %s\n", namespace)
+
+	ns := &apiv1.Namespace{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: namespace,
+		},
+	}
+
+	_, err := clientset.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
+	if err != nil {
+		if !errors.IsAlreadyExists(err) {
+			return fmt.Errorf("failed to create Namespace: %w", err)
+		}
+		log.Printf("Namespace %s already exists\n", namespace)
+	} else {
+		log.Printf("Namespace %s created\n", namespace)
+	}
+
+	return nil
+}
+
+func createDeployment(clientset *kubernetes.Clientset, namespace, deploymentName string) error {
+	fmt.Println("\033[1;37;40mCreating Deployment:", deploymentName, "\033[0m")
+
+	deployment := &appsv1.Deployment{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: deploymentName,
+		},
+		Spec: appsv1.DeploymentSpec{
+			Replicas: &replicas,
+			Selector: &metav1.LabelSelector{
+				MatchLabels: map[string]string{
+					"cid": namespace,
+				},
+			},
+			Template: apiv1.PodTemplateSpec{
+				ObjectMeta: metav1.ObjectMeta{
+					Labels: map[string]string{
+						"cid": namespace,
+					},
+				},
+				Spec: apiv1.PodSpec{
+					TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
+						{
+							MaxSkew:           1,
+							TopologyKey:       "kubernetes.io/hostname",
+							WhenUnsatisfiable: apiv1.DoNotSchedule,
+							LabelSelector: &metav1.LabelSelector{
+								MatchLabels: map[string]string{
+									"cid": namespace,
+								},
+							},
+						},
+					},
+					Containers: []apiv1.Container{
+						{
+							Name:  namespace,
+							Image: "192.168.20.119/apsserver/apsserver:v0.2",
+							Env: []apiv1.EnvVar{
+								{
+									Name:  "NODE_ID",
+									Value: namespace,
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+
+	_, err := clientset.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})
+	if err != nil {
+		if !errors.IsAlreadyExists(err) {
+			return fmt.Errorf("failed to create Deployment: %v", err)
+		}
+		fmt.Printf("Deployment %s already exists in Namespace %s\n", deploymentName, namespace)
+	} else {
+		fmt.Printf("Deployment %s created in Namespace %s\n", deploymentName, namespace)
+	}
+
+	return nil
+}
+
+// createService 鍒涘缓鎸囧畾鐨� Service
+func createService(clientset *kubernetes.Clientset, namespace, serviceName string) error {
+	fmt.Println("\033[1;37;40mCreating Service:", serviceName, "\033[0m")
+
+	nodePort, err := getRandomNodePort(clientset)
+	if err != nil {
+		return err
+	}
+
+	service := &apiv1.Service{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: serviceName,
+		},
+		Spec: apiv1.ServiceSpec{
+			Selector: map[string]string{
+				"cid": namespace,
+			},
+			Type: apiv1.ServiceTypeNodePort,
+			Ports: []apiv1.ServicePort{
+				{
+					Name:       "http",
+					Protocol:   apiv1.ProtocolTCP,
+					Port:       port,
+					TargetPort: intstr.FromInt(int(port)),
+					NodePort:   nodePort,
+				},
+			},
+		},
+	}
+
+	_, err = clientset.CoreV1().Services(namespace).Create(context.TODO(), service, metav1.CreateOptions{})
+	if err != nil {
+		if !errors.IsAlreadyExists(err) {
+			return fmt.Errorf("failed to create Service: %v", err)
+		}
+		fmt.Printf("Service %s already exists in Namespace %s\n", serviceName, namespace)
+	} else {
+		fmt.Printf("Service %s created in Namespace %s\n", serviceName, namespace)
+	}
+
+	return nil
+}
+
+// getRandomNodePort 鑾峰彇涓�涓湭浣跨敤鐨勯殢鏈� NodePort
+func getRandomNodePort(clientset *kubernetes.Clientset) (int32, error) {
+	// 鑾峰彇涓�涓殢鏈虹殑 NodePort
+	nodePort := int32(0)
+	for {
+		// 鐢熸垚涓�涓殢鏈虹殑 NodePort
+		nodePort = generateRandomNodePort()
+
+		// 妫�鏌ヨ NodePort 鏄惁宸茶浣跨敤
+		used, err := isNodePortUsed(clientset, nodePort)
+		if err != nil {
+			return 0, err
+
+		}
+
+		// 濡傛灉鏈浣跨敤锛屽垯鏍囪涓哄凡浣跨敤锛屽苟閫�鍑哄惊鐜�
+		if !used {
+			usedNodePorts[nodePort] = true
+			break
+		}
+	}
+
+	return nodePort, nil
+}
+
+// generateRandomNodePort 鐢熸垚涓�涓殢鏈虹殑 NodePort
+func generateRandomNodePort() int32 {
+	// 鍦ㄨ寖鍥� 30000-32767 涓敓鎴愰殢鏈烘暟浣滀负 NodePort
+	return int32(rand.Intn(32767-30000+1) + 30000)
+}
+
+// isNodePortUsed 妫�鏌ユ寚瀹氱殑 NodePort 鏄惁宸茶浣跨敤
+func isNodePortUsed(clientset *kubernetes.Clientset, nodePort int32) (bool, error) {
+	// 鑾峰彇鎵�鏈� Service
+	services, err := clientset.CoreV1().Services("").List(context.TODO(), metav1.ListOptions{})
+	if err != nil {
+		return false, err
+	}
+
+	// 妫�鏌ユ瘡涓� Service 鐨� NodePort 鏄惁涓庢寚瀹氱殑 NodePort 鐩稿悓
+	for _, svc := range services.Items {
+		for _, port := range svc.Spec.Ports {
+			if port.NodePort == nodePort {
+				return true, nil
+			}
+		}
+	}
+
+	return false, nil
+}
+
+// DeleteResources 鍒犻櫎鎸囧畾鐨� Namespace銆丏eployment 鍜� Service
+func DeleteResources(clientset *kubernetes.Clientset, namespace, deploymentName, serviceName string) error {
+	fmt.Println("\033[1;37;40mDeleting resources in Namespace:", namespace, "\033[0m")
+
+	// 鍒犻櫎 Deployment
+	err := deleteDeployment(clientset, namespace, deploymentName)
+	if err != nil {
+		return err
+	}
+
+	// 鍒犻櫎 Service
+	err = deleteService(clientset, namespace, serviceName)
+	if err != nil {
+		return err
+	}
+
+	// 鍒犻櫎 Namespace
+	err = deleteNamespace(clientset, namespace)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// deleteDeployment 鍒犻櫎鎸囧畾鐨� Deployment
+func deleteDeployment(clientset *kubernetes.Clientset, namespace, deploymentName string) error {
+	fmt.Println("\033[1;37;40mDeleting Deployment:", deploymentName, "\033[0m")
+
+	err := clientset.AppsV1().Deployments(namespace).Delete(context.TODO(), deploymentName, metav1.DeleteOptions{})
+	if err != nil {
+		if errors.IsNotFound(err) {
+			fmt.Printf("Deployment %s not found in Namespace %s\n", deploymentName, namespace)
+		} else {
+			return fmt.Errorf("failed to delete Deployment: %v", err)
+		}
+	} else {
+		fmt.Printf("Deployment %s deleted from Namespace %s\n", deploymentName, namespace)
+	}
+
+	return nil
+}
+
+// deleteService 鍒犻櫎鎸囧畾鐨� Service
+func deleteService(clientset *kubernetes.Clientset, namespace, serviceName string) error {
+	fmt.Println("\033[1;37;40mDeleting Service:", serviceName, "\033[0m")
+
+	err := clientset.CoreV1().Services(namespace).Delete(context.TODO(), serviceName, metav1.DeleteOptions{})
+	if err != nil {
+		if errors.IsNotFound(err) {
+			fmt.Printf("Service %s not found in Namespace %s\n", serviceName, namespace)
+		} else {
+			return fmt.Errorf("failed to delete Service: %v", err)
+		}
+	} else {
+		fmt.Printf("Service %s deleted from Namespace %s\n", serviceName, namespace)
+	}
+
+	return nil
+}
+
+// deleteNamespace 鍒犻櫎鎸囧畾鐨� Namespace
+func deleteNamespace(clientset *kubernetes.Clientset, namespace string) error {
+	fmt.Println("\033[1;37;40mDeleting Namespace:", namespace, "\033[0m")
+
+	err := clientset.CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{})
+	if err != nil {
+		if errors.IsNotFound(err) {
+			fmt.Printf("Namespace %s not found\n", namespace)
+		} else {
+			return fmt.Errorf("failed to delete Namespace: %v", err)
+		}
+	} else {
+		fmt.Printf("Namespace %s deleted\n", namespace)
+	}
+
+	return nil
+}
+
+// homeDir 鑾峰彇褰撳墠鐢ㄦ埛鐨勫鐩綍璺緞
+func homeDir() string {
+	if h := os.Getenv("HOME"); h != "" {
+		return h
+	}
+	return os.Getenv("USERPROFILE") // Windows 鐜涓嬭幏鍙栫敤鎴风洰褰�
+}
+
+// GetServiceNodePort 鑾峰彇鎸囧畾 Service 鐨� NodePort
+func GetServiceNodePort(clientset *kubernetes.Clientset, namespace, serviceName string) (int32, error) {
+	svc, err := clientset.CoreV1().Services(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
+	if err != nil {
+		return 0, fmt.Errorf("failed to get Service: %v", err)
+	}
+
+	// 妫�鏌� Service 绫诲瀷鏄惁涓� NodePort
+	if svc.Spec.Type != apiv1.ServiceTypeNodePort {
+		return 0, fmt.Errorf("Service %s is not of type NodePort", serviceName)
+	}
+
+	// 鑾峰彇绗竴涓鍙g殑 NodePort
+	if len(svc.Spec.Ports) > 0 {
+		return svc.Spec.Ports[0].NodePort, nil
+	}
+
+	return 0, fmt.Errorf("no ports defined for Service %s", serviceName)
+}

--
Gitblit v1.8.0