blob: 9cd0a4cb4d4411f44bdc74878c56180c37359882 [file] [log] [blame]
giolekva8aa73e82022-07-09 11:34:39 +04001package main
2
3import (
4 "context"
giolekva8aa73e82022-07-09 11:34:39 +04005 _ "embed"
giolekva8aa73e82022-07-09 11:34:39 +04006 "fmt"
giolekva8aa73e82022-07-09 11:34:39 +04007 "log"
8 "os"
9 "path/filepath"
10 "time"
11
Giorgi Lekveishvili402fff92023-07-09 19:38:24 +040012 "github.com/cenkalti/backoff/v4"
giolekva8aa73e82022-07-09 11:34:39 +040013 "github.com/spf13/cobra"
14 "helm.sh/helm/v3/pkg/action"
15 "helm.sh/helm/v3/pkg/chart/loader"
16 "helm.sh/helm/v3/pkg/kube"
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +040017
18 "github.com/giolekva/pcloud/core/installer"
19 "github.com/giolekva/pcloud/core/installer/soft"
giolekva8aa73e82022-07-09 11:34:39 +040020)
21
22var bootstrapFlags struct {
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040023 pcloudEnvName string
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040024 chartsDir string
25 adminPubKey string
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040026 storageDir string
27 volumeDefaultReplicaCount int
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040028 softServeIP string // TODO(giolekva): reserve using metallb IPAddressPool
giolekva8aa73e82022-07-09 11:34:39 +040029}
30
31func bootstrapCmd() *cobra.Command {
32 cmd := &cobra.Command{
33 Use: "bootstrap",
34 RunE: bootstrapCmdRun,
35 }
36 cmd.Flags().StringVar(
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040037 &bootstrapFlags.pcloudEnvName,
38 "pcloud-env-name",
39 "pcloud",
40 "",
41 )
42 cmd.Flags().StringVar(
giolekva8aa73e82022-07-09 11:34:39 +040043 &bootstrapFlags.chartsDir,
44 "charts-dir",
45 "",
46 "",
47 )
48 cmd.Flags().StringVar(
49 &bootstrapFlags.adminPubKey,
50 "admin-pub-key",
51 "",
52 "",
53 )
54 cmd.Flags().StringVar(
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040055 &bootstrapFlags.storageDir,
56 "storage-dir",
57 "",
58 "",
59 )
60 cmd.Flags().IntVar(
61 &bootstrapFlags.volumeDefaultReplicaCount,
62 "volume-default-replica-count",
63 3,
64 "",
65 )
66 cmd.Flags().StringVar(
67 &bootstrapFlags.softServeIP,
68 "soft-serve-ip",
69 "",
70 "",
71 )
giolekva8aa73e82022-07-09 11:34:39 +040072 return cmd
73}
74
75func bootstrapCmdRun(cmd *cobra.Command, args []string) error {
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040076 adminPubKey, err := os.ReadFile(bootstrapFlags.adminPubKey)
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +040077 if err != nil {
78 return err
79 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040080 bootstrapJobKeys, err := installer.NewSSHKeyPair()
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +040081 if err != nil {
82 return err
83 }
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +040084 if err := installMetallb(); err != nil {
85 return err
86 }
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +040087 if err := installLonghorn(); err != nil {
88 return err
89 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040090 time.Sleep(2 * time.Minute) // TODO(giolekva): implement proper wait
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040091 if err := installSoftServe(bootstrapJobKeys.Public); err != nil {
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +040092 return err
93 }
Giorgi Lekveishvili402fff92023-07-09 19:38:24 +040094 var ss *soft.Client
95 err = backoff.Retry(func() error {
96 var err error
97 ss, err = soft.NewClient(bootstrapFlags.softServeIP, 22, []byte(bootstrapJobKeys.Private), log.Default())
98 return err
99 }, backoff.NewConstantBackOff(5*time.Second))
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400100 if err != nil {
101 return err
102 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400103 if ss.AddPublicKey("admin", string(adminPubKey)); err != nil {
104 return err
105 }
106 if err := installFluxcd(ss, bootstrapFlags.pcloudEnvName); err != nil {
107 return err
108 }
109 repo, err := ss.GetRepo(bootstrapFlags.pcloudEnvName)
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +0400110 if err != nil {
111 return err
112 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400113 repoIO := installer.NewRepoIO(repo, ss.Signer)
114 if err := configurePCloudRepo(repoIO); err != nil {
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +0400115 return err
116 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400117 // TODO(giolekva): commit this to the repo above
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400118 global := installer.Values{
119 PCloudEnvName: bootstrapFlags.pcloudEnvName,
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400120 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400121 nsCreator, err := newNSCreator()
122 if err != nil {
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +0400123 return err
124 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400125 nsGen := installer.NewPrefixGenerator("pcloud-")
126 if err := installInfrastructureServices(repoIO, nsGen, nsCreator, global); err != nil {
127 return err
128 }
129 if err := installEnvManager(ss, repoIO, nsGen, nsCreator, global); err != nil {
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +0400130 return err
131 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400132 if ss.RemovePublicKey("admin", bootstrapJobKeys.Public); err != nil {
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +0400133 return err
134 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400135 return nil
136}
137
138func installMetallb() error {
139 if err := installMetallbNamespace(); err != nil {
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400140 return err
141 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400142 if err := installMetallbService(); err != nil {
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400143 return err
144 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400145 if err := installMetallbConfig(); err != nil {
Giorgi Lekveishvilid6e80cc2023-06-09 17:38:49 +0400146 return err
147 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400148 return nil
149}
150
151func installMetallbNamespace() error {
152 fmt.Println("Installing metallb namespace")
153 // config, err := createActionConfig("default")
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400154 config, err := createActionConfig(bootstrapFlags.pcloudEnvName)
giolekva8aa73e82022-07-09 11:34:39 +0400155 if err != nil {
156 return err
157 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400158 chart, err := loader.Load(filepath.Join(bootstrapFlags.chartsDir, "namespace"))
giolekva8aa73e82022-07-09 11:34:39 +0400159 if err != nil {
160 return err
161 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400162 values := map[string]interface{}{
163 // "namespace": "pcloud-metallb",
164 "namespace": "metallb-system",
165 "labels": []string{
166 "pod-security.kubernetes.io/audit: privileged",
167 "pod-security.kubernetes.io/enforce: privileged",
168 "pod-security.kubernetes.io/warn: privileged",
169 },
170 }
171 installer := action.NewInstall(config)
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400172 installer.Namespace = bootstrapFlags.pcloudEnvName
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400173 installer.ReleaseName = "metallb-ns"
174 installer.Wait = true
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400175 installer.WaitForJobs = true
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400176 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
177 return err
178 }
179 return nil
180}
181
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400182func installMetallbService() error {
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400183 fmt.Println("Installing metallb")
184 // config, err := createActionConfig("default")
185 config, err := createActionConfig("metallb-system")
giolekva8aa73e82022-07-09 11:34:39 +0400186 if err != nil {
187 return err
188 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400189 chart, err := loader.Load(filepath.Join(bootstrapFlags.chartsDir, "metallb"))
giolekva8aa73e82022-07-09 11:34:39 +0400190 if err != nil {
191 return err
192 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400193 values := map[string]interface{}{ // TODO(giolekva): add loadBalancerClass?
194 "controller": map[string]interface{}{
195 "image": map[string]interface{}{
196 "repository": "quay.io/metallb/controller",
197 "tag": "v0.13.9",
198 "pullPolicy": "IfNotPresent",
199 },
200 "logLevel": "info",
201 },
202 "speaker": map[string]interface{}{
203 "image": map[string]interface{}{
204 "repository": "quay.io/metallb/speaker",
205 "tag": "v0.13.9",
206 "pullPolicy": "IfNotPresent",
207 },
208 "logLevel": "info",
209 },
210 }
211 installer := action.NewInstall(config)
212 installer.Namespace = "metallb-system" // "pcloud-metallb"
213 installer.CreateNamespace = true
214 installer.ReleaseName = "metallb"
215 installer.IncludeCRDs = true
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400216 installer.Wait = true
217 installer.WaitForJobs = true
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400218 installer.Timeout = 20 * time.Minute
219 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
giolekva8aa73e82022-07-09 11:34:39 +0400220 return err
221 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400222 return nil
223}
224
225func installMetallbConfig() error {
226 fmt.Println("Installing metallb-config")
227 // config, err := createActionConfig("default")
228 config, err := createActionConfig("metallb-system")
229 if err != nil {
giolekva8aa73e82022-07-09 11:34:39 +0400230 return err
231 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400232 chart, err := loader.Load(filepath.Join(bootstrapFlags.chartsDir, "metallb-config"))
233 if err != nil {
giolekva8aa73e82022-07-09 11:34:39 +0400234 return err
235 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400236 values := map[string]interface{}{
237 "from": "192.168.0.210",
238 "to": "192.168.0.240",
239 }
240 installer := action.NewInstall(config)
241 installer.Namespace = "metallb-system" // "pcloud-metallb"
242 installer.CreateNamespace = true
243 installer.ReleaseName = "metallb-cfg"
244 installer.Wait = true
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400245 installer.WaitForJobs = true
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400246 installer.Timeout = 20 * time.Minute
247 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
248 return err
249 }
250 return nil
251}
252
253func installLonghorn() error {
254 fmt.Println("Installing Longhorn")
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400255 config, err := createActionConfig(bootstrapFlags.pcloudEnvName)
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400256 if err != nil {
257 return err
258 }
259 chart, err := loader.Load(filepath.Join(bootstrapFlags.chartsDir, "longhorn"))
260 if err != nil {
261 return err
262 }
263 values := map[string]interface{}{
264 "defaultSettings": map[string]interface{}{
265 "defaultDataPath": bootstrapFlags.storageDir,
266 },
267 "persistence": map[string]interface{}{
268 "defaultClassReplicaCount": bootstrapFlags.volumeDefaultReplicaCount,
269 },
270 "service": map[string]interface{}{
271 "ui": map[string]interface{}{
272 "type": "LoadBalancer",
273 },
274 },
275 "ingress": map[string]interface{}{
276 "enabled": false,
277 },
278 }
279 installer := action.NewInstall(config)
280 installer.Namespace = "longhorn-system"
281 installer.CreateNamespace = true
282 installer.ReleaseName = "longhorn"
283 installer.Wait = true
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400284 installer.WaitForJobs = true
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400285 installer.Timeout = 20 * time.Minute
286 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
giolekva8aa73e82022-07-09 11:34:39 +0400287 return err
288 }
289 return nil
290}
291
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400292func installSoftServe(adminPublicKey string) error {
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400293 fmt.Println("Installing SoftServe")
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400294 keys, err := installer.NewSSHKeyPair()
295 if err != nil {
296 return err
297 }
298 config, err := createActionConfig(bootstrapFlags.pcloudEnvName)
giolekva8aa73e82022-07-09 11:34:39 +0400299 if err != nil {
300 return err
301 }
302 chart, err := loader.Load(filepath.Join(bootstrapFlags.chartsDir, "soft-serve"))
303 if err != nil {
304 return err
305 }
306 values := map[string]interface{}{
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400307 "privateKey": keys.Private,
308 "publicKey": keys.Public,
309 "adminKey": adminPublicKey,
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400310 "reservedIP": bootstrapFlags.softServeIP,
giolekva8aa73e82022-07-09 11:34:39 +0400311 }
312 installer := action.NewInstall(config)
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400313 installer.Namespace = bootstrapFlags.pcloudEnvName
giolekva8aa73e82022-07-09 11:34:39 +0400314 installer.CreateNamespace = true
315 installer.ReleaseName = "soft-serve"
316 installer.Wait = true
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400317 installer.WaitForJobs = true
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400318 installer.Timeout = 20 * time.Minute
giolekva8aa73e82022-07-09 11:34:39 +0400319 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
320 return err
321 }
322 return nil
323}
324
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400325func installFluxcd(ss *soft.Client, pcloudEnvName string) error {
326 keys, err := installer.NewSSHKeyPair()
327 if err != nil {
328 return err
329 }
330 if err := ss.AddUser("flux", keys.Public); err != nil {
331 return err
332 }
333 if err := ss.MakeUserAdmin("flux"); err != nil {
334 return err
335 }
336 fmt.Printf("Creating /%s repo", pcloudEnvName)
337 if err := ss.AddRepository(pcloudEnvName, "# PCloud Systems"); err != nil {
338 return err
339 }
340 fmt.Println("Installing Flux")
341 ssPublic, err := ss.GetPublicKey()
342 if err != nil {
343 return err
344 }
345 if err := installFluxBootstrap(
346 ss.GetRepoAddress(pcloudEnvName),
347 ss.IP,
348 string(ssPublic),
349 keys.Private,
350 ); err != nil {
351 return err
352 }
353 return nil
354}
355
356func installFluxBootstrap(repoAddr, repoHost, repoHostPubKey, privateKey string) error {
357 config, err := createActionConfig(bootstrapFlags.pcloudEnvName)
giolekva8aa73e82022-07-09 11:34:39 +0400358 if err != nil {
359 return err
360 }
361 chart, err := loader.Load(filepath.Join(bootstrapFlags.chartsDir, "flux-bootstrap"))
362 if err != nil {
363 return err
364 }
Giorgi Lekveishvili402fff92023-07-09 19:38:24 +0400365 values := map[string]any{
366 "image": map[string]any{
367 "repository": "giolekva/flux",
368 "tag": "2.0.0",
369 "pullPolicy": "IfNotPresent",
370 },
giolekva8aa73e82022-07-09 11:34:39 +0400371 "repositoryAddress": repoAddr,
372 "repositoryHost": repoHost,
373 "repositoryHostPublicKey": repoHostPubKey,
374 "privateKey": privateKey,
375 }
376 installer := action.NewInstall(config)
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400377 installer.Namespace = bootstrapFlags.pcloudEnvName
giolekva8aa73e82022-07-09 11:34:39 +0400378 installer.CreateNamespace = true
379 installer.ReleaseName = "flux"
380 installer.Wait = true
381 installer.WaitForJobs = true
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400382 installer.Timeout = 20 * time.Minute
giolekva8aa73e82022-07-09 11:34:39 +0400383 if _, err := installer.RunWithContext(context.TODO(), chart, values); err != nil {
384 return err
385 }
386 return nil
387}
388
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400389func installInfrastructureServices(repo installer.RepoIO, nsGen installer.NamespaceGenerator, nsCreator installer.NamespaceCreator, global installer.Values) error {
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400390 appRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
391 install := func(name string) error {
392 app, err := appRepo.Find(name)
393 if err != nil {
394 return err
395 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400396 namespaces := make([]string, len(app.Namespaces))
397 for i, n := range app.Namespaces {
398 namespaces[i], err = nsGen.Generate(n)
399 if err != nil {
400 return err
401 }
402 }
403 for _, n := range namespaces {
404 if err := nsCreator.Create(n); err != nil {
405 return err
406 }
407 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400408 derived := installer.Derived{
409 Global: global,
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400410 }
411 if len(namespaces) > 0 {
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400412 derived.Release.Namespace = namespaces[0]
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400413 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400414 return repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), map[string]any{}, derived)
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400415 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400416 appsToInstall := []string{
417 "resource-renderer-controller",
418 "headscale-controller",
419 "csi-driver-smb",
420 "ingress-public",
421 "cert-manager",
422 "cert-manager-webhook-gandi",
423 "cert-manager-webhook-gandi-role",
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400424 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400425 for _, name := range appsToInstall {
426 if err := install(name); err != nil {
427 return err
428 }
Giorgi Lekveishvilid6e80cc2023-06-09 17:38:49 +0400429 }
430 return nil
431}
432
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400433func configurePCloudRepo(repo installer.RepoIO) error {
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400434 {
435 kust := installer.NewKustomization()
436 kust.AddResources("pcloud-flux", "infrastructure", "environments")
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(`
447apiVersion: source.toolkit.fluxcd.io/v1beta2
448kind: GitRepository
449metadata:
450 name: pcloud # TODO(giolekva): use more generic name
451 namespace: pcloud # TODO(giolekva): configurable
452spec:
453 interval: 1m0s
454 url: https://github.com/giolekva/pcloud
455 ref:
456 branch: main
457`))
458 if err != nil {
459 return err
460 }
461 }
462 infraKust := installer.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", installer.NewKustomization()); err != nil {
468 return err
469 }
470 if err := repo.CommitAndPush("initialize pcloud directory structure"); err != nil {
471 return err
472 }
473 }
474 return nil
475}
476
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400477func installEnvManager(ss *soft.Client, repo installer.RepoIO, nsGen installer.NamespaceGenerator, nsCreator installer.NamespaceCreator, global installer.Values) error {
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400478 keys, err := installer.NewSSHKeyPair()
479 if err != nil {
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400480 return err
481 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400482 user := fmt.Sprintf("%s-env-manager", bootstrapFlags.pcloudEnvName)
483 if err := ss.AddUser(user, keys.Public); err != nil {
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400484 return err
485 }
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400486 if err := ss.MakeUserAdmin(user); err != nil {
487 return err
488 }
489 appRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400490 app, err := appRepo.Find("env-manager")
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400491 if err != nil {
492 return err
493 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400494 namespaces := make([]string, len(app.Namespaces))
495 for i, n := range app.Namespaces {
496 namespaces[i], err = nsGen.Generate(n)
497 if err != nil {
498 return err
499 }
500 }
501 for _, n := range namespaces {
502 if err := nsCreator.Create(n); err != nil {
503 return err
504 }
505 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400506 derived := installer.Derived{
507 Global: global,
508 Values: map[string]any{
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400509 "RepoIP": bootstrapFlags.softServeIP,
510 "SSHPrivateKey": keys.Private,
511 },
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400512 }
513 if len(namespaces) > 0 {
514 derived.Release.Namespace = namespaces[0]
515 }
516 return repo.InstallApp(*app, filepath.Join("/infrastructure", app.Name), derived.Values, derived)
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +0400517}
518
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400519func createActionConfig(namespace string) (*action.Configuration, error) {
giolekva8aa73e82022-07-09 11:34:39 +0400520 config := new(action.Configuration)
521 if err := config.Init(
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400522 kube.GetConfig(rootFlags.kubeConfig, "", namespace),
523 namespace,
giolekva8aa73e82022-07-09 11:34:39 +0400524 "",
525 func(fmtString string, args ...interface{}) {
526 fmt.Printf(fmtString, args...)
527 fmt.Println()
528 },
529 ); err != nil {
530 return nil, err
531 }
532 return config, nil
533}