package models

import (
	"encoding/json"
	"errors"
	"github.com/astaxie/beego/logs"
	"k8s-console/dto/ingress"
	"k8s-console/utils"
	_ "k8s.io/api/core/v1"
	"k8s.io/api/extensions/v1beta1"
	metalV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes/scheme"
	"log"
	"regexp"
	"sigs.k8s.io/yaml"
	"sort"
	"strconv"
	"strings"
)

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

type IngressBean struct {
	Name       string   `json:"name"`
	Hosts      []string `json:"hosts"`
	Ports      []string `json:"ports"`
	ExternalIP string   `json:"externalIP"`
	CreateTime string   `json:"createTime"`
}

type IngressDetailBean struct {
	Name        string      `json:"name"`
	NameSpace   string      `json:"nameSpace"`
	Labels      interface{} `json:"labels"`
	Annotations interface{} `json:"annotations"`
	Rules       []HostBean  `json:"rules"`
}
type HostBean struct {
	Host         string   `json:"host"`
	Paths        []string `json:"paths"`
	ServiceNames []string `json:"serviceNames"`
	ServicePorts []string `json:"servicePorts"`
}

type IngressDetailByGui struct {
	Namespace   string            `json:"namespace"`
	Name        string            `json:"name"`
	Annotations map[string]string `json:"annotations"`
	IsHttps     bool              `json:"isHttps"`
	SecretName  string            `json:"secretName"`
	Rules       []RuleDetailGui
}

type RuleDetailGui struct {
	Host        string `json:"host"`
	Path        string `json:"path"`
	ServiceName string `json:"serviceName"`
	ServicePort string `json:"servicePort"`
}

//type PathBean struct {
//	Path        string `json:"path"`
//	ServiceName string `json:"serviceName"`
//	ServicePort string `json:"servicePort"`
//}

type ServiceConfingInfoBean struct {
	ServiceNames  []string               `json:"serviceNames"`
	ServiceConfig []ServiceNamePortsBean `json:"serviceConfig"`
}

type ServiceNamePortsBean struct {
	ServiceName  string   `json:"serviceName"`
	ServicePorts []string `json:"servicePorts"`
}

type TUdpIngressBean struct {
	ExposurePort string `json:"exposurePort"`
	NameSpace    string `json:"nameSpace"`
	ServiceName  string `json:"serviceName"`
	ServicePort  string `json:"servicePort"`
}

type TUdpIngressSlice []TUdpIngressBean

func (a TUdpIngressSlice) Len() int { // 重写 Len() 方法
	return len(a)
}
func (a TUdpIngressSlice) Swap(i, j int) { // 重写 Swap() 方法
	a[i], a[j] = a[j], a[i]
}
func (a TUdpIngressSlice) Less(i, j int) bool { // 重写 Less() 方法， 从大到小排序
	atoj, _ := strconv.Atoi(a[j].ExposurePort)
	btoi, _ := strconv.Atoi(a[i].ExposurePort)
	return atoj < btoi
}

func GetAllIngress(ns, lang string) ([]IngressBean, error) {
	var beans []IngressBean
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return nil, errors.New("连接k8s集群失败")
	}
	list, err := k8sClient.ExtensionsV1beta1().Ingresses(ns).List(metalV1.ListOptions{})
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	for _, v := range list.Items {
		bean := IngressBean{}
		bean.Name = v.Name
		rules := v.Spec.Rules
		arrTls := v.Spec.TLS

		hosts := []string{}
		ports := []string{}
		for _, b := range rules {
			hosts = append(hosts, b.Host)
		}
		for _, t := range arrTls {
			tlsHosts := t.Hosts
			for _, tl := range tlsHosts {
				hosts = append(hosts, tl)
			}
		}
		if len(rules) >= 1 {
			ports = append(ports, "80")
		}
		if len(arrTls) >= 1 {
			ports = append(ports, "443")
		}
		bean.Hosts = hosts
		bean.Ports = ports
		bean.ExternalIP = "<none>"
		//utils.ParseDateToString(lang, v.CreationTimestamp.Time)
		creationTimestamp := utils.GetDurationToString(lang, v.CreationTimestamp.Time, true)
		if err != nil {
			log.Println(err.Error())
			return nil, err
		}
		bean.CreateTime = creationTimestamp
		beans = append(beans, bean)
	}
	return beans, nil
}

