blob: fa1a997d1b20991e3a41b7d55a2b7ff895605171 [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 Lekveishvili5c1b06e2024-03-28 15:19:44 +040053 time.Sleep(30 * time.Second)
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 {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400386 fmt.Printf("Installing infrastructure service %s\n", name)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400387 app, err := appRepo.Find(name)
388 if err != nil {
389 return err
390 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400391 namespaces := make([]string, len(app.Namespaces()))
392 for i, n := range app.Namespaces() {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400393 namespaces[i], err = nsGen.Generate(n)
394 if err != nil {
395 return err
396 }
397 }
398 for _, n := range namespaces {
399 if err := nsCreator.Create(n); err != nil {
400 return err
401 }
402 }
403 derived := Derived{
404 Global: Values{
405 PCloudEnvName: env.Name,
406 },
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400407 Release: Release{},
408 Values: make(map[string]any),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400409 }
410 if len(namespaces) > 0 {
411 derived.Release.Namespace = namespaces[0]
412 }
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400413 values := map[string]any{}
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400414 return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), values, derived)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400415 }
416 appsToInstall := []string{
417 "resource-renderer-controller",
418 "headscale-controller",
419 "csi-driver-smb",
420 "ingress-public",
421 "cert-manager",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400422 }
423 for _, name := range appsToInstall {
424 if err := install(name); err != nil {
425 return err
426 }
427 }
428 return nil
429}
430
431func configureMainRepo(repo RepoIO, env EnvConfig) error {
432 if err := repo.WriteYaml("config.yaml", env); err != nil {
433 return err
434 }
Giorgi Lekveishvili9d5e3f52024-03-13 15:02:50 +0400435 if err := repo.WriteYaml("env-cidrs.yaml", EnvCIDRs{}); err != nil {
436 return err
437 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400438 kust := NewKustomization()
439 kust.AddResources(
440 fmt.Sprintf("%s-flux", env.Name),
441 "infrastructure",
442 "environments",
443 )
444 if err := repo.WriteKustomization("kustomization.yaml", kust); err != nil {
445 return err
446 }
447 {
448 out, err := repo.Writer("infrastructure/pcloud-charts.yaml")
449 if err != nil {
450 return err
451 }
452 defer out.Close()
453 _, err = out.Write([]byte(fmt.Sprintf(`
454apiVersion: source.toolkit.fluxcd.io/v1
455kind: GitRepository
456metadata:
457 name: pcloud # TODO(giolekva): use more generic name
458 namespace: %s
459spec:
460 interval: 1m0s
461 url: https://github.com/giolekva/pcloud
462 ref:
Giorgi Lekveishvili024757c2024-03-14 13:27:29 +0400463 branch: main
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400464`, env.Name)))
465 if err != nil {
466 return err
467 }
468 }
469 infraKust := NewKustomization()
470 infraKust.AddResources("pcloud-charts.yaml")
471 if err := repo.WriteKustomization("infrastructure/kustomization.yaml", infraKust); err != nil {
472 return err
473 }
474 if err := repo.WriteKustomization("environments/kustomization.yaml", NewKustomization()); err != nil {
475 return err
476 }
477 if err := repo.CommitAndPush("initialize pcloud directory structure"); err != nil {
478 return err
479 }
480 return nil
481}
482
483func (b Bootstrapper) installEnvManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400484 keys, err := NewSSHKeyPair("env-manager")
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400485 if err != nil {
486 return err
487 }
488 user := fmt.Sprintf("%s-env-manager", env.Name)
Giorgi Lekveishvilia1e77902023-11-06 14:48:27 +0400489 if err := ss.AddUser(user, keys.AuthorizedKey()); err != nil {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400490 return err
491 }
492 if err := ss.MakeUserAdmin(user); err != nil {
493 return err
494 }
495 appRepo := NewInMemoryAppRepository(CreateAllApps())
496 app, err := appRepo.Find("env-manager")
497 if err != nil {
498 return err
499 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400500 namespaces := make([]string, len(app.Namespaces()))
501 for i, n := range app.Namespaces() {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400502 namespaces[i], err = nsGen.Generate(n)
503 if err != nil {
504 return err
505 }
506 }
507 for _, n := range namespaces {
508 if err := nsCreator.Create(n); err != nil {
509 return err
510 }
511 }
512 derived := Derived{
513 Global: Values{
514 PCloudEnvName: env.Name,
515 },
516 Values: map[string]any{
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400517 "repoIP": env.ServiceIPs.ConfigRepo,
518 "repoPort": 22,
519 "repoName": "config",
520 "sshPrivateKey": string(keys.RawPrivateKey()),
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400521 },
522 }
523 if len(namespaces) > 0 {
524 derived.Release.Namespace = namespaces[0]
525 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400526 return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived)
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400527}
528
Giorgi Lekveishvili925f0de2024-03-14 18:51:56 +0400529func (b Bootstrapper) installOryHydraMaester(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
530 appRepo := NewInMemoryAppRepository(CreateAllApps())
531 app, err := appRepo.Find("hydra-maester")
532 if err != nil {
533 return err
534 }
535 namespaces := make([]string, len(app.Namespaces()))
536 for i, n := range app.Namespaces() {
537 namespaces[i], err = nsGen.Generate(n)
538 if err != nil {
539 return err
540 }
541 }
542 for _, n := range namespaces {
543 if err := nsCreator.Create(n); err != nil {
544 return err
545 }
546 }
547 derived := Derived{
548 Global: Values{
549 PCloudEnvName: env.Name,
550 },
551 Values: map[string]any{},
552 }
553 if len(namespaces) > 0 {
554 derived.Release.Namespace = namespaces[0]
555 }
556 return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived)
557}
558
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400559func (b Bootstrapper) installDNSZoneManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
560 const (
561 volumeClaimName = "dns-zone-configs"
562 volumeMountPath = "/etc/pcloud/dns-zone-configs"
563 )
564 ns, err := nsGen.Generate("dns-zone-manager")
565 if err != nil {
566 return err
567 }
568 if err := nsCreator.Create(ns); err != nil {
569 return err
570 }
571 appRepo := NewInMemoryAppRepository(CreateAllApps())
572 {
573 app, err := appRepo.Find("dns-zone-manager")
574 if err != nil {
575 return err
576 }
577 derived := Derived{
578 Global: Values{
579 PCloudEnvName: env.Name,
580 },
581 Values: map[string]any{
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400582 "volume": map[string]any{
583 "claimName": volumeClaimName,
584 "mountPath": volumeMountPath,
585 "size": "1Gi",
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400586 },
Giorgi Lekveishvilie009a5d2024-01-05 14:10:11 +0400587 "apiConfigMapName": dnsAPIConfigMapName,
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400588 },
589 Release: Release{
590 Namespace: ns,
591 },
592 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400593 if err := repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived); err != nil {
Giorgi Lekveishvili106a9352023-12-04 11:20:11 +0400594 return err
595 }
596 }
597 return nil
598}
599
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400600func (b Bootstrapper) installFluxcdReconciler(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
601 appRepo := NewInMemoryAppRepository(CreateAllApps())
602 app, err := appRepo.Find("fluxcd-reconciler")
603 if err != nil {
604 return err
605 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400606 ns, err := nsGen.Generate(app.Namespaces()[0])
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400607 if err != nil {
608 return err
609 }
610 if err := nsCreator.Create(ns); err != nil {
611 return err
612 }
613 derived := Derived{
614 Global: Values{
615 PCloudEnvName: env.Name,
616 },
617 Values: map[string]any{},
618 Release: Release{
619 Namespace: ns,
620 },
621 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +0400622 if err := repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived); err != nil {
Giorgi Lekveishvili2df23db2023-12-14 07:55:22 +0400623 return err
624 }
625 return nil
626}
627
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400628type HelmActionConfigFactory interface {
629 New(namespace string) (*action.Configuration, error)
630}
631
632type ChartLoader interface {
633 Load(name string) (*chart.Chart, error)
634}
635
636type fsChartLoader struct {
637 baseDir string
638}
639
640func NewFSChartLoader(baseDir string) ChartLoader {
641 return &fsChartLoader{baseDir}
642}
643
644func (l *fsChartLoader) Load(name string) (*chart.Chart, error) {
645 return loader.Load(filepath.Join(l.baseDir, name))
646}