blob: 8da05a250a65661964c45966577ca793cf70645b [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 Lekveishvili106a9352023-12-04 11:20:11 +0400100 fmt.Println("Environment ready to use")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400101 return nil
102}
103
104func (b Bootstrapper) installMetallb(env EnvConfig) error {
105 if err := b.installMetallbNamespace(env); err != nil {
106 return err
107 }
108 if err := b.installMetallbService(); err != nil {
109 return err
110 }
111 if err := b.installMetallbIPAddressPool(IPAddressPoolLocal, true, env.ServiceIPs.From, env.ServiceIPs.To); err != nil {
112 return err
113 }
114 if err := b.installMetallbIPAddressPool(IPAddressPoolConfigRepo, false, env.ServiceIPs.ConfigRepo, env.ServiceIPs.ConfigRepo); err != nil {
115 return err
116 }
117 if err := b.installMetallbIPAddressPool(IPAddressPoolIngressPublic, false, env.ServiceIPs.IngressPublic, env.ServiceIPs.IngressPublic); err != nil {
118 return err
119 }
120 return nil
121}
122
123func (b Bootstrapper) installMetallbNamespace(env EnvConfig) error {
124 fmt.Println("Installing metallb namespace")
125 config, err := b.ha.New(env.Name)
126 if err != nil {
127 return err
128 }
129 chart, err := b.cl.Load("namespace")
130 if err != nil {
131 return err
132 }
133 values := map[string]any{
134 "namespace": "metallb-system",
135 "labels": []string{
136 "pod-security.kubernetes.io/audit: privileged",
137 "pod-security.kubernetes.io/enforce: privileged",
138 "pod-security.kubernetes.io/warn: privileged",
139 },
140 }
141 installer := action.NewInstall(config)
142 installer.Namespace = env.Name
143 installer.ReleaseName = "metallb-ns"
144 installer.Wait = true
145 installer.WaitForJobs = true
146 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
147 return err
148 }
149 return nil
150}
151
152func (b Bootstrapper) installMetallbService() error {
153 fmt.Println("Installing metallb")
154 config, err := b.ha.New("metallb-system")
155 if err != nil {
156 return err
157 }
158 chart, err := b.cl.Load("metallb")
159 if err != nil {
160 return err
161 }
162 values := map[string]any{ // TODO(giolekva): add loadBalancerClass?
163 "controller": map[string]any{
164 "image": map[string]any{
165 "repository": "quay.io/metallb/controller",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400166 "tag": "v0.13.12",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400167 "pullPolicy": "IfNotPresent",
168 },
169 "logLevel": "info",
170 },
171 "speaker": map[string]any{
172 "image": map[string]any{
173 "repository": "quay.io/metallb/speaker",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400174 "tag": "v0.13.12",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400175 "pullPolicy": "IfNotPresent",
176 },
177 "logLevel": "info",
178 },
179 }
180 installer := action.NewInstall(config)
181 installer.Namespace = "metallb-system"
182 installer.CreateNamespace = true
183 installer.ReleaseName = "metallb"
184 installer.IncludeCRDs = true
185 installer.Wait = true
186 installer.WaitForJobs = true
187 installer.Timeout = 20 * time.Minute
188 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
189 return err
190 }
191 return nil
192}
193
194func (b Bootstrapper) installMetallbIPAddressPool(name string, autoAssign bool, from, to netip.Addr) error {
195 fmt.Printf("Installing metallb-ipaddresspool: %s\n", name)
196 config, err := b.ha.New("metallb-system")
197 if err != nil {
198 return err
199 }
200 chart, err := b.cl.Load("metallb-ipaddresspool")
201 if err != nil {
202 return err
203 }
204 values := map[string]any{
205 "name": name,
206 "autoAssign": autoAssign,
207 "from": from.String(),
208 "to": to.String(),
209 }
210 installer := action.NewInstall(config)
211 installer.Namespace = "metallb-system"
212 installer.CreateNamespace = true
213 installer.ReleaseName = name
214 installer.Wait = true
215 installer.WaitForJobs = true
216 installer.Timeout = 20 * time.Minute
217 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
218 return err
219 }
220 return nil
221}
222
223func (b Bootstrapper) installLonghorn(envName string, storageDir string, volumeDefaultReplicaCount int) error {
224 fmt.Println("Installing Longhorn")
225 config, err := b.ha.New(envName)
226 if err != nil {
227 return err
228 }
229 chart, err := b.cl.Load("longhorn")
230 if err != nil {
231 return err
232 }
233 values := map[string]any{
234 "defaultSettings": map[string]any{
235 "defaultDataPath": storageDir,
236 },
237 "persistence": map[string]any{
238 "defaultClassReplicaCount": volumeDefaultReplicaCount,
239 },
240 "service": map[string]any{
241 "ui": map[string]any{
242 "type": "LoadBalancer",
243 },
244 },
245 "ingress": map[string]any{
246 "enabled": false,
247 },
248 }
249 installer := action.NewInstall(config)
250 installer.Namespace = "longhorn-system"
251 installer.CreateNamespace = true
252 installer.ReleaseName = "longhorn"
253 installer.Wait = true
254 installer.WaitForJobs = true
255 installer.Timeout = 20 * time.Minute
256 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
257 return err
258 }
259 return nil
260}
261
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400262func (b Bootstrapper) installSoftServe(adminPublicKey string, namespace string, repoIP netip.Addr) error {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400263 fmt.Println("Installing SoftServe")
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400264 keys, err := NewSSHKeyPair("soft-serve")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400265 if err != nil {
266 return err
267 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400268 config, err := b.ha.New(namespace)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400269 if err != nil {
270 return err
271 }
272 chart, err := b.cl.Load("soft-serve")
273 if err != nil {
274 return err
275 }
276 values := map[string]any{
277 "image": map[string]any{
278 "repository": "charmcli/soft-serve",
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400279 "tag": "v0.7.1",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400280 "pullPolicy": "IfNotPresent",
281 },
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400282 "privateKey": string(keys.RawPrivateKey()),
283 "publicKey": string(keys.RawAuthorizedKey()),
284 "adminKey": adminPublicKey,
285 "reservedIP": repoIP.String(),
286 "serviceType": "LoadBalancer",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400287 }
288 installer := action.NewInstall(config)
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400289 installer.Namespace = namespace
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400290 installer.CreateNamespace = true
291 installer.ReleaseName = "soft-serve"
292 installer.Wait = true
293 installer.WaitForJobs = true
294 installer.Timeout = 20 * time.Minute
295 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
296 return err
297 }
298 return nil
299}
300
301func (b Bootstrapper) installFluxcd(ss *soft.Client, envName string) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400302 keys, err := NewSSHKeyPair("fluxcd")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400303 if err != nil {
304 return err
305 }
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400306 if err := ss.AddUser("flux", keys.AuthorizedKey()); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400307 return err
308 }
309 if err := ss.MakeUserAdmin("flux"); err != nil {
310 return err
311 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400312 if err := ss.AddRepository("config"); err != nil {
313 return err
314 }
315 repo, err := ss.GetRepo("config")
316 if err != nil {
317 return err
318 }
319 repoIO := NewRepoIO(repo, ss.Signer)
320 if err := repoIO.WriteCommitAndPush("README.md", fmt.Sprintf("# %s systems", envName), "readme"); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400321 return err
322 }
323 fmt.Println("Installing Flux")
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400324 ssPublicKeys, err := ss.GetPublicKeys()
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400325 if err != nil {
326 return err
327 }
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400328 host := strings.Split(ss.Addr, ":")[0]
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400329 if err := b.installFluxBootstrap(
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400330 ss.GetRepoAddress("config"),
331 host,
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400332 ssPublicKeys,
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400333 string(keys.RawPrivateKey()),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400334 envName,
335 ); err != nil {
336 return err
337 }
338 return nil
339}
340
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400341func (b Bootstrapper) installFluxBootstrap(repoAddr, repoHost string, repoHostPubKeys []string, privateKey, envName string) error {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400342 config, err := b.ha.New(envName)
343 if err != nil {
344 return err
345 }
346 chart, err := b.cl.Load("flux-bootstrap")
347 if err != nil {
348 return err
349 }
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400350 var lines []string
351 for _, k := range repoHostPubKeys {
352 lines = append(lines, fmt.Sprintf("%s %s", repoHost, k))
353 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400354 values := map[string]any{
355 "image": map[string]any{
Giorgi Lekveishvilic06164d2023-11-22 13:51:29 +0400356 "repository": "fluxcd/flux-cli",
357 "tag": "v2.1.2",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400358 "pullPolicy": "IfNotPresent",
359 },
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400360 "repositoryAddress": repoAddr,
361 "repositoryHost": repoHost,
362 "repositoryHostPublicKeys": strings.Join(lines, "\n"),
363 "privateKey": privateKey,
364 "installationNamespace": fmt.Sprintf("%s-flux", envName),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400365 }
366 installer := action.NewInstall(config)
367 installer.Namespace = envName
368 installer.CreateNamespace = true
369 installer.ReleaseName = "flux"
370 installer.Wait = true
371 installer.WaitForJobs = true
372 installer.Timeout = 20 * time.Minute
373 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
374 return err
375 }
376 return nil
377}
378
379func (b Bootstrapper) installInfrastructureServices(repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
380 appRepo := NewInMemoryAppRepository(CreateAllApps())
381 install := func(name string) error {
382 app, err := appRepo.Find(name)
383 if err != nil {
384 return err
385 }
386 namespaces := make([]string, len(app.Namespaces))
387 for i, n := range app.Namespaces {
388 namespaces[i], err = nsGen.Generate(n)
389 if err != nil {
390 return err
391 }
392 }
393 for _, n := range namespaces {
394 if err := nsCreator.Create(n); err != nil {
395 return err
396 }
397 }
398 derived := Derived{
399 Global: Values{
400 PCloudEnvName: env.Name,
401 },
402 }
403 if len(namespaces) > 0 {
404 derived.Release.Namespace = namespaces[0]
405 }
406 values := map[string]any{
407 "IngressPublicIP": env.ServiceIPs.IngressPublic.String(),
408 }
409 return repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), values, derived)
410 }
411 appsToInstall := []string{
412 "resource-renderer-controller",
413 "headscale-controller",
414 "csi-driver-smb",
415 "ingress-public",
416 "cert-manager",
Giorgi Lekveishvili5c2c0b92023-12-07 17:35:40 +0400417 "cert-manager-webhook-pcloud",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400418 }
419 for _, name := range appsToInstall {
420 if err := install(name); err != nil {
421 return err
422 }
423 }
424 return nil
425}
426
427func configureMainRepo(repo RepoIO, env EnvConfig) error {
428 if err := repo.WriteYaml("config.yaml", env); err != nil {
429 return err
430 }
431 kust := NewKustomization()
432 kust.AddResources(
433 fmt.Sprintf("%s-flux", env.Name),
434 "infrastructure",
435 "environments",
436 )
437 if err := repo.WriteKustomization("kustomization.yaml", kust); err != nil {
438 return err
439 }
440 {
441 out, err := repo.Writer("infrastructure/pcloud-charts.yaml")
442 if err != nil {
443 return err
444 }
445 defer out.Close()
446 _, err = out.Write([]byte(fmt.Sprintf(`
447apiVersion: source.toolkit.fluxcd.io/v1
448kind: GitRepository
449metadata:
450 name: pcloud # TODO(giolekva): use more generic name
451 namespace: %s
452spec:
453 interval: 1m0s
454 url: https://github.com/giolekva/pcloud
455 ref:
456 branch: main
457`, env.Name)))
458 if err != nil {
459 return err
460 }
461 }
462 infraKust := NewKustomization()
463 infraKust.AddResources("pcloud-charts.yaml")
464 if err := repo.WriteKustomization("infrastructure/kustomization.yaml", infraKust); err != nil {
465 return err
466 }
467 if err := repo.WriteKustomization("environments/kustomization.yaml", NewKustomization()); err != nil {
468 return err
469 }
470 if err := repo.CommitAndPush("initialize pcloud directory structure"); err != nil {
471 return err
472 }
473 return nil
474}
475
476func (b Bootstrapper) installEnvManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400477 keys, err := NewSSHKeyPair("env-manager")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400478 if err != nil {
479 return err
480 }
481 user := fmt.Sprintf("%s-env-manager", env.Name)
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400482 if err := ss.AddUser(user, keys.AuthorizedKey()); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400483 return err
484 }
485 if err := ss.MakeUserAdmin(user); err != nil {
486 return err
487 }
488 appRepo := NewInMemoryAppRepository(CreateAllApps())
489 app, err := appRepo.Find("env-manager")
490 if err != nil {
491 return err
492 }
493 namespaces := make([]string, len(app.Namespaces))
494 for i, n := range app.Namespaces {
495 namespaces[i], err = nsGen.Generate(n)
496 if err != nil {
497 return err
498 }
499 }
500 for _, n := range namespaces {
501 if err := nsCreator.Create(n); err != nil {
502 return err
503 }
504 }
505 derived := Derived{
506 Global: Values{
507 PCloudEnvName: env.Name,
508 },
509 Values: map[string]any{
510 "RepoIP": env.ServiceIPs.ConfigRepo,
511 "RepoPort": 22,
Giorgi Lekveishvili724885f2023-11-29 16:18:42 +0400512 "RepoName": "config",
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400513 "SSHPrivateKey": string(keys.RawPrivateKey()),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400514 },
515 }
516 if len(namespaces) > 0 {
517 derived.Release.Namespace = namespaces[0]
518 }
519 return repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), derived.Values, derived)
520}
521
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400522func (b Bootstrapper) installDNSZoneManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
523 const (
524 volumeClaimName = "dns-zone-configs"
525 volumeMountPath = "/etc/pcloud/dns-zone-configs"
526 )
527 ns, err := nsGen.Generate("dns-zone-manager")
528 if err != nil {
529 return err
530 }
531 if err := nsCreator.Create(ns); err != nil {
532 return err
533 }
534 appRepo := NewInMemoryAppRepository(CreateAllApps())
535 {
536 app, err := appRepo.Find("dns-zone-manager")
537 if err != nil {
538 return err
539 }
540 derived := Derived{
541 Global: Values{
542 PCloudEnvName: env.Name,
543 },
544 Values: map[string]any{
545 "Volume": map[string]any{
546 "ClaimName": volumeClaimName,
547 "MountPath": volumeMountPath,
548 "Size": "1Gi",
549 },
Giorgi Lekveishvili5c2c0b92023-12-07 17:35:40 +0400550 "APIConfigMapName": dnsAPIConfigMapName,
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400551 },
552 Release: Release{
553 Namespace: ns,
554 },
555 }
556 if err := repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), derived.Values, derived); err != nil {
557 return err
558 }
559 }
560 return nil
561}
562
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400563func (b Bootstrapper) installFluxcdReconciler(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
564 appRepo := NewInMemoryAppRepository(CreateAllApps())
565 app, err := appRepo.Find("fluxcd-reconciler")
566 if err != nil {
567 return err
568 }
569 ns, err := nsGen.Generate(app.Namespaces[0])
570 if err != nil {
571 return err
572 }
573 if err := nsCreator.Create(ns); err != nil {
574 return err
575 }
576 derived := Derived{
577 Global: Values{
578 PCloudEnvName: env.Name,
579 },
580 Values: map[string]any{},
581 Release: Release{
582 Namespace: ns,
583 },
584 }
585 if err := repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), derived.Values, derived); err != nil {
586 return err
587 }
588 return nil
589}
590
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400591type HelmActionConfigFactory interface {
592 New(namespace string) (*action.Configuration, error)
593}
594
595type ChartLoader interface {
596 Load(name string) (*chart.Chart, error)
597}
598
599type fsChartLoader struct {
600 baseDir string
601}
602
603func NewFSChartLoader(baseDir string) ChartLoader {
604 return &fsChartLoader{baseDir}
605}
606
607func (l *fsChartLoader) Load(name string) (*chart.Chart, error) {
608 return loader.Load(filepath.Join(l.baseDir, name))
609}