/**
  删除ingress服务
*/
func DeleteIngress(ingressName, ns string) error {
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New("连接k8s集群失败")
	}
	err := k8sClient.ExtensionsV1beta1().Ingresses(ns).Delete(ingressName, &metalV1.DeleteOptions{})
	return err
}

/**
  根据ingressName获取负载均衡详情
*/
func GetIngressDetailByName(ingressName, ns string) (*IngressDetailBean, error) {

	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		log.Printf("获取k8s集群失败")
		return nil, errors.New("连接k8s集群失败")
	}
	ingressResult, err := k8sClient.ExtensionsV1beta1().Ingresses(ns).Get(ingressName, metalV1.GetOptions{})
	if err != nil {
		log.Printf("根据名称：%s 获取详情失败：%s", ingressName, err.Error())
		return nil, err
	}
	ingressDetailbean := IngressDetailBean{}

	arrLabel := map[string]string{}
	arrAnnos := map[string]string{}
	ingressDetailbean.Name = ingressName
	ingressDetailbean.NameSpace = ingressResult.Namespace
	mapLabels := ingressResult.Labels
	for k, v := range mapLabels {
		//label := k + ":" + v
		//arrLabel = append(arrLabel, label)
		arrLabel[k] = v
	}
	mapAnnos := ingressResult.Annotations
	for k, v := range mapAnnos {
		//anno := k + ":" + v
		//arrAnnos = append(arrAnnos, anno)
		arrAnnos[k] = v
	}
	ingressDetailbean.Labels = arrLabel
	ingressDetailbean.Annotations = arrAnnos

	rules := ingressResult.Spec.Rules
	var arrHost []HostBean
	for _, bean := range rules {
		hostBean := HostBean{}
		hostBean.Host = bean.Host

		var arrPath []string
		var arrServiceName []string
		var arrServicePort []string
		//var arrPath []PathBean
		paths := bean.HTTP.Paths
		for _, p := range paths {
			arrPath = append(arrPath, p.Path)
			arrServiceName = append(arrServiceName, p.Backend.ServiceName)
			arrServicePort = append(arrServicePort, p.Backend.ServicePort.String())
		}
		hostBean.Paths = arrPath
		hostBean.ServiceNames = arrServiceName
		hostBean.ServicePorts = arrServicePort
		arrHost = append(arrHost, hostBean)
	}
	ingressDetailbean.Rules = arrHost

	return &ingressDetailbean, nil
}

/**
  负载均衡 编辑接口
*/
func EditIngressByName(ingressName, ns string) (map[string]interface{}, error) {
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		log.Printf("获取k8s集群失败")
		return nil, errors.New("连接k8s集群失败")
	}
	ingressResult, err := k8sClient.ExtensionsV1beta1().Ingresses(ns).Get(ingressName, metalV1.GetOptions{})
	if err != nil {
		log.Printf("根据名称：%s 获取详情失败：%s", ingressName, err.Error())
		return nil, err
	}
	ingressResult.APIVersion = "extensions/v1beta1"
	ingressResult.Kind = "Ingress"
	var ingressMap map[string]interface{}
	if ingressByte, err := json.Marshal(ingressResult); err != nil {
		log.Printf("转换byte失败: %s", err.Error())
	} else {
		if err := json.Unmarshal(ingressByte, &ingressMap); err != nil {
			log.Printf("转换map失败: %s", err.Error())
		}
	}
	if len(ingressMap) > 0 {
		metadataMap := ingressMap["metadata"].(map[string]interface{})
		delete(metadataMap, "selfLink")
		delete(metadataMap, "uid")
		delete(metadataMap, "resourceVersion")
		delete(metadataMap, "generation")
		delete(metadataMap, "creationTimestamp")
	}
	//	log.Println(ingressMap)
	return ingressMap, nil
}

