blob: 295c8ff84a730e161d1f25a1e69d63051aadeea4 [file] [log] [blame]
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +04001package installer
2
3import (
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +04004 "fmt"
Giorgi Lekveishvili03ee5852023-05-30 13:20:10 +04005 "io/ioutil"
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +04006 "path/filepath"
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +04007
Giorgi Lekveishvili7efe22f2023-05-30 13:01:53 +04008 "sigs.k8s.io/yaml"
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +04009)
10
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040011const appDir = "/apps"
Giorgi Lekveishvilibd6be7f2023-05-26 15:51:28 +040012const configFileName = "config.yaml"
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040013const kustomizationFileName = "kustomization.yaml"
14
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040015type AppManager struct {
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040016 repoIO RepoIO
17 nsCreator NamespaceCreator
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040018}
19
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040020func NewAppManager(repoIO RepoIO, nsCreator NamespaceCreator) (*AppManager, error) {
Giorgi Lekveishvilibd6be7f2023-05-26 15:51:28 +040021 return &AppManager{
Giorgi Lekveishvili0ccd1482023-06-21 15:02:24 +040022 repoIO,
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040023 nsCreator,
Giorgi Lekveishvilibd6be7f2023-05-26 15:51:28 +040024 }, nil
25}
26
Giorgi Lekveishvili7efe22f2023-05-30 13:01:53 +040027func (m *AppManager) Config() (Config, error) {
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040028 return m.repoIO.ReadConfig()
Giorgi Lekveishvili7efe22f2023-05-30 13:01:53 +040029}
30
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040031func (m *AppManager) FindAllInstances(name string) ([]AppConfig, error) {
32 return m.repoIO.FindAllInstances(appDir, name)
33}
34
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040035func (m *AppManager) FindInstance(id string) (AppConfig, error) {
36 return m.repoIO.FindInstance(appDir, id)
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040037}
38
39func (m *AppManager) AppConfig(name string) (AppConfig, error) {
40 configF, err := m.repoIO.Reader(filepath.Join(appDir, name, configFileName))
Giorgi Lekveishvili03ee5852023-05-30 13:20:10 +040041 if err != nil {
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040042 return AppConfig{}, err
Giorgi Lekveishvili03ee5852023-05-30 13:20:10 +040043 }
44 defer configF.Close()
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040045 var cfg AppConfig
Giorgi Lekveishvili03ee5852023-05-30 13:20:10 +040046 contents, err := ioutil.ReadAll(configF)
47 if err != nil {
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040048 return AppConfig{}, err
Giorgi Lekveishvili03ee5852023-05-30 13:20:10 +040049 }
50 err = yaml.UnmarshalStrict(contents, &cfg)
51 return cfg, err
52}
53
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +040054func (m *AppManager) Install(app App, ns NamespaceGenerator, suffixGen SuffixGenerator, config map[string]any) error {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +040055 if err := m.repoIO.Pull(); err != nil {
56 return err
57 }
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +040058 suffix, err := suffixGen.Generate()
59 if err != nil {
60 return err
61 }
gioef01fbb2024-04-12 16:52:59 +040062 nms, err := ns.Generate(app.Namespace())
63 if err != nil {
64 return err
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040065 }
gioef01fbb2024-04-12 16:52:59 +040066 nms = nms + suffix
67 if err := m.nsCreator.Create(nms); err != nil {
68 return err
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040069 }
70 globalConfig, err := m.repoIO.ReadConfig()
Giorgi Lekveishvili7efe22f2023-05-30 13:01:53 +040071 if err != nil {
72 return err
73 }
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +040074 derivedValues, err := deriveValues(config, app.Schema(), CreateNetworks(globalConfig))
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040075 if err != nil {
76 fmt.Println(err)
77 return err
78 }
79 derived := Derived{
80 Global: globalConfig.Values,
81 Values: derivedValues,
Giorgi Lekveishvili7efe22f2023-05-30 13:01:53 +040082 }
gioef01fbb2024-04-12 16:52:59 +040083 derived.Release.Namespace = nms
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040084 fmt.Printf("%+v\n", derived)
85 err = m.repoIO.InstallApp(
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +040086 app,
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +040087 filepath.Join(appDir, app.Name()+suffix),
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040088 config,
89 derived,
90 )
91 fmt.Println(err)
92 return err
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040093}
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040094
95func (m *AppManager) Update(app App, instanceId string, config map[string]any) error {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +040096 if err := m.repoIO.Pull(); err != nil {
97 return err
98 }
Giorgi Lekveishvili76951482023-06-30 23:25:09 +040099 globalConfig, err := m.repoIO.ReadConfig()
100 if err != nil {
101 return err
102 }
103 instanceDir := filepath.Join(appDir, instanceId)
104 instanceConfigPath := filepath.Join(instanceDir, configFileName)
105 appConfig, err := m.repoIO.ReadAppConfig(instanceConfigPath)
106 if err != nil {
107 return err
108 }
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +0400109 derivedValues, err := deriveValues(config, app.Schema(), CreateNetworks(globalConfig))
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400110 if err != nil {
111 return err
Giorgi Lekveishvili76951482023-06-30 23:25:09 +0400112 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400113 derived := Derived{
114 Global: globalConfig.Values,
115 Release: appConfig.Derived.Release,
116 Values: derivedValues,
117 }
118 return m.repoIO.InstallApp(app, instanceDir, config, derived)
119}
120
121func (m *AppManager) Remove(instanceId string) error {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400122 if err := m.repoIO.Pull(); err != nil {
123 return err
124 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400125 return m.repoIO.RemoveApp(filepath.Join(appDir, instanceId))
126}
127
Giorgi Lekveishvili67383962024-03-22 19:27:34 +0400128// TODO(gio): deduplicate with cue definition in app.go, this one should be removed.
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400129func CreateNetworks(global Config) []Network {
130 return []Network{
131 {
132 Name: "Public",
133 IngressClass: fmt.Sprintf("%s-ingress-public", global.Values.PCloudEnvName),
134 CertificateIssuer: fmt.Sprintf("%s-public", global.Values.Id),
135 Domain: global.Values.Domain,
Giorgi Lekveishvilib59b7c22024-04-03 22:17:50 +0400136 AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public/api/allocate", global.Values.PCloudEnvName),
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400137 },
138 {
Giorgi Lekveishvilib59b7c22024-04-03 22:17:50 +0400139 Name: "Private",
140 IngressClass: fmt.Sprintf("%s-ingress-private", global.Values.Id),
141 Domain: global.Values.PrivateDomain,
142 AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private/api/allocate", global.Values.Id),
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400143 },
144 }
Giorgi Lekveishvili76951482023-06-30 23:25:09 +0400145}