DodoApp: Support remote clusters

Change-Id: I6f4e6a0a32cc723b47c96518d83b1ffdb5169f14
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 0bddf29..9b28004 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -449,9 +449,15 @@
 			return ReleaseResources{}, err
 		}
 	}
-	clusters, err := m.GetClusters()
-	if err != nil {
-		return ReleaseResources{}, err
+	var clusters []Cluster
+	if o.Clusters != nil {
+		clusters = o.Clusters
+	} else {
+		if cls, err := m.GetClusters(); err != nil {
+			return ReleaseResources{}, err
+		} else {
+			clusters = ToAccessConfigs(cls)
+		}
 	}
 	var lg LocalChartGenerator
 	if o.LG != nil {
@@ -465,7 +471,7 @@
 		RepoAddr:      m.repo.FullAddress(),
 		AppDir:        appDir,
 	}
-	rendered, err := app.Render(release, env, networks, ToAccessConfigs(clusters), values, nil, m.vpnAPIClient)
+	rendered, err := app.Render(release, env, networks, clusters, values, nil, m.vpnAPIClient)
 	if err != nil {
 		return ReleaseResources{}, err
 	}
@@ -497,7 +503,7 @@
 	if o.FetchContainerImages {
 		release.ImageRegistry = imageRegistry
 	}
-	rendered, err = app.Render(release, env, networks, ToAccessConfigs(clusters), values, localCharts, m.vpnAPIClient)
+	rendered, err = app.Render(release, env, networks, clusters, values, localCharts, m.vpnAPIClient)
 	if err != nil {
 		return ReleaseResources{}, err
 	}
@@ -796,6 +802,7 @@
 	NoPublish            bool
 	Env                  *EnvConfig
 	Networks             []Network
+	Clusters             []Cluster
 	Branch               string
 	LG                   LocalChartGenerator
 	FetchContainerImages bool
@@ -821,6 +828,12 @@
 	return WithNetworks([]Network{})
 }
 
+func WithClusters(clusters []Cluster) InstallOption {
+	return func(o *installOptions) {
+		o.Clusters = clusters
+	}
+}
+
 func WithBranch(branch string) InstallOption {
 	return func(o *installOptions) {
 		o.Branch = branch