/**
  负载均衡校验接口，修改/保存之前都需要校验
*/
func CheckIngressContent(lang string, nameSpace string, operateType string, ingressOptions v1beta1.Ingress) 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(ingressOptions)
	if err != nil {
		errorLogger.Printf("转换yaml失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "checkServiceParams_invalidServiceFormat"))
	}
	infoLogger.Println(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, "checkServiceParams_invalidServiceFormat"))
	}
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New(utils.GetI18nLang(lang, "createK8sConFail"))
	}
	if "update" == operateType {
		err = k8sClient.ExtensionsV1beta1().RESTClient().Put().
			SetHeader("Accept", "application/json; dry-run").
			SetHeader("Content-Type", "application/json; verify").
			Namespace(nameSpace).
			Resource("ingresses").
			Name(ingressOptions.Name).
			Body(&ingressOptions).
			Param("dryRun", "All").
			Do().Error()
	} else if "create" == operateType {
		err = k8sClient.ExtensionsV1beta1().RESTClient().Post().
			SetHeader("Accept", "application/json; dry-run").
			SetHeader("Content-Type", "application/json; verify").
			Namespace(nameSpace).
			Resource("ingresses").
			Body(&ingressOptions).
			Param("dryRun", "All").
			Do().Error()
	}
	if err != nil {
		infoLogger.Printf("校验运行失败: %s", err.Error())
		return errors.New(utils.GetI18nLang(lang, "checkIngressParams_invalidIngressFormat"))
	}
	return nil
}

/**
  创建负载均衡服务
*/
func SaveAndupdateIngress(lang string, nameSpace string, operateType string, ingressOptions v1beta1.Ingress) error {

	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New(utils.GetI18nLang(lang, "createK8sConFail"))
	}
	ingressName := ingressOptions.Name
	if "update" == operateType {
		//更新service
		if _, err := k8sClient.ExtensionsV1beta1().Ingresses(nameSpace).Update(&ingressOptions); err != nil {
			errStr := err.Error()
			errorLogger.Printf("更新集群%s空间%s service失败: %s", nameSpace, ingressName, errStr)
			if !strings.Contains(errStr, "not found") {
				var errMsg = ""
				errMsg = utils.GetI18nLang(lang, "updateIngressResource_updateIngressFail")
				if m, _ := regexp.MatchString(".*([iI]nvalid).*", errStr); m {
					errMsg = utils.GetI18nLang(lang, "checkIngressParams_invalidIngressFormat")
				}
				return errors.New(errMsg)
			}
		}
		infoLogger.Printf("更新集群%s空间%s ingress成功", nameSpace, ingressName)
	} else if "create" == operateType {
		//查询ingress是否存在
		_, err := k8sClient.ExtensionsV1beta1().Ingresses(nameSpace).Get(ingressName, metalV1.GetOptions{})
		if err == nil {
			errorLogger.Printf("集群%s空间%s ingress已存在", nameSpace, ingressName)

			return errors.New(utils.GetI18nLang(lang, "saveIngressResource_ingressAlreadyExists"))
		}
		errStr := err.Error()
		if !strings.Contains(errStr, "not found") {
			errorLogger.Printf("查询集群%s空间%s  ingress 详情失败: %s", nameSpace, ingressName, errStr)

			return errors.New(utils.GetI18nLang(lang, "getIngressInfo_Fail"))
		}
		infoLogger.Printf("查询集群%s空间%s ingress详情返回结果: %s", nameSpace, ingressName, errStr)

		//创建ingress
		if _, err = k8sClient.ExtensionsV1beta1().Ingresses(nameSpace).Create(&ingressOptions); err != nil {
			errStr := err.Error()
			errorLogger.Printf("创建集群%s空间%s ingress失败: %s", nameSpace, ingressName, errStr)

			return errors.New(errStr)
		}
	}
	return nil
}

func WatchIngressLinster(nameSpace string) error {
	var lang = "zh"
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New(utils.GetI18nLang(lang, "createK8sConFail"))
	}
	watch, e := k8sClient.ExtensionsV1beta1().Ingresses(nameSpace).Watch(metalV1.ListOptions{})
	if e != nil {
		return e
	}
	resultChan := watch.ResultChan()
	ev := <-resultChan
	log.Println("=================watch===")
	log.Println(ev.Type)
	log.Println(ev.Object.DeepCopyObject())

	return nil
}

