github.com/oam-dev/kubevela@v1.9.11/vela-templates/definitions/internal/trait/gateway.cue (about)

     1  import "strconv"
     2  
     3  gateway: {
     4  	type: "trait"
     5  	annotations: {}
     6  	labels: {}
     7  	description: "Enable public web traffic for the component, the ingress API matches K8s v1.20+."
     8  	attributes: {
     9  		podDisruptive: false
    10  		appliesToWorkloads: ["deployments.apps", "statefulsets.apps"]
    11  
    12  		status: {
    13  			customStatus: #"""
    14  				let nameSuffix = {
    15  				  if parameter.name != _|_ { "-" + parameter.name }
    16  				  if parameter.name == _|_ { "" }
    17  				}
    18  				let ingressMetaName = context.name + nameSuffix
    19  				let ig  = [for i in context.outputs if (i.kind == "Ingress") && (i.metadata.name == ingressMetaName) {i}][0]
    20  				igs: *null | string
    21  				if ig != _|_ if ig.status != _|_ if ig.status.loadbalancer != _|_ {
    22  				  igs: ig.status.loadbalancer.ingress[0]
    23  				}
    24  				igr: *null | string
    25  				if ig != _|_ if ig.spec != _|_  {
    26  				  igr: ig.spec.rules[0]
    27  				}
    28  				if igs == _|_ {
    29  				  message: "No loadBalancer found, visiting by using 'vela port-forward " + context.appName + "'\n"
    30  				}
    31  				if igs != _|_ {
    32  				  if igs.ip != _|_ {
    33  				    if igr.host != _|_ {
    34  				      message: "Visiting URL: " + igr.host + ", IP: " + igs.ip + "\n"
    35  				    }
    36  				    if igr.host == _|_ {
    37  				      message: "Host not specified, visit the cluster or load balancer in front of the cluster, IP: " + igs.ip + "\n"
    38  				    }
    39  				  }
    40  				  if igs.ip == _|_ {
    41  				    if igr.host != _|_ {
    42  				      message: "Visiting URL: " + igr.host + "\n"
    43  				    }
    44  				    if igs.host == _|_ {
    45  				      message: "Host not specified, visit the cluster or load balancer in front of the cluster\n"
    46  				    }
    47  				  }
    48  				}
    49  				"""#
    50  			healthPolicy: #"""
    51  				let nameSuffix = {
    52  				  if parameter.name != _|_ { "-" + parameter.name }
    53  				  if parameter.name == _|_ { "" }
    54  				}
    55  				let ingressMetaName = context.name + nameSuffix
    56  				let igstat  = len([for i in context.outputs if (i.kind == "Ingress") && (i.metadata.name == ingressMetaName) {i}]) > 0
    57  				isHealth: igstat
    58  				"""#
    59  		}
    60  	}
    61  }
    62  template: {
    63  	let nameSuffix = {
    64  		if parameter.name != _|_ {"-" + parameter.name}
    65  		if parameter.name == _|_ {""}
    66  	}
    67  
    68  	let serviceMetaName = {
    69  		if (parameter.existingServiceName != _|_) {parameter.existingServiceName}
    70  		if (parameter.existingServiceName == _|_) {context.name + nameSuffix}
    71  	}
    72  
    73  	if (parameter.existingServiceName == _|_) {
    74  		let serviceOutputName = "service" + nameSuffix
    75  		outputs: (serviceOutputName): {
    76  			apiVersion: "v1"
    77  			kind:       "Service"
    78  			metadata: name: "\(serviceMetaName)"
    79  			spec: {
    80  				selector: "app.oam.dev/component": context.name
    81  				ports: [
    82  					for k, v in parameter.http {
    83  						name:       "port-" + strconv.FormatInt(v, 10)
    84  						port:       v
    85  						targetPort: v
    86  					},
    87  				]
    88  			}
    89  		}
    90  	}
    91  
    92  	let ingressOutputName = "ingress" + nameSuffix
    93  	let ingressMetaName = context.name + nameSuffix
    94  	legacyAPI: context.clusterVersion.minor < 19
    95  
    96  	outputs: (ingressOutputName): {
    97  		if legacyAPI {
    98  			apiVersion: "networking.k8s.io/v1beta1"
    99  		}
   100  		if !legacyAPI {
   101  			apiVersion: "networking.k8s.io/v1"
   102  		}
   103  		kind: "Ingress"
   104  		metadata: {
   105  			name: "\(ingressMetaName)"
   106  			annotations: {
   107  				if !parameter.classInSpec {
   108  					"kubernetes.io/ingress.class": parameter.class
   109  				}
   110  				if parameter.gatewayHost != _|_ {
   111  					"ingress.controller/host": parameter.gatewayHost
   112  				}
   113  				if parameter.annotations != _|_ {
   114  					for key, value in parameter.annotations {
   115  						"\(key)": "\(value)"
   116  					}
   117  				}
   118  			}
   119  			labels: {
   120  				if parameter.labels != _|_ {
   121  					for key, value in parameter.labels {
   122  						"\(key)": "\(value)"
   123  					}
   124  				}
   125  			}
   126  		}
   127  		spec: {
   128  			if parameter.classInSpec {
   129  				ingressClassName: parameter.class
   130  			}
   131  			if parameter.secretName != _|_ {
   132  				tls: [{
   133  					hosts: [
   134  						parameter.domain,
   135  					]
   136  					secretName: parameter.secretName
   137  				}]
   138  			}
   139  			rules: [{
   140  				if parameter.domain != _|_ {
   141  					host: parameter.domain
   142  				}
   143  				http: paths: [
   144  					for k, v in parameter.http {
   145  						path:     k
   146  						pathType: parameter.pathType
   147  						backend: {
   148  							if legacyAPI {
   149  								serviceName: serviceMetaName
   150  								servicePort: v
   151  							}
   152  							if !legacyAPI {
   153  								service: {
   154  									name: serviceMetaName
   155  									port: number: v
   156  								}
   157  							}
   158  						}
   159  					},
   160  				]
   161  			}]
   162  		}
   163  	}
   164  
   165  	parameter: {
   166  		// +usage=Specify the domain you want to expose
   167  		domain?: string
   168  
   169  		// +usage=Specify the mapping relationship between the http path and the workload port
   170  		http: [string]: int
   171  
   172  		// +usage=Specify the class of ingress to use
   173  		class: *"nginx" | string
   174  
   175  		// +usage=Set ingress class in '.spec.ingressClassName' instead of 'kubernetes.io/ingress.class' annotation.
   176  		classInSpec: *false | bool
   177  
   178  		// +usage=Specify the secret name you want to quote to use tls.
   179  		secretName?: string
   180  
   181  		// +usage=Specify the host of the ingress gateway, which is used to generate the endpoints when the host is empty.
   182  		gatewayHost?: string
   183  
   184  		// +usage=Specify a unique name for this gateway, required to support multiple gateway traits on a component
   185  		name?: string
   186  
   187  		// +usage=Specify a pathType for the ingress rules, defaults to "ImplementationSpecific"
   188  		pathType: *"ImplementationSpecific" | "Prefix" | "Exact"
   189  
   190  		// +usage=Specify the annotations to be added to the ingress
   191  		annotations?: [string]: string
   192  
   193  		// +usage=Specify the labels to be added to the ingress
   194  		labels?: [string]: string
   195  
   196  		// +usage=If specified, use an existing Service rather than creating one
   197  		existingServiceName?: string
   198  	}
   199  }