Installer: Handle custom networks/domains

Change-Id: Id88e82a0757365466d92fb31223e21b7199ef940
diff --git a/core/installer/welcome/appmanager.go b/core/installer/welcome/appmanager.go
index a4430b8..2c434c6 100644
--- a/core/installer/welcome/appmanager.go
+++ b/core/installer/welcome/appmanager.go
@@ -93,6 +93,7 @@
 func (s *AppManagerServer) Start() error {
 	r := mux.NewRouter()
 	r.PathPrefix("/static/").Handler(cachingHandler{http.FileServer(http.FS(staticAssets))})
+	r.HandleFunc("/api/networks", s.handleNetworks).Methods(http.MethodGet)
 	r.HandleFunc("/api/app-repo", s.handleAppRepo)
 	r.HandleFunc("/api/app/{slug}/install", s.handleAppInstall).Methods(http.MethodPost)
 	r.HandleFunc("/api/app/{slug}", s.handleApp).Methods(http.MethodGet)
@@ -116,6 +117,23 @@
 	Instances        []installer.AppInstanceConfig `json:"instances,omitempty"`
 }
 
+func (s *AppManagerServer) handleNetworks(w http.ResponseWriter, r *http.Request) {
+	env, err := s.m.Config()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	networks, err := s.m.CreateNetworks(env)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	if err := json.NewEncoder(w).Encode(networks); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
 func (s *AppManagerServer) handleAppRepo(w http.ResponseWriter, r *http.Request) {
 	all, err := s.r.GetAll()
 	if err != nil {
@@ -414,10 +432,15 @@
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
+	networks, err := s.m.CreateNetworks(global)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
 	data := appPageData{
 		App:               a,
 		Instances:         instances,
-		AvailableNetworks: installer.CreateNetworks(global),
+		AvailableNetworks: networks,
 		CurrentPage:       a.Name(),
 	}
 	if err := s.tmpl.app.Execute(w, data); err != nil {
@@ -452,12 +475,17 @@
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
+	networks, err := s.m.CreateNetworks(global)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
 	t := s.tasks[slug]
 	data := appPageData{
 		App:               a,
 		Instance:          instance,
 		Instances:         instances,
-		AvailableNetworks: installer.CreateNetworks(global),
+		AvailableNetworks: networks,
 		Task:              t,
 		CurrentPage:       instance.Id,
 	}
diff --git a/core/installer/welcome/dodo_app.go b/core/installer/welcome/dodo_app.go
index 75d12b9..20e881d 100644
--- a/core/installer/welcome/dodo_app.go
+++ b/core/installer/welcome/dodo_app.go
@@ -29,21 +29,22 @@
 )
 
 type DodoAppServer struct {
-	l                sync.Locker
-	st               Store
-	port             int
-	apiPort          int
-	self             string
-	sshKey           string
-	gitRepoPublicKey string
-	client           soft.Client
-	namespace        string
-	env              installer.EnvConfig
-	nsc              installer.NamespaceCreator
-	jc               installer.JobCreator
-	workers          map[string]map[string]struct{}
-	appNs            map[string]string
-	sc               *securecookie.SecureCookie
+	l                 sync.Locker
+	st                Store
+	port              int
+	apiPort           int
+	self              string
+	sshKey            string
+	gitRepoPublicKey  string
+	client            soft.Client
+	namespace         string
+	envAppManagerAddr string
+	env               installer.EnvConfig
+	nsc               installer.NamespaceCreator
+	jc                installer.JobCreator
+	workers           map[string]map[string]struct{}
+	appNs             map[string]string
+	sc                *securecookie.SecureCookie
 }
 
 // TODO(gio): Initialize appNs on startup
@@ -56,6 +57,7 @@
 	gitRepoPublicKey string,
 	client soft.Client,
 	namespace string,
+	envAppManagerAddr string,
 	nsc installer.NamespaceCreator,
 	jc installer.JobCreator,
 	env installer.EnvConfig,
@@ -74,6 +76,7 @@
 		gitRepoPublicKey,
 		client,
 		namespace,
+		envAppManagerAddr,
 		env,
 		nsc,
 		jc,
@@ -277,7 +280,11 @@
 	}
 	// TODO(gio): Create commit record on app init as well
 	go func() {
-		if err := s.updateDodoApp(req.Repository.Name, s.appNs[req.Repository.Name]); err != nil {
+		networks, err := getNetworks(fmt.Sprintf("%s/api/networks", s.envAppManagerAddr))
+		if err != nil {
+			return
+		}
+		if err := s.updateDodoApp(req.Repository.Name, s.appNs[req.Repository.Name], networks); err != nil {
 			if err := s.st.CreateCommit(req.Repository.Name, req.After, err.Error()); err != nil {
 				fmt.Printf("Error: %s\n", err.Error())
 				return
@@ -417,7 +424,11 @@
 	}
 	namespace := fmt.Sprintf("%s%s%s", s.env.NamespacePrefix, app.Namespace(), suffix)
 	s.appNs[appName] = namespace
-	if err := s.updateDodoApp(appName, namespace); err != nil {
+	networks, err := getNetworks(fmt.Sprintf("%s/api/networks", s.envAppManagerAddr))
+	if err != nil {
+		return "", err
+	}
+	if err := s.updateDodoApp(appName, namespace, networks); err != nil {
 		return "", err
 	}
 	repo, err := s.client.GetRepo(ConfigRepoName)
@@ -449,6 +460,7 @@
 				"gitRepoPublicKey": s.gitRepoPublicKey,
 			},
 			installer.WithConfig(&s.env),
+			installer.WithNetworks(networks),
 			installer.WithNoPublish(),
 			installer.WithNoLock(),
 		); err != nil {
@@ -509,7 +521,7 @@
 	}
 }
 
-func (s *DodoAppServer) updateDodoApp(name, namespace string) error {
+func (s *DodoAppServer) updateDodoApp(name, namespace string, networks []installer.Network) error {
 	repo, err := s.client.GetRepo(name)
 	if err != nil {
 		return err
@@ -540,6 +552,7 @@
 			"sshPrivateKey": s.sshKey,
 		},
 		installer.WithConfig(&s.env),
+		installer.WithNetworks(networks),
 		installer.WithLocalChartGenerator(lg),
 		installer.WithBranch("dodo"),
 		installer.WithForce(),
@@ -620,3 +633,15 @@
 func generatePassword() string {
 	return "foo"
 }
+
+func getNetworks(addr string) ([]installer.Network, error) {
+	resp, err := http.Get(addr)
+	if err != nil {
+		return nil, err
+	}
+	ret := []installer.Network{}
+	if json.NewDecoder(resp.Body).Decode(&ret); err != nil {
+		return nil, err
+	}
+	return ret, nil
+}