/**
  获取service服务名称和对应的端口列表
*/
func GetServiceNamePortsConfigInfo(ns string) (*ServiceConfingInfoBean, error) {
	var bean ServiceConfingInfoBean
	var lang = "zh"
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return nil, errors.New(utils.GetI18nLang(lang, "createK8sConFail"))
	}
	infos, e := GetServiceConfigInfo(ns)
	var serviceNames []string
	var serviceConfig []ServiceNamePortsBean
	if e == nil {
		if len(infos) > 0 {
			for _, b := range infos {
				serviceNames = append(serviceNames, b.ServiceName)
				bean := ServiceNamePortsBean{}
				bean.ServiceName = b.ServiceName
				bean.ServicePorts = b.ServicePorts
				serviceConfig = append(serviceConfig, bean)
			}
		}
	}
	bean.ServiceNames = serviceNames
	bean.ServiceConfig = serviceConfig
	return &bean, nil
}

/**
  获取四层负载 列表
*/
func GetTUdpIngressList(flag string, px string) ([]TUdpIngressBean, error) {
	beans := []TUdpIngressBean{}
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return nil, errors.New(utils.GetI18nLang("zh", "createK8sConFail"))
	}
	if "TCP" == flag || "tcp" == flag {
		tcpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-tcp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询tcp 负载 失败", e.Error())
			return beans, e
		}
		tcpData := tcpConfigMap.Data
		for k, v := range tcpData {
			bean := TUdpIngressBean{}
			bean.ExposurePort = k
			splits := strings.Split(v, ":")
			bean.ServicePort = splits[1]
			splitSer := strings.Split(splits[0], "/")
			bean.NameSpace = splitSer[0]
			bean.ServiceName = splitSer[1]
			//logs.Info(k,v)
			beans = append(beans, bean)
		}
	} else if "UDP" == flag || "udp" == flag {
		udpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-udp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询udp 负载 失败", e.Error())
			return beans, e
		}
		udpData := udpConfigMap.Data
		for k, v := range udpData {
			bean := TUdpIngressBean{}
			bean.ExposurePort = k
			splits := strings.Split(v, ":")
			bean.ServicePort = splits[1]
			splitSer := strings.Split(splits[0], "/")
			bean.NameSpace = splitSer[0]
			bean.ServiceName = splitSer[1]
			//logs.Info(k,v)
			beans = append(beans, bean)
		}
	}
	if "asc" == px {
		//端点升序   从小到大
		sort.Sort(sort.Reverse(TUdpIngressSlice(beans)))
	} else if "desc" == px {
		// 从大到小
		sort.Sort(TUdpIngressSlice(beans))
	}
	return beans, nil
}

/**
  四层负载详情接口
*/
func GetTUdpDetail(exposurePort string, flag string) (*TUdpIngressBean, error) {
	bean := TUdpIngressBean{}
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return nil, errors.New(utils.GetI18nLang("zh", "createK8sConFail"))
	}
	if "TCP" == flag || "tcp" == flag {
		tcpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-tcp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询tcp负载失败", e.Error())
			return &bean, e
		}
		tcpData := tcpConfigMap.Data
		for k, v := range tcpData {
			if k == exposurePort {
				bean.ExposurePort = k
				splits := strings.Split(v, ":")
				bean.ServicePort = splits[1]
				splitSer := strings.Split(splits[0], "/")
				bean.NameSpace = splitSer[0]
				bean.ServiceName = splitSer[1]
				break
			}
		}
	} else if "UDP" == flag || "udp" == flag {
		udpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-udp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询udp负载失败", e.Error())
			return &bean, e
		}
		udpData := udpConfigMap.Data
		for k, v := range udpData {
			if k == exposurePort {
				bean.ExposurePort = k
				splits := strings.Split(v, ":")
				bean.ServicePort = splits[1]
				splitSer := strings.Split(splits[0], "/")
				bean.NameSpace = splitSer[0]
				bean.ServiceName = splitSer[1]
				break
			}
		}
	}
	return &bean, nil
}

