DodoApp: Support multiple ingresses per service

Change-Id: I76fbf92c152a7c8e12bbded51cb8fea07ea9c045
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index 15fc825..b3da1ea 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -94,7 +94,7 @@
 #AppIngress: {
 	network: string
 	subdomain: string
-	auth: #Auth
+	auth: #Auth | *{ enabled: false }
 	port: { name: string } | { value: number } | *{ name: "web" }
 
 	_network: networks[strings.ToLower(network)]
@@ -126,7 +126,7 @@
 #AppTmpl: {
 	name: string | *"app"
 	type: string
-	ingress?: #AppIngress // TODO(gio): make it a list
+	ingress?: [...#AppIngress]
 	expose: [...#PortDomain] | *[]
 	rootDir: string
 	runConfiguration: [...#Command]
@@ -233,7 +233,7 @@
 
 #HugoAppTmpl: #AppTmpl & {
 	type: _hugoLatest
-	ingress: #AppIngress
+	ingress: [#AppIngress, ...#AppIngress]
 	ports: [...#Port] | *[{
 		name: "web"
 		value: 1313
@@ -251,7 +251,7 @@
 			"--watch=false",
 			"--bind=0.0.0.0",
 			"--port=1313",
-			"--baseURL=\(ingress.baseURL)",
+			"--baseURL=\(ingress[0].baseURL)",
 			"--appendPort=false",
         ]
 		env: lastCmdEnv
@@ -422,24 +422,26 @@
 											 ])
 					ingress: {
 						if svc.ingress != _|_ {
-							"\(svc.name)": {
-								label: "App"
-								network: networks[strings.ToLower(svc.ingress.network)]
-								subdomain: svc.ingress.subdomain
-								auth: svc.ingress.auth
-								if input.cluster != _|_ {
-									cluster: input.cluster
-								}
-								service: {
-									name: "app-app"
-									if svc.ingress.port.name != _|_ {
-										port: name: svc.ingress.port.name
+							{for i, ingress in svc.ingress {
+								"\(svc.name)-\(i)": {
+									label: svc.name
+									network: networks[strings.ToLower(ingress.network)]
+									subdomain: ingress.subdomain
+									auth: ingress.auth
+									if input.cluster != _|_ {
+										cluster: input.cluster
 									}
-									if svc.ingress.port.value != _|_ {
-										port: number: svc.ingress.port.value
+									service: {
+										name: "\(svc.name)-app"
+										if ingress.port.name != _|_ {
+											port: name: ingress.port.name
+										}
+										if ingress.port.value != _|_ {
+											port: number: ingress.port.value
+										}
 									}
 								}
-							}
+							}}
 						}
 					}
 					images: {
@@ -545,30 +547,30 @@
 					"\(svc.name)": #WithOut & {
 						ingress: {
 							if svc.ingress != _|_ {
-								{
-								"\(svc.name)": {
-									label: "App"
-									network: networks[strings.ToLower(svc.ingress.network)]
-									subdomain: svc.ingress.subdomain
-									auth: svc.ingress.auth
-									service: {
-										name: _vmName
-										port: name: "web"
+								{for i, ingress in svc.ingress {
+									"\(svc.name)-\(i)": {
+										label: svc.name
+										network: networks[strings.ToLower(ingress.network)]
+										subdomain: ingress.subdomain
+										auth: ingress.auth
+										service: {
+											name: _vmName
+											port: name: "web" // TODO(gio): why is this hardcoded?
+										}
 									}
-								}
-								// TODO(gio): code should work even without svc ingress
-								code: {
-									label: "VS Code"
-									home: "/?folder=/home/\(svc.dev.username)/code"
-									network: networks[strings.ToLower(svc.ingress.network)]
-									subdomain: "code-\(svc.ingress.subdomain)"
-									auth: enabled: false
-									service: {
-										name: _vmName
-										port: name: _codeServerPortName
+									// TODO(gio): code should work even without svc ingress
+									"code-\(i)": {
+										label: "VS Code"
+										home: "/?folder=/home/\(svc.dev.username)/code"
+										network: networks[strings.ToLower(ingress.network)]
+										subdomain: "code-\(ingress.subdomain)"
+										auth: enabled: false
+										service: {
+											name: _vmName
+											port: name: _codeServerPortName
+										}
 									}
-								}
-									}
+								}}
 							}
 						}
 						vm: {
diff --git a/core/installer/app_test.go b/core/installer/app_test.go
index f0fe537..4238ff5 100644
--- a/core/installer/app_test.go
+++ b/core/installer/app_test.go
@@ -405,11 +405,11 @@
     name: "app"
 	type: "golang:1.22.0"
 	run: "main.go"
-	ingress: {
+	ingress: [{
 		network: "private"
 		subdomain: "testapp"
 		auth: enabled: false
-	}
+	}]
 	dev: {
 		enabled: false
 	}
@@ -456,11 +456,11 @@
     name: "app"
 	type: "golang:1.22.0"
 	run: "main.go"
-	ingress: {
+	ingress: [{
 		network: "private"
 		subdomain: "testapp"
 		auth: enabled: false
-	}
+	}]
 	dev: {
 		enabled: false
 	}
@@ -472,11 +472,11 @@
     name: "app"
 	type: "golang:1.20.0"
 	run: "main.go"
-	ingress: {
+	ingress: [{
 		network: "private"
 		subdomain: "testapp"
 		auth: enabled: false
-	}
+	}]
 	volume: ["data"]
 	dev: {
 		enabled: true
diff --git a/core/installer/dodo_app_test.go b/core/installer/dodo_app_test.go
index 1367c65..3501620 100644
--- a/core/installer/dodo_app_test.go
+++ b/core/installer/dodo_app_test.go
@@ -14,11 +14,11 @@
     name: "app"
 	type: "golang:1.20.0"
 	run: "main.go"
-	ingress: {
+	ingress: [{
 		network: "private"
 		subdomain: "testapp"
 		auth: enabled: false
-	}
+	}]
     source: repository: "ssh://foo.bar"
     ports: [{
         name: "a"
@@ -162,7 +162,7 @@
                     "name": "DODO_POSTGRESQL_DB_CONNECTION_URL"
                 }
             ],
-            "ingress": {
+            "ingress": [{
                 "network": "Private",
                 "subdomain": "foo",
                 "port": {
@@ -171,7 +171,16 @@
                 "auth": {
                     "enabled": false
                 }
-            },
+            }, {
+                "network": "Public",
+                "subdomain": "foo",
+                "port": {
+                    "name": "web"
+                },
+                "auth": {
+                    "enabled": false
+                }
+            }],
             "expose": [],
             "dev": { "enabled": true, "username": "gio" }
         }