blob: e4756bebda0a15cfc07645a4d93d8e61f92777ed [file] [log] [blame]
gio3af43942024-04-16 08:13:50 +04001package installer
2
3import (
4 "fmt"
gio09a3e5b2024-04-26 14:11:06 +04005 "html/template"
gio3af43942024-04-16 08:13:50 +04006)
7
8type Release struct {
gio3cdee592024-04-17 10:15:56 +04009 AppInstanceId string `json:"appInstanceId"`
10 Namespace string `json:"namespace"`
11 RepoAddr string `json:"repoAddr"`
12 AppDir string `json:"appDir"`
giof8843412024-05-22 16:38:05 +040013 ImageRegistry string `json:"imageRegistry,omitempty"`
gio3af43942024-04-16 08:13:50 +040014}
15
16type Network struct {
giocdfa3722024-06-13 20:10:14 +040017 Name string `json:"name,omitempty"`
18 IngressClass string `json:"ingressClass,omitempty"`
19 CertificateIssuer string `json:"certificateIssuer,omitempty"`
20 Domain string `json:"domain,omitempty"`
21 AllocatePortAddr string `json:"allocatePortAddr,omitempty"`
22 ReservePortAddr string `json:"reservePortAddr,omitempty"`
23 DeallocatePortAddr string `json:"deallocatePortAddr,omitempty"`
gio3af43942024-04-16 08:13:50 +040024}
25
gioe72b54f2024-04-22 10:44:41 +040026type InfraAppInstanceConfig struct {
27 Id string `json:"id"`
28 AppId string `json:"appId"`
29 Infra InfraConfig `json:"infra"`
30 Release Release `json:"release"`
31 Values map[string]any `json:"values"`
32 Input map[string]any `json:"input"`
gio09a3e5b2024-04-26 14:11:06 +040033 URL string `json:"url"`
34 Help []HelpDocument `json:"help"`
35 Icon template.HTML `json:"icon"`
gioe72b54f2024-04-22 10:44:41 +040036}
37
gio3cdee592024-04-17 10:15:56 +040038type AppInstanceConfig struct {
gio3af43942024-04-16 08:13:50 +040039 Id string `json:"id"`
40 AppId string `json:"appId"`
gioe72b54f2024-04-22 10:44:41 +040041 Env EnvConfig `json:"env"`
gio3cdee592024-04-17 10:15:56 +040042 Release Release `json:"release"`
43 Values map[string]any `json:"values"`
44 Input map[string]any `json:"input"`
gio09a3e5b2024-04-26 14:11:06 +040045 URL string `json:"url"`
Davit Tabidze56f86a42024-04-09 19:15:25 +040046 Help []HelpDocument `json:"help"`
gio09a3e5b2024-04-26 14:11:06 +040047 Icon string `json:"icon"`
gio3af43942024-04-16 08:13:50 +040048}
49
gio3cdee592024-04-17 10:15:56 +040050func (a AppInstanceConfig) InputToValues(schema Schema) map[string]any {
51 ret, err := derivedToConfig(a.Input, schema)
gio3af43942024-04-16 08:13:50 +040052 if err != nil {
gio3cdee592024-04-17 10:15:56 +040053 panic(err)
gio3af43942024-04-16 08:13:50 +040054 }
55 return ret
56}
57
58func deriveValues(values any, schema Schema, networks []Network) (map[string]any, error) {
59 ret := make(map[string]any)
gio44f621b2024-04-29 09:44:38 +040060 for _, f := range schema.Fields() {
61 k := f.Name
62 def := f.Schema
gio3af43942024-04-16 08:13:50 +040063 // TODO(gio): validate that it is map
64 v, ok := values.(map[string]any)[k]
65 // TODO(gio): if missing use default value
66 if !ok {
67 if def.Kind() == KindSSHKey {
68 key, err := NewECDSASSHKeyPair("tmp")
69 if err != nil {
70 return nil, err
71 }
72 ret[k] = map[string]string{
73 "public": string(key.RawAuthorizedKey()),
74 "private": string(key.RawPrivateKey()),
75 }
76 }
77 continue
78 }
79 switch def.Kind() {
80 case KindBoolean:
81 ret[k] = v
82 case KindString:
83 ret[k] = v
84 case KindInt:
85 ret[k] = v
gioefa0ed42024-06-13 12:31:43 +040086 case KindPort:
87 ret[k] = v
gioe72b54f2024-04-22 10:44:41 +040088 case KindArrayString:
89 a, ok := v.([]string)
90 if !ok {
91 return nil, fmt.Errorf("expected string array")
92 }
93 ret[k] = a
gio3af43942024-04-16 08:13:50 +040094 case KindNetwork:
95 n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
96 if err != nil {
97 return nil, err
98 }
99 ret[k] = n
100 case KindAuth:
101 r, err := deriveValues(v, AuthSchema, networks)
102 if err != nil {
103 return nil, err
104 }
105 ret[k] = r
106 case KindSSHKey:
107 r, err := deriveValues(v, SSHKeySchema, networks)
108 if err != nil {
109 return nil, err
110 }
111 ret[k] = r
112 case KindStruct:
113 r, err := deriveValues(v, def, networks)
114 if err != nil {
115 return nil, err
116 }
117 ret[k] = r
118 default:
119 return nil, fmt.Errorf("Should not reach!")
120 }
121 }
122 return ret, nil
123}
124
125func derivedToConfig(derived map[string]any, schema Schema) (map[string]any, error) {
126 ret := make(map[string]any)
gio44f621b2024-04-29 09:44:38 +0400127 for _, f := range schema.Fields() {
128 k := f.Name
129 def := f.Schema
gio3af43942024-04-16 08:13:50 +0400130 v, ok := derived[k]
131 // TODO(gio): if missing use default value
132 if !ok {
133 continue
134 }
135 switch def.Kind() {
136 case KindBoolean:
137 ret[k] = v
138 case KindString:
139 ret[k] = v
140 case KindInt:
141 ret[k] = v
gioefa0ed42024-06-13 12:31:43 +0400142 case KindPort:
143 ret[k] = v
gioe72b54f2024-04-22 10:44:41 +0400144 case KindArrayString:
145 a, ok := v.([]string)
146 if !ok {
147 return nil, fmt.Errorf("expected string array")
148 }
149 ret[k] = a
gio3af43942024-04-16 08:13:50 +0400150 case KindNetwork:
151 vm, ok := v.(map[string]any)
152 if !ok {
153 return nil, fmt.Errorf("expected map")
154 }
155 name, ok := vm["name"]
156 if !ok {
157 return nil, fmt.Errorf("expected network name")
158 }
159 ret[k] = name
160 case KindAuth:
161 vm, ok := v.(map[string]any)
162 if !ok {
163 return nil, fmt.Errorf("expected map")
164 }
165 r, err := derivedToConfig(vm, AuthSchema)
166 if err != nil {
167 return nil, err
168 }
169 ret[k] = r
170 case KindSSHKey:
171 vm, ok := v.(map[string]any)
172 if !ok {
173 return nil, fmt.Errorf("expected map")
174 }
175 r, err := derivedToConfig(vm, SSHKeySchema)
176 if err != nil {
177 return nil, err
178 }
179 ret[k] = r
180 case KindStruct:
181 vm, ok := v.(map[string]any)
182 if !ok {
183 return nil, fmt.Errorf("expected map")
184 }
185 r, err := derivedToConfig(vm, def)
186 if err != nil {
187 return nil, err
188 }
189 ret[k] = r
190 default:
191 return nil, fmt.Errorf("Should not reach!")
192 }
193 }
194 return ret, nil
195}
196
197func findNetwork(networks []Network, name string) (Network, error) {
198 for _, n := range networks {
199 if n.Name == name {
200 return n, nil
201 }
202 }
203 return Network{}, fmt.Errorf("Network not found: %s", name)
204}