From 68c007e836384635d843bbc61174fae5b09ccd1c Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期六, 06 一月 2024 17:08:07 +0800
Subject: [PATCH] 增加对crm,wms,srm的部署支持

---
 src/k8s/create.go     |  467 ++++++++++++----------
 src/k8s/create_wms.go |  212 ++++++++++
 src/main/main.go      |   80 ++-
 .gitignore            |    1 
 src/k8s/create_crm.go |  208 +++++++++
 src/k8s/delete.go     |   30 +
 src/k8s/create_srm.go |  208 +++++++++
 7 files changed, 960 insertions(+), 246 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..485dee6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.idea
diff --git a/src/k8s/create.go b/src/k8s/create.go
index 6c4ccc2..2380d1e 100644
--- a/src/k8s/create.go
+++ b/src/k8s/create.go
@@ -20,11 +20,19 @@
 )
 
 var (
-	replicas      int32 = 3
+	replicas      int32 = 1
 	port          int32 = 9081
 	rpcPort       int32 = 9091
-	namespaces          = []string{"guangsheng", "geruimi", "tongsheng"}
+	namespaces          = []string{"testFactory1", "testFactory2", "testFactory3"}
 	usedNodePorts       = make(map[int32]bool)
+	Projects            = []string{ProjectAps, ProjectCrm, ProjectSrm, ProjectWms}
+)
+
+const (
+	ProjectAps = "aps"
+	ProjectCrm = "crm"
+	ProjectSrm = "srm"
+	ProjectWms = "wms"
 )
 
 type Config struct {
@@ -60,9 +68,16 @@
 
 	// 鍒涘缓澶氫釜 Namespace 涓嬬殑鐩稿悓鍚嶇О鐨� Deployment 鍜� Service
 	for _, ns := range namespaces {
-		err = CreateDeploymentAndService(Config{Client: clientset, NameSpace: ns, DeploymentName: ns, ServiceName: ns}, nil)
+		err = CreateNamespace(clientset, ns)
 		if err != nil {
 			panic(err)
+		}
+		for _, proj := range Projects {
+			obj := GetCreateObj(proj)
+			err = obj.CreateDeploymentAndService(Config{Client: clientset, NameSpace: ns, DeploymentName: proj, ServiceName: proj}, nil)
+			if err != nil {
+				panic(err)
+			}
 		}
 
 		nodeport, err := GetServiceNodePort(clientset, ns, ns)
@@ -71,7 +86,22 @@
 		}
 
 		log.Printf("Service NodePort: %d\n", nodeport)
+
 	}
+}
+
+func GetCreateObj(proj string) Create {
+	switch proj {
+	case ProjectAps:
+		return &ApsCreate{}
+	case ProjectCrm:
+		return &CrmCreate{}
+	case ProjectSrm:
+		return &SrmCreate{}
+	case ProjectWms:
+		return &WmsCreate{}
+	}
+	return nil
 }
 
 // CheckAndDeleteResources 妫�娴嬪苟鍒犻櫎鎸囧畾鐨� Namespace銆丏eployment 鍜� Service
@@ -129,36 +159,6 @@
 	return nil
 }
 
