# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/expose.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
  annotations:
    definition.oam.dev/description: Expose port to enable web traffic for your component.
  name: expose
  namespace: {{ include "systemDefinitionNamespace" . }}
spec:
  appliesToWorkloads:
    - deployments.apps
    - statefulsets.apps
  podDisruptive: false
  schematic:
    cue:
      template: |
        import (
        	"strconv"
        	"strings"
        )

        outputs: service: {
        	apiVersion: "v1"
        	kind:       "Service"
        	metadata: name:        context.name
        	metadata: annotations: parameter.annotations
        	spec: {
        		if parameter["matchLabels"] == _|_ {
        			selector: "app.oam.dev/component": context.name
        		}
        		if parameter["matchLabels"] != _|_ {
        			selector: parameter["matchLabels"]
        		}

        		// compatible with the old way
        		if parameter["port"] != _|_ if parameter["ports"] == _|_ {
        			ports: [
        				for p in parameter.port {
        					name:       "port-" + strconv.FormatInt(p, 10)
        					port:       p
        					targetPort: p
        				},
        			]
        		}
        		if parameter["ports"] != _|_ {
        			ports: [ for v in parameter.ports {
        				port:       v.port
        				targetPort: v.port
        				if v.name != _|_ {
        					name: v.name
        				}
        				if v.name == _|_ {
        					_name: "port-" + strconv.FormatInt(v.port, 10)
        					name:  *_name | string
        					if v.protocol != "TCP" {
        						name: _name + "-" + strings.ToLower(v.protocol)
        					}
        				}
        				if v.nodePort != _|_ if parameter.type == "NodePort" {
        					nodePort: v.nodePort
        				}
        				if v.protocol != _|_ {
        					protocol: v.protocol
        				}
        			},
        			]
        		}
        		type: parameter.type
        	}
        }
        parameter: {
        	// +usage=Deprecated, the old way to specify the exposion ports
        	port?: [...int]

        	// +usage=Specify portsyou want customer traffic sent to
        	ports?: [...{
        		// +usage=Number of port to expose on the pod's IP address
        		port: int
        		// +usage=Name of the port
        		name?: string
        		// +usage=Protocol for port. Must be UDP, TCP, or SCTP
        		protocol: *"TCP" | "UDP" | "SCTP"
        		// +usage=exposed node port. Only Valid when exposeType is NodePort
        		nodePort?: int
        	}]

        	// +usage=Specify the annotations of the exposed service
        	annotations: [string]: string

        	matchLabels?: [string]: string

        	// +usage=Specify what kind of Service you want. options: "ClusterIP","NodePort","LoadBalancer","ExternalName"
        	type: *"ClusterIP" | "NodePort" | "LoadBalancer" | "ExternalName"
        }
  stage: PostDispatch
  status:
    customStatus: |-
      message: *"" | string
      service: context.outputs.service
      if service.spec.type == "ClusterIP" {
      	message: "ClusterIP: \(service.spec.clusterIP)"
      }
      if service.spec.type == "LoadBalancer" {
      	status: service.status
      	isHealth: *false | bool
      	if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
      		isHealth: true
      	}
      	if !isHealth {
      		message: "ExternalIP: Pending"
      	}
      	if isHealth {
      		message: "ExternalIP: \(status.loadBalancer.ingress[0].ip)"
      	}
      }
    healthPolicy: |-
      service: context.outputs.service
      if service.spec.type == "LoadBalancer" {
      	status: service.status
      	isHealth: *false | bool
      	if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
      		isHealth: true
      	}
      }
      if service.spec.type != "LoadBalancer" {
      	isHealth: true
      }

