blob: 813939e03375caf6dfb032493dcf9086f426b068 [file] [log] [blame]
gio3af43942024-04-16 08:13:50 +04001package installer
2
3import (
4 "fmt"
5)
6
7type Release struct {
8 Namespace string `json:"namespace"`
9 RepoAddr string `json:"repoAddr"`
10 AppDir string `json:"appDir"`
11}
12
13type Derived struct {
14 Release Release `json:"release"`
15 Global Values `json:"global"`
16 Values map[string]any `json:"input"` // TODO(gio): rename to input
17}
18
19type Network struct {
20 Name string `json:"name,omitempty"`
21 IngressClass string `json:"ingressClass,omitempty"`
22 CertificateIssuer string `json:"certificateIssuer,omitempty"`
23 Domain string `json:"domain,omitempty"`
24 AllocatePortAddr string `json:"allocatePortAddr,omitempty"`
25}
26
27type AppConfig struct {
28 Id string `json:"id"`
29 AppId string `json:"appId"`
30 Config map[string]any `json:"config"`
31 Derived Derived `json:"derived"`
32}
33
34func (a AppConfig) Input(schema Schema) map[string]any {
35 ret, err := derivedToConfig(a.Derived.Values, schema)
36 if err != nil {
37 panic(err) // TODO(gio): handle
38 }
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}