blob: 2987c8024a218cf668a1e985248962bb7b53187d [file] [log] [blame]
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +04001package installer
2
3import (
gio0eaf2712024-04-14 13:08:46 +04004 _ "embed"
giocb34ad22024-07-11 08:01:13 +04005 "fmt"
gio3cdee592024-04-17 10:15:56 +04006 "net"
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +04007 "testing"
gio12e887d2024-08-18 16:09:47 +04008
9 "cuelang.org/go/cue/errors"
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +040010)
11
giocb34ad22024-07-11 08:01:13 +040012var (
13 env = EnvConfig{
14 InfraName: "dodo",
15 Id: "id",
16 ContactEmail: "foo@bar.ge",
17 Domain: "bar.ge",
18 PrivateDomain: "p.bar.ge",
19 PublicIP: []net.IP{net.ParseIP("1.2.3.4")},
20 NameserverIP: []net.IP{net.ParseIP("1.2.3.4")},
21 NamespacePrefix: "id-",
22 Network: EnvNetwork{
23 DNS: net.ParseIP("1.1.1.1"),
24 DNSInClusterIP: net.ParseIP("2.2.2.2"),
25 Ingress: net.ParseIP("3.3.3.3"),
26 Headscale: net.ParseIP("4.4.4.4"),
27 ServicesFrom: net.ParseIP("5.5.5.5"),
28 ServicesTo: net.ParseIP("6.6.6.6"),
29 },
30 }
31
gio7841f4f2024-07-26 19:53:49 +040032 infraNetworks = []InfraNetwork{
33 {
34 Name: "Public",
35 IngressClass: fmt.Sprintf("%s-ingress-public", env.InfraName),
36 CertificateIssuer: fmt.Sprintf("%s-public", env.Id),
37 AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/allocate", env.InfraName),
38 ReservePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/reserve", env.InfraName),
39 DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/remove", env.InfraName),
40 },
41 }
42
giocb34ad22024-07-11 08:01:13 +040043 networks = []Network{
44 {
45 Name: "Public",
46 IngressClass: fmt.Sprintf("%s-ingress-public", env.InfraName),
47 CertificateIssuer: fmt.Sprintf("%s-public", env.Id),
48 Domain: env.Domain,
49 AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/allocate", env.InfraName),
50 ReservePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/reserve", env.InfraName),
51 DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/remove", env.InfraName),
52 },
53 {
54 Name: "Private",
55 IngressClass: fmt.Sprintf("%s-ingress-private", env.Id),
56 Domain: env.PrivateDomain,
57 AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private.svc.cluster.local/api/allocate", env.Id),
58 ReservePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private.svc.cluster.local/api/reserve", env.Id),
59 DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private.svc.cluster.local/api/remove", env.Id),
60 },
61 }
62)
gioe72b54f2024-04-22 10:44:41 +040063
Giorgi Lekveishvili67383962024-03-22 19:27:34 +040064func TestAuthProxyEnabled(t *testing.T) {
Giorgi Lekveishvili186eae52024-02-15 14:21:41 +040065 r := NewInMemoryAppRepository(CreateAllApps())
gio7fbd4ad2024-08-27 10:06:39 +040066 for _, app := range []string{"rpuppy"} {
gio3cdee592024-04-17 10:15:56 +040067 a, err := FindEnvApp(r, app)
Giorgi Lekveishvili67383962024-03-22 19:27:34 +040068 if err != nil {
69 t.Fatal(err)
70 }
71 if a == nil {
72 t.Fatal("returned app is nil")
73 }
gio3cdee592024-04-17 10:15:56 +040074 release := Release{
75 Namespace: "foo",
76 }
gio3cdee592024-04-17 10:15:56 +040077 values := map[string]any{
78 "network": "Public",
79 "subdomain": "woof",
80 "auth": map[string]any{
81 "enabled": true,
82 "groups": "a,b",
Giorgi Lekveishvili67383962024-03-22 19:27:34 +040083 },
84 }
gio36b23b32024-08-25 12:20:54 +040085 rendered, err := a.Render(release, env, networks, values, nil, nil)
Giorgi Lekveishvili67383962024-03-22 19:27:34 +040086 if err != nil {
87 t.Fatal(err)
88 }
89 for _, r := range rendered.Resources {
90 t.Log(string(r))
91 }
92 }
93}
94
95func TestAuthProxyDisabled(t *testing.T) {
96 r := NewInMemoryAppRepository(CreateAllApps())
gio7fbd4ad2024-08-27 10:06:39 +040097 for _, app := range []string{"rpuppy"} {
gio3cdee592024-04-17 10:15:56 +040098 a, err := FindEnvApp(r, app)
Giorgi Lekveishvili67383962024-03-22 19:27:34 +040099 if err != nil {
100 t.Fatal(err)
101 }
102 if a == nil {
103 t.Fatal("returned app is nil")
104 }
gio3cdee592024-04-17 10:15:56 +0400105 release := Release{
106 Namespace: "foo",
107 }
gio3cdee592024-04-17 10:15:56 +0400108 values := map[string]any{
109 "network": "Public",
110 "subdomain": "woof",
111 "auth": map[string]any{
112 "enabled": false,
Giorgi Lekveishvili67383962024-03-22 19:27:34 +0400113 },
114 }
gio36b23b32024-08-25 12:20:54 +0400115 rendered, err := a.Render(release, env, networks, values, nil, nil)
Giorgi Lekveishvili67383962024-03-22 19:27:34 +0400116 if err != nil {
117 t.Fatal(err)
118 }
119 for _, r := range rendered.Resources {
120 t.Log(string(r))
121 }
122 }
123}
124
125func TestGroupMemberships(t *testing.T) {
126 r := NewInMemoryAppRepository(CreateAllApps())
gio3cdee592024-04-17 10:15:56 +0400127 a, err := FindEnvApp(r, "memberships")
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +0400128 if err != nil {
Giorgi Lekveishvili186eae52024-02-15 14:21:41 +0400129 t.Fatal(err)
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +0400130 }
Giorgi Lekveishvili186eae52024-02-15 14:21:41 +0400131 if a == nil {
132 t.Fatal("returned app is nil")
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +0400133 }
gio3cdee592024-04-17 10:15:56 +0400134 release := Release{
135 Namespace: "foo",
Giorgi Lekveishvili67383962024-03-22 19:27:34 +0400136 }
gio308105e2024-04-19 13:12:13 +0400137 values := map[string]any{
gio7841f4f2024-07-26 19:53:49 +0400138 "network": "Public",
gio308105e2024-04-19 13:12:13 +0400139 "authGroups": "foo,bar",
140 }
gio36b23b32024-08-25 12:20:54 +0400141 rendered, err := a.Render(release, env, networks, values, nil, nil)
Giorgi Lekveishvili67383962024-03-22 19:27:34 +0400142 if err != nil {
143 t.Fatal(err)
144 }
145 for _, r := range rendered.Resources {
146 t.Log(string(r))
147 }
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +0400148}
Giorgi Lekveishviliee15ee22024-03-28 12:35:10 +0400149
150func TestGerrit(t *testing.T) {
151 r := NewInMemoryAppRepository(CreateAllApps())
gio3cdee592024-04-17 10:15:56 +0400152 a, err := FindEnvApp(r, "gerrit")
Giorgi Lekveishviliee15ee22024-03-28 12:35:10 +0400153 if err != nil {
154 t.Fatal(err)
155 }
156 if a == nil {
157 t.Fatal("returned app is nil")
158 }
gio3cdee592024-04-17 10:15:56 +0400159 release := Release{
160 Namespace: "foo",
Giorgi Lekveishvili35982662024-04-05 13:05:40 +0400161 }
gio3cdee592024-04-17 10:15:56 +0400162 values := map[string]any{
163 "subdomain": "gerrit",
164 "network": "Private",
165 "key": map[string]any{
166 "public": "foo",
167 "private": "bar",
168 },
169 "sshPort": 22,
170 }
gio36b23b32024-08-25 12:20:54 +0400171 rendered, err := a.Render(release, env, networks, values, nil, nil)
Giorgi Lekveishvili35982662024-04-05 13:05:40 +0400172 if err != nil {
173 t.Fatal(err)
174 }
175 for _, r := range rendered.Resources {
176 t.Log(string(r))
177 }
178}
179
180func TestJenkins(t *testing.T) {
181 r := NewInMemoryAppRepository(CreateAllApps())
gio3cdee592024-04-17 10:15:56 +0400182 a, err := FindEnvApp(r, "jenkins")
Giorgi Lekveishvili35982662024-04-05 13:05:40 +0400183 if err != nil {
184 t.Fatal(err)
185 }
186 if a == nil {
187 t.Fatal("returned app is nil")
188 }
gio3cdee592024-04-17 10:15:56 +0400189 release := Release{
190 Namespace: "foo",
Giorgi Lekveishviliee15ee22024-03-28 12:35:10 +0400191 }
gio3cdee592024-04-17 10:15:56 +0400192 values := map[string]any{
193 "subdomain": "jenkins",
194 "network": "Private",
195 }
gio36b23b32024-08-25 12:20:54 +0400196 rendered, err := a.Render(release, env, networks, values, nil, nil)
Giorgi Lekveishviliee15ee22024-03-28 12:35:10 +0400197 if err != nil {
198 t.Fatal(err)
199 }
200 for _, r := range rendered.Resources {
201 t.Log(string(r))
202 }
203}
giodb274d12024-04-19 11:53:18 +0400204
205func TestIngressPublic(t *testing.T) {
206 r := NewInMemoryAppRepository(CreateAllApps())
207 a, err := FindInfraApp(r, "ingress-public")
208 if err != nil {
209 t.Fatal(err)
210 }
211 if a == nil {
212 t.Fatal("returned app is nil")
213 }
214 release := Release{
215 Namespace: "foo",
216 }
gioe72b54f2024-04-22 10:44:41 +0400217 infra := InfraConfig{
giodb274d12024-04-19 11:53:18 +0400218 Name: "dodo",
219 PublicIP: []net.IP{net.ParseIP("1.2.3.4")},
220 InfraNamespacePrefix: "id-",
221 InfraAdminPublicKey: []byte("foo"),
222 }
223 values := map[string]any{
224 "sshPrivateKey": "private",
225 }
gio7841f4f2024-07-26 19:53:49 +0400226 rendered, err := a.Render(release, infra, infraNetworks, values, nil)
giodb274d12024-04-19 11:53:18 +0400227 if err != nil {
228 t.Fatal(err)
229 }
230 for _, r := range rendered.Resources {
231 t.Log(string(r))
232 }
233}
234
235func TestPrivateNetwork(t *testing.T) {
236 r := NewInMemoryAppRepository(CreateAllApps())
237 a, err := FindEnvApp(r, "private-network")
238 if err != nil {
239 t.Fatal(err)
240 }
241 if a == nil {
242 t.Fatal("returned app is nil")
243 }
244 release := Release{
245 Namespace: "foo",
246 }
giodb274d12024-04-19 11:53:18 +0400247 values := map[string]any{
248 "privateNetwork": map[string]any{
249 "hostname": "foo",
250 "username": "bar",
251 "ipSubnet": "123123",
252 },
253 "sshPrivateKey": "private",
254 }
gio36b23b32024-08-25 12:20:54 +0400255 rendered, err := a.Render(release, env, networks, values, nil, nil)
giodb274d12024-04-19 11:53:18 +0400256 if err != nil {
257 t.Fatal(err)
258 }
259 for _, r := range rendered.Resources {
260 t.Log(string(r))
261 }
262}
gio308105e2024-04-19 13:12:13 +0400263
264func TestAppPackages(t *testing.T) {
265 contents, err := valuesTmpls.ReadFile("values-tmpl/rpuppy.cue")
266 if err != nil {
267 t.Fatal(err)
268 }
269 app, err := NewCueEnvApp(CueAppData{
gioe72b54f2024-04-22 10:44:41 +0400270 "base.cue": []byte(cueBaseConfig),
271 "app.cue": []byte(contents),
272 "global.cue": []byte(cueEnvAppGlobal),
gio308105e2024-04-19 13:12:13 +0400273 })
274 if err != nil {
275 t.Fatal(err)
276 }
277 release := Release{
278 Namespace: "foo",
279 }
gio308105e2024-04-19 13:12:13 +0400280 values := map[string]any{
281 "network": "Public",
282 "subdomain": "woof",
283 "auth": map[string]any{
284 "enabled": true,
285 "groups": "a,b",
286 },
287 }
gio36b23b32024-08-25 12:20:54 +0400288 rendered, err := app.Render(release, env, networks, values, nil, nil)
gio308105e2024-04-19 13:12:13 +0400289 if err != nil {
290 t.Fatal(err)
291 }
292 for _, r := range rendered.Resources {
293 t.Log(string(r))
294 }
295 for _, r := range rendered.Data {
296 t.Log(string(r))
297 }
298}
gioe72b54f2024-04-22 10:44:41 +0400299
300func TestDNSGateway(t *testing.T) {
301 contents, err := valuesTmpls.ReadFile("values-tmpl/dns-gateway.cue")
302 if err != nil {
303 t.Fatal(err)
304 }
305 app, err := NewCueInfraApp(CueAppData{
306 "base.cue": []byte(cueBaseConfig),
307 "app.cue": []byte(contents),
308 "global.cue": []byte(cueInfraAppGlobal),
309 })
310 if err != nil {
311 t.Fatal(err)
312 }
313 release := Release{
314 Namespace: "foo",
315 AppInstanceId: "dns-gateway",
316 RepoAddr: "ssh://192.168.100.210:22/config",
317 AppDir: "/infrastructure/gns-gateway",
318 }
319 infra := InfraConfig{
320 Name: "dodo",
321 PublicIP: []net.IP{net.ParseIP("135.181.48.180"), net.ParseIP("65.108.39.172")},
322 InfraNamespacePrefix: "dodo-",
323 InfraAdminPublicKey: []byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/ZRj0QJ0j+3udh0ANN9mJyEzrATZIOAHfNikDMpSHqrVbPZqpeHGbdYrSksCvXPXfissIZoYU4CCXX007jY0W6e1mPf1nObYh2eUT1dHo/8UtGaf9nYk+kEGU/k3utN4Uzkxa13IFh9pYERX+o0Ad3X5wh0vi5hjOBAJVKOCD9d3aipeR9piUb+qrkFDXf9fozMFn7D9nALkpJBVuGxwl/76f8K6hRxBEmPqZwIMfklzX15nRdLEcsGFJpYLYXsonbr1P3moMJFBBbQFv6M6JO9rrwA+swXpWMoScI7m/nziSEPLAb+ziv+/OyhqzeC9CQner73V0m8+2DmtcgTuSe1qHRtOScPyIjBfxoXaUx1IUkgq1NXt8k+EBO2mxnVpKdyDCvwT1Tb7088P8f8cSLtUOmUdEiAhB8bfQFprzm2KrlufenfhMvdvQPU4VfWlkQ4smLYt2yVaaXoxZMy5yD3X6LFurNXwee/Gn6di+DWqsASAOsmpsNgSCGhT8wxM= lekva@gl-mbp-m1-max.local"),
324 }
325 values := map[string]any{
326 "servers": []EnvDNS{EnvDNS{"v1.dodo.cloud", "10.0.1.2"}},
327 }
gio7841f4f2024-07-26 19:53:49 +0400328 rendered, err := app.Render(release, infra, infraNetworks, values, nil)
gioe72b54f2024-04-22 10:44:41 +0400329 if err != nil {
330 t.Fatal(err)
331 }
332 for _, r := range rendered.Resources {
333 t.Log(string(r))
334 }
335 for _, r := range rendered.Data {
336 t.Log(string(r))
337 }
338}
gio0eaf2712024-04-14 13:08:46 +0400339
gio7fbd4ad2024-08-27 10:06:39 +0400340var dodoAppDevDisabledCue = `
341app: {
342 type: "golang:1.22.0"
343 run: "main.go"
344 ingress: {
345 network: "private"
346 subdomain: "testapp"
347 auth: enabled: false
348 }
349 dev: {
350 enabled: false
351 }
352}`
gio0eaf2712024-04-14 13:08:46 +0400353
gio7fbd4ad2024-08-27 10:06:39 +0400354var dodoAppDevEnabledCue = `
355app: {
356 type: "golang:1.22.0"
357 run: "main.go"
358 ingress: {
359 network: "private"
360 subdomain: "testapp"
361 auth: enabled: false
362 }
363 dev: {
364 enabled: true
365 username: "gio"
366 }
367}`
368
369func TestDodoAppDevDisabled(t *testing.T) {
370 app, err := NewDodoApp([]byte(dodoAppDevDisabledCue))
gio1364e432024-06-29 11:39:18 +0400371 if err != nil {
gio12e887d2024-08-18 16:09:47 +0400372 for _, e := range errors.Errors(err) {
373 t.Log(e)
374 }
gio1364e432024-06-29 11:39:18 +0400375 t.Fatal(err)
376 }
gio12e887d2024-08-18 16:09:47 +0400377
gio1364e432024-06-29 11:39:18 +0400378 release := Release{
379 Namespace: "foo",
380 AppInstanceId: "foo-bar",
381 RepoAddr: "ssh://192.168.100.210:22/config",
382 AppDir: "/foo/bar",
383 }
gio7fbd4ad2024-08-27 10:06:39 +0400384 keyGen := testKeyGen{}
385 r, err := app.Render(release, env, networks, map[string]any{
386 "repoAddr": "",
387 "repoPublicAddr": "",
388 "managerAddr": "",
389 "appId": "",
390 "branch": "",
391 "sshPrivateKey": "",
392 }, nil, keyGen)
gio0eaf2712024-04-14 13:08:46 +0400393 if err != nil {
gio7fbd4ad2024-08-27 10:06:39 +0400394 for _, e := range errors.Errors(err) {
395 for _, f := range errors.Errors(e) {
396 for _, g := range errors.Errors(f) {
397 t.Log(g)
398 }
399 }
400 }
gio0eaf2712024-04-14 13:08:46 +0400401 t.Fatal(err)
402 }
gio7fbd4ad2024-08-27 10:06:39 +0400403 t.Log(string(r.Raw))
404}
405
406func TestDodoAppDevEnabled(t *testing.T) {
407 app, err := NewDodoApp([]byte(dodoAppDevEnabledCue))
408 if err != nil {
409 for _, e := range errors.Errors(err) {
410 t.Log(e)
411 }
412 t.Fatal(err)
413 }
414
415 release := Release{
416 Namespace: "foo",
417 AppInstanceId: "foo-bar",
418 RepoAddr: "ssh://192.168.100.210:22/config",
419 AppDir: "/foo/bar",
420 }
421 keyGen := testKeyGen{}
422 r, err := app.Render(release, env, networks, map[string]any{
423 "repoAddr": "",
424 "repoPublicAddr": "",
425 "managerAddr": "",
426 "appId": "",
427 "branch": "",
428 "sshPrivateKey": "",
429 "username": "",
430 }, nil, keyGen)
431 if err != nil {
432 for _, e := range errors.Errors(err) {
433 t.Log(e)
434 }
435 t.Fatal(err)
436 }
437 t.Log(string(r.Raw))
gio0eaf2712024-04-14 13:08:46 +0400438}
gio266c04f2024-07-03 14:18:45 +0400439
440func TestDodoAppInstance(t *testing.T) {
441 r := NewInMemoryAppRepository(CreateAllApps())
442 a, err := FindEnvApp(r, "dodo-app-instance")
443 if err != nil {
444 t.Fatal(err)
445 }
446 if a == nil {
447 t.Fatal("returned app is nil")
448 }
449 release := Release{
450 Namespace: "foo",
451 }
452 values := map[string]any{
gio266c04f2024-07-03 14:18:45 +0400453 "repoAddr": "",
gio7fbd4ad2024-08-27 10:06:39 +0400454 "repoPublicAddr": "",
gio33059762024-07-05 13:19:07 +0400455 "repoHost": "",
gio7fbd4ad2024-08-27 10:06:39 +0400456 "branch": "",
gio266c04f2024-07-03 14:18:45 +0400457 "gitRepoPublicKey": "",
gio7fbd4ad2024-08-27 10:06:39 +0400458 "username": "",
gio266c04f2024-07-03 14:18:45 +0400459 }
gio36b23b32024-08-25 12:20:54 +0400460 rendered, err := a.Render(release, env, networks, values, nil, nil)
gio266c04f2024-07-03 14:18:45 +0400461 if err != nil {
462 t.Fatal(err)
463 }
464 for _, r := range rendered.Resources {
465 t.Log(string(r))
466 }
467}
gio4ece99c2024-07-18 11:05:50 +0400468
469func TestDodoApp(t *testing.T) {
470 contents, err := valuesTmpls.ReadFile("values-tmpl/dodo-app.cue")
471 if err != nil {
472 t.Fatal(err)
473 }
474 app, err := NewCueEnvApp(CueAppData{
475 "base.cue": []byte(cueBaseConfig),
476 "app.cue": []byte(contents),
477 "global.cue": []byte(cueEnvAppGlobal),
478 })
479 if err != nil {
480 t.Fatal(err)
481 }
482 t.Log(app.Schema())
483}