cue eval *.cue
cue export *.cue --out yaml
We can do loop in Cuelang: Official documentation on loop
In the official documentation, it's a loop on a list, in our case, we want a loop on the sub-field port of our deployments.
The template deployments:
deployments: [Name=_]: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: Name
labels: {
app: Name
domain: string | *"prod"
}
}
}
The port isn't present in the template because is optional, so we need a condition inside the loop. The official documention on conditional fields.
The loop:
for name, dep in deployments {
if dep["ports"] != _|_ {
First line: it's a key/value loop on deployments:
- name: name of the deployment
- dep: the data of a deployment
Second line: we test if the field port exist with if dep["ports"] != _|_
.
The _|_
is bottom, it's an error or missing field (the documentation on Values):
At the bottom of the lattice is the value called bottom, denoted _|_. A bottom value usually indicates an error. Bottom is an instance of every value.
Important:
Don't use the name of a field as variable of the loop (name and dep in the example). Otherwise, the loop acts strangely.
Then we need to create an element **services** and to use the loop to create every **service**
The template services:
services: [Name=_]: {
apiVersion: "apps/v1"
kind: "Service"
}
and the loop:
for name, dep in deployments {
if dep["ports"] != _|_ {
services: "\(name)": {
spec: selector: dep.metadata.labels
spec: ports: [
for p in dep.ports {
port: *p | int
targetPort: *p | int
},
]
}
}
}
dep refer to the data of the deployment and services to the template of service:
for name, dep in deployments
: a loop on every deploymentif dep["ports"] != _|_
: only if the field ports exist in the deploymentservices: "\(name)":
it will create a new service with the name of the deployment (name come from the loop)spec: selector: dep.metadata.labels
: we use the labels of the deployment as selector of the servicespec: ports: [
: we add a field ports in the new servicefor p in dep.ports {
: second loop to map every portsport: *p | int
andtargetPort: *p | int
to add source and target port in the service definition
- the deployments original and changed haven't any port
- the deployment exposed have ports 8080 and 50