blob: 3cc1afb0cb4b5917f9060f34211b32424cb56afd [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)
53 for k, def := range schema.Fields() {
54 // TODO(gio): validate that it is map
55 v, ok := values.(map[string]any)[k]
56 // TODO(gio): if missing use default value
57 if !ok {
58 if def.Kind() == KindSSHKey {
59 key, err := NewECDSASSHKeyPair("tmp")
60 if err != nil {
61 return nil, err
62 }
63 ret[k] = map[string]string{
64 "public": string(key.RawAuthorizedKey()),
65 "private": string(key.RawPrivateKey()),
66 }
67 }
68 continue
69 }
70 switch def.Kind() {
71 case KindBoolean:
72 ret[k] = v
73 case KindString:
74 ret[k] = v
75 case KindInt:
76 ret[k] = v
gioe72b54f2024-04-22 10:44:41 +040077 case KindArrayString:
78 a, ok := v.([]string)
79 if !ok {
80 return nil, fmt.Errorf("expected string array")
81 }
82 ret[k] = a
gio3af43942024-04-16 08:13:50 +040083 case KindNetwork:
84 n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
85 if err != nil {
86 return nil, err
87 }
88 ret[k] = n
89 case KindAuth:
90 r, err := deriveValues(v, AuthSchema, networks)
91 if err != nil {
92 return nil, err
93 }
94 ret[k] = r
95 case KindSSHKey:
96 r, err := deriveValues(v, SSHKeySchema, networks)
97 if err != nil {
98 return nil, err
99 }
100 ret[k] = r
101 case KindStruct:
102 r, err := deriveValues(v, def, networks)
103 if err != nil {
104 return nil, err
105 }
106 ret[k] = r
107 default:
108 return nil, fmt.Errorf("Should not reach!")
109 }
110 }
111 return ret, nil
112}
113
114func derivedToConfig(derived map[string]any, schema Schema) (map[string]any, error) {
115 ret := make(map[string]any)
116 for k, def := range schema.Fields() {
117 v, ok := derived[k]
118 // TODO(gio): if missing use default value
119 if !ok {
120 continue
121 }
122 switch def.Kind() {
123 case KindBoolean:
124 ret[k] = v
125 case KindString:
126 ret[k] = v
127 case KindInt:
128 ret[k] = v
gioe72b54f2024-04-22 10:44:41 +0400129 case KindArrayString:
130 a, ok := v.([]string)
131 if !ok {
132 return nil, fmt.Errorf("expected string array")
133 }
134 ret[k] = a
gio3af43942024-04-16 08:13:50 +0400135 case KindNetwork:
136 vm, ok := v.(map[string]any)
137 if !ok {
138 return nil, fmt.Errorf("expected map")
139 }
140 name, ok := vm["name"]
141 if !ok {
142 return nil, fmt.Errorf("expected network name")
143 }
144 ret[k] = name
145 case KindAuth:
146 vm, ok := v.(map[string]any)
147 if !ok {
148 return nil, fmt.Errorf("expected map")
149 }
150 r, err := derivedToConfig(vm, AuthSchema)
151 if err != nil {
152 return nil, err
153 }
154 ret[k] = r
155 case KindSSHKey:
156 vm, ok := v.(map[string]any)
157 if !ok {
158 return nil, fmt.Errorf("expected map")
159 }
160 r, err := derivedToConfig(vm, SSHKeySchema)
161 if err != nil {
162 return nil, err
163 }
164 ret[k] = r
165 case KindStruct:
166 vm, ok := v.(map[string]any)
167 if !ok {
168 return nil, fmt.Errorf("expected map")
169 }
170 r, err := derivedToConfig(vm, def)
171 if err != nil {
172 return nil, err
173 }
174 ret[k] = r
175 default:
176 return nil, fmt.Errorf("Should not reach!")
177 }
178 }
179 return ret, nil
180}
181
182func findNetwork(networks []Network, name string) (Network, error) {
183 for _, n := range networks {
184 if n.Name == name {
185 return n, nil
186 }
187 }
188 return Network{}, fmt.Errorf("Network not found: %s", name)
189}