blob: b87b81e0f00761cc7647f749033be80037b3527e [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
gio3cdee592024-04-17 10:15:56 +040022type AppInstanceConfig struct {
gio3af43942024-04-16 08:13:50 +040023 Id string `json:"id"`
24 AppId string `json:"appId"`
gio3cdee592024-04-17 10:15:56 +040025 Env AppEnvConfig `json:"env"`
26 Release Release `json:"release"`
27 Values map[string]any `json:"values"`
28 Input map[string]any `json:"input"`
Davit Tabidze56f86a42024-04-09 19:15:25 +040029 Icon string `json:"icon"`
30 Help []HelpDocument `json:"help"`
31 Url string `json:"url"`
gio3af43942024-04-16 08:13:50 +040032}
33
gio3cdee592024-04-17 10:15:56 +040034func (a AppInstanceConfig) InputToValues(schema Schema) map[string]any {
35 ret, err := derivedToConfig(a.Input, schema)
gio3af43942024-04-16 08:13:50 +040036 if err != nil {
gio3cdee592024-04-17 10:15:56 +040037 panic(err)
gio3af43942024-04-16 08:13:50 +040038 }
39 return ret
40}
41
42func deriveValues(values any, schema Schema, networks []Network) (map[string]any, error) {
43 ret := make(map[string]any)
44 for k, def := range schema.Fields() {
45 // TODO(gio): validate that it is map
46 v, ok := values.(map[string]any)[k]
47 // TODO(gio): if missing use default value
48 if !ok {
49 if def.Kind() == KindSSHKey {
50 key, err := NewECDSASSHKeyPair("tmp")
51 if err != nil {
52 return nil, err
53 }
54 ret[k] = map[string]string{
55 "public": string(key.RawAuthorizedKey()),
56 "private": string(key.RawPrivateKey()),
57 }
58 }
59 continue
60 }
61 switch def.Kind() {
62 case KindBoolean:
63 ret[k] = v
64 case KindString:
65 ret[k] = v
66 case KindInt:
67 ret[k] = v
68 case KindNetwork:
69 n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
70 if err != nil {
71 return nil, err
72 }
73 ret[k] = n
74 case KindAuth:
75 r, err := deriveValues(v, AuthSchema, networks)
76 if err != nil {
77 return nil, err
78 }
79 ret[k] = r
80 case KindSSHKey:
81 r, err := deriveValues(v, SSHKeySchema, networks)
82 if err != nil {
83 return nil, err
84 }
85 ret[k] = r
86 case KindStruct:
87 r, err := deriveValues(v, def, networks)
88 if err != nil {
89 return nil, err
90 }
91 ret[k] = r
92 default:
93 return nil, fmt.Errorf("Should not reach!")
94 }
95 }
96 return ret, nil
97}
98
99func derivedToConfig(derived map[string]any, schema Schema) (map[string]any, error) {
100 ret := make(map[string]any)
101 for k, def := range schema.Fields() {
102 v, ok := derived[k]
103 // TODO(gio): if missing use default value
104 if !ok {
105 continue
106 }
107 switch def.Kind() {
108 case KindBoolean:
109 ret[k] = v
110 case KindString:
111 ret[k] = v
112 case KindInt:
113 ret[k] = v
114 case KindNetwork:
115 vm, ok := v.(map[string]any)
116 if !ok {
117 return nil, fmt.Errorf("expected map")
118 }
119 name, ok := vm["name"]
120 if !ok {
121 return nil, fmt.Errorf("expected network name")
122 }
123 ret[k] = name
124 case KindAuth:
125 vm, ok := v.(map[string]any)
126 if !ok {
127 return nil, fmt.Errorf("expected map")
128 }
129 r, err := derivedToConfig(vm, AuthSchema)
130 if err != nil {
131 return nil, err
132 }
133 ret[k] = r
134 case KindSSHKey:
135 vm, ok := v.(map[string]any)
136 if !ok {
137 return nil, fmt.Errorf("expected map")
138 }
139 r, err := derivedToConfig(vm, SSHKeySchema)
140 if err != nil {
141 return nil, err
142 }
143 ret[k] = r
144 case KindStruct:
145 vm, ok := v.(map[string]any)
146 if !ok {
147 return nil, fmt.Errorf("expected map")
148 }
149 r, err := derivedToConfig(vm, def)
150 if err != nil {
151 return nil, err
152 }
153 ret[k] = r
154 default:
155 return nil, fmt.Errorf("Should not reach!")
156 }
157 }
158 return ret, nil
159}
160
161func findNetwork(networks []Network, name string) (Network, error) {
162 for _, n := range networks {
163 if n.Name == name {
164 return n, nil
165 }
166 }
167 return Network{}, fmt.Errorf("Network not found: %s", name)
168}