blob: e4967090f9016545618eff601bacd158c52be8dd [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 {
27 cl ChartLoader
28 ns NamespaceCreator
29 ha HelmActionConfigFactory
30}
31
32func NewBootstrapper(cl ChartLoader, ns NamespaceCreator, ha HelmActionConfigFactory) Bootstrapper {
33 return Bootstrapper{cl, ns, ha}
34}
35
36func (b Bootstrapper) Run(env EnvConfig) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +040037 if err := b.ns.Create(env.Name); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040038 return err
39 }
40 if err := b.installMetallb(env); err != nil {
41 return err
42 }
43 if err := b.installLonghorn(env.Name, env.StorageDir, env.VolumeDefaultReplicaCount); err != nil {
44 return err
45 }
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +040046 bootstrapJobKeys, err := NewSSHKeyPair("bootstrapper")
47 if err != nil {
48 return err
49 }
50 if err := b.installSoftServe(bootstrapJobKeys.AuthorizedKey(), env.Name, env.ServiceIPs.ConfigRepo); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040051 return err
52 }
Giorgi Lekveishvilid6805822023-12-20 19:30:05 +040053 time.Sleep(2 * time.Minute)
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +040054 ss, err := soft.WaitForClient(
55 netip.AddrPortFrom(env.ServiceIPs.ConfigRepo, 22).String(),
56 bootstrapJobKeys.RawPrivateKey(),
57 log.Default())
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040058 if err != nil {
59 return err
60 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +040061 defer func() {
62 if ss.RemovePublicKey("admin", bootstrapJobKeys.AuthorizedKey()); err != nil {
63 fmt.Printf("Failed to remove admin public key: %s\n", err.Error())
64 }
65 }()
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040066 if ss.AddPublicKey("admin", string(env.AdminPublicKey)); err != nil {
67 return err
68 }
69 if err := b.installFluxcd(ss, env.Name); err != nil {
70 return err
71 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040072 fmt.Println("Fluxcd installed")
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +040073 repo, err := ss.GetRepo("config")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040074 if err != nil {
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040075 fmt.Println("Failed to get config repo")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040076 return err
77 }
78 repoIO := NewRepoIO(repo, ss.Signer)
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040079 fmt.Println("Configuring main repo")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040080 if err := configureMainRepo(repoIO, env); err != nil {
81 return err
82 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040083 fmt.Println("Installing infrastructure services")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040084 nsGen := NewPrefixGenerator(env.NamespacePrefix)
85 if err := b.installInfrastructureServices(repoIO, nsGen, b.ns, env); err != nil {
86 return err
87 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040088 fmt.Println("Installing DNS Zone Manager")
89 if err := b.installDNSZoneManager(ss, repoIO, nsGen, b.ns, env); err != nil {
90 return err
91 }
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +040092 fmt.Println("Installing Fluxcd Reconciler")
93 if err := b.installFluxcdReconciler(ss, repoIO, nsGen, b.ns, env); err != nil {
94 return err
95 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +040096 fmt.Println("Installing env manager")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040097 if err := b.installEnvManager(ss, repoIO, nsGen, b.ns, env); err != nil {
98 return err
99 }
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400100 fmt.Println("Installing Ory Hydra Maester")
101 if err := b.installOryHydraMaester(ss, repoIO, nsGen, b.ns, env); err != nil {
102 return err
103 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400104 fmt.Println("Environment ready to use")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400105 return nil
106}
107
108func (b Bootstrapper) installMetallb(env EnvConfig) error {
109 if err := b.installMetallbNamespace(env); err != nil {
110 return err
111 }
112 if err := b.installMetallbService(); err != nil {
113 return err
114 }
115 if err := b.installMetallbIPAddressPool(IPAddressPoolLocal, true, env.ServiceIPs.From, env.ServiceIPs.To); err != nil {
116 return err
117 }
118 if err := b.installMetallbIPAddressPool(IPAddressPoolConfigRepo, false, env.ServiceIPs.ConfigRepo, env.ServiceIPs.ConfigRepo); err != nil {
119 return err
120 }
121 if err := b.installMetallbIPAddressPool(IPAddressPoolIngressPublic, false, env.ServiceIPs.IngressPublic, env.ServiceIPs.IngressPublic); err != nil {
122 return err
123 }
124 return nil
125}
126
127func (b Bootstrapper) installMetallbNamespace(env EnvConfig) error {
128 fmt.Println("Installing metallb namespace")
129 config, err := b.ha.New(env.Name)
130 if err != nil {
131 return err
132 }
133 chart, err := b.cl.Load("namespace")
134 if err != nil {
135 return err
136 }
137 values := map[string]any{
138 "namespace": "metallb-system",
139 "labels": []string{
140 "pod-security.kubernetes.io/audit: privileged",
141 "pod-security.kubernetes.io/enforce: privileged",
142 "pod-security.kubernetes.io/warn: privileged",
143 },
144 }
145 installer := action.NewInstall(config)
146 installer.Namespace = env.Name
147 installer.ReleaseName = "metallb-ns"
148 installer.Wait = true
149 installer.WaitForJobs = true
150 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
151 return err
152 }
153 return nil
154}
155
156func (b Bootstrapper) installMetallbService() error {
157 fmt.Println("Installing metallb")
158 config, err := b.ha.New("metallb-system")
159 if err != nil {
160 return err
161 }
162 chart, err := b.cl.Load("metallb")
163 if err != nil {
164 return err
165 }
166 values := map[string]any{ // TODO(giolekva): add loadBalancerClass?
167 "controller": map[string]any{
168 "image": map[string]any{
169 "repository": "quay.io/metallb/controller",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400170 "tag": "v0.13.12",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400171 "pullPolicy": "IfNotPresent",
172 },
173 "logLevel": "info",
174 },
175 "speaker": map[string]any{
176 "image": map[string]any{
177 "repository": "quay.io/metallb/speaker",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400178 "tag": "v0.13.12",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400179 "pullPolicy": "IfNotPresent",
180 },
181 "logLevel": "info",
182 },
183 }
184 installer := action.NewInstall(config)
185 installer.Namespace = "metallb-system"
186 installer.CreateNamespace = true
187 installer.ReleaseName = "metallb"
188 installer.IncludeCRDs = true
189 installer.Wait = true
190 installer.WaitForJobs = true
191 installer.Timeout = 20 * time.Minute
192 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
193 return err
194 }
195 return nil
196}
197
198func (b Bootstrapper) installMetallbIPAddressPool(name string, autoAssign bool, from, to netip.Addr) error {
199 fmt.Printf("Installing metallb-ipaddresspool: %s\n", name)
200 config, err := b.ha.New("metallb-system")
201 if err != nil {
202 return err
203 }
204 chart, err := b.cl.Load("metallb-ipaddresspool")
205 if err != nil {
206 return err
207 }
208 values := map[string]any{
209 "name": name,
210 "autoAssign": autoAssign,
211 "from": from.String(),
212 "to": to.String(),
213 }
214 installer := action.NewInstall(config)
215 installer.Namespace = "metallb-system"
216 installer.CreateNamespace = true
217 installer.ReleaseName = name
218 installer.Wait = true
219 installer.WaitForJobs = true
220 installer.Timeout = 20 * time.Minute
221 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
222 return err
223 }
224 return nil
225}
226
227func (b Bootstrapper) installLonghorn(envName string, storageDir string, volumeDefaultReplicaCount int) error {
228 fmt.Println("Installing Longhorn")
229 config, err := b.ha.New(envName)
230 if err != nil {
231 return err
232 }
233 chart, err := b.cl.Load("longhorn")
234 if err != nil {
235 return err
236 }
237 values := map[string]any{
238 "defaultSettings": map[string]any{
239 "defaultDataPath": storageDir,
240 },
241 "persistence": map[string]any{
242 "defaultClassReplicaCount": volumeDefaultReplicaCount,
243 },
244 "service": map[string]any{
245 "ui": map[string]any{
246 "type": "LoadBalancer",
247 },
248 },
249 "ingress": map[string]any{
250 "enabled": false,
251 },
252 }
253 installer := action.NewInstall(config)
254 installer.Namespace = "longhorn-system"
255 installer.CreateNamespace = true
256 installer.ReleaseName = "longhorn"
257 installer.Wait = true
258 installer.WaitForJobs = true
259 installer.Timeout = 20 * time.Minute
260 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
261 return err
262 }
263 return nil
264}
265
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400266func (b Bootstrapper) installSoftServe(adminPublicKey string, namespace string, repoIP netip.Addr) error {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400267 fmt.Println("Installing SoftServe")
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400268 keys, err := NewSSHKeyPair("soft-serve")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400269 if err != nil {
270 return err
271 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400272 config, err := b.ha.New(namespace)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400273 if err != nil {
274 return err
275 }
276 chart, err := b.cl.Load("soft-serve")
277 if err != nil {
278 return err
279 }
280 values := map[string]any{
281 "image": map[string]any{
282 "repository": "charmcli/soft-serve",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400283 "tag": "v0.7.1",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400284 "pullPolicy": "IfNotPresent",
285 },
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400286 "privateKey": string(keys.RawPrivateKey()),
287 "publicKey": string(keys.RawAuthorizedKey()),
288 "adminKey": adminPublicKey,
289 "reservedIP": repoIP.String(),
290 "serviceType": "LoadBalancer",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400291 }
292 installer := action.NewInstall(config)
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400293 installer.Namespace = namespace
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400294 installer.CreateNamespace = true
295 installer.ReleaseName = "soft-serve"
296 installer.Wait = true
297 installer.WaitForJobs = true
298 installer.Timeout = 20 * time.Minute
299 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
300 return err
301 }
302 return nil
303}
304
305func (b Bootstrapper) installFluxcd(ss *soft.Client, envName string) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400306 keys, err := NewSSHKeyPair("fluxcd")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400307 if err != nil {
308 return err
309 }
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400310 if err := ss.AddUser("flux", keys.AuthorizedKey()); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400311 return err
312 }
313 if err := ss.MakeUserAdmin("flux"); err != nil {
314 return err
315 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400316 if err := ss.AddRepository("config"); err != nil {
317 return err
318 }
319 repo, err := ss.GetRepo("config")
320 if err != nil {
321 return err
322 }
323 repoIO := NewRepoIO(repo, ss.Signer)
324 if err := repoIO.WriteCommitAndPush("README.md", fmt.Sprintf("# %s systems", envName), "readme"); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400325 return err
326 }
327 fmt.Println("Installing Flux")
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400328 ssPublicKeys, err := ss.GetPublicKeys()
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400329 if err != nil {
330 return err
331 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400332 host := strings.Split(ss.Addr, ":")[0]
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400333 if err := b.installFluxBootstrap(
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400334 ss.GetRepoAddress("config"),
335 host,
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400336 ssPublicKeys,
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400337 string(keys.RawPrivateKey()),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400338 envName,
339 ); err != nil {
340 return err
341 }
342 return nil
343}
344
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400345func (b Bootstrapper) installFluxBootstrap(repoAddr, repoHost string, repoHostPubKeys []string, privateKey, envName string) error {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400346 config, err := b.ha.New(envName)
347 if err != nil {
348 return err
349 }
350 chart, err := b.cl.Load("flux-bootstrap")
351 if err != nil {
352 return err
353 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400354 var lines []string
355 for _, k := range repoHostPubKeys {
356 lines = append(lines, fmt.Sprintf("%s %s", repoHost, k))
357 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400358 values := map[string]any{
359 "image": map[string]any{
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400360 "repository": "fluxcd/flux-cli",
361 "tag": "v2.1.2",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400362 "pullPolicy": "IfNotPresent",
363 },
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400364 "repositoryAddress": repoAddr,
365 "repositoryHost": repoHost,
366 "repositoryHostPublicKeys": strings.Join(lines, "\n"),
367 "privateKey": privateKey,
368 "installationNamespace": fmt.Sprintf("%s-flux", envName),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400369 }
370 installer := action.NewInstall(config)
371 installer.Namespace = envName
372 installer.CreateNamespace = true
373 installer.ReleaseName = "flux"
374 installer.Wait = true
375 installer.WaitForJobs = true
376 installer.Timeout = 20 * time.Minute
377 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
378 return err
379 }
380 return nil
381}
382
383func (b Bootstrapper) installInfrastructureServices(repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
384 appRepo := NewInMemoryAppRepository(CreateAllApps())
385 install := func(name string) error {
386 app, err := appRepo.Find(name)
387 if err != nil {
388 return err
389 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400390 namespaces := make([]string, len(app.Namespaces()))
391 for i, n := range app.Namespaces() {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400392 namespaces[i], err = nsGen.Generate(n)
393 if err != nil {
394 return err
395 }
396 }
397 for _, n := range namespaces {
398 if err := nsCreator.Create(n); err != nil {
399 return err
400 }
401 }
402 derived := Derived{
403 Global: Values{
404 PCloudEnvName: env.Name,
405 },
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400406 Release: Release{},
407 Values: make(map[string]any),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400408 }
409 if len(namespaces) > 0 {
410 derived.Release.Namespace = namespaces[0]
411 }
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400412 values := map[string]any{}
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400413 return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), values, derived)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400414 }
415 appsToInstall := []string{
416 "resource-renderer-controller",
417 "headscale-controller",
418 "csi-driver-smb",
419 "ingress-public",
420 "cert-manager",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400421 }
422 for _, name := range appsToInstall {
423 if err := install(name); err != nil {
424 return err
425 }
426 }
427 return nil
428}
429
430func configureMainRepo(repo RepoIO, env EnvConfig) error {
431 if err := repo.WriteYaml("config.yaml", env); err != nil {
432 return err
433 }
Giorgi Lekveishvili9d5e3f52024-03-13 15:02:50 +0400434 if err := repo.WriteYaml("env-cidrs.yaml", EnvCIDRs{}); err != nil {
435 return err
436 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400437 kust := NewKustomization()
438 kust.AddResources(
439 fmt.Sprintf("%s-flux", env.Name),
440 "infrastructure",
441 "environments",
442 )
443 if err := repo.WriteKustomization("kustomization.yaml", kust); err != nil {
444 return err
445 }
446 {
447 out, err := repo.Writer("infrastructure/pcloud-charts.yaml")
448 if err != nil {
449 return err
450 }
451 defer out.Close()
452 _, err = out.Write([]byte(fmt.Sprintf(`
453apiVersion: source.toolkit.fluxcd.io/v1
454kind: GitRepository
455metadata:
456 name: pcloud # TODO(giolekva): use more generic name
457 namespace: %s
458spec:
459 interval: 1m0s
460 url: https://github.com/giolekva/pcloud
461 ref:
Giorgi Lekveishvili024757c2024-03-14 13:27:29 +0400462 branch: main
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400463`, env.Name)))
464 if err != nil {
465 return err
466 }
467 }
468 infraKust := NewKustomization()
469 infraKust.AddResources("pcloud-charts.yaml")
470 if err := repo.WriteKustomization("infrastructure/kustomization.yaml", infraKust); err != nil {
471 return err
472 }
473 if err := repo.WriteKustomization("environments/kustomization.yaml", NewKustomization()); err != nil {
474 return err
475 }
476 if err := repo.CommitAndPush("initialize pcloud directory structure"); err != nil {
477 return err
478 }
479 return nil
480}
481
482func (b Bootstrapper) installEnvManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400483 keys, err := NewSSHKeyPair("env-manager")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400484 if err != nil {
485 return err
486 }
487 user := fmt.Sprintf("%s-env-manager", env.Name)
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400488 if err := ss.AddUser(user, keys.AuthorizedKey()); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400489 return err
490 }
491 if err := ss.MakeUserAdmin(user); err != nil {
492 return err
493 }
494 appRepo := NewInMemoryAppRepository(CreateAllApps())
495 app, err := appRepo.Find("env-manager")
496 if err != nil {
497 return err
498 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400499 namespaces := make([]string, len(app.Namespaces()))
500 for i, n := range app.Namespaces() {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400501 namespaces[i], err = nsGen.Generate(n)
502 if err != nil {
503 return err
504 }
505 }
506 for _, n := range namespaces {
507 if err := nsCreator.Create(n); err != nil {
508 return err
509 }
510 }
511 derived := Derived{
512 Global: Values{
513 PCloudEnvName: env.Name,
514 },
515 Values: map[string]any{
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400516 "repoIP": env.ServiceIPs.ConfigRepo,
517 "repoPort": 22,
518 "repoName": "config",
519 "sshPrivateKey": string(keys.RawPrivateKey()),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400520 },
521 }
522 if len(namespaces) > 0 {
523 derived.Release.Namespace = namespaces[0]
524 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400525 return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400526}
527
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400528func (b Bootstrapper) installOryHydraMaester(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
529 appRepo := NewInMemoryAppRepository(CreateAllApps())
530 app, err := appRepo.Find("hydra-maester")
531 if err != nil {
532 return err
533 }
534 namespaces := make([]string, len(app.Namespaces()))
535 for i, n := range app.Namespaces() {
536 namespaces[i], err = nsGen.Generate(n)
537 if err != nil {
538 return err
539 }
540 }
541 for _, n := range namespaces {
542 if err := nsCreator.Create(n); err != nil {
543 return err
544 }
545 }
546 derived := Derived{
547 Global: Values{
548 PCloudEnvName: env.Name,
549 },
550 Values: map[string]any{},
551 }
552 if len(namespaces) > 0 {
553 derived.Release.Namespace = namespaces[0]
554 }
555 return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived)
556}
557
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400558func (b Bootstrapper) installDNSZoneManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
559 const (
560 volumeClaimName = "dns-zone-configs"
561 volumeMountPath = "/etc/pcloud/dns-zone-configs"
562 )
563 ns, err := nsGen.Generate("dns-zone-manager")
564 if err != nil {
565 return err
566 }
567 if err := nsCreator.Create(ns); err != nil {
568 return err
569 }
570 appRepo := NewInMemoryAppRepository(CreateAllApps())
571 {
572 app, err := appRepo.Find("dns-zone-manager")
573 if err != nil {
574 return err
575 }
576 derived := Derived{
577 Global: Values{
578 PCloudEnvName: env.Name,
579 },
580 Values: map[string]any{
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400581 "volume": map[string]any{
582 "claimName": volumeClaimName,
583 "mountPath": volumeMountPath,
584 "size": "1Gi",
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400585 },
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400586 "apiConfigMapName": dnsAPIConfigMapName,
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400587 },
588 Release: Release{
589 Namespace: ns,
590 },
591 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400592 if err := repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived); err != nil {
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400593 return err
594 }
595 }
596 return nil
597}
598
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400599func (b Bootstrapper) installFluxcdReconciler(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
600 appRepo := NewInMemoryAppRepository(CreateAllApps())
601 app, err := appRepo.Find("fluxcd-reconciler")
602 if err != nil {
603 return err
604 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400605 ns, err := nsGen.Generate(app.Namespaces()[0])
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400606 if err != nil {
607 return err
608 }
609 if err := nsCreator.Create(ns); err != nil {
610 return err
611 }
612 derived := Derived{
613 Global: Values{
614 PCloudEnvName: env.Name,
615 },
616 Values: map[string]any{},
617 Release: Release{
618 Namespace: ns,
619 },
620 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400621 if err := repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived); err != nil {
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400622 return err
623 }
624 return nil
625}
626
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400627type HelmActionConfigFactory interface {
628 New(namespace string) (*action.Configuration, error)
629}
630
631type ChartLoader interface {
632 Load(name string) (*chart.Chart, error)
633}
634
635type fsChartLoader struct {
636 baseDir string
637}
638
639func NewFSChartLoader(baseDir string) ChartLoader {
640 return &fsChartLoader{baseDir}
641}
642
643func (l *fsChartLoader) Load(name string) (*chart.Chart, error) {
644 return loader.Load(filepath.Join(l.baseDir, name))
645}