package deployment

import (
	"encoding/json"
	"errors"
	"github.com/astaxie/beego"
	"k8s-console/dto"
	"k8s-console/dto/deployment"
	"k8s-console/utils"
	"k8s.io/api/apps/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	"regexp"
	"sigs.k8s.io/yaml"
	"strconv"
	"strings"
)

var (
	infoLogger  = utils.InfoLogger
	errorLogger = utils.ErrorLogger
)

// DeploymentController operations for harborImage
type DeploymentController struct {
	beego.Controller
}

// URLMapping ...
func (c *DeploymentController) URLMapping() {
	c.Mapping("getDeploymentList", c.GetDeploymentList)
	c.Mapping("removeDeployment", c.RemoveDeployment)
	c.Mapping("scaleDeployment", c.ScaleDeployment)
	c.Mapping("queryDeploymentDetails", c.QueryDeploymentDetails)
	c.Mapping("checkDeploymentContent", c.CheckDeploymentContent)
	c.Mapping("createDeployment", c.CreateDeployment)
	c.Mapping("saveDeploymentDetailsForEdit", c.SaveDeploymentDetailsForEdit)
	c.Mapping("getDeploymentDetailsForEdit", c.GetDeploymentDetailsForEdit)
	c.Mapping("getDeploymentDetailsTemplate", c.GetDeploymentDetailsTemplate)
}