/**
  添加TCP/UDP 四层负载
*/
func AddTUdpIngress(lang string, reqtParam ingress.AddTUdpIngressRequestDto) error {
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New(utils.GetI18nLang("zh", "createK8sConFail"))
	}
	if strings.Contains(reqtParam.ServicePort, "(") {
		// 格式为：http(8080)  存在name值，不用port值
		index := strings.Index(reqtParam.ServicePort, "(")
		str := reqtParam.ServicePort[0:index]
		reqtParam.ServicePort = str
	} else {
		if utils.IsNumber(reqtParam.ServicePort) {
			reqtParam.ServicePort = reqtParam.ServicePort
		}
	}
	logs.Info("四层负载servicePor:", reqtParam.ServicePort)
	if "TCP" == reqtParam.ProtocalType || "tcp" == reqtParam.ProtocalType {
		tcpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-tcp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询tcp负载失败", e.Error())
			return e
		}
		tcpData := tcpConfigMap.Data
		if tcpData == nil {
			tcpData = make(map[string]string)
		}
		for k, _ := range tcpData {
			if k == reqtParam.ExposurePort {
				return errors.New(utils.GetI18nLang(lang, "tudpCreate01"))
			}
		}
		k := reqtParam.ExposurePort
		v := reqtParam.NameSpace + "/" + reqtParam.ServiceName + ":" + reqtParam.ServicePort
		tcpData[k] = v
		tcpConfigMap.Kind = "ConfigMap"
		tcpConfigMap.APIVersion = "v1"
		tcpConfigMap.Data = tcpData
		_, e = k8sClient.CoreV1().ConfigMaps("kube-system").Update(tcpConfigMap)
		if e != nil {
			return e
		}
	} else if "UDP" == reqtParam.ProtocalType || "udp" == reqtParam.ProtocalType {
		udpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-udp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询udp负载失败", e.Error())
			return e
		}
		udpData := udpConfigMap.Data
		if udpData == nil {
			udpData = make(map[string]string)
		}
		for k, _ := range udpData {
			if k == reqtParam.ExposurePort {
				return errors.New("端点已存在")
			}
		}
		k := reqtParam.ExposurePort
		v := reqtParam.NameSpace + "/" + reqtParam.ServiceName + ":" + reqtParam.ServicePort
		udpData[k] = v
		udpConfigMap.Kind = "ConfigMap"
		udpConfigMap.APIVersion = "v1"
		udpConfigMap.Data = udpData
		_, e = k8sClient.CoreV1().ConfigMaps("kube-system").Update(udpConfigMap)
		if e != nil {
			return e
		}
	}
	return nil
}

/**
  删除 四层负载tcp/upd
*/
func DeleteTUdpIngress(lang, exporPort, protocalType string) error {
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New(utils.GetI18nLang("zh", "createK8sConFail"))
	}
	if "TCP" == protocalType || "tcp" == protocalType {
		tcpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-tcp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询tcp负载失败", e.Error())
			return e
		}
		delete(tcpConfigMap.Data, exporPort)
		_, e = k8sClient.CoreV1().ConfigMaps("kube-system").Update(tcpConfigMap)
		if e != nil {
			return e
		}
	} else if "UDP" == protocalType || "udp" == protocalType {
		udpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-udp", metalV1.GetOptions{})
		if e != nil {
			logs.Error("查询udp负载失败", e.Error())
			return e
		}
		delete(udpConfigMap.Data, exporPort)
		_, e = k8sClient.CoreV1().ConfigMaps("kube-system").Update(udpConfigMap)
		if e != nil {
			return e
		}
	}
	return nil
}

