blob: ec78325274b89096e13b2ea698f2cde04fbd4917 [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 = `
gio842db3f2025-05-30 11:57:20 +040013input: {
14 key: {
15 private: "asd"
16 public: "qwe"
17 }
18}
giofc441e32024-11-11 16:26:14 +040019service: [{
20 name: "app"
gio561724f2024-11-04 08:37:34 +040021 type: "golang:1.20.0"
22 run: "main.go"
gio4fa7eb32025-04-16 17:23:06 +040023 ingress: [{
gio561724f2024-11-04 08:37:34 +040024 network: "private"
25 subdomain: "testapp"
26 auth: enabled: false
gio4fa7eb32025-04-16 17:23:06 +040027 }]
giofc441e32024-11-11 16:26:14 +040028 source: repository: "ssh://foo.bar"
29 ports: [{
30 name: "a"
31 value: 100
32 }, {
33 name: "web"
34 value: 8080
35 }, {
36 name: "b"
37 value: 101
38 }]
39 expose: [{
40 network: "private"
41 subdomain: "1"
42 port: value: 100
43 }, {
44 network: "public"
45 subdomain:"2"
46 port: name: "web"
47 }, {
48 network: "private"
49 subdomain: "3"
50 port: value: 101
gioa1f29472025-05-14 13:05:05 +040051 }],
52 dev: enabled: false
giofc441e32024-11-11 16:26:14 +040053}]
gio561724f2024-11-04 08:37:34 +040054
55postgresql: [{
56 name: "db_1"
giofc441e32024-11-11 16:26:14 +040057 expose: [{
58 network: "private"
59 subdomain: "1"
60 }, {
61 network: "public"
62 subdomain:"2"
63 }, {
64 network: "private"
65 subdomain: "3"
66 }]
gio561724f2024-11-04 08:37:34 +040067}, {
68 name: "db_2"
giofc441e32024-11-11 16:26:14 +040069 expose: [{
70 network: "public"
71 subdomain: "1"
72 }, {
73 network: "private"
74 subdomain:"2"
75 }, {
76 network: "public"
77 subdomain: "3"
78 }]
79}]
gio561724f2024-11-04 08:37:34 +040080
giofc441e32024-11-11 16:26:14 +040081mongodb: [{
82 name: "mdb_1"
83 expose: [{
84 network: "public"
85 subdomain: "1"
86 }, {
87 network: "private"
88 subdomain:"2"
89 }, {
90 network: "public"
91 subdomain: "3"
92 }]
93}, {
94 name: "mdb_2"
95 expose: [{
96 network: "private"
97 subdomain: "1"
98 }, {
99 network: "public"
100 subdomain:"2"
101 }, {
102 network: "private"
103 subdomain: "3"
104 }]
105}]
106`
107
108func TestExposedPorts(t *testing.T) {
109 app, err := NewDodoApp([]byte(exposed))
gio561724f2024-11-04 08:37:34 +0400110 if err != nil {
111 for _, e := range errors.Errors(err) {
112 t.Log(e)
113 }
114 t.Fatal(err)
115 }
gio561724f2024-11-04 08:37:34 +0400116 release := Release{
117 Namespace: "foo",
118 AppInstanceId: "foo-bar",
119 RepoAddr: "ssh://192.168.100.210:22/config",
120 AppDir: "/foo/bar",
121 }
122 keyGen := testKeyGen{}
123 r, err := app.Render(release, env, networks, nil, map[string]any{
giofc441e32024-11-11 16:26:14 +0400124 "managerAddr": "",
125 "appId": "",
126 "sshPrivateKey": "",
127 "port_postgresql_db_1_0": 1,
128 "port_postgresql_db_1_1": 2,
129 "port_postgresql_db_1_2": 3,
130 "port_postgresql_db_2_0": 4,
131 "port_postgresql_db_2_1": 5,
132 "port_postgresql_db_2_2": 6,
133 "port_mongodb_mdb_1_0": 1,
134 "port_mongodb_mdb_1_1": 2,
135 "port_mongodb_mdb_1_2": 3,
136 "port_mongodb_mdb_2_0": 4,
137 "port_mongodb_mdb_2_1": 5,
138 "port_mongodb_mdb_2_2": 6,
139 "port_service_app_0": 7,
140 "port_service_app_1": 8,
141 "port_service_app_2": 9,
gio561724f2024-11-04 08:37:34 +0400142 }, nil, keyGen)
143 if err != nil {
giofc441e32024-11-11 16:26:14 +0400144 t.Fatal(err)
145 }
146 t.Log(string(r.Raw))
147}
148
149const canvas = `
150{
151 "service": [
152 {
153 "type": "nextjs:deno-2.0.0",
154 "name": "app",
155 "source": {
156 "repository": "ssh://d.p.v1.dodo.cloud:62533/myblog",
157 "branch": "master",
158 "rootDir": "/"
159 },
160 "ports": [
161 {
162 "name": "web",
163 "value": 3000,
164 "protocol": "TCP"
165 }
166 ],
167 "env": [
168 {
169 "name": "DODO_POSTGRESQL_DB_CONNECTION_URL"
170 }
171 ],
gio4fa7eb32025-04-16 17:23:06 +0400172 "ingress": [{
giofc441e32024-11-11 16:26:14 +0400173 "network": "Private",
174 "subdomain": "foo",
175 "port": {
176 "name": "web"
177 },
178 "auth": {
179 "enabled": false
180 }
gio4fa7eb32025-04-16 17:23:06 +0400181 }, {
182 "network": "Public",
183 "subdomain": "foo",
184 "port": {
185 "name": "web"
186 },
187 "auth": {
188 "enabled": false
189 }
190 }],
giofc441e32024-11-11 16:26:14 +0400191 "expose": [],
192 "dev": { "enabled": true, "username": "gio" }
193 }
194 ],
195 "volume": [],
196 "postgresql": [
197 {
198 "name": "db",
199 "size": "1Gi",
200 "expose": []
201 }
202 ],
203 "mongodb": []
204}
205`
206
207func TestCanvas(t *testing.T) {
208 app, err := NewDodoApp([]byte(canvas))
209 if err != nil {
gio561724f2024-11-04 08:37:34 +0400210 for _, e := range errors.Errors(err) {
giofc441e32024-11-11 16:26:14 +0400211 t.Log(e)
gio561724f2024-11-04 08:37:34 +0400212 }
213 t.Fatal(err)
214 }
giofc441e32024-11-11 16:26:14 +0400215 release := Release{
216 Namespace: "foo",
217 AppInstanceId: "foo-bar",
218 RepoAddr: "ssh://192.168.100.210:22/config",
219 AppDir: "/foo/bar",
220 }
221 keyGen := testKeyGen{}
222 r, err := app.Render(release, env, networks, nil, map[string]any{
223 "managerAddr": "",
224 "appId": "",
225 "sshPrivateKey": "",
226 }, nil, keyGen)
227 if err != nil {
228 t.Fatal(err)
229 }
gio561724f2024-11-04 08:37:34 +0400230 t.Log(string(r.Raw))
231}
gio721c0042025-04-03 11:56:36 +0400232
giof4344632025-04-08 20:04:35 +0400233const exposeRemoteClusterPrivateNetwork = `
gio721c0042025-04-03 11:56:36 +0400234{
235 "cluster": "remote",
236 "postgresql": [{
237 "name": "db",
238 "size": "1Gi",
239 "expose": [{
240 "network": "Private",
241 "subdomain": "pg"
242 }]
243 }],
244}
245`
246
giof4344632025-04-08 20:04:35 +0400247func TestExposeRemoteClusterPrivateNetwork(t *testing.T) {
gio721c0042025-04-03 11:56:36 +0400248 var buf bytes.Buffer
giof4344632025-04-08 20:04:35 +0400249 if _, err := buf.WriteString(exposeRemoteClusterPrivateNetwork); err != nil {
gio721c0042025-04-03 11:56:36 +0400250 t.Fatal(err)
251 }
252 clusters := []Cluster{{
253 Name: "remote",
254 Kubeconfig: "<KUBECONFIG>",
255 IngressClassName: "<INGRESS_CLASS_NAME>",
256 }}
257 if err := json.NewEncoder(&buf).Encode(struct {
258 Clusters []Cluster `json:"clusters"`
259 }{
260 clusters,
261 }); err != nil {
262 t.Fatal(err)
263 }
264 app, err := NewDodoApp(buf.Bytes())
265 if err != nil {
266 for _, e := range errors.Errors(err) {
267 t.Log(e)
268 }
269 t.Fatal(err)
270 }
271 release := Release{
272 Namespace: "foo",
273 AppInstanceId: "foo-bar",
274 RepoAddr: "ssh://192.168.100.210:22/config",
275 AppDir: "/foo/bar",
276 }
277 keyGen := testKeyGen{}
278 r, err := app.Render(release, env, networks, clusters, map[string]any{
279 "managerAddr": "",
280 "appId": "",
281 "sshPrivateKey": "",
282 "port_postgresql_db_0": 1,
283 "port_postgresql_db_0_cluster": 2,
284 }, nil, keyGen)
285 if err != nil {
286 t.Fatal(err)
287 }
288 t.Log(string(r.Raw))
giod78896a2025-04-10 07:42:13 +0400289 t.Log(fmt.Sprintf("%+v", r.Ports))
gio721c0042025-04-03 11:56:36 +0400290}
giof4344632025-04-08 20:04:35 +0400291
292const exposeRemoteClusterPublicNetwork = `
293{
294 "cluster": "remote",
295 "postgresql": [{
296 "name": "db",
297 "size": "1Gi",
298 "expose": [{
299 "network": "Public",
300 "subdomain": "pg"
301 }]
302 }],
303}
304`
305
306func TestExposeRemoteClusterPublicNetwork(t *testing.T) {
307 var buf bytes.Buffer
308 if _, err := buf.WriteString(exposeRemoteClusterPublicNetwork); err != nil {
309 t.Fatal(err)
310 }
311 clusters := []Cluster{{
312 Name: "remote",
313 Kubeconfig: "<KUBECONFIG>",
314 IngressClassName: "<INGRESS_CLASS_NAME>",
315 }}
316 if err := json.NewEncoder(&buf).Encode(struct {
317 Clusters []Cluster `json:"clusters"`
318 }{
319 clusters,
320 }); err != nil {
321 t.Fatal(err)
322 }
323 app, err := NewDodoApp(buf.Bytes())
324 if err != nil {
325 for _, e := range errors.Errors(err) {
326 t.Log(e)
327 }
328 t.Fatal(err)
329 }
330 release := Release{
331 Namespace: "foo",
332 AppInstanceId: "foo-bar",
333 RepoAddr: "ssh://192.168.100.210:22/config",
334 AppDir: "/foo/bar",
335 }
336 keyGen := testKeyGen{}
337 r, err := app.Render(release, env, networks, clusters, map[string]any{
338 "managerAddr": "",
339 "appId": "",
340 "sshPrivateKey": "",
341 "port_postgresql_db_0": 1,
342 "port_postgresql_db_0_cluster": 2,
343 "port_postgresql_db_0_private": 3,
344 }, nil, keyGen)
345 if err != nil {
346 t.Fatal(err)
347 }
348 t.Log(string(r.Raw))
349}
giof55ab362025-04-11 17:48:17 +0400350
351const exposeSVCRemoteCluster = `
352{
gioa1f29472025-05-14 13:05:05 +0400353 "cluster": "remote",
354 "service": [
355 {
356 "name": "echo",
357 "type": "golang:1.20.0",
358 "source": {
359 "repository": "ssh://foo.bar"
360 },
361 "ports": [
362 {
363 "name": "echo",
364 "value": 9090
365 }
366 ],
367 "expose": [
368 {
369 "port": {
370 "name": "echo"
371 },
372 "network": "Private",
373 "subdomain": "echo"
374 }
375 ],
376 "dev": {
377 "enabled": false
378 }
379 }
380 ]
giof55ab362025-04-11 17:48:17 +0400381}
382`
383
384func TestExposeSVCRemoteCluster(t *testing.T) {
385 var buf bytes.Buffer
386 if _, err := buf.WriteString(exposeSVCRemoteCluster); err != nil {
387 t.Fatal(err)
388 }
389 clusters := []Cluster{{
390 Name: "remote",
391 Kubeconfig: "<KUBECONFIG>",
392 IngressClassName: "<INGRESS_CLASS_NAME>",
393 }}
394 if err := json.NewEncoder(&buf).Encode(struct {
395 Clusters []Cluster `json:"clusters"`
396 }{
397 clusters,
398 }); err != nil {
399 t.Fatal(err)
400 }
401 app, err := NewDodoApp(buf.Bytes())
402 if err != nil {
403 for _, e := range errors.Errors(err) {
404 t.Log(e)
405 }
406 t.Fatal(err)
407 }
408 release := Release{
409 Namespace: "foo",
410 AppInstanceId: "foo-bar",
411 RepoAddr: "ssh://192.168.100.210:22/config",
412 AppDir: "/foo/bar",
413 }
414 keyGen := testKeyGen{}
415 r, err := app.Render(release, env, networks, clusters, map[string]any{
416 "managerAddr": "",
417 "appId": "",
418 "sshPrivateKey": "",
419 "port_service_echo_0": 1,
420 "port_service_echo_0_cluster": 2,
421 }, nil, keyGen)
422 if err != nil {
423 t.Fatal(err)
424 }
425 t.Log(string(r.Raw))
426 t.Log(fmt.Sprintf("%+v", r.Ports))
427}
gioa1f29472025-05-14 13:05:05 +0400428
429const sshCodeServer = `
430{
431 "service": [
432 {
433 "type": "nextjs:deno-2.0.0",
434 "name": "app",
435 "source": {
436 "repository": "ssh://d.p.v1.dodo.cloud:62533/myblog",
437 "branch": "master",
438 "rootDir": "/"
439 },
440 "ports": [
441 {
442 "name": "web",
443 "value": 3000,
444 "protocol": "TCP"
445 }
446 ],
447 "env": [
448 {
449 "name": "DODO_POSTGRESQL_DB_CONNECTION_URL"
450 }
451 ],
452 "ingress": [
453 {
454 "network": "Private",
455 "subdomain": "foo",
456 "port": {
457 "name": "web"
458 },
459 "auth": {
460 "enabled": false
461 }
462 },
463 {
464 "network": "Public",
465 "subdomain": "foo",
466 "port": {
467 "name": "web"
468 },
469 "auth": {
470 "enabled": false
471 }
472 }
473 ],
474 "expose": [{
475 "network": "Public",
476 "subdomain": "foo",
477 "port": {
478 "name": "web"
479 },
480 }],
481 "dev": {
482 "enabled": true,
483 "username": "gio",
484 "codeServer": {
485 "network": "Private",
486 "subdomain": "code"
487 },
488 "ssh": {
489 "network": "Public",
490 "subdomain": "ssh"
491 }
492 }
493 }
494 ],
495 "volume": [],
496 "postgresql": [
497 {
498 "name": "db",
499 "size": "1Gi",
500 "expose": []
501 }
502 ],
503 "mongodb": []
504}
505`
506
507func TestSSHCodeServer(t *testing.T) {
508 app, err := NewDodoApp([]byte(sshCodeServer))
509 if err != nil {
510 for _, e := range errors.Errors(err) {
511 t.Log(e)
512 }
513 t.Fatal(err)
514 }
515 release := Release{
516 Namespace: "foo",
517 AppInstanceId: "foo-bar",
518 RepoAddr: "ssh://192.168.100.210:22/config",
519 AppDir: "/foo/bar",
520 }
521 keyGen := testKeyGen{}
522 r, err := app.Render(release, env, networks, nil, map[string]any{
523 "managerAddr": "",
524 "appId": "",
525 "sshPrivateKey": "",
526 "port_service_app_ssh": 12,
527 "port_service_app_0": 13,
528 }, nil, keyGen)
529 if err != nil {
530 t.Fatal(err)
531 }
532 t.Log(string(r.Raw))
533}
giob1d3bd72025-05-15 07:20:06 +0400534
535const foo = `
536{
537 "service": [
538 {
539 "type": "deno:2.2.0",
540 "name": "qwe",
541 "source": {
542 "repository": "git@github.com:giolekva/dodo-blog.git"
543 },
544 "ports": [
545 {
546 "name": "web",
547 "value": 8080,
548 "protocol": "TCP"
549 }
550 ],
551 "env": [
552 {
553 "name": "DODO_POSTGRESQL_DB_URL"
554 },
555 {
556 "name": "DODO_PORT_WEB"
557 }
558 ],
559 "ingress": [
560 {
561 "network": "Private",
562 "subdomain": "blog",
563 "port": {
564 "name": "web"
565 },
566 "auth": {
567 "enabled": false
568 }
569 }
570 ],
gio6ce44812025-05-17 07:31:54 +0400571 "expose": [
572 {
573 "network": "Private",
574 "subdomain": "blog",
575 "port": {
576 "name": "web"
577 }
578 }
579 ],
giob1d3bd72025-05-15 07:20:06 +0400580 "preBuildCommands": [],
581 "dev": {
582 "enabled": true,
583 "username": "gio",
584 "codeServer": {
585 "network": "Private",
586 "subdomain": "code"
587 },
588 "ssh": {
589 "network": "Public",
590 "subdomain": "code"
591 }
592 }
593 }
594 ],
595 "volume": [],
596 "postgresql": [
597 {
598 "name": "db",
599 "size": "1Gi",
gio6ce44812025-05-17 07:31:54 +0400600 "expose": [
601 {
602 "network": "Private",
603 "subdomain": "pg"
604 }
605 ]
giob1d3bd72025-05-15 07:20:06 +0400606 }
607 ],
608 "mongodb": []
609}
610`
611
612func TestFoo(t *testing.T) {
613 app, err := NewDodoApp([]byte(foo))
614 if err != nil {
615 for _, e := range errors.Errors(err) {
616 t.Log(e)
617 }
618 t.Fatal(err)
619 }
620 release := Release{
621 Namespace: "foo",
622 AppInstanceId: "foo-bar",
623 RepoAddr: "ssh://192.168.100.210:22/config",
624 AppDir: "/foo/bar",
625 }
626 keyGen := testKeyGen{}
627 r, err := app.Render(release, env, networks, nil, map[string]any{
628 "managerAddr": "",
629 "appId": "",
630 "sshPrivateKey": "",
gio6ce44812025-05-17 07:31:54 +0400631 "port_service_qwe_ssh": 1,
632 "port_service_qwe_0": 2,
633 "port_postgresql_db_0": 3,
giob1d3bd72025-05-15 07:20:06 +0400634 }, nil, keyGen)
635 if err != nil {
636 t.Fatal(err)
637 }
gio6ce44812025-05-17 07:31:54 +0400638 access, err := json.Marshal(r.Access)
639 if err != nil {
640 t.Fatal(err)
641 }
642 t.Log(string(access))
giob1d3bd72025-05-15 07:20:06 +0400643}