blob: 4684e02079e2518e330350febb1a5775c7bf91bc [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 }
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +040062 namespaces := make([]string, len(app.Namespaces()))
63 for i, n := range app.Namespaces() {
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +040064 ns, err := ns.Generate(n)
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040065 if err != nil {
66 return err
67 }
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +040068 namespaces[i] = ns + suffix
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040069 }
70 for _, n := range namespaces {
71 if err := m.nsCreator.Create(n); err != nil {
72 return err
73 }
74 }
75 globalConfig, err := m.repoIO.ReadConfig()
Giorgi Lekveishvili7efe22f2023-05-30 13:01:53 +040076 if err != nil {
77 return err
78 }
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +040079 derivedValues, err := deriveValues(config, app.Schema(), CreateNetworks(globalConfig))
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040080 if err != nil {
81 fmt.Println(err)
82 return err
83 }
84 derived := Derived{
85 Global: globalConfig.Values,
86 Values: derivedValues,
Giorgi Lekveishvili7efe22f2023-05-30 13:01:53 +040087 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040088 if len(namespaces) > 0 {
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040089 derived.Release.Namespace = namespaces[0]
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040090 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040091 fmt.Printf("%+v\n", derived)
92 err = m.repoIO.InstallApp(
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +040093 app,
Giorgi Lekveishvili08af67a2024-01-18 08:53:05 +040094 filepath.Join(appDir, app.Name()+suffix),
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +040095 config,
96 derived,
97 )
98 fmt.Println(err)
99 return err
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +0400100}
Giorgi Lekveishvili76951482023-06-30 23:25:09 +0400101
102func (m *AppManager) Update(app App, instanceId string, config map[string]any) error {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400103 if err := m.repoIO.Pull(); err != nil {
104 return err
105 }
Giorgi Lekveishvili76951482023-06-30 23:25:09 +0400106 globalConfig, err := m.repoIO.ReadConfig()
107 if err != nil {
108 return err
109 }
110 instanceDir := filepath.Join(appDir, instanceId)
111 instanceConfigPath := filepath.Join(instanceDir, configFileName)
112 appConfig, err := m.repoIO.ReadAppConfig(instanceConfigPath)
113 if err != nil {
114 return err
115 }
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +0400116 derivedValues, err := deriveValues(config, app.Schema(), CreateNetworks(globalConfig))
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400117 if err != nil {
118 return err
Giorgi Lekveishvili76951482023-06-30 23:25:09 +0400119 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400120 derived := Derived{
121 Global: globalConfig.Values,
122 Release: appConfig.Derived.Release,
123 Values: derivedValues,
124 }
125 return m.repoIO.InstallApp(app, instanceDir, config, derived)
126}
127
128func (m *AppManager) Remove(instanceId string) error {
Giorgi Lekveishvili5c1b06e2024-03-28 15:19:44 +0400129 if err := m.repoIO.Pull(); err != nil {
130 return err
131 }
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400132 return m.repoIO.RemoveApp(filepath.Join(appDir, instanceId))
133}
134
Giorgi Lekveishvili67383962024-03-22 19:27:34 +0400135// TODO(gio): deduplicate with cue definition in app.go, this one should be removed.
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400136func CreateNetworks(global Config) []Network {
137 return []Network{
138 {
139 Name: "Public",
140 IngressClass: fmt.Sprintf("%s-ingress-public", global.Values.PCloudEnvName),
141 CertificateIssuer: fmt.Sprintf("%s-public", global.Values.Id),
142 Domain: global.Values.Domain,
Giorgi Lekveishvilib59b7c22024-04-03 22:17:50 +0400143 AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public/api/allocate", global.Values.PCloudEnvName),
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400144 },
145 {
Giorgi Lekveishvilib59b7c22024-04-03 22:17:50 +0400146 Name: "Private",
147 IngressClass: fmt.Sprintf("%s-ingress-private", global.Values.Id),
148 Domain: global.Values.PrivateDomain,
149 AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private/api/allocate", global.Values.Id),
Giorgi Lekveishvili4257b902023-07-07 17:08:42 +0400150 },
151 }
Giorgi Lekveishvili76951482023-06-30 23:25:09 +0400152}