blob: d177ff568c5b295918360ce03eb73fe5881b28ff [file] [log] [blame]
giolekva8aa73e82022-07-09 11:34:39 +04001package main
2
3import (
giolekva8aa73e82022-07-09 11:34:39 +04004 _ "embed"
giolekva8aa73e82022-07-09 11:34:39 +04005 "fmt"
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +04006 "net/netip"
giolekva8aa73e82022-07-09 11:34:39 +04007 "os"
giolekva8aa73e82022-07-09 11:34:39 +04008
giolekva8aa73e82022-07-09 11:34:39 +04009 "github.com/spf13/cobra"
10 "helm.sh/helm/v3/pkg/action"
giolekva8aa73e82022-07-09 11:34:39 +040011 "helm.sh/helm/v3/pkg/kube"
Giorgi Lekveishvili3550b432023-06-09 19:37:51 +040012
13 "github.com/giolekva/pcloud/core/installer"
giolekva8aa73e82022-07-09 11:34:39 +040014)
15
16var bootstrapFlags struct {
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040017 envName string
18 publicIP string
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040019 chartsDir string
20 adminPubKey string
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040021 storageDir string
22 volumeDefaultReplicaCount int
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040023 fromIP string
24 toIP string
giolekva8aa73e82022-07-09 11:34:39 +040025}
26
27func bootstrapCmd() *cobra.Command {
28 cmd := &cobra.Command{
29 Use: "bootstrap",
30 RunE: bootstrapCmdRun,
31 }
32 cmd.Flags().StringVar(
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040033 &bootstrapFlags.envName,
34 "env-name",
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040035 "pcloud",
36 "",
37 )
38 cmd.Flags().StringVar(
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040039 &bootstrapFlags.envName,
40 "public-ip",
41 "",
42 "",
43 )
44 cmd.Flags().StringVar(
giolekva8aa73e82022-07-09 11:34:39 +040045 &bootstrapFlags.chartsDir,
46 "charts-dir",
47 "",
48 "",
49 )
50 cmd.Flags().StringVar(
51 &bootstrapFlags.adminPubKey,
52 "admin-pub-key",
53 "",
54 "",
55 )
56 cmd.Flags().StringVar(
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040057 &bootstrapFlags.storageDir,
58 "storage-dir",
59 "",
60 "",
61 )
62 cmd.Flags().IntVar(
63 &bootstrapFlags.volumeDefaultReplicaCount,
64 "volume-default-replica-count",
65 3,
66 "",
67 )
68 cmd.Flags().StringVar(
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040069 &bootstrapFlags.fromIP,
70 "from-ip",
71 "",
72 "",
73 )
74 cmd.Flags().StringVar(
75 &bootstrapFlags.toIP,
76 "to-ip",
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040077 "",
78 "",
79 )
giolekva8aa73e82022-07-09 11:34:39 +040080 return cmd
81}
82
83func bootstrapCmdRun(cmd *cobra.Command, args []string) error {
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040084 adminPubKey, err := os.ReadFile(bootstrapFlags.adminPubKey)
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +040085 if err != nil {
86 return err
87 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040088 nsCreator, err := newNSCreator()
89 if err != nil {
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +040090 return err
91 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040092 serviceIPs, err := newServiceIPs(bootstrapFlags.fromIP, bootstrapFlags.toIP)
93 if err != nil {
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040094 return err
95 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +040096 envConfig := installer.EnvConfig{
97 Name: bootstrapFlags.envName,
98 PublicIP: bootstrapFlags.publicIP,
99 NamespacePrefix: fmt.Sprintf("%s-", bootstrapFlags.envName),
100 StorageDir: bootstrapFlags.storageDir,
101 VolumeDefaultReplicaCount: bootstrapFlags.volumeDefaultReplicaCount,
102 AdminPublicKey: adminPubKey,
103 ServiceIPs: serviceIPs,
Giorgi Lekveishvili677b4572023-05-26 15:02:37 +0400104 }
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400105 b := installer.NewBootstrapper(
106 installer.NewFSChartLoader(bootstrapFlags.chartsDir),
107 nsCreator,
108 actionConfigFactory{rootFlags.kubeConfig},
109 )
110 return b.Run(envConfig)
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +0400111}
112
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400113type actionConfigFactory struct {
114 kubeConfigPath string
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400115}
116
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400117func (f actionConfigFactory) New(namespace string) (*action.Configuration, error) {
giolekva8aa73e82022-07-09 11:34:39 +0400118 config := new(action.Configuration)
119 if err := config.Init(
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400120 kube.GetConfig(f.kubeConfigPath, "", namespace),
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400121 namespace,
giolekva8aa73e82022-07-09 11:34:39 +0400122 "",
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400123 func(fmtString string, args ...any) {
giolekva8aa73e82022-07-09 11:34:39 +0400124 fmt.Printf(fmtString, args...)
125 fmt.Println()
126 },
127 ); err != nil {
128 return nil, err
129 }
130 return config, nil
131}
Giorgi Lekveishvili94cda9d2023-07-20 10:16:09 +0400132
133func newServiceIPs(from, to string) (installer.EnvServiceIPs, error) {
134 f, err := netip.ParseAddr(from)
135 if err != nil {
136 return installer.EnvServiceIPs{}, err
137 }
138 t, err := netip.ParseAddr(to)
139 if err != nil {
140 return installer.EnvServiceIPs{}, err
141 }
142 configRepo := f
143 ingressPublic := configRepo.Next()
144 restFrom := ingressPublic.Next()
145 return installer.EnvServiceIPs{
146 ConfigRepo: configRepo,
147 IngressPublic: ingressPublic,
148 From: restFrom,
149 To: t,
150 }, nil
151}