Soft-Serve: ingress with port-forward

Change-Id: I44dcef24276a86902ad5fa7df2de24cc813b37a9
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 56129f5..44e39e6 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -188,9 +188,6 @@
 	data CueAppData,
 	opts ...soft.DoOption,
 ) (ReleaseResources, error) {
-	// if err := openPorts(rendered.Ports); err != nil {
-	// 	return err
-	// }
 	return ReleaseResources{}, repo.Do(func(r soft.RepoFS) (string, error) {
 		if err := r.RemoveDir(appDir); err != nil {
 			return "", err
@@ -270,6 +267,10 @@
 	if _, err := InstallApp(m.repoIO, appDir, rendered.Name, rendered.Config, rendered.Ports, rendered.Resources, rendered.Data); err != nil {
 		return ReleaseResources{}, err
 	}
+	// TODO(gio): add ingress-nginx to release resources
+	if err := openPorts(rendered.Ports); err != nil {
+		return ReleaseResources{}, err
+	}
 	return ReleaseResources{
 		Helm: extractHelm(rendered.Resources),
 	}, nil
diff --git a/core/installer/values-tmpl/private-network.cue b/core/installer/values-tmpl/private-network.cue
index 1cee202..65bfeaf 100644
--- a/core/installer/values-tmpl/private-network.cue
+++ b/core/installer/values-tmpl/private-network.cue
@@ -126,7 +126,7 @@
 		values: {
 			repoAddr: release.repoAddr
 			sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
-			ingressNginxPath: "\(release.appDir)/ingress-nginx.yaml"
+			ingressNginxPath: "\(release.appDir)/resources/ingress-nginx.yaml"
 			image: {
 				repository: images.portAllocator.fullName
 				tag: images.portAllocator.tag
diff --git a/core/installer/values-tmpl/soft-serve.cue b/core/installer/values-tmpl/soft-serve.cue
index c31c855..be7f30e 100644
--- a/core/installer/values-tmpl/soft-serve.cue
+++ b/core/installer/values-tmpl/soft-serve.cue
@@ -1,10 +1,11 @@
 input: {
+	network: #Network @name(Network)
 	subdomain: string @name(Subdomain)
+	sshPort: int @name(SSH Port)
 	adminKey: string @name(Admin SSH Public Key)
 }
 
 _domain: "\(input.subdomain).\(global.privateDomain)"
-url: "https://\(_domain)"
 
 name: "Soft-Serve"
 namespace: "app-soft-serve"
@@ -33,18 +34,37 @@
 	}
 }
 
+ingress: {
+	gerrit: {
+		auth: enabled: false
+		network: input.network
+		subdomain: input.subdomain
+		service: {
+			name: "soft-serve"
+			port: number: 80
+		}
+	}
+}
+
+portForward: [#PortForward & {
+	allocator: input.network.allocatePortAddr
+	sourcePort: input.sshPort
+	// TODO(gio): namespace part must be populated by app manager. Otherwise
+	// third-party app developer might point to a service from different namespace.
+	targetService: "\(release.namespace)/soft-serve"
+	targetPort: 22
+}]
+
 helm: {
 	softserve: {
 		chart: charts.softserve
 		values: {
-			serviceType: "LoadBalancer"
-			reservedIP: ""
-			addressPool: global.id
+			serviceType: "ClusterIP"
 			adminKey: input.adminKey
-			privateKey: ""
-			publicKey: ""
+			sshPublicPort: input.sshPort
 			ingress: {
 				enabled: false
+				domain: _domain
 			}
 			image: {
 				repository: images.softserve.fullName
@@ -54,3 +74,15 @@
 		}
 	}
 }
+
+help: [{
+	title: "Access"
+	contents: """
+	SSH CLI: ssh \(_domain) -p \(input.sshPort) help  
+	SSH TUI: ssh \(_domain) -p \(input.sshPort)  
+	HTTP: git clone https://\(_domain)/<REPO-NAME>  
+	SSH: git clone ssh://\(_domain):\(input.sshPort)/<REPO-NAME>  
+
+	See following resource on what you can do with Soft-Serve TUI: [https://github.com/charmbracelet/soft-serve](https://github.com/charmbracelet/soft-serve)
+	"""
+}]