blob: b2cca5d323c76df24b828831afb93df73ee2e886 [file] [log] [blame]
gio561724f2024-11-04 08:37:34 +04001package installer
2
3import (
gio721c0042025-04-03 11:56:36 +04004 "bytes"
5 "encoding/json"
giod78896a2025-04-10 07:42:13 +04006 "fmt"
gio561724f2024-11-04 08:37:34 +04007 "testing"
8
9 "cuelang.org/go/cue/errors"
10)
11
giofc441e32024-11-11 16:26:14 +040012var exposed = `
13service: [{
14 name: "app"
gio561724f2024-11-04 08:37:34 +040015 type: "golang:1.20.0"
16 run: "main.go"
gio4fa7eb32025-04-16 17:23:06 +040017 ingress: [{
gio561724f2024-11-04 08:37:34 +040018 network: "private"
19 subdomain: "testapp"
20 auth: enabled: false
gio4fa7eb32025-04-16 17:23:06 +040021 }]
giofc441e32024-11-11 16:26:14 +040022 source: repository: "ssh://foo.bar"
23 ports: [{
24 name: "a"
25 value: 100
26 }, {
27 name: "web"
28 value: 8080
29 }, {
30 name: "b"
31 value: 101
32 }]
33 expose: [{
34 network: "private"
35 subdomain: "1"
36 port: value: 100
37 }, {
38 network: "public"
39 subdomain:"2"
40 port: name: "web"
41 }, {
42 network: "private"
43 subdomain: "3"
44 port: value: 101
gioa1f29472025-05-14 13:05:05 +040045 }],
46 dev: enabled: false
giofc441e32024-11-11 16:26:14 +040047}]
gio561724f2024-11-04 08:37:34 +040048
49postgresql: [{
50 name: "db_1"
giofc441e32024-11-11 16:26:14 +040051 expose: [{
52 network: "private"
53 subdomain: "1"
54 }, {
55 network: "public"
56 subdomain:"2"
57 }, {
58 network: "private"
59 subdomain: "3"
60 }]
gio561724f2024-11-04 08:37:34 +040061}, {
62 name: "db_2"
giofc441e32024-11-11 16:26:14 +040063 expose: [{
64 network: "public"
65 subdomain: "1"
66 }, {
67 network: "private"
68 subdomain:"2"
69 }, {
70 network: "public"
71 subdomain: "3"
72 }]
73}]
gio561724f2024-11-04 08:37:34 +040074
giofc441e32024-11-11 16:26:14 +040075mongodb: [{
76 name: "mdb_1"
77 expose: [{
78 network: "public"
79 subdomain: "1"
80 }, {
81 network: "private"
82 subdomain:"2"
83 }, {
84 network: "public"
85 subdomain: "3"
86 }]
87}, {
88 name: "mdb_2"
89 expose: [{
90 network: "private"
91 subdomain: "1"
92 }, {
93 network: "public"
94 subdomain:"2"
95 }, {
96 network: "private"
97 subdomain: "3"
98 }]
99}]
100`
101
102func TestExposedPorts(t *testing.T) {
103 app, err := NewDodoApp([]byte(exposed))
gio561724f2024-11-04 08:37:34 +0400104 if err != nil {
105 for _, e := range errors.Errors(err) {
106 t.Log(e)
107 }
108 t.Fatal(err)
109 }
gio561724f2024-11-04 08:37:34 +0400110 release := Release{
111 Namespace: "foo",
112 AppInstanceId: "foo-bar",
113 RepoAddr: "ssh://192.168.100.210:22/config",
114 AppDir: "/foo/bar",
115 }
116 keyGen := testKeyGen{}
117 r, err := app.Render(release, env, networks, nil, map[string]any{
giofc441e32024-11-11 16:26:14 +0400118 "managerAddr": "",
119 "appId": "",
120 "sshPrivateKey": "",
121 "port_postgresql_db_1_0": 1,
122 "port_postgresql_db_1_1": 2,
123 "port_postgresql_db_1_2": 3,
124 "port_postgresql_db_2_0": 4,
125 "port_postgresql_db_2_1": 5,
126 "port_postgresql_db_2_2": 6,
127 "port_mongodb_mdb_1_0": 1,
128 "port_mongodb_mdb_1_1": 2,
129 "port_mongodb_mdb_1_2": 3,
130 "port_mongodb_mdb_2_0": 4,
131 "port_mongodb_mdb_2_1": 5,
132 "port_mongodb_mdb_2_2": 6,
133 "port_service_app_0": 7,
134 "port_service_app_1": 8,
135 "port_service_app_2": 9,
gio561724f2024-11-04 08:37:34 +0400136 }, nil, keyGen)
137 if err != nil {
giofc441e32024-11-11 16:26:14 +0400138 t.Fatal(err)
139 }
140 t.Log(string(r.Raw))
141}
142
143const canvas = `
144{
145 "service": [
146 {
147 "type": "nextjs:deno-2.0.0",
148 "name": "app",
149 "source": {
150 "repository": "ssh://d.p.v1.dodo.cloud:62533/myblog",
151 "branch": "master",
152 "rootDir": "/"
153 },
154 "ports": [
155 {
156 "name": "web",
157 "value": 3000,
158 "protocol": "TCP"
159 }
160 ],
161 "env": [
162 {
163 "name": "DODO_POSTGRESQL_DB_CONNECTION_URL"
164 }
165 ],
gio4fa7eb32025-04-16 17:23:06 +0400166 "ingress": [{
giofc441e32024-11-11 16:26:14 +0400167 "network": "Private",
168 "subdomain": "foo",
169 "port": {
170 "name": "web"
171 },
172 "auth": {
173 "enabled": false
174 }
gio4fa7eb32025-04-16 17:23:06 +0400175 }, {
176 "network": "Public",
177 "subdomain": "foo",
178 "port": {
179 "name": "web"
180 },
181 "auth": {
182 "enabled": false
183 }
184 }],
giofc441e32024-11-11 16:26:14 +0400185 "expose": [],
186 "dev": { "enabled": true, "username": "gio" }
187 }
188 ],
189 "volume": [],
190 "postgresql": [
191 {
192 "name": "db",
193 "size": "1Gi",
194 "expose": []
195 }
196 ],
197 "mongodb": []
198}
199`
200
201func TestCanvas(t *testing.T) {
202 app, err := NewDodoApp([]byte(canvas))
203 if err != nil {
gio561724f2024-11-04 08:37:34 +0400204 for _, e := range errors.Errors(err) {
giofc441e32024-11-11 16:26:14 +0400205 t.Log(e)
gio561724f2024-11-04 08:37:34 +0400206 }
207 t.Fatal(err)
208 }
giofc441e32024-11-11 16:26:14 +0400209 release := Release{
210 Namespace: "foo",
211 AppInstanceId: "foo-bar",
212 RepoAddr: "ssh://192.168.100.210:22/config",
213 AppDir: "/foo/bar",
214 }
215 keyGen := testKeyGen{}
216 r, err := app.Render(release, env, networks, nil, map[string]any{
217 "managerAddr": "",
218 "appId": "",
219 "sshPrivateKey": "",
220 }, nil, keyGen)
221 if err != nil {
222 t.Fatal(err)
223 }
gio561724f2024-11-04 08:37:34 +0400224 t.Log(string(r.Raw))
225}
gio721c0042025-04-03 11:56:36 +0400226
giof4344632025-04-08 20:04:35 +0400227const exposeRemoteClusterPrivateNetwork = `
gio721c0042025-04-03 11:56:36 +0400228{
229 "cluster": "remote",
230 "postgresql": [{
231 "name": "db",
232 "size": "1Gi",
233 "expose": [{
234 "network": "Private",
235 "subdomain": "pg"
236 }]
237 }],
238}
239`
240
giof4344632025-04-08 20:04:35 +0400241func TestExposeRemoteClusterPrivateNetwork(t *testing.T) {
gio721c0042025-04-03 11:56:36 +0400242 var buf bytes.Buffer
giof4344632025-04-08 20:04:35 +0400243 if _, err := buf.WriteString(exposeRemoteClusterPrivateNetwork); err != nil {
gio721c0042025-04-03 11:56:36 +0400244 t.Fatal(err)
245 }
246 clusters := []Cluster{{
247 Name: "remote",
248 Kubeconfig: "<KUBECONFIG>",
249 IngressClassName: "<INGRESS_CLASS_NAME>",
250 }}
251 if err := json.NewEncoder(&buf).Encode(struct {
252 Clusters []Cluster `json:"clusters"`
253 }{
254 clusters,
255 }); err != nil {
256 t.Fatal(err)
257 }
258 app, err := NewDodoApp(buf.Bytes())
259 if err != nil {
260 for _, e := range errors.Errors(err) {
261 t.Log(e)
262 }
263 t.Fatal(err)
264 }
265 release := Release{
266 Namespace: "foo",
267 AppInstanceId: "foo-bar",
268 RepoAddr: "ssh://192.168.100.210:22/config",
269 AppDir: "/foo/bar",
270 }
271 keyGen := testKeyGen{}
272 r, err := app.Render(release, env, networks, clusters, map[string]any{
273 "managerAddr": "",
274 "appId": "",
275 "sshPrivateKey": "",
276 "port_postgresql_db_0": 1,
277 "port_postgresql_db_0_cluster": 2,
278 }, nil, keyGen)
279 if err != nil {
280 t.Fatal(err)
281 }
282 t.Log(string(r.Raw))
giod78896a2025-04-10 07:42:13 +0400283 t.Log(fmt.Sprintf("%+v", r.Ports))
gio721c0042025-04-03 11:56:36 +0400284}
giof4344632025-04-08 20:04:35 +0400285
286const exposeRemoteClusterPublicNetwork = `
287{
288 "cluster": "remote",
289 "postgresql": [{
290 "name": "db",
291 "size": "1Gi",
292 "expose": [{
293 "network": "Public",
294 "subdomain": "pg"
295 }]
296 }],
297}
298`
299
300func TestExposeRemoteClusterPublicNetwork(t *testing.T) {
301 var buf bytes.Buffer
302 if _, err := buf.WriteString(exposeRemoteClusterPublicNetwork); err != nil {
303 t.Fatal(err)
304 }
305 clusters := []Cluster{{
306 Name: "remote",
307 Kubeconfig: "<KUBECONFIG>",
308 IngressClassName: "<INGRESS_CLASS_NAME>",
309 }}
310 if err := json.NewEncoder(&buf).Encode(struct {
311 Clusters []Cluster `json:"clusters"`
312 }{
313 clusters,
314 }); err != nil {
315 t.Fatal(err)
316 }
317 app, err := NewDodoApp(buf.Bytes())
318 if err != nil {
319 for _, e := range errors.Errors(err) {
320 t.Log(e)
321 }
322 t.Fatal(err)
323 }
324 release := Release{
325 Namespace: "foo",
326 AppInstanceId: "foo-bar",
327 RepoAddr: "ssh://192.168.100.210:22/config",
328 AppDir: "/foo/bar",
329 }
330 keyGen := testKeyGen{}
331 r, err := app.Render(release, env, networks, clusters, map[string]any{
332 "managerAddr": "",
333 "appId": "",
334 "sshPrivateKey": "",
335 "port_postgresql_db_0": 1,
336 "port_postgresql_db_0_cluster": 2,
337 "port_postgresql_db_0_private": 3,
338 }, nil, keyGen)
339 if err != nil {
340 t.Fatal(err)
341 }
342 t.Log(string(r.Raw))
343}
giof55ab362025-04-11 17:48:17 +0400344
345const exposeSVCRemoteCluster = `
346{
gioa1f29472025-05-14 13:05:05 +0400347 "cluster": "remote",
348 "service": [
349 {
350 "name": "echo",
351 "type": "golang:1.20.0",
352 "source": {
353 "repository": "ssh://foo.bar"
354 },
355 "ports": [
356 {
357 "name": "echo",
358 "value": 9090
359 }
360 ],
361 "expose": [
362 {
363 "port": {
364 "name": "echo"
365 },
366 "network": "Private",
367 "subdomain": "echo"
368 }
369 ],
370 "dev": {
371 "enabled": false
372 }
373 }
374 ]
giof55ab362025-04-11 17:48:17 +0400375}
376`
377
378func TestExposeSVCRemoteCluster(t *testing.T) {
379 var buf bytes.Buffer
380 if _, err := buf.WriteString(exposeSVCRemoteCluster); err != nil {
381 t.Fatal(err)
382 }
383 clusters := []Cluster{{
384 Name: "remote",
385 Kubeconfig: "<KUBECONFIG>",
386 IngressClassName: "<INGRESS_CLASS_NAME>",
387 }}
388 if err := json.NewEncoder(&buf).Encode(struct {
389 Clusters []Cluster `json:"clusters"`
390 }{
391 clusters,
392 }); err != nil {
393 t.Fatal(err)
394 }
395 app, err := NewDodoApp(buf.Bytes())
396 if err != nil {
397 for _, e := range errors.Errors(err) {
398 t.Log(e)
399 }
400 t.Fatal(err)
401 }
402 release := Release{
403 Namespace: "foo",
404 AppInstanceId: "foo-bar",
405 RepoAddr: "ssh://192.168.100.210:22/config",
406 AppDir: "/foo/bar",
407 }
408 keyGen := testKeyGen{}
409 r, err := app.Render(release, env, networks, clusters, map[string]any{
410 "managerAddr": "",
411 "appId": "",
412 "sshPrivateKey": "",
413 "port_service_echo_0": 1,
414 "port_service_echo_0_cluster": 2,
415 }, nil, keyGen)
416 if err != nil {
417 t.Fatal(err)
418 }
419 t.Log(string(r.Raw))
420 t.Log(fmt.Sprintf("%+v", r.Ports))
421}
gioa1f29472025-05-14 13:05:05 +0400422
423const sshCodeServer = `
424{
425 "service": [
426 {
427 "type": "nextjs:deno-2.0.0",
428 "name": "app",
429 "source": {
430 "repository": "ssh://d.p.v1.dodo.cloud:62533/myblog",
431 "branch": "master",
432 "rootDir": "/"
433 },
434 "ports": [
435 {
436 "name": "web",
437 "value": 3000,
438 "protocol": "TCP"
439 }
440 ],
441 "env": [
442 {
443 "name": "DODO_POSTGRESQL_DB_CONNECTION_URL"
444 }
445 ],
446 "ingress": [
447 {
448 "network": "Private",
449 "subdomain": "foo",
450 "port": {
451 "name": "web"
452 },
453 "auth": {
454 "enabled": false
455 }
456 },
457 {
458 "network": "Public",
459 "subdomain": "foo",
460 "port": {
461 "name": "web"
462 },
463 "auth": {
464 "enabled": false
465 }
466 }
467 ],
468 "expose": [{
469 "network": "Public",
470 "subdomain": "foo",
471 "port": {
472 "name": "web"
473 },
474 }],
475 "dev": {
476 "enabled": true,
477 "username": "gio",
478 "codeServer": {
479 "network": "Private",
480 "subdomain": "code"
481 },
482 "ssh": {
483 "network": "Public",
484 "subdomain": "ssh"
485 }
486 }
487 }
488 ],
489 "volume": [],
490 "postgresql": [
491 {
492 "name": "db",
493 "size": "1Gi",
494 "expose": []
495 }
496 ],
497 "mongodb": []
498}
499`
500
501func TestSSHCodeServer(t *testing.T) {
502 app, err := NewDodoApp([]byte(sshCodeServer))
503 if err != nil {
504 for _, e := range errors.Errors(err) {
505 t.Log(e)
506 }
507 t.Fatal(err)
508 }
509 release := Release{
510 Namespace: "foo",
511 AppInstanceId: "foo-bar",
512 RepoAddr: "ssh://192.168.100.210:22/config",
513 AppDir: "/foo/bar",
514 }
515 keyGen := testKeyGen{}
516 r, err := app.Render(release, env, networks, nil, map[string]any{
517 "managerAddr": "",
518 "appId": "",
519 "sshPrivateKey": "",
520 "port_service_app_ssh": 12,
521 "port_service_app_0": 13,
522 }, nil, keyGen)
523 if err != nil {
524 t.Fatal(err)
525 }
526 t.Log(string(r.Raw))
527}
giob1d3bd72025-05-15 07:20:06 +0400528
529const foo = `
530{
531 "service": [
532 {
533 "type": "deno:2.2.0",
534 "name": "qwe",
535 "source": {
536 "repository": "git@github.com:giolekva/dodo-blog.git"
537 },
538 "ports": [
539 {
540 "name": "web",
541 "value": 8080,
542 "protocol": "TCP"
543 }
544 ],
545 "env": [
546 {
547 "name": "DODO_POSTGRESQL_DB_URL"
548 },
549 {
550 "name": "DODO_PORT_WEB"
551 }
552 ],
553 "ingress": [
554 {
555 "network": "Private",
556 "subdomain": "blog",
557 "port": {
558 "name": "web"
559 },
560 "auth": {
561 "enabled": false
562 }
563 }
564 ],
gio6ce44812025-05-17 07:31:54 +0400565 "expose": [
566 {
567 "network": "Private",
568 "subdomain": "blog",
569 "port": {
570 "name": "web"
571 }
572 }
573 ],
giob1d3bd72025-05-15 07:20:06 +0400574 "preBuildCommands": [],
575 "dev": {
576 "enabled": true,
577 "username": "gio",
578 "codeServer": {
579 "network": "Private",
580 "subdomain": "code"
581 },
582 "ssh": {
583 "network": "Public",
584 "subdomain": "code"
585 }
586 }
587 }
588 ],
589 "volume": [],
590 "postgresql": [
591 {
592 "name": "db",
593 "size": "1Gi",
gio6ce44812025-05-17 07:31:54 +0400594 "expose": [
595 {
596 "network": "Private",
597 "subdomain": "pg"
598 }
599 ]
giob1d3bd72025-05-15 07:20:06 +0400600 }
601 ],
602 "mongodb": []
603}
604`
605
606func TestFoo(t *testing.T) {
607 app, err := NewDodoApp([]byte(foo))
608 if err != nil {
609 for _, e := range errors.Errors(err) {
610 t.Log(e)
611 }
612 t.Fatal(err)
613 }
614 release := Release{
615 Namespace: "foo",
616 AppInstanceId: "foo-bar",
617 RepoAddr: "ssh://192.168.100.210:22/config",
618 AppDir: "/foo/bar",
619 }
620 keyGen := testKeyGen{}
621 r, err := app.Render(release, env, networks, nil, map[string]any{
622 "managerAddr": "",
623 "appId": "",
624 "sshPrivateKey": "",
gio6ce44812025-05-17 07:31:54 +0400625 "port_service_qwe_ssh": 1,
626 "port_service_qwe_0": 2,
627 "port_postgresql_db_0": 3,
giob1d3bd72025-05-15 07:20:06 +0400628 }, nil, keyGen)
629 if err != nil {
630 t.Fatal(err)
631 }
gio6ce44812025-05-17 07:31:54 +0400632 access, err := json.Marshal(r.Access)
633 if err != nil {
634 t.Fatal(err)
635 }
636 t.Log(string(access))
giob1d3bd72025-05-15 07:20:06 +0400637}