blob: bc7d7f87401b27389bbc6f7cff5cf4513c3d24a5 [file] [log] [blame]
gio3af43942024-04-16 08:13:50 +04001package installer
2
3import (
4 "fmt"
5)
6
7type Release struct {
gio3cdee592024-04-17 10:15:56 +04008 AppInstanceId string `json:"appInstanceId"`
9 Namespace string `json:"namespace"`
10 RepoAddr string `json:"repoAddr"`
11 AppDir string `json:"appDir"`
gio3af43942024-04-16 08:13:50 +040012}
13
14type Network struct {
15 Name string `json:"name,omitempty"`
16 IngressClass string `json:"ingressClass,omitempty"`
17 CertificateIssuer string `json:"certificateIssuer,omitempty"`
18 Domain string `json:"domain,omitempty"`
19 AllocatePortAddr string `json:"allocatePortAddr,omitempty"`
20}
21
gioe72b54f2024-04-22 10:44:41 +040022type InfraAppInstanceConfig struct {
23 Id string `json:"id"`
24 AppId string `json:"appId"`
25 Infra InfraConfig `json:"infra"`
26 Release Release `json:"release"`
27 Values map[string]any `json:"values"`
28 Input map[string]any `json:"input"`
29}
30
gio3cdee592024-04-17 10:15:56 +040031type AppInstanceConfig struct {
gio3af43942024-04-16 08:13:50 +040032 Id string `json:"id"`
33 AppId string `json:"appId"`
gioe72b54f2024-04-22 10:44:41 +040034 Env EnvConfig `json:"env"`
gio3cdee592024-04-17 10:15:56 +040035 Release Release `json:"release"`
36 Values map[string]any `json:"values"`
37 Input map[string]any `json:"input"`
Davit Tabidze56f86a42024-04-09 19:15:25 +040038 Icon string `json:"icon"`
39 Help []HelpDocument `json:"help"`
40 Url string `json:"url"`
gio3af43942024-04-16 08:13:50 +040041}
42
gio3cdee592024-04-17 10:15:56 +040043func (a AppInstanceConfig) InputToValues(schema Schema) map[string]any {
44 ret, err := derivedToConfig(a.Input, schema)
gio3af43942024-04-16 08:13:50 +040045 if err != nil {
gio3cdee592024-04-17 10:15:56 +040046 panic(err)
gio3af43942024-04-16 08:13:50 +040047 }
48 return ret
49}
50
51func deriveValues(values any, schema Schema, networks []Network) (map[string]any, error) {
52 ret := make(map[string]any)
gio44f621b2024-04-29 09:44:38 +040053 for _, f := range schema.Fields() {
54 k := f.Name
55 def := f.Schema
gio3af43942024-04-16 08:13:50 +040056 // TODO(gio): validate that it is map
57 v, ok := values.(map[string]any)[k]
58 // TODO(gio): if missing use default value
59 if !ok {
60 if def.Kind() == KindSSHKey {
61 key, err := NewECDSASSHKeyPair("tmp")
62 if err != nil {
63 return nil, err
64 }
65 ret[k] = map[string]string{
66 "public": string(key.RawAuthorizedKey()),
67 "private": string(key.RawPrivateKey()),
68 }
69 }
70 continue
71 }
72 switch def.Kind() {
73 case KindBoolean:
74 ret[k] = v
75 case KindString:
76 ret[k] = v
77 case KindInt:
78 ret[k] = v
gioe72b54f2024-04-22 10:44:41 +040079 case KindArrayString:
80 a, ok := v.([]string)
81 if !ok {
82 return nil, fmt.Errorf("expected string array")
83 }
84 ret[k] = a
gio3af43942024-04-16 08:13:50 +040085 case KindNetwork:
86 n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
87 if err != nil {
88 return nil, err
89 }
90 ret[k] = n
91 case KindAuth:
92 r, err := deriveValues(v, AuthSchema, networks)
93 if err != nil {
94 return nil, err
95 }
96 ret[k] = r
97 case KindSSHKey:
98 r, err := deriveValues(v, SSHKeySchema, networks)
99 if err != nil {
100 return nil, err
101 }
102 ret[k] = r
103 case KindStruct:
104 r, err := deriveValues(v, def, networks)
105 if err != nil {
106 return nil, err
107 }
108 ret[k] = r
109 default:
110 return nil, fmt.Errorf("Should not reach!")
111 }
112 }
113 return ret, nil
114}
115
116func derivedToConfig(derived map[string]any, schema Schema) (map[string]any, error) {
117 ret := make(map[string]any)
gio44f621b2024-04-29 09:44:38 +0400118 for _, f := range schema.Fields() {
119 k := f.Name
120 def := f.Schema
gio3af43942024-04-16 08:13:50 +0400121 v, ok := derived[k]
122 // TODO(gio): if missing use default value
123 if !ok {
124 continue
125 }
126 switch def.Kind() {
127 case KindBoolean:
128 ret[k] = v
129 case KindString:
130 ret[k] = v
131 case KindInt:
132 ret[k] = v
gioe72b54f2024-04-22 10:44:41 +0400133 case KindArrayString:
134 a, ok := v.([]string)
135 if !ok {
136 return nil, fmt.Errorf("expected string array")
137 }
138 ret[k] = a
gio3af43942024-04-16 08:13:50 +0400139 case KindNetwork:
140 vm, ok := v.(map[string]any)
141 if !ok {
142 return nil, fmt.Errorf("expected map")
143 }
144 name, ok := vm["name"]
145 if !ok {
146 return nil, fmt.Errorf("expected network name")
147 }
148 ret[k] = name
149 case KindAuth:
150 vm, ok := v.(map[string]any)
151 if !ok {
152 return nil, fmt.Errorf("expected map")
153 }
154 r, err := derivedToConfig(vm, AuthSchema)
155 if err != nil {
156 return nil, err
157 }
158 ret[k] = r
159 case KindSSHKey:
160 vm, ok := v.(map[string]any)
161 if !ok {
162 return nil, fmt.Errorf("expected map")
163 }
164 r, err := derivedToConfig(vm, SSHKeySchema)
165 if err != nil {
166 return nil, err
167 }
168 ret[k] = r
169 case KindStruct:
170 vm, ok := v.(map[string]any)
171 if !ok {
172 return nil, fmt.Errorf("expected map")
173 }
174 r, err := derivedToConfig(vm, def)
175 if err != nil {
176 return nil, err
177 }
178 ret[k] = r
179 default:
180 return nil, fmt.Errorf("Should not reach!")
181 }
182 }
183 return ret, nil
184}
185
186func findNetwork(networks []Network, name string) (Network, error) {
187 for _, n := range networks {
188 if n.Name == name {
189 return n, nil
190 }
191 }
192 return Network{}, fmt.Errorf("Network not found: %s", name)
193}