blob: 20e428d02d10c134cba0bc65ff60d11025315837 [file] [log] [blame]
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +04001package tasks
2
3import (
4 "fmt"
5 "log"
6 "path/filepath"
7
8 "github.com/giolekva/pcloud/core/installer"
gioe72b54f2024-04-22 10:44:41 +04009 "github.com/giolekva/pcloud/core/installer/io"
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040010 "github.com/giolekva/pcloud/core/installer/soft"
11)
12
gioe72b54f2024-04-22 10:44:41 +040013func SetupConfigRepoTask(env installer.EnvConfig, st *state) Task {
Giorgi Lekveishviliab7ff6e2024-03-29 13:11:30 +040014 ret := newSequentialParentTask(
15 "Configure Git repository",
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +040016 true,
17 newSequentialParentTask(
18 "Start up Git server",
19 false,
20 NewCreateConfigRepoTask(env, st),
21 CreateGitClientTask(env, st),
22 ),
Giorgi Lekveishvili378ea882023-12-12 13:59:18 +040023 NewInitConfigRepoTask(env, st),
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +040024 NewActivateEnvTask(env, st),
25 newSequentialParentTask(
26 "Create initial commit",
27 false,
28 CreateRepoClient(env, st),
29 CommitEnvironmentConfiguration(env, st),
30 ConfigureFirstAccount(env, st),
31 ),
Giorgi Lekveishvili378ea882023-12-12 13:59:18 +040032 )
Giorgi Lekveishviliab7ff6e2024-03-29 13:11:30 +040033 ret.beforeStart = func() {
34 st.infoListener("dodo is driven by GitOps, changes are committed to the repository before updating an environment. This unlocks functionalities such as: rolling back to old working state, migrating dodo to new infrastructure (for example from Cloud to on-prem).")
35 }
36 return ret
Giorgi Lekveishvili378ea882023-12-12 13:59:18 +040037}
38
gioe72b54f2024-04-22 10:44:41 +040039func NewCreateConfigRepoTask(env installer.EnvConfig, st *state) Task {
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040040 t := newLeafTask("Install Git server", func() error {
41 appsRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
gio3cdee592024-04-17 10:15:56 +040042 app, err := installer.FindInfraApp(appsRepo, "config-repo")
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040043 if err != nil {
44 return err
45 }
gioe72b54f2024-04-22 10:44:41 +040046 adminKeys, err := installer.NewSSHKeyPair(fmt.Sprintf("%s-config-repo-admin-keys", env.Id))
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040047 if err != nil {
48 return err
49 }
gio3cdee592024-04-17 10:15:56 +040050 st.ssAdminKeys = adminKeys
gioe72b54f2024-04-22 10:44:41 +040051 keys, err := installer.NewSSHKeyPair(fmt.Sprintf("%s-config-repo-keys", env.Id))
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040052 if err != nil {
53 return err
54 }
gioe72b54f2024-04-22 10:44:41 +040055 appDir := filepath.Join("/environments", env.Id, "config-repo")
56 return st.infraAppManager.Install(app, appDir, env.Id, map[string]any{
gio3cdee592024-04-17 10:15:56 +040057 "privateKey": string(keys.RawPrivateKey()),
58 "publicKey": string(keys.RawAuthorizedKey()),
59 "adminKey": string(adminKeys.RawAuthorizedKey()),
60 })
Giorgi Lekveishvili378ea882023-12-12 13:59:18 +040061 })
62 return &t
63}
64
gioe72b54f2024-04-22 10:44:41 +040065func CreateGitClientTask(env installer.EnvConfig, st *state) Task {
Giorgi Lekveishvili378ea882023-12-12 13:59:18 +040066 t := newLeafTask("Wait git server to come up", func() error {
gioe72b54f2024-04-22 10:44:41 +040067 ssClient, err := st.repoClient.Get(
68 fmt.Sprintf("soft-serve.%s.svc.cluster.local:%d", env.Id, 22),
Giorgi Lekveishvili378ea882023-12-12 13:59:18 +040069 st.ssAdminKeys.RawPrivateKey(),
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040070 log.Default())
71 if err != nil {
72 return err
73 }
74 if err := ssClient.AddPublicKey("admin", env.AdminPublicKey); err != nil {
75 return err
76 }
77 // // TODO(gio): defer?
78 // // TODO(gio): remove at the end of final task cleanup
79 // if err := ssClient.RemovePublicKey("admin", string(ssAdminKeys.RawAuthorizedKey())); err != nil {
80 // t.callDoneListeners(err)
81 // return
82 // }
83 st.ssClient = ssClient
84 return nil
85 })
86 return &t
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +040087}
88
gioe72b54f2024-04-22 10:44:41 +040089func NewInitConfigRepoTask(env installer.EnvConfig, st *state) Task {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +040090 t := newLeafTask("Configure access control lists", func() error {
gioe72b54f2024-04-22 10:44:41 +040091 st.fluxUserName = fmt.Sprintf("flux-%s", env.Id)
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +040092 keys, err := installer.NewSSHKeyPair(st.fluxUserName)
93 if err != nil {
94 return err
95 }
96 st.keys = keys
97 if err := st.ssClient.AddRepository("config"); err != nil {
98 return err
99 }
gioe72b54f2024-04-22 10:44:41 +0400100 repoIO, err := st.ssClient.GetRepo("config")
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +0400101 if err != nil {
102 return err
103 }
gioe72b54f2024-04-22 10:44:41 +0400104 if err := repoIO.Do(func(r soft.RepoFS) (string, error) {
gio3af43942024-04-16 08:13:50 +0400105 w, err := r.Writer("README.md")
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400106 if err != nil {
gio3af43942024-04-16 08:13:50 +0400107 return "", err
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400108 }
109 defer w.Close()
gioe72b54f2024-04-22 10:44:41 +0400110 if _, err := fmt.Fprintf(w, "# %s PCloud environment", env.Id); err != nil {
gio3af43942024-04-16 08:13:50 +0400111 return "", err
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400112 }
gioe72b54f2024-04-22 10:44:41 +0400113 if err := soft.WriteYaml(r, "kustomization.yaml", io.NewKustomization()); err != nil {
gio3af43942024-04-16 08:13:50 +0400114 return "", err
115 }
116 return "init", nil
117 }); err != nil {
Giorgi Lekveishvili77ee2dc2023-12-11 16:51:10 +0400118 return err
119 }
120 if err := st.ssClient.AddUser(st.fluxUserName, keys.AuthorizedKey()); err != nil {
121 return err
122 }
123 if err := st.ssClient.AddReadOnlyCollaborator("config", st.fluxUserName); err != nil {
124 return err
125 }
126 return nil
127 })
128 return &t
Giorgi Lekveishvili46743d42023-12-10 15:47:23 +0400129}