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