blob: ad011400d6d60d5b95da561f9cc78190015b05c6 [file] [log] [blame]
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +04001package installer
2
3import (
4 "context"
5 _ "embed"
6 "fmt"
7 "log"
8 "net/netip"
9 "path/filepath"
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +040010 "strings"
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040011 "time"
12
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040013 "helm.sh/helm/v3/pkg/action"
14 "helm.sh/helm/v3/pkg/chart"
15 "helm.sh/helm/v3/pkg/chart/loader"
16
17 "github.com/giolekva/pcloud/core/installer/soft"
18)
19
20const IPAddressPoolLocal = "local"
21const IPAddressPoolConfigRepo = "config-repo"
22const IPAddressPoolIngressPublic = "ingress-public"
23
Giorgi Lekveishvili5c2c0b92023-12-07 17:35:40 +040024const dnsAPIConfigMapName = "api-config"
25
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040026type Bootstrapper struct {
gio3af43942024-04-16 08:13:50 +040027 cl ChartLoader
28 ns NamespaceCreator
29 ha HelmActionConfigFactory
30 appRepo AppRepository
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040031}
32
gio3af43942024-04-16 08:13:50 +040033func NewBootstrapper(cl ChartLoader, ns NamespaceCreator, ha HelmActionConfigFactory, appRepo AppRepository) Bootstrapper {
34 return Bootstrapper{cl, ns, ha, appRepo}
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040035}
36
37func (b Bootstrapper) Run(env EnvConfig) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +040038 if err := b.ns.Create(env.Name); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040039 return err
40 }
41 if err := b.installMetallb(env); err != nil {
42 return err
43 }
44 if err := b.installLonghorn(env.Name, env.StorageDir, env.VolumeDefaultReplicaCount); err != nil {
45 return err
46 }
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +040047 bootstrapJobKeys, err := NewSSHKeyPair("bootstrapper")
48 if err != nil {
49 return err
50 }
51 if err := b.installSoftServe(bootstrapJobKeys.AuthorizedKey(), env.Name, env.ServiceIPs.ConfigRepo); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040052 return err
53 }
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +040054 time.Sleep(30 * time.Second)
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +040055 ss, err := soft.WaitForClient(
56 netip.AddrPortFrom(env.ServiceIPs.ConfigRepo, 22).String(),
57 bootstrapJobKeys.RawPrivateKey(),
58 log.Default())
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040059 if err != nil {
60 return err
61 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +040062 defer func() {
63 if ss.RemovePublicKey("admin", bootstrapJobKeys.AuthorizedKey()); err != nil {
64 fmt.Printf("Failed to remove admin public key: %s\n", err.Error())
65 }
66 }()
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040067 if ss.AddPublicKey("admin", string(env.AdminPublicKey)); err != nil {
68 return err
69 }
70 if err := b.installFluxcd(ss, env.Name); err != nil {
71 return err
72 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040073 fmt.Println("Fluxcd installed")
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +040074 repo, err := ss.GetRepo("config")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040075 if err != nil {
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040076 fmt.Println("Failed to get config repo")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040077 return err
78 }
gio3af43942024-04-16 08:13:50 +040079 repoIO, err := NewRepoIO(repo, ss.Signer)
80 if err != nil {
81 return err
82 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040083 fmt.Println("Configuring main repo")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040084 if err := configureMainRepo(repoIO, env); err != nil {
85 return err
86 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040087 fmt.Println("Installing infrastructure services")
gio3af43942024-04-16 08:13:50 +040088 if err := b.installInfrastructureServices(repoIO, env); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040089 return err
90 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040091 fmt.Println("Installing DNS Zone Manager")
gio3af43942024-04-16 08:13:50 +040092 if err := b.installDNSZoneManager(repoIO, env); err != nil {
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040093 return err
94 }
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +040095 fmt.Println("Installing Fluxcd Reconciler")
gio3af43942024-04-16 08:13:50 +040096 if err := b.installFluxcdReconciler(repoIO, ss, env); err != nil {
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +040097 return err
98 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040099 fmt.Println("Installing env manager")
gio3af43942024-04-16 08:13:50 +0400100 if err := b.installEnvManager(repoIO, ss, env); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400101 return err
102 }
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400103 fmt.Println("Installing Ory Hydra Maester")
gio3af43942024-04-16 08:13:50 +0400104 if err := b.installOryHydraMaester(repoIO, env); err != nil {
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400105 return err
106 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400107 fmt.Println("Environment ready to use")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400108 return nil
109}
110
111func (b Bootstrapper) installMetallb(env EnvConfig) error {
112 if err := b.installMetallbNamespace(env); err != nil {
113 return err
114 }
115 if err := b.installMetallbService(); err != nil {
116 return err
117 }
118 if err := b.installMetallbIPAddressPool(IPAddressPoolLocal, true, env.ServiceIPs.From, env.ServiceIPs.To); err != nil {
119 return err
120 }
121 if err := b.installMetallbIPAddressPool(IPAddressPoolConfigRepo, false, env.ServiceIPs.ConfigRepo, env.ServiceIPs.ConfigRepo); err != nil {
122 return err
123 }
124 if err := b.installMetallbIPAddressPool(IPAddressPoolIngressPublic, false, env.ServiceIPs.IngressPublic, env.ServiceIPs.IngressPublic); err != nil {
125 return err
126 }
127 return nil
128}
129
130func (b Bootstrapper) installMetallbNamespace(env EnvConfig) error {
131 fmt.Println("Installing metallb namespace")
132 config, err := b.ha.New(env.Name)
133 if err != nil {
134 return err
135 }
136 chart, err := b.cl.Load("namespace")
137 if err != nil {
138 return err
139 }
140 values := map[string]any{
141 "namespace": "metallb-system",
142 "labels": []string{
143 "pod-security.kubernetes.io/audit: privileged",
144 "pod-security.kubernetes.io/enforce: privileged",
145 "pod-security.kubernetes.io/warn: privileged",
146 },
147 }
148 installer := action.NewInstall(config)
149 installer.Namespace = env.Name
150 installer.ReleaseName = "metallb-ns"
151 installer.Wait = true
152 installer.WaitForJobs = true
153 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
154 return err
155 }
156 return nil
157}
158
159func (b Bootstrapper) installMetallbService() error {
160 fmt.Println("Installing metallb")
161 config, err := b.ha.New("metallb-system")
162 if err != nil {
163 return err
164 }
165 chart, err := b.cl.Load("metallb")
166 if err != nil {
167 return err
168 }
169 values := map[string]any{ // TODO(giolekva): add loadBalancerClass?
170 "controller": map[string]any{
171 "image": map[string]any{
172 "repository": "quay.io/metallb/controller",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400173 "tag": "v0.13.12",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400174 "pullPolicy": "IfNotPresent",
175 },
176 "logLevel": "info",
177 },
178 "speaker": map[string]any{
179 "image": map[string]any{
180 "repository": "quay.io/metallb/speaker",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400181 "tag": "v0.13.12",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400182 "pullPolicy": "IfNotPresent",
183 },
184 "logLevel": "info",
185 },
186 }
187 installer := action.NewInstall(config)
188 installer.Namespace = "metallb-system"
189 installer.CreateNamespace = true
190 installer.ReleaseName = "metallb"
191 installer.IncludeCRDs = true
192 installer.Wait = true
193 installer.WaitForJobs = true
194 installer.Timeout = 20 * time.Minute
195 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
196 return err
197 }
198 return nil
199}
200
201func (b Bootstrapper) installMetallbIPAddressPool(name string, autoAssign bool, from, to netip.Addr) error {
202 fmt.Printf("Installing metallb-ipaddresspool: %s\n", name)
203 config, err := b.ha.New("metallb-system")
204 if err != nil {
205 return err
206 }
207 chart, err := b.cl.Load("metallb-ipaddresspool")
208 if err != nil {
209 return err
210 }
211 values := map[string]any{
212 "name": name,
213 "autoAssign": autoAssign,
214 "from": from.String(),
215 "to": to.String(),
216 }
217 installer := action.NewInstall(config)
218 installer.Namespace = "metallb-system"
219 installer.CreateNamespace = true
220 installer.ReleaseName = name
221 installer.Wait = true
222 installer.WaitForJobs = true
223 installer.Timeout = 20 * time.Minute
224 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
225 return err
226 }
227 return nil
228}
229
230func (b Bootstrapper) installLonghorn(envName string, storageDir string, volumeDefaultReplicaCount int) error {
231 fmt.Println("Installing Longhorn")
232 config, err := b.ha.New(envName)
233 if err != nil {
234 return err
235 }
236 chart, err := b.cl.Load("longhorn")
237 if err != nil {
238 return err
239 }
240 values := map[string]any{
241 "defaultSettings": map[string]any{
242 "defaultDataPath": storageDir,
243 },
244 "persistence": map[string]any{
245 "defaultClassReplicaCount": volumeDefaultReplicaCount,
246 },
247 "service": map[string]any{
248 "ui": map[string]any{
249 "type": "LoadBalancer",
250 },
251 },
252 "ingress": map[string]any{
253 "enabled": false,
254 },
255 }
256 installer := action.NewInstall(config)
257 installer.Namespace = "longhorn-system"
258 installer.CreateNamespace = true
259 installer.ReleaseName = "longhorn"
260 installer.Wait = true
261 installer.WaitForJobs = true
262 installer.Timeout = 20 * time.Minute
263 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
264 return err
265 }
266 return nil
267}
268
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400269func (b Bootstrapper) installSoftServe(adminPublicKey string, namespace string, repoIP netip.Addr) error {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400270 fmt.Println("Installing SoftServe")
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400271 keys, err := NewSSHKeyPair("soft-serve")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400272 if err != nil {
273 return err
274 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400275 config, err := b.ha.New(namespace)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400276 if err != nil {
277 return err
278 }
279 chart, err := b.cl.Load("soft-serve")
280 if err != nil {
281 return err
282 }
283 values := map[string]any{
284 "image": map[string]any{
285 "repository": "charmcli/soft-serve",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400286 "tag": "v0.7.1",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400287 "pullPolicy": "IfNotPresent",
288 },
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400289 "privateKey": string(keys.RawPrivateKey()),
290 "publicKey": string(keys.RawAuthorizedKey()),
291 "adminKey": adminPublicKey,
292 "reservedIP": repoIP.String(),
293 "serviceType": "LoadBalancer",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400294 }
295 installer := action.NewInstall(config)
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400296 installer.Namespace = namespace
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400297 installer.CreateNamespace = true
298 installer.ReleaseName = "soft-serve"
299 installer.Wait = true
300 installer.WaitForJobs = true
301 installer.Timeout = 20 * time.Minute
302 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
303 return err
304 }
305 return nil
306}
307
308func (b Bootstrapper) installFluxcd(ss *soft.Client, envName string) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400309 keys, err := NewSSHKeyPair("fluxcd")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400310 if err != nil {
311 return err
312 }
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400313 if err := ss.AddUser("flux", keys.AuthorizedKey()); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400314 return err
315 }
316 if err := ss.MakeUserAdmin("flux"); err != nil {
317 return err
318 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400319 if err := ss.AddRepository("config"); err != nil {
320 return err
321 }
322 repo, err := ss.GetRepo("config")
323 if err != nil {
324 return err
325 }
gio3af43942024-04-16 08:13:50 +0400326 repoIO, err := NewRepoIO(repo, ss.Signer)
327 if err != nil {
328 return err
329 }
330 if err := repoIO.Atomic(func(r RepoFS) (string, error) {
331 w, err := r.Writer("README.md")
332 if err != nil {
333 return "", err
334 }
335 if _, err := fmt.Fprintf(w, "# %s systems", envName); err != nil {
336 return "", err
337 }
338 return "readme", nil
339 }); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400340 return err
341 }
342 fmt.Println("Installing Flux")
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400343 ssPublicKeys, err := ss.GetPublicKeys()
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400344 if err != nil {
345 return err
346 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400347 host := strings.Split(ss.Addr, ":")[0]
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400348 if err := b.installFluxBootstrap(
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400349 ss.GetRepoAddress("config"),
350 host,
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400351 ssPublicKeys,
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400352 string(keys.RawPrivateKey()),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400353 envName,
354 ); err != nil {
355 return err
356 }
357 return nil
358}
359
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400360func (b Bootstrapper) installFluxBootstrap(repoAddr, repoHost string, repoHostPubKeys []string, privateKey, envName string) error {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400361 config, err := b.ha.New(envName)
362 if err != nil {
363 return err
364 }
365 chart, err := b.cl.Load("flux-bootstrap")
366 if err != nil {
367 return err
368 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400369 var lines []string
370 for _, k := range repoHostPubKeys {
371 lines = append(lines, fmt.Sprintf("%s %s", repoHost, k))
372 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400373 values := map[string]any{
374 "image": map[string]any{
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400375 "repository": "fluxcd/flux-cli",
376 "tag": "v2.1.2",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400377 "pullPolicy": "IfNotPresent",
378 },
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400379 "repositoryAddress": repoAddr,
380 "repositoryHost": repoHost,
381 "repositoryHostPublicKeys": strings.Join(lines, "\n"),
382 "privateKey": privateKey,
383 "installationNamespace": fmt.Sprintf("%s-flux", envName),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400384 }
385 installer := action.NewInstall(config)
386 installer.Namespace = envName
387 installer.CreateNamespace = true
388 installer.ReleaseName = "flux"
389 installer.Wait = true
390 installer.WaitForJobs = true
391 installer.Timeout = 20 * time.Minute
392 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
393 return err
394 }
395 return nil
396}
397
gio3af43942024-04-16 08:13:50 +0400398func (b Bootstrapper) installInfrastructureServices(repo RepoIO, env EnvConfig) error {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400399 install := func(name string) error {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400400 fmt.Printf("Installing infrastructure service %s\n", name)
gio3af43942024-04-16 08:13:50 +0400401 app, err := b.appRepo.Find(name)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400402 if err != nil {
403 return err
404 }
gio3af43942024-04-16 08:13:50 +0400405 namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400406 derived := Derived{
407 Global: Values{
408 PCloudEnvName: env.Name,
409 },
410 }
gio3af43942024-04-16 08:13:50 +0400411 return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, nil, derived)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400412 }
413 appsToInstall := []string{
414 "resource-renderer-controller",
415 "headscale-controller",
416 "csi-driver-smb",
417 "ingress-public",
418 "cert-manager",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400419 }
420 for _, name := range appsToInstall {
421 if err := install(name); err != nil {
422 return err
423 }
424 }
425 return nil
426}
427
428func configureMainRepo(repo RepoIO, env EnvConfig) error {
gio3af43942024-04-16 08:13:50 +0400429 return repo.Atomic(func(r RepoFS) (string, error) {
430 if err := WriteYaml(r, "config.yaml", env); err != nil {
431 return "", err
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400432 }
gio3af43942024-04-16 08:13:50 +0400433 if err := WriteYaml(r, "env-cidrs.yaml", EnvCIDRs{}); err != nil {
434 return "", err
435 }
436 kust := NewKustomization()
437 kust.AddResources(
438 fmt.Sprintf("%s-flux", env.Name),
439 "infrastructure",
440 "environments",
441 )
442 if err := WriteYaml(r, "kustomization.yaml", kust); err != nil {
443 return "", err
444 }
445 {
446 out, err := r.Writer("infrastructure/pcloud-charts.yaml")
447 if err != nil {
448 return "", err
449 }
450 defer out.Close()
451 _, err = out.Write([]byte(fmt.Sprintf(`
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400452apiVersion: source.toolkit.fluxcd.io/v1
453kind: GitRepository
454metadata:
455 name: pcloud # TODO(giolekva): use more generic name
456 namespace: %s
457spec:
458 interval: 1m0s
459 url: https://github.com/giolekva/pcloud
460 ref:
Giorgi Lekveishvili024757c2024-03-14 13:27:29 +0400461 branch: main
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400462`, env.Name)))
gio3af43942024-04-16 08:13:50 +0400463 if err != nil {
464 return "", err
465 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400466 }
gio3af43942024-04-16 08:13:50 +0400467 infraKust := NewKustomization()
468 infraKust.AddResources("pcloud-charts.yaml")
469 if err := WriteYaml(r, "infrastructure/kustomization.yaml", infraKust); err != nil {
470 return "", err
471 }
472 if err := WriteYaml(r, "environments/kustomization.yaml", NewKustomization()); err != nil {
473 return "", err
474 }
475 return "initialize pcloud directory structure", nil
476 })
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400477}
478
gio3af43942024-04-16 08:13:50 +0400479func (b Bootstrapper) installEnvManager(repo RepoIO, ss *soft.Client, env EnvConfig) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400480 keys, err := NewSSHKeyPair("env-manager")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400481 if err != nil {
482 return err
483 }
484 user := fmt.Sprintf("%s-env-manager", env.Name)
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400485 if err := ss.AddUser(user, keys.AuthorizedKey()); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400486 return err
487 }
488 if err := ss.MakeUserAdmin(user); err != nil {
489 return err
490 }
gio3af43942024-04-16 08:13:50 +0400491 app, err := b.appRepo.Find("env-manager")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400492 if err != nil {
493 return err
494 }
gio3af43942024-04-16 08:13:50 +0400495 namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400496 derived := Derived{
497 Global: Values{
498 PCloudEnvName: env.Name,
499 },
500 Values: map[string]any{
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400501 "repoIP": env.ServiceIPs.ConfigRepo,
502 "repoPort": 22,
503 "repoName": "config",
504 "sshPrivateKey": string(keys.RawPrivateKey()),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400505 },
506 }
gio3af43942024-04-16 08:13:50 +0400507 return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, derived.Values, derived)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400508}
509
gio3af43942024-04-16 08:13:50 +0400510func (b Bootstrapper) installOryHydraMaester(repo RepoIO, env EnvConfig) error {
511 app, err := b.appRepo.Find("hydra-maester")
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400512 if err != nil {
513 return err
514 }
gio3af43942024-04-16 08:13:50 +0400515 namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400516 derived := Derived{
517 Global: Values{
518 PCloudEnvName: env.Name,
519 },
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400520 }
gio3af43942024-04-16 08:13:50 +0400521 return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, nil, derived)
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400522}
523
gio3af43942024-04-16 08:13:50 +0400524func (b Bootstrapper) installDNSZoneManager(repo RepoIO, env EnvConfig) error {
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400525 const (
526 volumeClaimName = "dns-zone-configs"
527 volumeMountPath = "/etc/pcloud/dns-zone-configs"
528 )
gio3af43942024-04-16 08:13:50 +0400529 app, err := b.appRepo.Find("dns-zone-manager")
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400530 if err != nil {
531 return err
532 }
gio3af43942024-04-16 08:13:50 +0400533 namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400534 derived := Derived{
535 Global: Values{
536 PCloudEnvName: env.Name,
537 },
gio3af43942024-04-16 08:13:50 +0400538 Values: map[string]any{
539 "volume": map[string]any{
540 "claimName": volumeClaimName,
541 "mountPath": volumeMountPath,
542 "size": "1Gi",
543 },
544 "apiConfigMapName": dnsAPIConfigMapName,
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400545 },
546 }
gio3af43942024-04-16 08:13:50 +0400547 return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, derived.Values, derived)
548}
549
550func (b Bootstrapper) installFluxcdReconciler(repo RepoIO, ss *soft.Client, env EnvConfig) error {
551 app, err := b.appRepo.Find("fluxcd-reconciler")
552 if err != nil {
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400553 return err
554 }
gio3af43942024-04-16 08:13:50 +0400555 namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
556 derived := Derived{
557 Global: Values{
558 PCloudEnvName: env.Name,
559 },
560 }
561 return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, nil, derived)
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400562}
563
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400564type HelmActionConfigFactory interface {
565 New(namespace string) (*action.Configuration, error)
566}
567
568type ChartLoader interface {
569 Load(name string) (*chart.Chart, error)
570}
571
572type fsChartLoader struct {
573 baseDir string
574}
575
576func NewFSChartLoader(baseDir string) ChartLoader {
577 return &fsChartLoader{baseDir}
578}
579
580func (l *fsChartLoader) Load(name string) (*chart.Chart, error) {
581 return loader.Load(filepath.Join(l.baseDir, name))
582}