installer: env form
diff --git a/core/installer/cmd/env.go b/core/installer/cmd/env.go
deleted file mode 100644
index 045b258..0000000
--- a/core/installer/cmd/env.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// TODO
-// * flux -n lekva create source git pcloud --url=ssh://192.168.0.211/pcloud-apps --branch=main --private-key-file=/Users/lekva/.ssh/id_rsa
-
-package main
-
-import (
- "embed"
- "encoding/base64"
- "fmt"
- "github.com/spf13/cobra"
- "log"
- "os"
- "path"
- "text/template"
-
- "github.com/giolekva/pcloud/core/installer"
- "github.com/giolekva/pcloud/core/installer/soft"
-)
-
-//go:embed env-tmpl
-var filesTmpls embed.FS
-
-var createEnvFlags struct {
- name string
- ip string
- port int
- adminPrivKey string
- adminUsername string
-}
-
-func createEnvCmd() *cobra.Command {
- cmd := &cobra.Command{
- Use: "create-env",
- RunE: createEnvCmdRun,
- }
- cmd.Flags().StringVar(
- &createEnvFlags.name,
- "name",
- "",
- "",
- )
- cmd.Flags().StringVar(
- &createEnvFlags.ip,
- "ip",
- "",
- "",
- )
- cmd.Flags().IntVar(
- &createEnvFlags.port,
- "port",
- 22,
- "",
- )
- cmd.Flags().StringVar(
- &createEnvFlags.adminPrivKey,
- "admin-priv-key",
- "",
- "",
- )
- cmd.Flags().StringVar(
- &createEnvFlags.adminUsername,
- "admin-username",
- "",
- "",
- )
- return cmd
-}
-
-func createEnvCmdRun(cmd *cobra.Command, args []string) error {
- adminPrivKey, err := os.ReadFile(createEnvFlags.adminPrivKey)
- if err != nil {
- return err
- }
- ss, err := soft.NewClient(createEnvFlags.ip, createEnvFlags.port, adminPrivKey, log.Default())
- if err != nil {
- return err
- }
- ssPubKey, err := ss.GetPublicKey()
- if err != nil {
- return err
- }
- keys, err := installer.NewSSHKeyPair()
- if err != nil {
- return err
- }
- if 1 == 2 {
- readme := fmt.Sprintf("# %s PCloud environment", createEnvFlags.name)
- if err := ss.AddRepository(createEnvFlags.name, readme); err != nil {
- return err
- }
- fluxUserName := fmt.Sprintf("flux-%s", createEnvFlags.name)
- if err := ss.AddUser(fluxUserName, keys.Public); err != nil {
- return err
- }
- if err := ss.AddCollaborator(createEnvFlags.name, fluxUserName); err != nil {
- return err
- }
- }
- envRepo, err := ss.GetRepo(createEnvFlags.name)
- if envRepo == nil {
- return err
- }
- if err := initEnvRepo(installer.NewRepoIO(envRepo, ss.Signer)); err != nil {
- return err
- }
- if 1 == 2 {
- repo, err := ss.GetRepo("pcloud")
- if err != nil {
- return err
- }
- repoIO := installer.NewRepoIO(repo, ss.Signer)
- kust, err := repoIO.ReadKustomization("environments/kustomization.yaml")
- if err != nil {
- return err
- }
- kust.AddResources(createEnvFlags.name)
- tmpls, err := template.ParseFS(filesTmpls, "env-tmpl/*.yaml")
- if err != nil {
- return err
- }
- for _, tmpl := range tmpls.Templates() {
- dstPath := path.Join("environments", createEnvFlags.name, tmpl.Name())
- dst, err := repoIO.Writer(dstPath)
- if err != nil {
- return err
- }
- defer dst.Close()
- if err := tmpl.Execute(dst, map[string]string{
- "Name": createEnvFlags.name,
- "PrivateKey": base64.StdEncoding.EncodeToString([]byte(keys.Private)),
- "PublicKey": base64.StdEncoding.EncodeToString([]byte(keys.Public)),
- "GitHost": createEnvFlags.ip,
- "KnownHosts": base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s %s", createEnvFlags.ip, ssPubKey))),
- }); err != nil {
- return err
- }
- }
- if err := repoIO.WriteKustomization("environments/kustomization.yaml", *kust); err != nil {
- return err
- }
- if err := repoIO.CommitAndPush(fmt.Sprintf("%s: initialize environment", createEnvFlags.name)); err != nil {
- return err
- }
- }
- return nil
-}
-
-func initEnvRepo(r installer.RepoIO) error {
- appManager, err := installer.NewAppManager(r)
- if err != nil {
- return err
- }
- appsRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
- if 1 == 2 {
- config := installer.Config{ // TODO(gioleka): configurable
- Values: installer.Values{
- PCloudEnvName: "pcloud",
- Id: "lekva",
- ContactEmail: "giolekva@gmail.com",
- Domain: "lekva.me",
- PrivateDomain: "p.lekva.me",
- PublicIP: "46.49.35.44",
- NamespacePrefix: "lekva-",
- },
- }
- if err := r.WriteYaml("config.yaml", config); err != nil {
- return err
- }
- {
- out, err := r.Writer("pcloud-charts.yaml")
- if err != nil {
- return err
- }
- defer out.Close()
- _, err = out.Write([]byte(`
-apiVersion: source.toolkit.fluxcd.io/v1beta2
-kind: GitRepository
-metadata:
- name: pcloud
- namespace: lekva
-spec:
- interval: 1m0s
- url: https://github.com/giolekva/pcloud
- ref:
- branch: main
-`))
- if err != nil {
- return err
- }
- }
- rootKust := installer.NewKustomization()
- rootKust.AddResources("pcloud-charts.yaml", "apps")
- if err := r.WriteKustomization("kustomization.yaml", rootKust); err != nil {
- return err
- }
- appsKust := installer.NewKustomization()
- if err := r.WriteKustomization("apps/kustomization.yaml", appsKust); err != nil {
- return err
- }
- r.CommitAndPush("initialize config")
- {
- app, err := appsRepo.Find("metallb-config-env")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "IngressPrivate": "10.1.0.1",
- "Headscale": "10.1.0.2",
- "SoftServe": "10.1.0.3",
- "Rest": map[string]any{
- "From": "10.1.0.100",
- "To": "10.1.0.255",
- },
- }); err != nil {
- return err
- }
- }
- {
- app, err := appsRepo.Find("ingress-private")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "GandiAPIToken": "", // TODO(gioleka): configurable
- }); err != nil {
- return err
- }
- }
- {
- app, err := appsRepo.Find("core-auth")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "Subdomain": "test", // TODO(giolekva): make core-auth chart actually use this
- }); err != nil {
- return err
- }
- }
- }
- {
- app, err := appsRepo.Find("headscale")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "Subdomain": "headscale",
- }); err != nil {
- return err
- }
- }
- if 1 == 2 {
- {
- app, err := appsRepo.Find("tailscale-proxy")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "Username": createEnvFlags.adminUsername,
- "IPSubnet": "10.1.0.0/24",
- }); err != nil {
- return err
- }
- // TODO(giolekva): headscale accept routes
- }
- }
- return nil
-}
diff --git a/core/installer/cmd/env_manager.go b/core/installer/cmd/env_manager.go
index 33b4058..647850d 100644
--- a/core/installer/cmd/env_manager.go
+++ b/core/installer/cmd/env_manager.go
@@ -1,19 +1,14 @@
package main
import (
- "encoding/base64"
- "encoding/json"
- "fmt"
"log"
"os"
- "path"
- "text/template"
- "github.com/labstack/echo/v4"
"github.com/spf13/cobra"
"github.com/giolekva/pcloud/core/installer"
"github.com/giolekva/pcloud/core/installer/soft"
+ "github.com/giolekva/pcloud/core/installer/welcome"
)
var envManagerFlags struct {
@@ -60,277 +55,20 @@
if err != nil {
return err
}
- fmt.Println(string(sshKey))
ss, err := soft.NewClient(envManagerFlags.repoIP, envManagerFlags.repoPort, sshKey, log.Default())
if err != nil {
return err
}
- b, err := ss.GetPublicKey()
- if err != nil {
- return err
- }
- fmt.Println(string(b))
- fmt.Println(111)
repo, err := ss.GetRepo("pcloud")
- fmt.Println(222)
if err != nil {
return err
}
- fmt.Println(333)
repoIO := installer.NewRepoIO(repo, ss.Signer)
- s := &envServer{
- port: envManagerFlags.port,
- ss: ss,
- repo: repoIO,
- }
- s.start()
- return nil
-}
-
-type envServer struct {
- port int
- ss *soft.Client
- repo installer.RepoIO
-}
-
-func (s *envServer) start() {
- e := echo.New()
- e.POST("/env", s.createEnv)
- log.Fatal(e.Start(fmt.Sprintf(":%d", s.port)))
-}
-
-type createEnvReq struct {
- Name string `json:"name"`
- ContactEmail string `json:"contactEmail"`
- Domain string `json:"domain"`
-}
-
-func (s *envServer) createEnv(c echo.Context) error {
- var req createEnvReq
- if err := json.NewDecoder(c.Request().Body).Decode(&req); err != nil {
- return err
- }
- keys, err := installer.NewSSHKeyPair()
- if err != nil {
- return err
- }
- {
- readme := fmt.Sprintf("# %s PCloud environment", req.Name)
- if err := s.ss.AddRepository(req.Name, readme); err != nil {
- return err
- }
- fluxUserName := fmt.Sprintf("flux-%s", req.Name)
- if err := s.ss.AddUser(fluxUserName, keys.Public); err != nil {
- return err
- }
- if err := s.ss.AddCollaborator(req.Name, fluxUserName); err != nil {
- return err
- }
- }
- {
- repo, err := s.ss.GetRepo(req.Name)
- if repo == nil {
- return err
- }
- if err := initNewEnv(s.ss, installer.NewRepoIO(repo, s.ss.Signer), req); err != nil {
- return err
- }
- }
- {
- repo, err := s.ss.GetRepo("pcloud")
- if err != nil {
- return err
- }
- ssPubKey, err := s.ss.GetPublicKey()
- if err != nil {
- return err
- }
- if err := addNewEnv(
- installer.NewRepoIO(repo, s.ss.Signer),
- req,
- keys,
- ssPubKey,
- ); err != nil {
- return err
- }
- }
- return nil
-}
-
-func initNewEnv(ss *soft.Client, r installer.RepoIO, req createEnvReq) error {
- appManager, err := installer.NewAppManager(r)
- if err != nil {
- return err
- }
- appsRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
- // TODO(giolekva): env name and ip should come from pcloud repo config.yaml
- // TODO(giolekva): private domain can be configurable as well
- config := installer.Config{
- Values: installer.Values{
- PCloudEnvName: "pcloud",
- Id: req.Name,
- ContactEmail: req.ContactEmail,
- Domain: req.Domain,
- PrivateDomain: fmt.Sprintf("p.%s", req.Domain),
- PublicIP: "46.49.35.44",
- NamespacePrefix: fmt.Sprintf("%s-", req.Name),
- },
- }
- if err := r.WriteYaml("config.yaml", config); err != nil {
- return err
- }
- {
- out, err := r.Writer("pcloud-charts.yaml")
- if err != nil {
- return err
- }
- defer out.Close()
- _, err = out.Write([]byte(`
-apiVersion: source.toolkit.fluxcd.io/v1beta2
-kind: GitRepository
-metadata:
- name: pcloud
- namespace: lekva
-spec:
- interval: 1m0s
- url: https://github.com/giolekva/pcloud
- ref:
- branch: main
-`))
- if err != nil {
- return err
- }
- }
- rootKust := installer.NewKustomization()
- rootKust.AddResources("pcloud-charts.yaml", "apps")
- if err := r.WriteKustomization("kustomization.yaml", rootKust); err != nil {
- return err
- }
- appsKust := installer.NewKustomization()
- if err := r.WriteKustomization("apps/kustomization.yaml", appsKust); err != nil {
- return err
- }
- r.CommitAndPush("initialize config")
- {
- app, err := appsRepo.Find("metallb-config-env")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "IngressPrivate": "10.1.0.1",
- "Headscale": "10.1.0.2",
- "SoftServe": "10.1.0.3",
- "Rest": map[string]any{
- "From": "10.1.0.100",
- "To": "10.1.0.255",
- },
- }); err != nil {
- return err
- }
- }
- {
- app, err := appsRepo.Find("ingress-private")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{}); err != nil {
- return err
- }
- }
- {
- app, err := appsRepo.Find("certificate-issuer-public")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{}); err != nil {
- return err
- }
- }
- {
- app, err := appsRepo.Find("core-auth")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "Subdomain": "test", // TODO(giolekva): make core-auth chart actually use this
- }); err != nil {
- return err
- }
- }
- {
- app, err := appsRepo.Find("headscale")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "Subdomain": "headscale",
- }); err != nil {
- return err
- }
- }
- {
- keys, err := installer.NewSSHKeyPair()
- if err != nil {
- return err
- }
- user := fmt.Sprintf("%s-welcome", req.Name)
- if err := ss.AddUser(user, keys.Public); err != nil {
- return err
- }
- if err := ss.AddCollaborator(req.Name, user); err != nil {
- return err
- }
- app, err := appsRepo.Find("welcome")
- if err != nil {
- return err
- }
- if err := appManager.Install(*app, map[string]any{
- "RepoAddr": ss.GetRepoAddress(req.Name),
- "SSHPrivateKey": keys.Private,
- }); err != nil {
- return err
- }
- }
- return nil
-}
-
-func addNewEnv(
- repoIO installer.RepoIO,
- req createEnvReq,
- keys installer.KeyPair,
- pcloudRepoPublicKey []byte,
-) error {
- kust, err := repoIO.ReadKustomization("environments/kustomization.yaml")
- if err != nil {
- return err
- }
- kust.AddResources(req.Name)
- tmpls, err := template.ParseFS(filesTmpls, "env-tmpl/*.yaml")
- if err != nil {
- return err
- }
- for _, tmpl := range tmpls.Templates() {
- dstPath := path.Join("environments", req.Name, tmpl.Name())
- dst, err := repoIO.Writer(dstPath)
- if err != nil {
- return err
- }
- defer dst.Close()
- if err := tmpl.Execute(dst, map[string]string{
- "Name": req.Name,
- "PrivateKey": base64.StdEncoding.EncodeToString([]byte(keys.Private)),
- "PublicKey": base64.StdEncoding.EncodeToString([]byte(keys.Public)),
- "GitHost": envManagerFlags.repoIP,
- "KnownHosts": base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s %s", envManagerFlags.repoIP, pcloudRepoPublicKey))),
- }); err != nil {
- return err
- }
- }
- if err := repoIO.WriteKustomization("environments/kustomization.yaml", *kust); err != nil {
- return err
- }
- if err := repoIO.CommitAndPush(fmt.Sprintf("%s: initialize environment", req.Name)); err != nil {
- return err
- }
+ s := welcome.NewEnvServer(
+ envManagerFlags.port,
+ ss,
+ repoIO,
+ )
+ s.Start()
return nil
}
diff --git a/core/installer/cmd/main.go b/core/installer/cmd/main.go
index 8a5e04b..e879c62 100644
--- a/core/installer/cmd/main.go
+++ b/core/installer/cmd/main.go
@@ -23,7 +23,6 @@
"",
)
rootCmd.AddCommand(bootstrapCmd())
- rootCmd.AddCommand(createEnvCmd())
rootCmd.AddCommand(installCmd())
rootCmd.AddCommand(appManagerCmd())
rootCmd.AddCommand(envManagerCmd())
diff --git a/core/installer/soft/client.go b/core/installer/soft/client.go
index 59e94a8..2a820a0 100644
--- a/core/installer/soft/client.go
+++ b/core/installer/soft/client.go
@@ -1,7 +1,6 @@
package soft
import (
- "encoding/base64"
"fmt"
"golang.org/x/crypto/ssh"
"log"
@@ -30,10 +29,6 @@
}
log.SetPrefix("SOFT-SERVE: ")
log.Printf("Created signer")
- pub := signer.PublicKey().Marshal()
- b := make([]byte, 100)
- base64.StdEncoding.Encode(b, pub)
- log.Printf("%s\n", string(b))
return &Client{
ip,
port,
diff --git a/core/installer/welcome/index.html b/core/installer/welcome/create-admin-account.html
similarity index 100%
rename from core/installer/welcome/index.html
rename to core/installer/welcome/create-admin-account.html
diff --git a/core/installer/welcome/create-env.html b/core/installer/welcome/create-env.html
new file mode 100644
index 0000000..6633d65
--- /dev/null
+++ b/core/installer/welcome/create-env.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en" data-theme="light">
+ <head>
+ <link rel="stylesheet" href="/static/pico.min.css">
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ </head>
+ <body>
+ <div style="display: contents">
+ <main class="container">
+ <article class="grid">
+ <div>
+ <form action="/env" method="POST">
+ <input
+ type="text"
+ name="name"
+ placeholder="Name"
+ required
+ />
+ <input
+ type="test"
+ name="domain"
+ placeholder="Domain"
+ required
+ />
+ <input
+ type="email"
+ name="contact-email"
+ placeholder="Contact Email"
+ required
+ />
+ <button type="submit" class="contrast">Create Environment</button>
+ </form>
+ </div>
+ </article>
+ </main>
+ </div>
+ </body>
+</html>
diff --git a/core/installer/cmd/env-tmpl/config-kustomization.yaml b/core/installer/welcome/env-tmpl/config-kustomization.yaml
similarity index 100%
rename from core/installer/cmd/env-tmpl/config-kustomization.yaml
rename to core/installer/welcome/env-tmpl/config-kustomization.yaml
diff --git a/core/installer/cmd/env-tmpl/config-secret.yaml b/core/installer/welcome/env-tmpl/config-secret.yaml
similarity index 100%
rename from core/installer/cmd/env-tmpl/config-secret.yaml
rename to core/installer/welcome/env-tmpl/config-secret.yaml
diff --git a/core/installer/cmd/env-tmpl/config-source.yaml b/core/installer/welcome/env-tmpl/config-source.yaml
similarity index 100%
rename from core/installer/cmd/env-tmpl/config-source.yaml
rename to core/installer/welcome/env-tmpl/config-source.yaml
diff --git a/core/installer/cmd/env-tmpl/kustomization.yaml b/core/installer/welcome/env-tmpl/kustomization.yaml
similarity index 100%
rename from core/installer/cmd/env-tmpl/kustomization.yaml
rename to core/installer/welcome/env-tmpl/kustomization.yaml
diff --git a/core/installer/cmd/env-tmpl/namespace.yaml b/core/installer/welcome/env-tmpl/namespace.yaml
similarity index 100%
rename from core/installer/cmd/env-tmpl/namespace.yaml
rename to core/installer/welcome/env-tmpl/namespace.yaml
diff --git a/core/installer/welcome/env.go b/core/installer/welcome/env.go
new file mode 100644
index 0000000..e871830
--- /dev/null
+++ b/core/installer/welcome/env.go
@@ -0,0 +1,304 @@
+package welcome
+
+import (
+ "embed"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "log"
+ "net/http"
+ "path"
+ "text/template"
+
+ "github.com/labstack/echo/v4"
+
+ "github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/soft"
+)
+
+//go:embed env-tmpl
+var filesTmpls embed.FS
+
+//go:embed create-env.html
+var createEnvFormHtml string
+
+type EnvServer struct {
+ port int
+ ss *soft.Client
+ repo installer.RepoIO
+}
+
+func NewEnvServer(port int, ss *soft.Client, repo installer.RepoIO) *EnvServer {
+ return &EnvServer{
+ port,
+ ss,
+ repo,
+ }
+}
+
+func (s *EnvServer) Start() {
+ e := echo.New()
+ e.StaticFS("/static", echo.MustSubFS(staticAssets, "static"))
+ e.GET("/env", s.createEnvForm)
+ e.POST("/env", s.createEnv)
+ log.Fatal(e.Start(fmt.Sprintf(":%d", s.port)))
+}
+
+func (s *EnvServer) createEnvForm(c echo.Context) error {
+ return c.HTML(http.StatusOK, createEnvFormHtml)
+}
+
+type createEnvReq struct {
+ Name string `json:"name"`
+ ContactEmail string `json:"contactEmail"`
+ Domain string `json:"domain"`
+}
+
+func (s *EnvServer) createEnv(c echo.Context) error {
+ var req createEnvReq
+ if err := func() error {
+ var err error
+ f, err := c.FormParams()
+ if err != nil {
+ return err
+ }
+ if req.Name, err = getFormValue(f, "name"); err != nil {
+ return err
+ }
+ if req.Domain, err = getFormValue(f, "domain"); err != nil {
+ return err
+ }
+ if req.ContactEmail, err = getFormValue(f, "contact-email"); err != nil {
+ return err
+ }
+ return nil
+ }(); err != nil {
+ if err := json.NewDecoder(c.Request().Body).Decode(&req); err != nil {
+ return err
+ }
+ }
+ keys, err := installer.NewSSHKeyPair()
+ if err != nil {
+ return err
+ }
+ {
+ readme := fmt.Sprintf("# %s PCloud environment", req.Name)
+ if err := s.ss.AddRepository(req.Name, readme); err != nil {
+ return err
+ }
+ fluxUserName := fmt.Sprintf("flux-%s", req.Name)
+ if err := s.ss.AddUser(fluxUserName, keys.Public); err != nil {
+ return err
+ }
+ if err := s.ss.AddCollaborator(req.Name, fluxUserName); err != nil {
+ return err
+ }
+ }
+ {
+ repo, err := s.ss.GetRepo(req.Name)
+ if repo == nil {
+ return err
+ }
+ if err := initNewEnv(s.ss, installer.NewRepoIO(repo, s.ss.Signer), req); err != nil {
+ return err
+ }
+ }
+ {
+ repo, err := s.ss.GetRepo("pcloud")
+ if err != nil {
+ return err
+ }
+ ssPubKey, err := s.ss.GetPublicKey()
+ if err != nil {
+ return err
+ }
+ if err := addNewEnv(
+ installer.NewRepoIO(repo, s.ss.Signer),
+ req,
+ keys,
+ ssPubKey,
+ ); err != nil {
+ return err
+ }
+ }
+ return c.String(http.StatusOK, "OK")
+}
+
+func initNewEnv(ss *soft.Client, r installer.RepoIO, req createEnvReq) error {
+ appManager, err := installer.NewAppManager(r)
+ if err != nil {
+ return err
+ }
+ appsRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
+ // TODO(giolekva): env name and ip should come from pcloud repo config.yaml
+ // TODO(giolekva): private domain can be configurable as well
+ config := installer.Config{
+ Values: installer.Values{
+ PCloudEnvName: "pcloud",
+ Id: req.Name,
+ ContactEmail: req.ContactEmail,
+ Domain: req.Domain,
+ PrivateDomain: fmt.Sprintf("p.%s", req.Domain),
+ PublicIP: "46.49.35.44",
+ NamespacePrefix: fmt.Sprintf("%s-", req.Name),
+ },
+ }
+ if err := r.WriteYaml("config.yaml", config); err != nil {
+ return err
+ }
+ {
+ out, err := r.Writer("pcloud-charts.yaml")
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+ _, err = out.Write([]byte(`
+apiVersion: source.toolkit.fluxcd.io/v1beta2
+kind: GitRepository
+metadata:
+ name: pcloud
+ namespace: lekva
+spec:
+ interval: 1m0s
+ url: https://github.com/giolekva/pcloud
+ ref:
+ branch: main
+`))
+ if err != nil {
+ return err
+ }
+ }
+ rootKust := installer.NewKustomization()
+ rootKust.AddResources("pcloud-charts.yaml", "apps")
+ if err := r.WriteKustomization("kustomization.yaml", rootKust); err != nil {
+ return err
+ }
+ appsKust := installer.NewKustomization()
+ if err := r.WriteKustomization("apps/kustomization.yaml", appsKust); err != nil {
+ return err
+ }
+ r.CommitAndPush("initialize config")
+ {
+ app, err := appsRepo.Find("metallb-config-env")
+ if err != nil {
+ return err
+ }
+ if err := appManager.Install(*app, map[string]any{
+ "IngressPrivate": "10.1.0.1",
+ "Headscale": "10.1.0.2",
+ "SoftServe": "10.1.0.3",
+ "Rest": map[string]any{
+ "From": "10.1.0.100",
+ "To": "10.1.0.255",
+ },
+ }); err != nil {
+ return err
+ }
+ }
+ {
+ app, err := appsRepo.Find("ingress-private")
+ if err != nil {
+ return err
+ }
+ if err := appManager.Install(*app, map[string]any{}); err != nil {
+ return err
+ }
+ }
+ {
+ app, err := appsRepo.Find("certificate-issuer-public")
+ if err != nil {
+ return err
+ }
+ if err := appManager.Install(*app, map[string]any{}); err != nil {
+ return err
+ }
+ }
+ {
+ app, err := appsRepo.Find("core-auth")
+ if err != nil {
+ return err
+ }
+ if err := appManager.Install(*app, map[string]any{
+ "Subdomain": "test", // TODO(giolekva): make core-auth chart actually use this
+ }); err != nil {
+ return err
+ }
+ }
+ {
+ app, err := appsRepo.Find("headscale")
+ if err != nil {
+ return err
+ }
+ if err := appManager.Install(*app, map[string]any{
+ "Subdomain": "headscale",
+ }); err != nil {
+ return err
+ }
+ }
+ {
+ keys, err := installer.NewSSHKeyPair()
+ if err != nil {
+ return err
+ }
+ user := fmt.Sprintf("%s-welcome", req.Name)
+ if err := ss.AddUser(user, keys.Public); err != nil {
+ return err
+ }
+ if err := ss.AddCollaborator(req.Name, user); err != nil {
+ return err
+ }
+ app, err := appsRepo.Find("welcome")
+ if err != nil {
+ return err
+ }
+ if err := appManager.Install(*app, map[string]any{
+ "RepoAddr": ss.GetRepoAddress(req.Name),
+ "SSHPrivateKey": keys.Private,
+ }); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func addNewEnv(
+ repoIO installer.RepoIO,
+ req createEnvReq,
+ keys installer.KeyPair,
+ pcloudRepoPublicKey []byte,
+) error {
+ kust, err := repoIO.ReadKustomization("environments/kustomization.yaml")
+ if err != nil {
+ return err
+ }
+ kust.AddResources(req.Name)
+ tmpls, err := template.ParseFS(filesTmpls, "env-tmpl/*.yaml")
+ if err != nil {
+ return err
+ }
+ repoIP := "192.168.0.211" // TODO(giolekva): configure
+ for _, tmpl := range tmpls.Templates() {
+ dstPath := path.Join("environments", req.Name, tmpl.Name())
+ dst, err := repoIO.Writer(dstPath)
+ if err != nil {
+ return err
+ }
+ defer dst.Close()
+ if err := tmpl.Execute(dst, map[string]string{
+ "Name": req.Name,
+ "PrivateKey": base64.StdEncoding.EncodeToString([]byte(keys.Private)),
+ "PublicKey": base64.StdEncoding.EncodeToString([]byte(keys.Public)),
+ "GitHost": repoIP,
+ "KnownHosts": base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s %s", repoIP, pcloudRepoPublicKey))),
+ }); err != nil {
+ return err
+ }
+ }
+ if err := repoIO.WriteKustomization("environments/kustomization.yaml", *kust); err != nil {
+ return err
+ }
+ if err := repoIO.CommitAndPush(fmt.Sprintf("%s: initialize environment", req.Name)); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/core/installer/welcome/main.go b/core/installer/welcome/welcome.go
similarity index 98%
rename from core/installer/welcome/main.go
rename to core/installer/welcome/welcome.go
index 03a4047..04e08f5 100644
--- a/core/installer/welcome/main.go
+++ b/core/installer/welcome/welcome.go
@@ -13,7 +13,7 @@
"github.com/giolekva/pcloud/core/installer"
)
-//go:embed index.html
+//go:embed create-admin-account.html
var indexHtml string
//go:embed static/*