-func CreateDeploymentAndService(config Config, extendEnvs map[string]string) error {
-	fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
-
-	// 妫�娴嬪苟鍒犻櫎宸插瓨鍦ㄧ殑 Deployment 鍜� Service
-	err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
-	if err != nil {
-		return err
-	}
-
-	config.HttpPort, config.RpcPort, err = getTwoNodePort(config.Client)
-	if err != nil {
-		return err
-	}
-
-	// 鍒涘缓 Deployment
-	err = createDeployment(config, extendEnvs)
-	if err != nil {
-		return err
-	}
-
-	log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
-	// 鍒涘缓 Service
-	err = createService(config)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
 // CreateNamespace 鍒涘缓鎸囧畾鐨� Namespace
 func CreateNamespace(clientset *kubernetes.Clientset, namespace string) error {
 	log.Printf("Creating Namespace: %s\n", namespace)
@@ -177,184 +177,6 @@
 		log.Printf("Namespace %s already exists\n", namespace)
 	} else {
 		log.Printf("Namespace %s created\n", namespace)
-	}
-
-	return nil
-}
-func createEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
-	envs := []apiv1.EnvVar{
-		{
-			Name:  "GRPC_PORT",
-			Value: fmt.Sprint(config.RpcPort),
-		},
-		{
-			Name: "DB_HOST",
-			ValueFrom: &apiv1.EnvVarSource{
-				FieldRef: &apiv1.ObjectFieldSelector{
-					APIVersion: "v1",
-					FieldPath:  "status.hostIP",
-				},
-			},
-		},
-		{
-			Name: "HOST",
-			ValueFrom: &apiv1.EnvVarSource{
-				FieldRef: &apiv1.ObjectFieldSelector{
-					APIVersion: "v1",
-					FieldPath:  "status.hostIP",
-				},
-			},
-		},
-		{
-			Name:  "DB_NAME",
-			Value: config.DBName,
-		},
-		{
-			Name:  "DB_PORT",
-			Value: strconv.Itoa(6446),
-		},
-		{
-			Name:  "DB_USER",
-			Value: config.NameSpace,
-		},
-		{
-			Name:  "DB_PASSWD",
-			Value: config.NameSpace + "@Basic2023",
-		},
-	}
-
-	if config.ALHost != "" {
-		envs = append(envs, apiv1.EnvVar{
-			Name:  "AL_HOST",
-			Value: config.ALHost,
-		})
-	}
-
-	if config.NodeID != "" {
-		envs = append(envs, apiv1.EnvVar{
-			Name:  "NODE_ID",
-			Value: config.NodeID,
-		})
-	}
-
-	if len(pairs) > 0 {
-		for name, value := range pairs {
-			envs = append(envs, apiv1.EnvVar{
-				Name:  name,
-				Value: value,
-			})
-		}
-	}
-	for name, value := range pairs {
-		envs = append(envs, apiv1.EnvVar{
-			Name:  name,
-			Value: value,
-		})
-	}
-	return envs
-}
-func createDeployment(config Config, extendEnvs map[string]string) error {
-	fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
-
-	envs := createEnv(config, extendEnvs)
-	deployment := &appsv1.Deployment{
-		ObjectMeta: metav1.ObjectMeta{
-			Name: config.DeploymentName,
-		},
-		Spec: appsv1.DeploymentSpec{
-			Replicas: &replicas,
-			Selector: &metav1.LabelSelector{
-				MatchLabels: map[string]string{
-					"cid": config.NameSpace,
-				},
-			},
-			Template: apiv1.PodTemplateSpec{
-				ObjectMeta: metav1.ObjectMeta{
-					Labels: map[string]string{
-						"cid": config.NameSpace,
-					},
-				},
-				Spec: apiv1.PodSpec{
-					TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
-						{
-							MaxSkew:           1,
-							TopologyKey:       "kubernetes.io/hostname",
-							WhenUnsatisfiable: apiv1.DoNotSchedule,
-							LabelSelector: &metav1.LabelSelector{
-								MatchLabels: map[string]string{
-									"cid": config.NameSpace,
-								},
-							},
-						},
-					},
-					Containers: []apiv1.Container{
-						{
-							Name:            config.NameSpace,
-							Image:           config.Image,
-							Env:             envs,
-							ImagePullPolicy: apiv1.PullAlways, // 璁剧疆闀滃儚鎷夊彇绛栫暐涓� Always
-						},
-					},
-				},
-			},
-		},
-	}
-
-	_, err := config.Client.AppsV1().Deployments(config.DeploymentName).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", config.DeploymentName, config.NameSpace)
-	} else {
-		fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
-	}
-
-	return nil
-}
-
-// createService 鍒涘缓鎸囧畾鐨� Service
-func createService(config Config) error {
-	fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
-
-	service := &apiv1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name: config.ServiceName,
-		},
-		Spec: apiv1.ServiceSpec{
-			Selector: map[string]string{
-				"cid": config.NameSpace,
-			},
-			Type: apiv1.ServiceTypeNodePort,
-			Ports: []apiv1.ServicePort{
-				{
-					Name:       "http",
-					Protocol:   apiv1.ProtocolTCP,
-					Port:       port,                      // 闆嗙兢鍐呴儴璁块棶绔彛
-					TargetPort: intstr.FromInt(int(port)), // 瀹瑰櫒瀵瑰绔彛
-					NodePort:   config.HttpPort,           // 澶栭儴璁块棶绔彛
-				},
-				{
-					Name:       "tcp",
-					Protocol:   apiv1.ProtocolTCP,
-					Port:       rpcPort,
-					TargetPort: intstr.FromInt(int(rpcPort)),
-					NodePort:   config.RpcPort,
-				},
-			},
-			SessionAffinity: apiv1.ServiceAffinityClientIP,
-		},
-	}
-
-	_, err := config.Client.CoreV1().Services(config.ServiceName).Create(context.TODO(), service, metav1.CreateOptions{})
-
-	if err != nil {
-		if !errors.IsAlreadyExists(err) {
-			return fmt.Errorf("failed to create Service: %v", err)
-		}
-		log.Printf("Service %s already exists in Namespace %s\n", config.ServiceName, config.NameSpace)
-	} else {
-		log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
 	}
 
 	return nil
@@ -456,3 +278,226 @@
 
 	return 0, fmt.Errorf("no ports defined for Service %s", serviceName)
 }
