installer: env form
diff --git a/core/installer/cmd/env-tmpl/config-kustomization.yaml b/core/installer/cmd/env-tmpl/config-kustomization.yaml
deleted file mode 100644
index d76bf0f..0000000
--- a/core/installer/cmd/env-tmpl/config-kustomization.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
-kind: Kustomization
-metadata:
- name: {{ .Name }}
- namespace: {{ .Name }}
-spec:
- interval: 1m
- path: "./"
- sourceRef:
- kind: GitRepository
- name: {{ .Name }}
- namespace: {{ .Name }}
- prune: true
diff --git a/core/installer/cmd/env-tmpl/config-secret.yaml b/core/installer/cmd/env-tmpl/config-secret.yaml
deleted file mode 100644
index 3ea515b..0000000
--- a/core/installer/cmd/env-tmpl/config-secret.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: v1
-data:
- identity: {{ .PrivateKey }}
- identity.pub: {{ .PublicKey }}
- known_hosts: {{ .KnownHosts }}
-kind: Secret
-metadata:
- name: {{ .Name }}
- namespace: {{ .Name }}
-type: Opaque
diff --git a/core/installer/cmd/env-tmpl/config-source.yaml b/core/installer/cmd/env-tmpl/config-source.yaml
deleted file mode 100644
index 113a0b4..0000000
--- a/core/installer/cmd/env-tmpl/config-source.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: source.toolkit.fluxcd.io/v1beta2
-kind: GitRepository
-metadata:
- name: {{ .Name }}
- namespace: {{ .Name }}
-spec:
- gitImplementation: go-git
- interval: 1m0s
- ref:
- branch: master
- secretRef:
- name: {{ .Name }}
- timeout: 60s
- url: ssh://{{ .GitHost }}/{{ .Name }}
diff --git a/core/installer/cmd/env-tmpl/kustomization.yaml b/core/installer/cmd/env-tmpl/kustomization.yaml
deleted file mode 100644
index 70db25f..0000000
--- a/core/installer/cmd/env-tmpl/kustomization.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-resources:
-- namespace.yaml
-- config-secret.yaml
-- config-source.yaml
-- config-kustomization.yaml
diff --git a/core/installer/cmd/env-tmpl/namespace.yaml b/core/installer/cmd/env-tmpl/namespace.yaml
deleted file mode 100644
index 0c14654..0000000
--- a/core/installer/cmd/env-tmpl/namespace.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
- name: {{ .Name }}
- labels:
- pcloud-instance-id: {{ .Name }}
- annotations:
- helm.sh/resource-policy: keep
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())