/**
  修改TCP/UDP 四层负载
*/
func UpdateTUdpIngress(lang string, origExport string, origProtocalType string, reqtParam ingress.AddTUdpIngressRequestDto) error {
	exposurePort := reqtParam.ExposurePort
	if origExport != exposurePort {
		return errors.New(utils.GetI18nLang(lang, "tudapUpdate01"))
	}
	// 获取k8s客户端
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		return errors.New(utils.GetI18nLang("zh", "createK8sConFail"))
	}
	if strings.Contains(reqtParam.ServicePort, "(") {
		// 格式为：http(8080)  存在name值，不用port值
		index := strings.Index(reqtParam.ServicePort, "(")
		str := reqtParam.ServicePort[0:index]
		reqtParam.ServicePort = str
	} else {
		if utils.IsNumber(reqtParam.ServicePort) {
			reqtParam.ServicePort = reqtParam.ServicePort
		}
	}
	logs.Info("修改四层负载servicePor:", reqtParam.ServicePort)
	if origProtocalType == reqtParam.ProtocalType {
		//修改时，负载协议为改变
		logs.Info("修改时暴露端口：", exposurePort, "协议未修改")
		isExsit := false
		if "TCP" == reqtParam.ProtocalType || "tcp" == reqtParam.ProtocalType {
			tcpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-tcp", metalV1.GetOptions{})
			if e != nil {
				logs.Error("查询tcp负载失败", e.Error())
				return e
			}
			tcpData := tcpConfigMap.Data
			if tcpData == nil {
				tcpData = make(map[string]string)
			}
			for k, _ := range tcpData {
				if k == exposurePort {
					isExsit = true
				}
			}
			if isExsit {
				s := tcpData[exposurePort]
				s = reqtParam.NameSpace + "/" + reqtParam.ServiceName + ":" + reqtParam.ServicePort
				tcpData[exposurePort] = s

				tcpConfigMap.Data = tcpData
				_, e := k8sClient.CoreV1().ConfigMaps("kube-system").Update(tcpConfigMap)
				if e != nil {
					return errors.New(utils.GetI18nLang("zh", "tudapUpdate03"))
				}
				return nil
			} else {
				return errors.New(utils.GetI18nLang(lang, "tudapUpdate02"))
			}
		} else if "UDP" == reqtParam.ProtocalType || "udp" == reqtParam.ProtocalType {
			udpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-udp", metalV1.GetOptions{})
			if e != nil {
				logs.Error("查询udp负载失败", e.Error())
				return e
			}
			udpData := udpConfigMap.Data
			if udpData == nil {
				udpData = make(map[string]string)
			}
			for k, _ := range udpData {
				if k == exposurePort {
					isExsit = true
				}
			}
			if isExsit {
				s := udpData[exposurePort]
				s = reqtParam.NameSpace + "/" + reqtParam.ServiceName + ":" + reqtParam.ServicePort
				udpData[exposurePort] = s

				udpConfigMap.Data = udpData
				_, e := k8sClient.CoreV1().ConfigMaps("kube-system").Update(udpConfigMap)
				if e != nil {
					return errors.New(utils.GetI18nLang("zh", "tudapUpdate03"))
				}
				return nil
			} else {
				return errors.New(utils.GetI18nLang(lang, "tudapUpdate02"))
			}
		}
	} else {
		// 修改时协议被修改了
		logs.Info("修改时暴露端口：", exposurePort, "协议被修改")
		isExsit := false
		if "TCP" == reqtParam.ProtocalType || "tcp" == reqtParam.ProtocalType {
			tcpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-tcp", metalV1.GetOptions{})
			if e != nil {
				logs.Error("查询tcp负载失败", e.Error())
				return e
			}
			tcpData := tcpConfigMap.Data
			if tcpData == nil {
				tcpData = make(map[string]string)
			}
			for k, _ := range tcpData {
				if k == exposurePort {
					isExsit = true
					break
				}
			}
			if isExsit {
				return errors.New(utils.GetI18nLang(lang, "tudapUpdate04"))
			} else {
				logs.Info("原origprotocalType:", origProtocalType, "--- 现在 protocalType :", reqtParam.ProtocalType)
				logs.Info("删除之前协议暴露端口数据", ",在修改的协议中添加一个暴露端口数据")
				tcpData[exposurePort] = reqtParam.NameSpace + "/" + reqtParam.ServiceName + ":" + reqtParam.ServicePort
				tcpConfigMap.Data = tcpData
				_, e := k8sClient.CoreV1().ConfigMaps("kube-system").Update(tcpConfigMap)
				//删除原协议暴露端口
				udpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-udp", metalV1.GetOptions{})
				if e != nil {
					logs.Error("查询udp负载失败", e.Error())
					return e
				}
				delete(udpConfigMap.Data, exposurePort)
				k8sClient.CoreV1().ConfigMaps("kube-system").Update(udpConfigMap)
				if e != nil {
					return errors.New(utils.GetI18nLang(lang, "tudapUpdate03"))
				}
			}
		} else if "UDP" == reqtParam.ProtocalType || "udp" == reqtParam.ProtocalType {
			udpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-udp", metalV1.GetOptions{})
			if e != nil {
				logs.Error("查询udp负载失败", e.Error())
				return e
			}
			udpData := udpConfigMap.Data
			if udpData == nil {
				udpData = make(map[string]string)
			}
			for k, _ := range udpData {
				if k == exposurePort {
					isExsit = true
					break
				}
			}
			if isExsit {
				return errors.New(utils.GetI18nLang(lang, "tudapUpdate04"))
			} else {
				logs.Info("原origprotocalType:", origProtocalType, "--- 现在 protocalType :", reqtParam.ProtocalType)
				logs.Info("删除之前协议暴露端口数据", ",在修改的协议中添加一个暴露端口数据")
				udpData[exposurePort] = reqtParam.NameSpace + "/" + reqtParam.ServiceName + ":" + reqtParam.ServicePort
				udpConfigMap.Data = udpData
				_, e := k8sClient.CoreV1().ConfigMaps("kube-system").Update(udpConfigMap)
				//删除原协议暴露端口
				tcpConfigMap, e := k8sClient.CoreV1().ConfigMaps("kube-system").Get("nginx-ingress-controller-tcp", metalV1.GetOptions{})
				if e != nil {
					logs.Error("查询udp负载失败", e.Error())
					return e
				}
				delete(tcpConfigMap.Data, exposurePort)
				k8sClient.CoreV1().ConfigMaps("kube-system").Update(tcpConfigMap)
				if e != nil {
					return errors.New(utils.GetI18nLang(lang, "tudapUpdate03"))
				}
			}
		}
	}
	return nil
}