+
+type Create interface {
+	CreateDeploymentAndService(config Config, extendEnv map[string]string) error
+	CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar
+	CreateDeployment(config Config, extendEnv map[string]string) error
+	CreateService(config Config) error
+	GetCid(config Config) string
+}
+
+type ApsCreate struct{}
+
+func (c *ApsCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
+
+	// 妫�娴嬪苟鍒犻櫎宸插瓨鍦ㄧ殑 Deployment 鍜� Service
+	err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
+	if err != nil {
+		return err
+	}
+
+	config.HttpPort, config.RpcPort, err = getTwoNodePort(config.Client)
+	if err != nil {
+		return err
+	}
+
+	// 鍒涘缓 Deployment
+	err = c.CreateDeployment(config, extendEnv)
+	if err != nil {
+		return err
+	}
+
+	log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
+	// 鍒涘缓 Service
+	err = c.CreateService(config)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *ApsCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
+	envs := []apiv1.EnvVar{
+		{
+			Name:  "GRPC_PORT",
+			Value: fmt.Sprint(config.RpcPort),
+		},
+		{
+			Name: "DB_HOST",
+			ValueFrom: &apiv1.EnvVarSource{
+				FieldRef: &apiv1.ObjectFieldSelector{
+					APIVersion: "v1",
+					FieldPath:  "status.hostIP",
+				},
+			},
+		},
+		{
+			Name: "HOST",
+			ValueFrom: &apiv1.EnvVarSource{
+				FieldRef: &apiv1.ObjectFieldSelector{
+					APIVersion: "v1",
+					FieldPath:  "status.hostIP",
+				},
+			},
+		},
+		{
+			Name:  "DB_NAME",
+			Value: config.NameSpace,
+		},
+		{
+			Name:  "DB_PORT",
+			Value: strconv.Itoa(6446),
+		},
+		{
+			Name:  "DB_USER",
+			Value: config.NameSpace,
+		},
+		{
+			Name:  "DB_PASSWD",
+			Value: config.NameSpace + "@Basic2023",
+		},
+	}
+
+	if config.ALHost != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "AL_HOST",
+			Value: config.ALHost,
+		})
+	}
+
+	if config.NodeID != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "NODE_ID",
+			Value: config.NodeID,
+		})
+	}
+
+	if len(pairs) > 0 {
+		for name, value := range pairs {
+			envs = append(envs, apiv1.EnvVar{
+				Name:  name,
+				Value: value,
+			})
+		}
+	}
+	for name, value := range pairs {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  name,
+			Value: value,
+		})
+	}
+	return envs
+}
+func (c *ApsCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
+	log.Printf("Aps CreateDeployment config:%+v\n", config)
+	envs := c.CreateEnv(config, extendEnv)
+	deployment := &appsv1.Deployment{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.DeploymentName,
+		},
+		Spec: appsv1.DeploymentSpec{
+			Replicas: &replicas,
+			Selector: &metav1.LabelSelector{
+				MatchLabels: map[string]string{
+					"cid": c.GetCid(config),
+				},
+			},
+			Template: apiv1.PodTemplateSpec{
+				ObjectMeta: metav1.ObjectMeta{
+					Labels: map[string]string{
+						"cid": c.GetCid(config),
+					},
+				},
+				Spec: apiv1.PodSpec{
+					TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
+						{
+							MaxSkew:           1,
+							TopologyKey:       "kubernetes.io/hostname",
+							WhenUnsatisfiable: apiv1.DoNotSchedule,
+							LabelSelector: &metav1.LabelSelector{
+								MatchLabels: map[string]string{
+									"cid": c.GetCid(config),
+								},
+							},
+						},
+					},
+					Containers: []apiv1.Container{
+						{
+							Name:            config.NameSpace,
+							Image:           config.Image,
+							Env:             envs,
+							ImagePullPolicy: apiv1.PullIfNotPresent, // 璁剧疆闀滃儚鎷夊彇绛栫暐涓� Always
+						},
+					},
+				},
+			},
+		},
+	}
+
+	_, err := config.Client.AppsV1().Deployments(config.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", config.DeploymentName, config.NameSpace)
+	} else {
+		fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
+	}
+
+	return nil
+}
+
+// createService 鍒涘缓鎸囧畾鐨� Service
+func (c *ApsCreate) CreateService(config Config) error {
+	fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
+
+	service := &apiv1.Service{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.ServiceName,
+		},
+		Spec: apiv1.ServiceSpec{
+			Selector: map[string]string{
+				"cid": c.GetCid(config),
+			},
+			Type: apiv1.ServiceTypeNodePort,
+			Ports: []apiv1.ServicePort{
+				{
+					Name:       "http",
+					Protocol:   apiv1.ProtocolTCP,
+					Port:       port,                      // 闆嗙兢鍐呴儴璁块棶绔彛
+					TargetPort: intstr.FromInt(int(port)), // 瀹瑰櫒瀵瑰绔彛
+					NodePort:   config.HttpPort,           // 澶栭儴璁块棶绔彛
+				},
+				{
+					Name:       "tcp",
+					Protocol:   apiv1.ProtocolTCP,
+					Port:       rpcPort,
+					TargetPort: intstr.FromInt(int(rpcPort)),
+					NodePort:   config.RpcPort,
+				},
+			},
+			SessionAffinity: apiv1.ServiceAffinityClientIP,
+		},
+	}
+
+	_, err := config.Client.CoreV1().Services(config.NameSpace).Create(context.TODO(), service, metav1.CreateOptions{})
+
+	if err != nil {
+		if !errors.IsAlreadyExists(err) {
+			return fmt.Errorf("failed to create Service: %v", err)
+		}
+		log.Printf("Service %s already exists in Namespace %s\n", config.ServiceName, config.NameSpace)
+	} else {
+		log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
+	}
+
+	return nil
+}
+
+func (c *ApsCreate) GetCid(config Config) string {
+	return fmt.Sprintf("%v-%v", config.NameSpace, "aps")
+}
diff --git a/src/k8s/create_crm.go b/src/k8s/create_crm.go
new file mode 100644
index 0000000..a65b6ab
--- /dev/null
+++ b/src/k8s/create_crm.go
@@ -0,0 +1,208 @@
+package k8s
+
+import (
+	"context"
+	"fmt"
+	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"
+	"log"
+	"strconv"
+)
+
+type CrmCreate struct{}
+
+func (c *CrmCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
+	fmt.Printf("Crm CreateDeployment config:%+v\n", config)
+	// 妫�娴嬪苟鍒犻櫎宸插瓨鍦ㄧ殑 Deployment 鍜� Service
+	err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
+	if err != nil {
+		return err
+	}
+
+	config.HttpPort, err = getRandomNodePort(config.Client)
+	if err != nil {
+		return err
+	}
+
+	// 鍒涘缓 Deployment
+	err = c.CreateDeployment(config, extendEnv)
+	if err != nil {
+		return err
+	}
+
+	log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
+	// 鍒涘缓 Service
+	err = c.CreateService(config)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *CrmCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
+	envs := []apiv1.EnvVar{
+		{
+			Name: "DB_HOST",
+			ValueFrom: &apiv1.EnvVarSource{
+				FieldRef: &apiv1.ObjectFieldSelector{
+					APIVersion: "v1",
+					FieldPath:  "status.hostIP",
+				},
+			},
+		},
+		{
+			Name:  "DB_PORT",
+			Value: strconv.Itoa(6446),
+		},
+		{
+			Name:  "DB_NAME",
+			Value: config.NameSpace + "_crm",
+		},
+		{
+			Name:  "DB_USER",
+			Value: config.NameSpace,
+		},
+		{
+			Name:  "DB_PASSWD",
+			Value: config.NameSpace + "@Basic2023",
+		},
+	}
+
+	if config.ALHost != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "AL_HOST",
+			Value: config.ALHost,
+		})
+	}
+
+	if config.NodeID != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "NODE_ID",
+			Value: config.NodeID,
+		})
+	}
+
+	if len(pairs) > 0 {
+		for name, value := range pairs {
+			envs = append(envs, apiv1.EnvVar{
+				Name:  name,
+				Value: value,
+			})
+		}
+	}
+	for name, value := range pairs {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  name,
+			Value: value,
+		})
+	}
+	return envs
+}
+func (c *CrmCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
+
+	envs := c.CreateEnv(config, extendEnv)
+	deployment := &appsv1.Deployment{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.DeploymentName,
+		},
+		Spec: appsv1.DeploymentSpec{
+			Replicas: &replicas,
+			Selector: &metav1.LabelSelector{
+				MatchLabels: map[string]string{
+					"cid": c.GetCid(config),
+				},
+			},
+			Template: apiv1.PodTemplateSpec{
+				ObjectMeta: metav1.ObjectMeta{
+					Labels: map[string]string{
+						"cid": c.GetCid(config),
+					},
+				},
+				Spec: apiv1.PodSpec{
+					TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
+						{
+							MaxSkew:           1,
+							TopologyKey:       "kubernetes.io/hostname",
+							WhenUnsatisfiable: apiv1.DoNotSchedule,
+							LabelSelector: &metav1.LabelSelector{
+								MatchLabels: map[string]string{
+									"cid": c.GetCid(config),
+								},
+							},
+						},
+					},
+					Containers: []apiv1.Container{
+						{
+							Name:            config.DeploymentName,
+							Image:           config.Image,
+							Env:             envs,
+							ImagePullPolicy: apiv1.PullIfNotPresent, // 璁剧疆闀滃儚鎷夊彇绛栫暐涓� Always
+						},
+					},
+				},
+			},
+		},
+	}
+
+	_, err := config.Client.AppsV1().Deployments(config.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", config.DeploymentName, config.NameSpace)
+	} else {
+		fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
+	}
+
+	return nil
+}
+
+// createService 鍒涘缓鎸囧畾鐨� Service
+func (c *CrmCreate) CreateService(config Config) error {
+	fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
+
+	service := &apiv1.Service{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.ServiceName,
+		},
+		Spec: apiv1.ServiceSpec{
+			Selector: map[string]string{
+				"cid": c.GetCid(config),
+			},
+			Type: apiv1.ServiceTypeNodePort,
+			Ports: []apiv1.ServicePort{
+				{
+					Name:       "http",
+					Protocol:   apiv1.ProtocolTCP,
+					Port:       port,                      // 闆嗙兢鍐呴儴璁块棶绔彛
+					TargetPort: intstr.FromInt(int(port)), // 瀹瑰櫒瀵瑰绔彛
+					NodePort:   config.HttpPort,           // 澶栭儴璁块棶绔彛
+				},
+			},
+			SessionAffinity: apiv1.ServiceAffinityClientIP,
+		},
+	}
+
+	_, err := config.Client.CoreV1().Services(config.NameSpace).Create(context.TODO(), service, metav1.CreateOptions{})
+
+	if err != nil {
+		if !errors.IsAlreadyExists(err) {
+			return fmt.Errorf("failed to create Service: %v", err)
+		}
+		log.Printf("Service %s already exists in Namespace %s\n", config.ServiceName, config.NameSpace)
+	} else {
+		log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
+	}
+
+	return nil
+}
+
+func (c *CrmCreate) GetCid(config Config) string {
+	return fmt.Sprintf("%v-%v", config.NameSpace, "crm")
+}
diff --git a/src/k8s/create_srm.go b/src/k8s/create_srm.go
new file mode 100644
index 0000000..e612e14
--- /dev/null
+++ b/src/k8s/create_srm.go
@@ -0,0 +1,208 @@
+package k8s
+
+import (
+	"context"
+	"fmt"
+	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"
+	"log"
+	"strconv"
+)
+
+type SrmCreate struct{}
+
+func (c *SrmCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
+
+	// 妫�娴嬪苟鍒犻櫎宸插瓨鍦ㄧ殑 Deployment 鍜� Service
+	err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
+	if err != nil {
+		return err
+	}
+
+	config.HttpPort, err = getRandomNodePort(config.Client)
+	if err != nil {
+		return err
+	}
+
+	// 鍒涘缓 Deployment
+	err = c.CreateDeployment(config, extendEnv)
+	if err != nil {
+		return err
+	}
+
+	log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
+	// 鍒涘缓 Service
+	err = c.CreateService(config)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *SrmCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
+	envs := []apiv1.EnvVar{
+		{
+			Name: "DB_HOST",
+			ValueFrom: &apiv1.EnvVarSource{
+				FieldRef: &apiv1.ObjectFieldSelector{
+					APIVersion: "v1",
+					FieldPath:  "status.hostIP",
+				},
+			},
+		},
+		{
+			Name:  "DB_NAME",
+			Value: config.NameSpace,
+		},
+		{
+			Name:  "DB_PORT",
+			Value: strconv.Itoa(6446),
+		},
+		{
+			Name:  "DB_USER",
+			Value: config.NameSpace,
+		},
+		{
+			Name:  "DB_PASSWD",
+			Value: config.NameSpace + "@Basic2023",
+		},
+	}
+
+	if config.ALHost != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "AL_HOST",
+			Value: config.ALHost,
+		})
+	}
+
+	if config.NodeID != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "NODE_ID",
+			Value: config.NodeID,
+		})
+	}
+
+	if len(pairs) > 0 {
+		for name, value := range pairs {
+			envs = append(envs, apiv1.EnvVar{
+				Name:  name,
+				Value: value,
+			})
+		}
+	}
+	for name, value := range pairs {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  name,
+			Value: value,
+		})
+	}
+	return envs
+}
+func (c *SrmCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
+	fmt.Printf("Srm CreateDeployment config:%+v\n", config)
+	envs := c.CreateEnv(config, extendEnv)
+	deployment := &appsv1.Deployment{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.DeploymentName,
+		},
+		Spec: appsv1.DeploymentSpec{
+			Replicas: &replicas,
+			Selector: &metav1.LabelSelector{
+				MatchLabels: map[string]string{
+					"cid": c.GetCid(config),
+				},
+			},
+			Template: apiv1.PodTemplateSpec{
+				ObjectMeta: metav1.ObjectMeta{
+					Labels: map[string]string{
+						"cid": c.GetCid(config),
+					},
+				},
+				Spec: apiv1.PodSpec{
+					TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
+						{
+							MaxSkew:           1,
+							TopologyKey:       "kubernetes.io/hostname",
+							WhenUnsatisfiable: apiv1.DoNotSchedule,
+							LabelSelector: &metav1.LabelSelector{
+								MatchLabels: map[string]string{
+									"cid": c.GetCid(config),
+								},
+							},
+						},
+					},
+					Containers: []apiv1.Container{
+						{
+							Name:            config.DeploymentName,
+							Image:           config.Image,
+							Env:             envs,
+							ImagePullPolicy: apiv1.PullIfNotPresent, // 璁剧疆闀滃儚鎷夊彇绛栫暐涓� Always
+						},
+					},
+				},
+			},
+		},
+	}
+
+	_, err := config.Client.AppsV1().Deployments(config.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", config.DeploymentName, config.NameSpace)
+	} else {
+		fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
+	}
+
+	return nil
+}
+
+// createService 鍒涘缓鎸囧畾鐨� Service
+func (c *SrmCreate) CreateService(config Config) error {
+	fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
+
+	service := &apiv1.Service{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.ServiceName,
+		},
+		Spec: apiv1.ServiceSpec{
+			Selector: map[string]string{
+				"cid": c.GetCid(config),
+			},
+			Type: apiv1.ServiceTypeNodePort,
+			Ports: []apiv1.ServicePort{
+				{
+					Name:       "http",
+					Protocol:   apiv1.ProtocolTCP,
+					Port:       port,                      // 闆嗙兢鍐呴儴璁块棶绔彛
+					TargetPort: intstr.FromInt(int(port)), // 瀹瑰櫒瀵瑰绔彛
+					NodePort:   config.HttpPort,           // 澶栭儴璁块棶绔彛
+				},
+			},
+			SessionAffinity: apiv1.ServiceAffinityClientIP,
+		},
+	}
+
+	_, err := config.Client.CoreV1().Services(config.NameSpace).Create(context.TODO(), service, metav1.CreateOptions{})
+
+	if err != nil {
+		if !errors.IsAlreadyExists(err) {
+			return fmt.Errorf("failed to create Service: %v", err)
+		}
+		log.Printf("Service %s already exists in Namespace %s\n", config.ServiceName, config.NameSpace)
+	} else {
+		log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
+	}
+
+	return nil
+}
+
+func (c *SrmCreate) GetCid(config Config) string {
+	return fmt.Sprintf("%v-%v", config.NameSpace, "srm")
+}
diff --git a/src/k8s/create_wms.go b/src/k8s/create_wms.go
new file mode 100644
index 0000000..29c477e
--- /dev/null
+++ b/src/k8s/create_wms.go
@@ -0,0 +1,212 @@
+package k8s
+
+import (
+	"context"
+	"fmt"
+	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"
+	"log"
+	"strconv"
+)
+
+type WmsCreate struct{}
+
+func (c *WmsCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
+	fmt.Printf("Wms CreateDeployment config:%+v\n", config)
+	// 妫�娴嬪苟鍒犻櫎宸插瓨鍦ㄧ殑 Deployment 鍜� Service
+	err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
+	if err != nil {
+		return err
+	}
+
+	config.HttpPort, err = getRandomNodePort(config.Client)
+	if err != nil {
+		return err
+	}
+
+	// 鍒涘缓 Deployment
+	err = c.CreateDeployment(config, extendEnv)
+	if err != nil {
+		return err
+	}
+
+	log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
+	// 鍒涘缓 Service
+	err = c.CreateService(config)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *WmsCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
+	envs := []apiv1.EnvVar{
+		{
+			Name:  "GRPC_PORT",
+			Value: fmt.Sprint(config.RpcPort),
+		},
+		{
+			Name: "DB_HOST",
+			ValueFrom: &apiv1.EnvVarSource{
+				FieldRef: &apiv1.ObjectFieldSelector{
+					APIVersion: "v1",
+					FieldPath:  "status.hostIP",
+				},
+			},
+		},
+		{
+			Name:  "DB_NAME",
+			Value: config.NameSpace,
+		},
+		{
+			Name:  "DB_PORT",
+			Value: strconv.Itoa(6446),
+		},
+		{
+			Name:  "DB_USER",
+			Value: config.NameSpace,
+		},
+		{
+			Name:  "DB_PASSWD",
+			Value: config.NameSpace + "@Basic2023",
+		},
+	}
+
+	if config.ALHost != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "AL_HOST",
+			Value: config.ALHost,
+		})
+	}
+
+	if config.NodeID != "" {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  "NODE_ID",
+			Value: config.NodeID,
+		})
+	}
+
+	if len(pairs) > 0 {
+		for name, value := range pairs {
+			envs = append(envs, apiv1.EnvVar{
+				Name:  name,
+				Value: value,
+			})
+		}
+	}
+	for name, value := range pairs {
+		envs = append(envs, apiv1.EnvVar{
+			Name:  name,
+			Value: value,
+		})
+	}
+	return envs
+}
+func (c *WmsCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
+	fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
+
+	envs := c.CreateEnv(config, extendEnv)
+	deployment := &appsv1.Deployment{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.DeploymentName,
+		},
+		Spec: appsv1.DeploymentSpec{
+			Replicas: &replicas,
+			Selector: &metav1.LabelSelector{
+				MatchLabels: map[string]string{
+					"cid": c.GetCid(config),
+				},
+			},
+			Template: apiv1.PodTemplateSpec{
+				ObjectMeta: metav1.ObjectMeta{
+					Labels: map[string]string{
+						"cid": c.GetCid(config),
+					},
+				},
+				Spec: apiv1.PodSpec{
+					TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
+						{
+							MaxSkew:           1,
+							TopologyKey:       "kubernetes.io/hostname",
+							WhenUnsatisfiable: apiv1.DoNotSchedule,
+							LabelSelector: &metav1.LabelSelector{
+								MatchLabels: map[string]string{
+									"cid": c.GetCid(config),
+								},
+							},
+						},
+					},
+					Containers: []apiv1.Container{
+						{
+							Name:            config.DeploymentName,
+							Image:           config.Image,
+							Env:             envs,
+							ImagePullPolicy: apiv1.PullIfNotPresent, // 璁剧疆闀滃儚鎷夊彇绛栫暐涓� Always
+						},
+					},
+				},
+			},
+		},
+	}
+
+	_, err := config.Client.AppsV1().Deployments(config.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", config.DeploymentName, config.NameSpace)
+	} else {
+		fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
+	}
+
+	return nil
+}
+
+// createService 鍒涘缓鎸囧畾鐨� Service
+func (c *WmsCreate) CreateService(config Config) error {
+	fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
+
+	service := &apiv1.Service{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: config.ServiceName,
+		},
+		Spec: apiv1.ServiceSpec{
+			Selector: map[string]string{
+				"cid": c.GetCid(config),
+			},
+			Type: apiv1.ServiceTypeNodePort,
+			Ports: []apiv1.ServicePort{
+				{
+					Name:       "http",
+					Protocol:   apiv1.ProtocolTCP,
+					Port:       port,                      // 闆嗙兢鍐呴儴璁块棶绔彛
+					TargetPort: intstr.FromInt(int(port)), // 瀹瑰櫒瀵瑰绔彛
+					NodePort:   config.HttpPort,           // 澶栭儴璁块棶绔彛
+				},
+			},
+			SessionAffinity: apiv1.ServiceAffinityClientIP,
+		},
+	}
+
+	_, err := config.Client.CoreV1().Services(config.NameSpace).Create(context.TODO(), service, metav1.CreateOptions{})
+
+	if err != nil {
+		if !errors.IsAlreadyExists(err) {
+			return fmt.Errorf("failed to create Service: %v", err)
+		}
+		log.Printf("Service %s already exists in Namespace %s\n", config.ServiceName, config.NameSpace)
+	} else {
+		log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
+	}
+
+	return nil
+}
+
+func (c *WmsCreate) GetCid(config Config) string {
+	return fmt.Sprintf("%v-%v", config.NameSpace, "wms")
+}
diff --git a/src/k8s/delete.go b/src/k8s/delete.go
index 8d99f16..8410b76 100644
--- a/src/k8s/delete.go
+++ b/src/k8s/delete.go
@@ -14,9 +14,6 @@
 )
 
 func delete_test() {
-	var (
-		namespaces = []string{"guangsheng", "geruimi", "tongsheng"}
-	)
 
 	// 閰嶇疆 Kubernetes 闆嗙兢鐨� kubeconfig 璺緞
 	kubeconfig := flag.String("kubeconfig", filepath.Join(util.HomeDir(), ".kube", "config"), "kubeconfig file")
@@ -35,7 +32,32 @@
 
 	// 鍒犻櫎澶氫釜 Namespace 涓嬬殑鐩稿悓鍚嶇О鐨� Deployment 鍜� Service
 	for _, ns := range namespaces {
-		err = DeleteResources(clientset, ns, ns, ns)
+		for _, proj := range Projects {
+			if proj == ProjectAps {
+				err := deleteDeployment(clientset, ns, ns)
+				if err != nil {
+					panic(err)
+				}
+				// 鍒犻櫎 Service
+				err = deleteService(clientset, ns, ns)
+				if err != nil {
+					panic(err)
+				}
+			} else {
+				err := deleteDeployment(clientset, ns, proj)
+				if err != nil {
+					panic(err)
+				}
+				// 鍒犻櫎 Service
+				err = deleteService(clientset, ns, proj)
+				if err != nil {
+					panic(err)
+				}
+			}
+		}
+
+		// 鍒犻櫎 Namespace
+		err = DeleteNamespace(Config{Client: clientset, NameSpace: ns})
 		if err != nil {
 			panic(err)
 		}
diff --git a/src/main/main.go b/src/main/main.go
index 530cf63..41dfb85 100644
--- a/src/main/main.go
+++ b/src/main/main.go
@@ -20,10 +20,10 @@
 )
 
 var (
-	replicas      int32 = 3
+	replicas      int32 = 1
 	port          int32 = 9081
 	usedNodePorts       = make(map[int32]bool)
-	namespaces          = []string{"guangsheng", "geruimi", "tongsheng"}
+	namespaces          = []string{"testFactory1", "testFactory2", "testFactory3"}
 )
 
 func rancher_install_test(node rancher.Node) {
@@ -127,8 +127,9 @@
 
 	createNamespace := createCmd.String("ns", "", "Namespace name")
 	createDeployment := createCmd.String("deployment", "", "Deployment name")
+	fmt.Println(createDeployment)
 	createService := createCmd.String("service", "", "Service name")
-
+	fmt.Println(createService)
 	deleteNamespace := deleteCmd.String("ns", "", "Namespace name")
 	deleteDeployment := deleteCmd.String("deployment", "", "Deployment name")
 	deleteService := deleteCmd.String("service", "", "Service name")
@@ -176,9 +177,9 @@
 		rancherClusterConfig.Nodes = make([]rancher.Node, 3)
 		rancherClusterConfig.Nodes[0] = rancher.Node{
 			Roles:       []string{"worker"},
-			IP:          "192.168.20.189",
-			SSHUsername: "basic",
-			SSHPassword: "123",
+			IP:          "192.168.49.1",
+			SSHUsername: "me",
+			SSHPassword: "123456",
 			SSHPort:     22,
 		}
 
@@ -208,23 +209,31 @@
 			panic(err.Error())
 		}
 
-		if *createNamespace == "" || *createDeployment == "" || *createService == "" {
+		if *createNamespace == "" {
 			fmt.Println("Namespace, Deployment, and Service names are required")
 			createCmd.PrintDefaults()
 			os.Exit(1)
 		}
 
-		err = k8s.CreateDeploymentAndService(k8s.Config{
-			Client:         clientset,
-			NameSpace:      *createNamespace,
-			DeploymentName: *createDeployment,
-			ServiceName:    *createService,
-		}, nil)
+		err = k8s.CreateNamespace(clientset, *createNamespace)
 		if err != nil {
 			panic(err)
 		}
+		for _, proj := range k8s.Projects {
+			obj := k8s.GetCreateObj(proj)
+			err = obj.CreateDeploymentAndService(k8s.Config{
+				Client:         clientset,
+				NameSpace:      *createNamespace,
+				DeploymentName: proj,
+				ServiceName:    proj,
+				Image:          "fai365.com:9088/aps/aps",
+			}, nil)
+			if err != nil {
+				panic(err)
+			}
+		}
 
-		nodeport, err := k8s.GetServiceNodePort(clientset, *createNamespace, *createService)
+		nodeport, err := k8s.GetServiceNodePort(clientset, *createNamespace, "aps")
 		if err != nil {
 			panic(err)
 		}
@@ -255,9 +264,14 @@
 			os.Exit(1)
 		}
 
-		err = k8s.DeleteResources(clientset, *deleteNamespace, *deleteDeployment, *deleteService)
-		if err != nil {
-			panic(err)
+		for _, proj := range k8s.Projects {
+			err = k8s.DeleteResources(clientset, *deleteNamespace, proj, proj)
+			if err != nil {
+				panic(err)
+			}
+			if err != nil {
+				panic(err)
+			}
 		}
 
 		fmt.Println("Resources deleted.")
@@ -287,23 +301,27 @@
 		for _, ns := range namespaces {
 			deploymentName := ns
 			serviceName := ns
-			err := k8s.CreateDeploymentAndService(k8s.Config{
-				Client:         clientset,
-				NameSpace:      ns,
-				DeploymentName: deploymentName,
-				ServiceName:    serviceName,
-			}, nil)
-			if err != nil {
-				log.Printf("\033[97;41mFailed to create resources in namespace %s: %v\033[0m\n", ns, err)
-			} else {
-				nodeport, err := k8s.GetServiceNodePort(clientset, ns, ns)
+			for _, proj := range k8s.Projects {
+				obj := k8s.GetCreateObj(proj)
+				err = obj.CreateDeploymentAndService(k8s.Config{
+					Client:         clientset,
+					NameSpace:      ns,
+					DeploymentName: deploymentName,
+					ServiceName:    serviceName,
+				}, nil)
 				if err != nil {
-					panic(err)
-				}
+					log.Printf("\033[97;41mFailed to create resources in namespace %s: %v\033[0m\n", ns, err)
+				} else {
+					nodeport, err := k8s.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)
+					log.Printf("Service NodePort: %d\n", nodeport)
+					log.Printf("\033[97;42mSuccessfully created resources in namespace %s\033[0m\n", ns)
+				}
 			}
+
 		}
 
 		// 寤惰繜 1000 绉掑悗鍒犻櫎鍒涘缓鐨勮祫婧�

--
Gitblit v1.8.0