// Post ...
// @Title GetDeploymentList
// @Description get DeploymentList
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.GetDeploymentListRequestDto	true	""
// @Success 200
// @Failure 300 {object} dto.BaseResponseDto
// @router /getDeploymentList [post]
func (c *DeploymentController) GetDeploymentList() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.GetDeploymentListRequestDto
	var errorResponseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	var successResponseDto = dto.GetPageListBaseResponseDto{}
	successResponseDto.Status = 200
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("查询所有部署请求参数: ", requestDto)

	pageIndex := requestDto.PageIndex
	pageSize := requestDto.PageSize
	if pageIndex < 0 {
		errorResponseDto.Message = utils.GetI18nLang(lang, "pageIndexRange")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	if pageSize <= 0 {
		errorResponseDto.Message = utils.GetI18nLang(lang, "pageSizeRange")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	nameSpace := requestDto.NameSpace

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		errorResponseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	//查询集群所有命名空间信息
	nameSpaceList, err := k8sClient.CoreV1().Namespaces().List(metav1.ListOptions{})
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getClusterAllNamespacesFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	allNameSpaceList := []string{}
	infoLogger.Println(nameSpaceList.Items)
	for _, item := range nameSpaceList.Items {
		infoLogger.Println(item.Name)
		allNameSpaceList = append(allNameSpaceList, item.Name)
	}

	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		errorResponseDto.Message = utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	//查询命名空间下所有deployment信息
	deploymentList, err := k8sClient.AppsV1().Deployments(nameSpace).List(metav1.ListOptions{})
	if err != nil {
		errorLogger.Printf("查询集群%s空间所有deployment失败: %s", nameSpace, err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getDeploymentListByNameSpaceFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	itemList := deploymentList.Items

	totalRecords := len(itemList)
	totalPages := 0

	result := []deployment.GetDeploymentListResultDataResponseDto{}
	for _, item := range deploymentList.Items {
		infoLogger.Println(item.Name)                                                                               // 名称
		readyStr := utils.Int32ToString(item.Status.ReadyReplicas) + "/" + utils.Int32ToString(*item.Spec.Replicas) // 容器组

		infoLogger.Println(readyStr)
		infoLogger.Println(item.CreationTimestamp)
		infoLogger.Println(item.CreationTimestamp.Time)
		creationTimestamp, err := utils.ParseDateToString(lang, item.CreationTimestamp.Time)
		if err != nil {
			errorLogger.Printf("时间格式转换失败: %s", err.Error())
		}
		infoLogger.Println(creationTimestamp) // 已创建时间

		// 镜像
		containerImages := []deployment.ContainerImage{}
		for _, container := range item.Spec.Template.Spec.Containers {
			infoLogger.Println("container.Image: " + container.Image)
			imageKey := ""
			imageVal := ""
			lastIndexSeparator := strings.LastIndex(container.Image, "/") // 最后一个斜杠的索引值
			lastIndexColon := strings.LastIndex(container.Image, ":")     // 最后一个冒号的索引值
			isContainsColon := strings.Contains(container.Image, ":")     // 是否包含冒号
			if lastIndexSeparator > 0 && isContainsColon && lastIndexSeparator < lastIndexColon {
				newImageStr := container.Image[lastIndexSeparator+1 : len(container.Image)]
				imageKey = strings.Split(newImageStr, ":")[0]
				imageVal = strings.Split(newImageStr, ":")[1]
			} else if lastIndexSeparator < 0 && isContainsColon {
				imageKey = strings.Split(container.Image, ":")[0]
				imageVal = strings.Split(container.Image, ":")[1]
			} else {
				imageKey = container.Image
			}
			containerImage := deployment.ContainerImage{
				ImageKey:      imageKey,
				ImageValue:    imageVal,
				ImageFullName: container.Image,
			}
			containerImages = append(containerImages, containerImage)
		}

		o := deployment.GetDeploymentListResultDataResponseDto{
			DeploymentName: item.Name,
			ContainerGroup: readyStr,
			CreatedTime:    creationTimestamp,
			Images:         containerImages,
			Labels:         item.Labels,
			ReplicasNum:    *item.Spec.Replicas,
		}
		result = append(result, o)
	}

	resultList := []deployment.GetDeploymentListResultDataResponseDto{}
	if totalRecords > 0 {
		totalPages = totalRecords/pageSize + 1
		if totalRecords%pageSize == 0 {
			totalPages = totalRecords / pageSize
		}
		if totalRecords <= pageIndex*pageSize {
			errorResponseDto.Message = utils.GetI18nLang(lang, "pageIndexOutRange")
			c.Data["json"] = errorResponseDto
			c.ServeJSON()
			return
		}
		resultList = result[pageIndex*pageSize:]
		if len(result)-pageIndex*pageSize >= pageSize {
			resultList = result[pageIndex*pageSize : (pageIndex+1)*pageSize]
		}

	} else {
		if totalRecords < pageIndex*pageSize {
			errorResponseDto.Message = utils.GetI18nLang(lang, "pageIndexOutRange")
			c.Data["json"] = errorResponseDto
			c.ServeJSON()
			return
		}
	}

	successResponseDto.Result = resultList
	successResponseDto.PageInfo = dto.PageInfoBaseResponseDto{
		TotalRecords: totalRecords,
		TotalPages:   totalPages,
	}
	c.Data["json"] = successResponseDto
	c.ServeJSON()
}

// Post ...
// @Title GetDeploymentDetailsTemplate
// @Description get DeploymentDetailsTemplate
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.GetDeploymentDetailsTemplateRequestDto	true	""
// @Success 200
// @Failure 300 {object} dto.BaseResponseDto
// @router /getDeploymentDetailsTemplate [post]
func (c *DeploymentController) GetDeploymentDetailsTemplate() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.GetDeploymentDetailsTemplateRequestDto
	var errorResponseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	var successResponseDto = deployment.GetDeploymentDetailsTemplateResponseDto{}
	successResponseDto.Status = 200
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("部署详情模板查询接口请求参数: ", requestDto)

	pageIndex := requestDto.PageIndex
	pageSize := requestDto.PageSize
	if pageIndex < 0 {
		errorResponseDto.Message = utils.GetI18nLang(lang, "pageIndexRange")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	if pageSize <= 0 {
		errorResponseDto.Message = utils.GetI18nLang(lang, "pageSizeRange")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	nameSpace := requestDto.NameSpace
	deploymentName := requestDto.DeploymentName
	if strings.TrimSpace(nameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	if strings.TrimSpace(deploymentName) == "" {
		errorLogger.Println("部署名称不能为空")
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		errorResponseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	//查询集群所有命名空间信息
	nameSpaceList, err := k8sClient.CoreV1().Namespaces().List(metav1.ListOptions{})
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getClusterAllNamespacesFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	allNameSpaceList := []string{}
	for _, item := range nameSpaceList.Items {
		infoLogger.Println(item.Name)
		allNameSpaceList = append(allNameSpaceList, item.Name)
	}

	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		errorResponseDto.Message = utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	//查询命名空间下所有deployment信息
	deploymentInfo, err := k8sClient.AppsV1().Deployments(nameSpace).Get(deploymentName, metav1.GetOptions{})
	if err != nil {
		errorLogger.Printf("根据%s空间获取%s部署失败: %s", requestDto.NameSpace, requestDto.DeploymentName, err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getDeploymentInfo_getTheDeploymentInfoFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	containers := deploymentInfo.Spec.Template.Spec.Containers

	totalRecords := len(containers)
	totalPages := 0

	pods := []deployment.Pod{}
	for _, container := range containers {
		// 镜像
		imagesMap := make(map[string]string)
		infoLogger.Println("container.Image: " + container.Image)

		lastIndexSeparator := strings.LastIndex(container.Image, "/") // 最后一个斜杠的索引值
		lastIndexColon := strings.LastIndex(container.Image, ":")     // 最后一个冒号的索引值
		isContainsColon := strings.Contains(container.Image, ":")     // 是否包含冒号
		if lastIndexSeparator > 0 && isContainsColon && lastIndexSeparator < lastIndexColon {
			newImageStr := container.Image[lastIndexSeparator+1 : len(container.Image)]
			imagesMap[strings.Split(newImageStr, ":")[0]] = strings.Split(newImageStr, ":")[1]
		} else if lastIndexSeparator < 0 && isContainsColon {
			imageKey := strings.Split(container.Image, ":")[0]
			imageVal := strings.Split(container.Image, ":")[1]
			imagesMap[imageKey] = imageVal
		} else {
			imagesMap[container.Image] = ""
		}

		portArray := []string{}
		for _, port := range container.Ports {
			containerPort := utils.Int32ToString(port.ContainerPort) + "/" + string(port.Protocol)
			portArray = append(portArray, containerPort)
		}

		pod := deployment.Pod{
			ContainerName:  container.Name,
			ContainerImage: imagesMap,
			ContainerPort:  portArray,
		}
		pods = append(pods, pod)
	}

	resultList := []deployment.Pod{}
	if totalRecords > 0 {
		totalPages = totalRecords/pageSize + 1
		if totalRecords%pageSize == 0 {
			totalPages = totalRecords / pageSize
		}
		if totalRecords <= pageIndex*pageSize {
			errorResponseDto.Message = utils.GetI18nLang(lang, "pageIndexOutRange")
			c.Data["json"] = errorResponseDto
			c.ServeJSON()
			return
		}
		resultList = pods[pageIndex*pageSize:]
		if len(pods)-pageIndex*pageSize >= pageSize {
			resultList = pods[pageIndex*pageSize : (pageIndex+1)*pageSize]
		}
	} else {
		if totalRecords < pageIndex*pageSize {
			errorResponseDto.Message = utils.GetI18nLang(lang, "pageIndexOutRange")
			c.Data["json"] = errorResponseDto
			c.ServeJSON()
			return
		}
	}

	successResponseDto.TemplateLabels = deploymentInfo.Spec.Template.ObjectMeta.Labels
	successResponseDto.Pods = resultList
	successResponseDto.PageInfo = deployment.PageInfoResponseDto{
		TotalRecords: totalRecords,
		TotalPages:   totalPages,
	}
	c.Data["json"] = successResponseDto
	c.ServeJSON()
}

// Post ...
// @Title RemoveDeployment
// @Description remove Deployment
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.DeploymentRequestDto	 true	""
// @Success 200 {object} dto.BaseResponseDto
// @Failure 300 {object} dto.BaseResponseDto
// @router /removeDeployment [post]
func (c *DeploymentController) RemoveDeployment() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.DeploymentRequestDto
	var responseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("删除部署接口请求参数: ", requestDto)

	nameSpace := requestDto.NameSpace
	deploymentName := requestDto.DeploymentName
	if strings.TrimSpace(nameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	if strings.TrimSpace(deploymentName) == "" {
		errorLogger.Println("deployment名称不能为空")
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	//查询集群所有命名空间信息
	allNameSpaceList, err := utils.GetClusterAllNameSpaces(lang)
	infoLogger.Println(allNameSpaceList)
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "getClusterAllNamespacesFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		responseDto.Message = utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		responseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	var dpf metav1.DeletionPropagation = metav1.DeletePropagationForeground // Foreground级联删除策略，删除相应的pod
	if err := k8sClient.AppsV1().Deployments(nameSpace).Delete(deploymentName, &metav1.DeleteOptions{PropagationPolicy: &dpf}); err != nil {
		errorLogger.Printf("移除%s空间deployment:%s失败:%s", nameSpace, deploymentName, err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "removeDeployment_removeDeploymentFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	// 此处增加删除延时处理，直到无法再次获取该部署时才表示彻底删除，否则部署列表会出现分页数据没有及时刷新的问题
	deleteIsTrue := false
	for {
		if deleteIsTrue {
			break
		} else {
			if _, err := k8sClient.AppsV1().Deployments(nameSpace).Get(deploymentName, metav1.GetOptions{}); err != nil {
				errStr := err.Error()
				errorLogger.Printf("彻底删除集群%s空间%s的deployment: %s", nameSpace, deploymentName, errStr)
				if strings.Contains(errStr, "not found") {
					deleteIsTrue = true
				}
			}
		}
	}

	responseDto.Status = 200
	responseDto.Message = utils.GetI18nLang(lang, "success")
	c.Data["json"] = responseDto
	c.ServeJSON()
}

// Post ...
// @Title ScaleDeployment
// @Description scale Deployment
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.ScaleDeploymentRequestDto	 true	""
// @Success 200 {object} dto.BaseResponseDto
// @Failure 300 {object} dto.BaseResponseDto
// @router /scaleDeployment [post]
func (c *DeploymentController) ScaleDeployment() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.ScaleDeploymentRequestDto
	var responseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	paramMap := make(map[string]interface{})

	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &paramMap); err != nil {
		errorLogger.Println(err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("伸缩部署接口请求参数转map: ", paramMap)
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("伸缩部署接口请求参数转结构体: ", requestDto)

	if _, ok := paramMap["replicasNum"]; !ok {
		responseDto.Message = "副本数量参数不能为空"
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	if paramMap["replicasNum"] == nil {
		responseDto.Message = "副本数量参数值类型有误"
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	// 正则校验副本数量只能输入0-100,包括0和100的数字
	replicasNumMatched, err := regexp.MatchString("^^(?:[1-9]?\\d|100)$", strconv.Itoa(requestDto.ReplicasNum))
	if err != nil {
		errorLogger.Printf("根据部署名称%s验证副本数量值匹配正则表达式时发生异常，错误信息: %s", requestDto.DeploymentName, err.Error())
		responseDto.Message = err.Error()
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	if !replicasNumMatched {
		responseDto.Message = "副本数量校验失败，只能输入0至100以內的整数,包括0和100"
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	if strings.TrimSpace(requestDto.NameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	if strings.TrimSpace(requestDto.DeploymentName) == "" {
		errorLogger.Println("部署名称不能为空")
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	//查询集群所有命名空间信息
	allNameSpaceList, err := utils.GetClusterAllNameSpaces(lang)
	infoLogger.Println(allNameSpaceList)
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "getClusterAllNamespacesFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, requestDto.NameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		responseDto.Message = utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		responseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	// 应用资源的可用部署数量校验
	var allDeployReplicasNum, availableDeployNum int32
	if deployNum, err := getAllDeployReplicasNum(lang, requestDto.NameSpace, requestDto.DeploymentName, int32(requestDto.ReplicasNum), k8sClient); err == nil {
		allDeployReplicasNum = deployNum
	}
	if resourceQuotaResourceLimitData, err := utils.GetResourceQuotaResourceLimitData(requestDto.NameSpace, lang); err == nil {
		availableDeployNum = int32(resourceQuotaResourceLimitData.AvailableDeploy)
	}
	// default、paas空间不需要校验，availableDeployNum数量为0，所以需要加上availableDeployNum大于0的判断
	if availableDeployNum > 0 && availableDeployNum < allDeployReplicasNum {
		errorLogger.Printf("%s空间应用资源的可用部署数量%s小于当前所有部署中伸缩副本数量%s，无法进行伸缩", requestDto.NameSpace, availableDeployNum, allDeployReplicasNum)
		responseDto.Message = utils.GetI18nLang(lang, "scaleDeploymentFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	//deployment, err := k8sClient.AppsV1().Deployments(requestDto.NameSpace).Get(requestDto.DeploymentName, metav1.GetOptions{})
	scale, err := k8sClient.AppsV1().Deployments(requestDto.NameSpace).GetScale(requestDto.DeploymentName, metav1.GetOptions{})
	if err != nil {
		errorLogger.Printf("根据%s空间获取部署%s的副本数量失败: %s", requestDto.NameSpace, requestDto.DeploymentName, err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "scaleDeploymentFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	replicasNum := int32(requestDto.ReplicasNum)
	infoLogger.Printf("伸缩前的副本数量: %s; 当前需要伸缩的副本数量: %s", replicasNum, scale.Spec.Replicas)
	//deployment.Spec.Replicas = &replicasNum
	scale.Spec.Replicas = replicasNum

	//_, err = k8sClient.AppsV1().Deployments(requestDto.NameSpace).Update(deployment)
	_, err = k8sClient.AppsV1().Deployments(requestDto.NameSpace).UpdateScale(requestDto.DeploymentName, scale)
	if err != nil {
		errorLogger.Printf("根据部署名称%s伸缩副本数量时发生异常: %s", requestDto.DeploymentName, err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "scaleDeploymentFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	responseDto.Status = 200
	responseDto.Message = utils.GetI18nLang(lang, "success")
	c.Data["json"] = responseDto
	c.ServeJSON()
}

// Post ...
// @Title QueryDeploymentDetails
// @Description query DeploymentDetails
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.DeploymentRequestDto	true	""
// @Success 200 {object} dto.BaseResultResponseDto
// @Failure 300 {object} dto.BaseResponseDto
// @router /queryDeploymentDetails [post]
func (c *DeploymentController) QueryDeploymentDetails() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.DeploymentRequestDto
	var errorResponseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	var successResponseDto = dto.BaseResultResponseDto{}
	successResponseDto.Status = 200
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("部署详情查询接口请求参数: ", requestDto)

	nameSpace := requestDto.NameSpace
	deploymentName := requestDto.DeploymentName
	if strings.TrimSpace(nameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	if strings.TrimSpace(deploymentName) == "" {
		errorLogger.Println("部署名称不能为空")
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	//查询集群所有命名空间信息
	allNameSpaceList, err := utils.GetClusterAllNameSpaces(lang)
	infoLogger.Println(allNameSpaceList)
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getClusterAllNamespacesFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		errorResponseDto.Message = utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		errorResponseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	//查询deployment详情
	deploymentInfo, err := k8sClient.AppsV1().Deployments(nameSpace).Get(deploymentName, metav1.GetOptions{})
	if err != nil {
		errorLogger.Printf("查询集群%s空间%s的deployment详情失败: %s", nameSpace, deploymentName, err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getDeploymentInfo_getTheDeploymentInfoFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	infoLogger.Println(deploymentInfo.Name)
	infoLogger.Println(deploymentInfo.Namespace)
	infoLogger.Println(deploymentInfo.CreationTimestamp)
	deploymentLabels := deploymentInfo.ObjectMeta.Labels
	deploymentAnnotations := deploymentInfo.ObjectMeta.Annotations
	deploymentSelector := deploymentInfo.Spec.Selector.MatchLabels
	infoLogger.Println(deploymentLabels)
	infoLogger.Println(deploymentAnnotations)
	infoLogger.Println(deploymentSelector)
	infoLogger.Println(string(deploymentInfo.Spec.Strategy.Type))
	infoLogger.Printf("%d desired | %d updated | %d total | %d available | %d unavailable",
		deploymentInfo.Spec.Replicas, deploymentInfo.Status.ReadyReplicas, deploymentInfo.Status.Replicas,
		deploymentInfo.Status.AvailableReplicas, deploymentInfo.Status.UnavailableReplicas)

	// 版本
	version := "-"
	if ver, ok := deploymentLabels["version"]; ok {
		version = ver
	}

	// 状态
	state := -1
	// 未运行
	if deploymentInfo.Status.AvailableReplicas == 0 {
		state = 0
	}
	// 运行中
	if (deploymentInfo.Status.UpdatedReplicas == deploymentInfo.Status.AvailableReplicas) && (deploymentInfo.Status.AvailableReplicas != 0) {
		state = 1
	}
	// 正在伸缩
	if (deploymentInfo.Status.UpdatedReplicas != deploymentInfo.Status.AvailableReplicas) && (deploymentInfo.Status.AvailableReplicas != 0) {
		state = 2
	}

	deploy := deployment.GetDeploymentInfoResultDataResponseDto{
		deploymentInfo.Name,
		deploymentInfo.Namespace,
		deploymentInfo.CreationTimestamp.Format("2006-01-02 15:04:05"),
		deploymentLabels,
		deploymentAnnotations,
		deploymentSelector,
		string(deploymentInfo.Spec.Strategy.Type),
		*deploymentInfo.Spec.Replicas,
		version,
		state,
		*deploymentInfo.Spec.Replicas,
		deploymentInfo.Status.ReadyReplicas,
		deploymentInfo.Status.Replicas,
		deploymentInfo.Status.AvailableReplicas,
		deploymentInfo.Status.UnavailableReplicas,
	}
	successResponseDto.Result = deploy
	c.Data["json"] = successResponseDto
	c.ServeJSON()
}

// Post ...
// @Title GetDeploymentDetailsForEdit
// @Description get deployment details for edit
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.DeploymentRequestDto	true	""
// @Success 200 {object} dto.BaseResultResponseDto
// @Failure 300 {object} dto.BaseResponseDto
// @router /getDeploymentDetailsForEdit [post]
func (c *DeploymentController) GetDeploymentDetailsForEdit() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.DeploymentRequestDto
	var errorResponseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	var successResponseDto = dto.BaseResultResponseDto{}
	successResponseDto.Status = 200
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("部署编辑详情查询接口请求参数: ", requestDto)

	nameSpace := requestDto.NameSpace
	deploymentName := requestDto.DeploymentName
	if strings.TrimSpace(nameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	if strings.TrimSpace(deploymentName) == "" {
		errorLogger.Println("部署名称不能为空")
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	//查询集群所有命名空间信息
	allNameSpaceList, err := utils.GetClusterAllNameSpaces(lang)
	infoLogger.Println(allNameSpaceList)
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getClusterAllNamespacesFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		errorResponseDto.Message = utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		errorResponseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	//查询deployment详情
	deploymentInfo, err := k8sClient.AppsV1().Deployments(nameSpace).Get(deploymentName, metav1.GetOptions{})
	if err != nil {
		errorLogger.Printf("查询集群%s空间%s的deployment详情失败: %s", nameSpace, deploymentName, err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "getDeploymentInfo_getTheDeploymentInfoFail")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}

	deploymentInfo.APIVersion = "apps/v1"
	deploymentInfo.Kind = "Deployment"
	var deploymentYaml string
	deploymentByte, err := yaml.Marshal(deploymentInfo)
	if err != nil {
		errorLogger.Printf("部署编辑详情转换yaml失败: %s", err.Error())
		errorResponseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = errorResponseDto
		c.ServeJSON()
		return
	}
	deploymentYaml = string(deploymentByte)
	infoLogger.Println("\n" + deploymentYaml)
	successResponseDto.Result = deploymentYaml
	c.Data["json"] = successResponseDto
	c.ServeJSON()

}

// Post ...
// @Title CheckDeploymentDetailsForEdit
// @Description check deployment content
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.DeploymentValidRequestDto	true	""
// @Success 200 {object} dto.BaseResponseDto
// @Failure 300 {object} dto.BaseResponseDto
// @router /checkDeploymentContent [post]
func (c *DeploymentController) CheckDeploymentContent() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.DeploymentValidRequestDto
	var responseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("部署校验接口请求参数: ", requestDto)

	deploymentOptions := v1.Deployment{}
	// 复制字段
	utils.StructCopy(&deploymentOptions, &requestDto)

	// 校验请求参数
	if err := validDeploymentContent(lang, requestDto.NameSpace, requestDto.OperateType, deploymentOptions); err != nil {
		errorLogger.Printf("校验部署内容请求参数失败: %s", err.Error())
		responseDto.Message = err.Error()
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	responseDto.Status = 200
	responseDto.Message = utils.GetI18nLang(lang, "success")
	c.Data["json"] = responseDto
	c.ServeJSON()
}

// Post ...
// @Title SaveDeploymentDetailsForEdit
// @Description save deployment details for edit
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.DeploymentEditRequestDto	true	""
// @Success 200 {object} dto.BaseResponseDto
// @Failure 300 {object} dto.BaseResponseDto
// @router /saveDeploymentDetailsForEdit [post]
func (c *DeploymentController) SaveDeploymentDetailsForEdit() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.DeploymentEditRequestDto
	var responseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("部署编辑保存接口请求参数: ", requestDto)

	nameSpace := requestDto.NameSpace
	oldDeploymentName := requestDto.DeploymentName
	deploymentOptions := v1.Deployment{}
	// 复制字段
	utils.StructCopy(&deploymentOptions, &requestDto)

	// 校验请求参数
	if err := checkDeploymentParams(lang, nameSpace, oldDeploymentName, deploymentOptions); err != nil {
		errorLogger.Printf("校验编辑保存部署请求参数失败: %s", err.Error())
		responseDto.Message = err.Error()
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	deploymentName := deploymentOptions.ObjectMeta.Name

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		responseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	// 应用资源的可用部署数量校验
	var allDeployReplicasNum, availableDeployNum int32
	if deployNum, err := getAllDeployReplicasNum(lang, nameSpace, deploymentName, *deploymentOptions.Spec.Replicas, k8sClient); err == nil {
		allDeployReplicasNum = deployNum
	}
	// default、paas空间不需要校验，availableDeployNum数量为0，所以需要加上availableDeployNum大于0的判断
	if resourceQuotaResourceLimitData, err := utils.GetResourceQuotaResourceLimitData(nameSpace, lang); err == nil {
		availableDeployNum = int32(resourceQuotaResourceLimitData.AvailableDeploy)
	}
	if availableDeployNum > 0 && availableDeployNum < allDeployReplicasNum {
		errorLogger.Printf("%s空间应用资源的可用部署数量%s小于当前所有部署中伸缩副本数量%s，无法编辑更新部署", requestDto.NameSpace, availableDeployNum, allDeployReplicasNum)
		responseDto.Message = utils.GetI18nLang(lang, "outOfReplicasRange")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	//查询deployment是否存在
	if _, err := k8sClient.AppsV1().Deployments(nameSpace).Get(deploymentName, metav1.GetOptions{}); err != nil {
		errorLogger.Printf("更新查询集群%s空间%s的deployment详情失败: %s", nameSpace, deploymentName, err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "getDeploymentInfo_getTheDeploymentInfoFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	} else {
		//存在则更新deployment
		if _, err := k8sClient.AppsV1().Deployments(nameSpace).Update(&deploymentOptions); err != nil {
			errorLogger.Printf("更新集群%s空间%s的deployment失败: %s", nameSpace, deploymentOptions, err.Error())
			responseDto.Message = strings.Join([]string{utils.GetI18nLang(lang, "saveDeploymentResource_updateDeploymentFail"), err.Error()}, ",")
			c.Data["json"] = responseDto
			c.ServeJSON()
			return
		}
		infoLogger.Printf("更新集群%s空间%s的deployment成功", nameSpace, deploymentOptions)
	}

	responseDto.Status = 200
	responseDto.Message = utils.GetI18nLang(lang, "success")
	c.Data["json"] = responseDto
	c.ServeJSON()
}

// Post ...
// @Title CreateDeployment
// @Description create deployment
// @Param	lang		query 	string	true	"api result language type"
// @Param	body		body 	deployment.DeploymentCreateRequestDto	true	""
// @Success 200 {object} dto.BaseResponseDto
// @Failure 300 {object} dto.BaseResponseDto
// @router /createDeployment [post]
func (c *DeploymentController) CreateDeployment() {
	lang := c.GetString("lang")
	infoLogger.Println("语言: ", lang)
	var requestDto deployment.DeploymentCreateRequestDto
	var responseDto = dto.BaseResponseDto{300, utils.GetI18nLang(lang, "sysError")}
	infoLogger.Println("部署新建接口转换前的请求参数: ", string(c.Ctx.Input.RequestBody))
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestDto); err != nil {
		errorLogger.Println(err.Error())
		responseDto.Message = utils.GetI18nLang(lang, "requestParamIncorrectFormat")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}
	infoLogger.Println("部署新建接口转换后的请求参数: ", requestDto)

	nameSpace := requestDto.NameSpace
	deploymentOptions := v1.Deployment{}
	// 复制字段
	utils.StructCopy(&deploymentOptions, &requestDto)

	// 校验请求参数
	if err := createDeploymentValid(lang, nameSpace, deploymentOptions); err != nil {
		errorLogger.Printf("校验保存部署请求参数失败: %s", err.Error())
		responseDto.Message = err.Error()
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	deploymentName := deploymentOptions.ObjectMeta.Name

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		responseDto.Message = utils.GetI18nLang(lang, "createK8sConFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return
	}

	//查询deployment是否存在
	if _, err := k8sClient.AppsV1().Deployments(nameSpace).Get(deploymentName, metav1.GetOptions{}); err != nil {
		errStr := err.Error()
		errorLogger.Printf("查询集群%s空间%s的deployment详情失败: %s", nameSpace, deploymentName, errStr)
		if !strings.Contains(errStr, "not found") {
			responseDto.Message = utils.GetI18nLang(lang, "getDeploymentInfo_getTheDeploymentInfoFail")
			c.Data["json"] = responseDto
			c.ServeJSON()
			return
		}

		if deploymentOptions.ObjectMeta.Labels == nil {
			deploymentOptions.ObjectMeta.Labels = map[string]string{}
		}
		if deploymentOptions.Spec.Selector == nil {
			deploymentOptions.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{}}
		}
		if deploymentOptions.Spec.Selector.MatchLabels == nil {
			deploymentOptions.Spec.Selector.MatchLabels = map[string]string{}
		}
		if deploymentOptions.Spec.Template.Labels == nil {
			deploymentOptions.Spec.Template.Labels = map[string]string{}
		}
		label := nameSpace + "-deployment-" + deploymentName
		// 添加label 使用命名空间+资源名称+deploy名称作为key 用于防止service根据
		// selector查询deploy时label的key重复 不能查询所有的deploy
		deploymentOptions.ObjectMeta.Labels[label] = label
		deploymentOptions.Spec.Selector.MatchLabels[label] = label
		deploymentOptions.Spec.Template.Labels[label] = label

		// 应用资源的可用部署数量校验
		var allDeployReplicasNum, availableDeployNum int32
		if deployNum, err := getAllDeployReplicasNum(lang, nameSpace, deploymentName, *deploymentOptions.Spec.Replicas, k8sClient); err == nil {
			allDeployReplicasNum = deployNum
		}
		if resourceQuotaResourceLimitData, err := utils.GetResourceQuotaResourceLimitData(nameSpace, lang); err == nil {
			availableDeployNum = int32(resourceQuotaResourceLimitData.AvailableDeploy)
		}
		// default、paas空间不需要校验，availableDeployNum数量为0，所以需要加上availableDeployNum大于0的判断
		if availableDeployNum > 0 && availableDeployNum < allDeployReplicasNum {
			errorLogger.Printf("%s空间应用资源的可用部署数量%s小于当前所有部署中伸缩副本数量%s，无法创建部署", requestDto.NameSpace, availableDeployNum, allDeployReplicasNum)
			responseDto.Message = utils.GetI18nLang(lang, "outOfReplicasRange")
			c.Data["json"] = responseDto
			c.ServeJSON()
			return
		}

		//不存在则创建deployment
		_, err := k8sClient.AppsV1().Deployments(nameSpace).Create(&deploymentOptions)
		if err != nil {
			errorLogger.Printf("创建集群%s空间%s的deployment失败: %s", nameSpace, deploymentName, err.Error())
			responseDto.Message = utils.GetI18nLang(lang, "saveDeploymentResource_createDeploymentFail") + err.Error()
			c.Data["json"] = responseDto
			c.ServeJSON()
			return
		}
		infoLogger.Printf("创建集群%s空间%s的deployment成功", nameSpace, deploymentName)

	} else {
		//存在则提示
		errorLogger.Printf("%s空间名为%s的deployment已存在，无法创建", nameSpace, deploymentName)
		responseDto.Message = utils.GetI18nLang(lang, "saveDeploymentResource_createDeploymentFail")
		c.Data["json"] = responseDto
		c.ServeJSON()
		return

	}

	responseDto.Status = 200
	responseDto.Message = utils.GetI18nLang(lang, "success")
	c.Data["json"] = responseDto
	c.ServeJSON()

}

// 校验部署编辑的请求参数
func checkDeploymentParams(lang string, nameSpace string, oldDeploymentName string, deploymentOptions v1.Deployment) error {

	if strings.TrimSpace(nameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	//查询集群所有命名空间信息
	allNameSpaceList, err := utils.GetClusterAllNameSpaces(lang)
	infoLogger.Println(allNameSpaceList)
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "getClusterAllNamespacesFail"))
	}
	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		return errors.New(utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster"))
	}

	if strings.TrimSpace(deploymentOptions.TypeMeta.APIVersion) == "" ||
		!utils.IsContains([]string{"apps/v1", "extensions/v1beta1"}, strings.TrimSpace(deploymentOptions.TypeMeta.APIVersion)) {
		errorLogger.Println("ApiVersion值有误")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	if strings.TrimSpace(deploymentOptions.TypeMeta.Kind) == "" || strings.TrimSpace(deploymentOptions.TypeMeta.Kind) != "Deployment" {
		errorLogger.Println("Kind值有误")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	newDeploymentName := deploymentOptions.ObjectMeta.Name
	if newDeploymentName != oldDeploymentName {
		errorLogger.Println("部署名称不能修改")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	deploymentNameSpace := deploymentOptions.ObjectMeta.Namespace
	if deploymentNameSpace != nameSpace {
		errorLogger.Println("命名空间必须与当前命名空间一致")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	return nil
}

// 部署创建校验
func createDeploymentValid(lang string, nameSpace string, deploymentOptions v1.Deployment) error {

	if strings.TrimSpace(nameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	//查询集群所有命名空间信息
	allNameSpaceList, err := utils.GetClusterAllNameSpaces(lang)
	infoLogger.Println(allNameSpaceList)
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "getClusterAllNamespacesFail"))
	}
	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		return errors.New(utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster"))
	}

	deploymentNameSpace := deploymentOptions.ObjectMeta.Namespace
	if strings.TrimSpace(deploymentNameSpace) != "" && deploymentNameSpace != nameSpace {
		errorLogger.Println("命名空间必须与当前命名空间一致")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	/**
	基础配置校验
		名称：只能包含小写字母、数字和横杠-，且必须以字母和数字开头和结尾，长度为2-50
		版本：只能包含小写字母、数字、横杠-和小数点，且最大长度为20个字符
		容器镜像：只能包含大小写字母、数字、斜线、横杠和小数点，且必须以字母开头，长度为2-128字符
		副本数量：0-100，且必须为整数
		容器端口：最多只能添加5个，名称校验：只能包含小写字母、数字和横杠-，长度1-15个字符，端口号校验1-65535
	*/
	if utils.IsNil(deploymentOptions.ObjectMeta) {
		errorLogger.Println("ObjectMeta is nil")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	if len([]rune(deploymentOptions.ObjectMeta.Name)) < 2 || len([]rune(deploymentOptions.ObjectMeta.Name)) > 50 {
		errorLogger.Println("名称长度范围2-50")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	nameMatched, err := regexp.MatchString("^[a-z0-9]+([-]*[a-z0-9]+)*$", deploymentOptions.ObjectMeta.Name)
	if err != nil {
		errorLogger.Println("名称正则校验异常")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	if !nameMatched {
		errorLogger.Println("名称正则校验失败")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	if utils.IsNil(deploymentOptions.TypeMeta) {
		errorLogger.Println("TypeMeta is nil")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	labelsMap := deploymentOptions.ObjectMeta.Labels
	if name, ok := labelsMap["app"]; ok {
		//errorLogger.Println("基础配置中的名称不能为空")
		//return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		if name != "" {
			if len([]rune(name)) < 2 || len([]rune(name)) > 50 {
				errorLogger.Println("基础配置中的名称长度范围2-50")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}

			labelNameMatched, err := regexp.MatchString("^[a-z0-9]+([-]*[a-z0-9]+)*$", name)
			if err != nil {
				errorLogger.Println("基础配置中的名称正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !labelNameMatched {
				errorLogger.Println("基础配置中的名称正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}

	}

	if version, ok := labelsMap["version"]; ok {
		//errorLogger.Println("基础配置中的版本不能为空")
		//return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		if version != "" {
			if len([]rune(version)) > 20 {
				errorLogger.Println("基础配置中的版本最大长度为20")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}

			versionMatched, err := regexp.MatchString("^[a-z0-9\\.-]*$", version)
			if err != nil {
				errorLogger.Println("基础配置中的版本正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !versionMatched {
				errorLogger.Println("基础配置中的版本正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}
	}
	infoLogger.Println(deploymentOptions.Spec.Template.Spec.Containers)
	if len(deploymentOptions.Spec.Template.Spec.Containers) <= 0 {
		errorLogger.Println("DeploymentSpec is nil")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	container := deploymentOptions.Spec.Template.Spec.Containers[0]

	if len([]rune(container.Image)) < 2 || len([]rune(container.Image)) > 128 {
		errorLogger.Println("容器镜像长度范围为2-128")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	imageMatched, err := regexp.MatchString("^[a-zA-Z]+[a-zA-Z0-9-/\\.:]+$", container.Image)
	if err != nil {
		errorLogger.Println("容器镜像正则校验异常")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	if !imageMatched {
		errorLogger.Println("容器镜像正则校验失败")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	// 正则校验副本数量只能输入0-100,包括0和100的数字
	replicasMatched, err := regexp.MatchString("^^(?:[1-9]?\\d|100)$", utils.Int32ToString(*deploymentOptions.Spec.Replicas))
	if err != nil {
		errorLogger.Println("副本数量正则校验异常")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	if !replicasMatched {
		errorLogger.Println("副本数量正则校验失败")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	ports := container.Ports
	if len(ports) > 5 {
		errorLogger.Println("容器端口最多只能添加5个")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	for _, port := range ports {
		if len([]rune(port.Name)) < 1 || len([]rune(port.Name)) > 15 {
			errorLogger.Println("容器端口名称长度范围为1-15")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		portNameMatched, err := regexp.MatchString("^[a-z0-9-]*[a-z]+[a-z0-9-]*$", port.Name)
		if err != nil {
			errorLogger.Println("容器端口名称正则校验异常")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		if !portNameMatched {
			errorLogger.Println("容器端口名称正则校验失败")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		containerPortMatched, err := regexp.MatchString("^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", utils.Int32ToString(port.ContainerPort))
		if err != nil {
			errorLogger.Println("容器端口号正则校验异常")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		if !containerPortMatched {
			errorLogger.Println("容器端口号正则校验失败")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
	}

	/**
	资源分配校验（可跳过）
		资源申请，CPU单位为m，1000m=1核，内存单位为Mi，1000Mi=1G，cpu最小10m，最大10000m，内存最小10Mi，最大50000Mi
		资源限制，资源限制必须大于等于资源申请，最小和最大值与资源申请一致
	*/
	if !utils.IsNil(container.Resources) {
		// 资源申请
		requestsMap := container.Resources.Requests
		var requestCpu, requestMemory int
		for k, v := range requestsMap {
			if string(k) == "cpu" {
				infoLogger.Println("资源申请CPU为：", v.String())
				cpuVal := strings.ReplaceAll(v.String(), "m", "")
				if cpuNum, err := strconv.Atoi(cpuVal); err == nil {
					if cpuNum < 10 || cpuNum > 10000 {
						errorLogger.Println("资源申请CPU数值范围有误")
						return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
					}
					requestCpu = cpuNum
				}
			} else if string(k) == "memory" {
				infoLogger.Println("资源申请内存为：", v.String())
				memoryVal := strings.ReplaceAll(v.String(), "Mi", "")
				if memoryNum, err := strconv.Atoi(memoryVal); err == nil {
					if memoryNum < 10 || memoryNum > 50000 {
						errorLogger.Println("资源申请内存数值范围有误")
						return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
					}
					requestMemory = memoryNum
				}
			}
		}

		// 资源限制
		limitsMap := container.Resources.Limits
		var limitCpu, limitMemory int
		for k, v := range limitsMap {
			if string(k) == "cpu" {
				infoLogger.Println("资源限制CPU为：", v.String())
				cpuVal := strings.ReplaceAll(v.String(), "m", "")
				if cpuNum, err := strconv.Atoi(cpuVal); err == nil {
					if cpuNum < 10 || cpuNum > 10000 {
						errorLogger.Println("资源限制CPU数值范围有误")
						return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
					}
					limitCpu = cpuNum
				}
			} else if string(k) == "memory" {
				infoLogger.Println("资源限制内存为：", v.String())
				memoryVal := strings.ReplaceAll(v.String(), "Mi", "")
				if memoryNum, err := strconv.Atoi(memoryVal); err == nil {
					if memoryNum < 10 || memoryNum > 50000 {
						errorLogger.Println("资源限制内存数值范围有误")
						return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
					}
					limitMemory = memoryNum
				}
			}
		}

		if limitCpu < requestCpu || limitMemory < requestMemory {
			errorLogger.Println("资源限制CPU、内存数值必须大于等于资源申请的CPU、内存数值")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
	}

	/**
	健康检查校验（可跳过）
		就绪探针（ReadinessProbe）表示pod是否以及处于可接受service请求的状态。
		存活探针（LivenessProbe）表示pod运行是否正常，如果不正常将会重启pod。
		不管是就绪探针还是存活探针，探针策略和更多参数都是相同的。
		HTTP策略（httpGet）当根据路径和端口，调用接口其响应代码在200~400之间，设为成功
			路径和端口，路径必须以斜线/开头，且长度为1-100小写和数字字符，该策略只接受Get请求
			端口号校验1-65536
		TCP策略（tcpSocket）执行一个TCP检查使用container的IP地址和指定的端口作为socket。如果端口处于打开状态视为成功
			端口，端口号校验1-65535
		Exec策略（Exec）在container中执行指定的命令。当其执行成功时，将其退出码设置为0，表示成功
			命令，支持添加多个，每行一个，长度1-200字符，个数1-20
		更多参数
			首次探测时间（initialDelaySeconds）：用来表示初始化延迟的时间，也就是告诉监测从多久之后开始运行，单位是秒
			探测超时（timeoutSeconds）: 用来表示监测的超时时间，如果超过这个时长后，则认为监测失败，默认1秒，最小1秒
			探测频率（ periodSeconds ）： 循环执行探测的频率。默认是10秒/次，最小1秒。
			探测成功认定次数（successThreshold）： 探测 失败后检查成功的最小连续成功次数。默认为1.活跃度必须为1。最小值为1。
			探测失败认定次数（failureThreshold）： 探测失败的重试次数，重试一定次数后将认为失败 ， 默认是3。最小值是1
	*/
	// 就绪探针
	readinessProbe := container.ReadinessProbe
	if !utils.IsNil(readinessProbe) {
		if !utils.IsNil(readinessProbe.HTTPGet) {
			path := readinessProbe.HTTPGet.Path
			if len([]rune(path)) < 1 || len([]rune(path)) > 100 {
				errorLogger.Println("就绪探针中HTTP策略路径长度范围为1-100")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			pathMatched, err := regexp.MatchString("^[/]([a-z0-9]+[/]*[a-z0-9]*)*$", path)
			if err != nil {
				errorLogger.Println("就绪探针中HTTP策略路径正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !pathMatched {
				errorLogger.Println("就绪探针中HTTP策略路径正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			port := readinessProbe.HTTPGet.Port.IntVal
			portMatched, err := regexp.MatchString("^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", utils.Int32ToString(port))
			if err != nil {
				errorLogger.Println("就绪探针中HTTP策略端口号正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !portMatched {
				errorLogger.Println("就绪探针中HTTP策略端口号正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}

		if !utils.IsNil(readinessProbe.TCPSocket) {
			port := readinessProbe.TCPSocket.Port.IntVal
			portMatched, err := regexp.MatchString("^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", utils.Int32ToString(port))
			if err != nil {
				errorLogger.Println("就绪探针中TCP策略端口号正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !portMatched {
				errorLogger.Println("就绪探针中TCP策略端口号正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}

		if !utils.IsNil(readinessProbe.Exec) {
			command := readinessProbe.Exec.Command
			if len(command) < 1 || len(command) > 20 {
				errorLogger.Println("就绪探针中Exec策略命令行个数范围为1-20")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			for _, commandStr := range command {
				if len([]rune(commandStr)) < 1 || len([]rune(commandStr)) > 200 {
					errorLogger.Println("就绪探针中Exec策略命令每行字符长度范围为1-200")
					return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
				}
			}

		}

		if readinessProbe.FailureThreshold != 0 && readinessProbe.PeriodSeconds != 0 && readinessProbe.SuccessThreshold != 0 && readinessProbe.TimeoutSeconds != 0 {
			if readinessProbe.FailureThreshold < 1 || readinessProbe.PeriodSeconds < 1 || readinessProbe.SuccessThreshold < 1 || readinessProbe.TimeoutSeconds < 1 {
				errorLogger.Println("就绪探针更多参数中的探测超时、探测频率、探测成功认定次数、探测失败认定次数最小值为须为1")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}

	}

	// 存活探针
	livenessProbe := container.LivenessProbe
	if !utils.IsNil(livenessProbe) {
		if !utils.IsNil(livenessProbe.HTTPGet) {
			path := livenessProbe.HTTPGet.Path
			if len([]rune(path)) < 1 || len([]rune(path)) > 100 {
				errorLogger.Println("存活探针中HTTP策略路径长度范围为1-100")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			pathMatched, err := regexp.MatchString("^[/]([a-z0-9]+[/]*[a-z0-9]*)*$", path)
			if err != nil {
				errorLogger.Println("存活探针中HTTP策略路径正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !pathMatched {
				errorLogger.Println("存活探针中HTTP策略路径正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			port := livenessProbe.HTTPGet.Port.IntVal
			portMatched, err := regexp.MatchString("^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-6])$", utils.Int32ToString(port))
			if err != nil {
				errorLogger.Println("存活探针中HTTP策略端口号正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !portMatched {
				errorLogger.Println("存活探针中HTTP策略端口号正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}

		if !utils.IsNil(livenessProbe.TCPSocket) {
			port := livenessProbe.TCPSocket.Port.IntVal
			portMatched, err := regexp.MatchString("^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$", utils.Int32ToString(port))
			if err != nil {
				errorLogger.Println("存活探针中TCP策略端口号正则校验异常")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			if !portMatched {
				errorLogger.Println("存活探针中TCP策略端口号正则校验失败")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}

		if !utils.IsNil(livenessProbe.Exec) {
			command := livenessProbe.Exec.Command
			if len(command) < 1 || len(command) > 20 {
				errorLogger.Println("存活探针中Exec策略命令行个数范围为1-20")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
			for _, commandStr := range command {
				if len([]rune(commandStr)) < 1 || len([]rune(commandStr)) > 200 {
					errorLogger.Println("存活探针中Exec策略命令每行字符长度范围为1-200")
					return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
				}
			}

		}
		if livenessProbe.FailureThreshold != 0 && livenessProbe.PeriodSeconds != 0 && livenessProbe.SuccessThreshold != 0 && livenessProbe.TimeoutSeconds != 0 {
			if livenessProbe.FailureThreshold < 1 || livenessProbe.PeriodSeconds < 1 || livenessProbe.SuccessThreshold < 1 || livenessProbe.TimeoutSeconds < 1 {
				errorLogger.Println("存活探针更多参数中的探测超时、探测频率、探测成功认定次数、探测失败认定次数最小值为须为1")
				return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
			}
		}
	}

	/**
	环境变量校验
		环境变量是指定义声明pod中需要使用到的环境变量键值对，k8s本身除了文本字符串以外，还支持引用configmap、secret中的值，这里我们第一个版本稍微简化一些，只引用字符串。
		环境变量最多支持添加20个键值对
		环境变量可添加可移除
		环境变量名称，只能包含、大小写字母、数字、下划线_、横杠-、小数点.，并且不能以数字开头，长度为1-40
		环境变量值，只有长度校验，长度范围为1-40
	*/
	env := container.Env // 环境变量数组
	if len(env) > 20 {
		errorLogger.Println("环境变量最多只能添加20个")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	// 环境变量名称数组
	envName := []string{}
	for _, envVar := range env {
		if len([]rune(envVar.Name)) < 1 || len([]rune(envVar.Name)) > 40 {
			errorLogger.Println("环境变量名称字符长度范围为1-40")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		envNameMatched, err := regexp.MatchString("^[a-zA-Z-_\\.]+[a-zA-Z0-9-_\\.]*$", envVar.Name)
		if err != nil {
			errorLogger.Println("环境变量名称正则校验异常")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		if !envNameMatched {
			errorLogger.Println("环境变量名称正则校验失败")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		if len([]rune(envVar.Value)) < 1 || len([]rune(envVar.Value)) > 40 {
			errorLogger.Println("环境变量值字符长度范围为1-40")
			return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
		}
		envName = append(envName, envVar.Name)
	}
	infoLogger.Println("环境变量名称数组: ", envName)
	// 去重后的环境变量名称数组
	newEnvName := utils.RemoveDuplicatesAndEmpty(envName)
	infoLogger.Println("去重后的环境变量名称数组: ", newEnvName)
	if len(envName) != len(newEnvName) {
		errorLogger.Println("环境变量名称须保持唯一，不可重复")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	return nil
}

// 部署校验
func validDeploymentContent(lang string, nameSpace string, operateType string, deploymentOptions v1.Deployment) (err error) {
	if strings.TrimSpace(nameSpace) == "" {
		errorLogger.Println("命名空间不能为空")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}
	//查询集群所有命名空间信息
	allNameSpaceList, err := utils.GetClusterAllNameSpaces(lang)
	infoLogger.Println(allNameSpaceList)
	if err != nil {
		errorLogger.Printf("查询集群所有命名空间失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "getClusterAllNamespacesFail"))
	}
	if len(allNameSpaceList) > 0 && !utils.IsContains(allNameSpaceList, nameSpace) {
		errorLogger.Println("集群不存在此命名空间")
		return errors.New(utils.GetI18nLang(lang, "theNameSpaceNotExistInCluster"))
	}
	if !utils.IsContains([]string{"update", "create"}, operateType) {
		errorLogger.Println("操作类型operateType的值只能为更新update和创建create")
		return errors.New(utils.GetI18nLang(lang, "requestParamIncorrectFormat"))
	}

	// 转换yaml格式
	yamlBytes, err := yaml.Marshal(deploymentOptions)
	if err != nil {
		errorLogger.Printf("转换yaml失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "checkDeploymentParams_invalidDeploymentFormat"))
	}
	infoLogger.Println("\n" + string(yamlBytes))

	decode := scheme.Codecs.UniversalDeserializer()
	_, _, err = decode.Decode(yamlBytes, nil, nil)
	if err != nil {
		errorLogger.Printf("转换yaml文件失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "checkDeploymentParams_invalidDeploymentFormat"))
	}
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New(utils.GetI18nLang(lang, "createK8sConFail"))
	}

	if operateType == "update" {
		err = k8sClient.AppsV1().RESTClient().Put().
			SetHeader("Accept", "application/json; dry-run").
			SetHeader("Content-Type", "application/json; verify").
			Param("dryRun", "All").
			Namespace(nameSpace).
			Resource("deployments").
			Name(deploymentOptions.ObjectMeta.Name).
			Body(&deploymentOptions).
			Do().Error()
	} else if operateType == "create" {
		err = k8sClient.AppsV1().RESTClient().Post().
			SetHeader("Accept", "application/json; dry-run").
			SetHeader("Content-Type", "application/json; verify").
			Param("dryRun", "All").
			Namespace(nameSpace).
			Resource("deployments").
			Body(&deploymentOptions).
			Do().Error()
	}

	if err != nil {
		infoLogger.Printf("校验运行失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "checkDeploymentParams_invalidDeploymentFormat"))
	}

	return nil
}

// 查询命名空间下所有deployment的可伸缩副本数量
func getAllDeployReplicasNum(lang string, nameSpace string, deployName string, scaleReplicasNum int32, k8sClient *kubernetes.Clientset) (int32, error) {
	// 先获取命名空间下所有deployment信息
	deploymentList, err := k8sClient.AppsV1().Deployments(nameSpace).List(metav1.ListOptions{})
	if err != nil {
		errorLogger.Printf("查询集群%s空间所有deployment失败: %s", nameSpace, err.Error())
		return 0, errors.New(utils.GetI18nLang(lang, "getDeploymentListByNameSpaceFail"))
	}
	var replicasNum int32
	// 循环累加所有部署中的副本数量，但是需去除要伸缩的那个部署中的副本数量
	for _, item := range deploymentList.Items {
		if item.Name == deployName {
			continue
		}
		replicasNum += *item.Spec.Replicas
	}
	// 累加后再加上现在要伸缩的副本数量
	replicasNum += scaleReplicasNum

	return replicasNum, nil
}