/**
  根据负载均衡名称和名称空间   返回详情
*/
func GetIngressDetailToGui(ingressName, namespace string) (*IngressDetailByGui, error) {
	ingressDetal := IngressDetailByGui{}
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		log.Printf("获取k8s集群失败")
		return nil, errors.New("连接k8s集群失败")
	}
	ingressResult, err := k8sClient.ExtensionsV1beta1().Ingresses(namespace).Get(ingressName, metalV1.GetOptions{})
	if err != nil {
		log.Printf("根据名称：%s 获取详情失败：%s", ingressName, err.Error())
		return nil, err
	}
	ingressDetal.Name = ingressResult.Name
	ingressDetal.Namespace = ingressResult.Namespace
	ingressDetal.Annotations = ingressResult.Annotations
	ingressDetal.IsHttps = false
	ingressDetal.SecretName = ""
	rules := []RuleDetailGui{}
	for _, v := range ingressResult.Spec.Rules {
		rulebean := RuleDetailGui{}
		rulebean.Host = v.Host
		if len(v.HTTP.Paths) > 0 {
			rulebean.Path = v.HTTP.Paths[0].Path
			rulebean.ServiceName = v.HTTP.Paths[0].Backend.ServiceName
			rulebean.ServicePort = v.HTTP.Paths[0].Backend.ServicePort.String()
		}
		rules = append(rules, rulebean)
	}
	ingressDetal.Rules = rules
	if ingressResult.Spec.TLS != nil {
		ingressDetal.IsHttps = true
		secretName := ingressResult.Spec.TLS[0].SecretName
		ingressDetal.SecretName = secretName
	}
	return &ingressDetal, nil
}

/**
  获取 tls名称列表方法
*/
func GetTlsNames(ns string) ([]string, error) {
	tlsNames := []string{}
	k8sClient := utils.GetK8sClient()
	if k8sClient == nil {
		log.Printf("获取k8s集群失败")
		return tlsNames, errors.New("连接k8s集群失败")
	}
	tlsList, err := k8sClient.CoreV1().Secrets(ns).List(metalV1.ListOptions{FieldSelector: "type=kubernetes.io/tls"})
	if err != nil {
		logs.Error(err.Error())
		return tlsNames, err
	}
	for _, v := range tlsList.Items {
		tlsNames = append(tlsNames, v.Name)
	}
	//if "default" != ns {
	//	tlsNames = append(tlsNames, "k2-tls")
	//}
	return tlsNames, nil
}
