AppManager: Support exposing cross-cluster ports

Change-Id: I4bdb3573209935f6777656ec2f3481e79d84a9c9
diff --git a/core/installer/dodo_app_test.go b/core/installer/dodo_app_test.go
index 5b0f3b1..eaad590 100644
--- a/core/installer/dodo_app_test.go
+++ b/core/installer/dodo_app_test.go
@@ -1,6 +1,8 @@
 package installer
 
 import (
+	"bytes"
+	"encoding/json"
 	"testing"
 
 	"cuelang.org/go/cue/errors"
@@ -210,3 +212,61 @@
 	}
 	t.Log(string(r.Raw))
 }
+
+const exposeRemoteCluster = `
+{
+    "cluster": "remote",
+    "postgresql": [{
+		"name": "db",
+		"size": "1Gi",
+		"expose": [{
+			"network": "Private",
+			"subdomain": "pg"
+		}]
+	}],
+}
+`
+
+func TestExposeRemoteCluster(t *testing.T) {
+	var buf bytes.Buffer
+	if _, err := buf.WriteString(exposeRemoteCluster); err != nil {
+		t.Fatal(err)
+	}
+	clusters := []Cluster{{
+		Name:             "remote",
+		Kubeconfig:       "<KUBECONFIG>",
+		IngressClassName: "<INGRESS_CLASS_NAME>",
+	}}
+	if err := json.NewEncoder(&buf).Encode(struct {
+		Clusters []Cluster `json:"clusters"`
+	}{
+		clusters,
+	}); err != nil {
+		t.Fatal(err)
+	}
+	app, err := NewDodoApp(buf.Bytes())
+	if err != nil {
+		for _, e := range errors.Errors(err) {
+			t.Log(e)
+		}
+		t.Fatal(err)
+	}
+	release := Release{
+		Namespace:     "foo",
+		AppInstanceId: "foo-bar",
+		RepoAddr:      "ssh://192.168.100.210:22/config",
+		AppDir:        "/foo/bar",
+	}
+	keyGen := testKeyGen{}
+	r, err := app.Render(release, env, networks, clusters, map[string]any{
+		"managerAddr":                  "",
+		"appId":                        "",
+		"sshPrivateKey":                "",
+		"port_postgresql_db_0":         1,
+		"port_postgresql_db_0_cluster": 2,
+	}, nil, keyGen)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Log(string(r.Raw))
+}