-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patharch.gd
927 lines (767 loc) · 29.8 KB
/
arch.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
extends Control
class_name Arch
const MAX_ZINDEX = 10
const metadata_pill_scene = preload("res://pills/metadata_pill_sm.tscn")
const indexreport_pill_scene = preload("res://pills/index_report_pill_sm.tscn")
const vulnreport_pill_scene = preload("res://pills/vuln_report_pill_sm.tscn")
const sig_pill_scene = preload("res://pills/signatures_pill_sm.tscn")
const sig_verify_pill_scene = preload("res://pills/signature_verification_pill_sm.tscn")
const error_scene = preload("res://error_popup.tscn")
const image_status_mini = preload("res://ImageStatusMini.tscn")
const play_icon = preload("res://assets/play-svgrepo-com-16x16.png")
const pause_icon = preload("res://assets/pause-svgrepo-com-16x16.png")
const version_txt_path = "res://version.txt"
const nil:Callable = Callable()
const _PathSegment = preload("res://scripts/path_segment.gd")
const pill_scenes:Array = [
metadata_pill_scene,
indexreport_pill_scene,
vulnreport_pill_scene,
sig_pill_scene,
sig_verify_pill_scene
]
enum {MD,IR,VR,SIG,SIGV}
var have_metadata:bool = false
var have_index_report:bool = false
var have_vuln_report:bool = false
var have_signatures:bool = false
var have_sigverification:bool = false
var have_error:bool = false
var cur_path_segment_idx=0
var pause_seg:PathSegment
var pausing:bool = false
var pausing_enabled:bool = false
var c1Paths:Node2D = Node2D.new()
var c2Paths:Node2D = Node2D.new()
var cluster_cpaths = {}
var animationPlayers:Array[AnimationPlayer] = []
var animationRegHighlight:String = "highlight-registry"
var initial_log_letter = 64
var last_log_letter:int = initial_log_letter
var done_ready:bool = false
@onready var big_cloud:Node2D = $BigCloud
@onready var big_cloud_label:Label = $BigCloud/BigCloudLabel
@onready var prod_cluster:Control = $ProdCluster
@onready var dev_cluster:Control = $DevCluster
@onready var other_cluster:Control = $OtherCluster
@onready var pause:Path2D = $Paths/pause
@onready var paths:Node2D = $Paths
@onready var c_paths:Node2D = $Paths/cPaths
@onready var speed_slider:HSlider = $FlowControls/SpeedSlider
@onready var forward_step_button = $FlowControls/ForwardStepButton
@onready var back_step_button = $FlowControls/BackStepButton
@onready var pause_play_button = $FlowControls/PausePlayButton
@onready var image_status_zoomed = $ImageStatusZoomed
@onready var c_0_to_central = $"Paths/c0-to-central"
@onready var central_to_c_0 = $"Paths/central-to-c0"
@onready var c_1_to_central = $"Paths/c1-to-central"
@onready var central_to_c_1 = $"Paths/central-to-c1"
@onready var c_2_to_central = $"Paths/c2-to-central"
@onready var central_to_c_2 = $"Paths/central-to-c2"
@onready var central_from_sensor_start = $"Paths/central-from-sensor-start"
@onready var central_error_from_sensor = $"Paths/central-error-from-sensor"
@onready var central_scan_error = $"Paths/central-scan-error"
@onready var central_match = $"Paths/central-match"
@onready var central_scan = $"Paths/central-scan"
@onready var central_roxctl_start = $"Paths/central-roxctl-start"
@onready var central_roxctl_to_central_scan = $"Paths/central-roxctl-to-central-scan"
@onready var central_delegate_error = $"Paths/central-delegate-error"
@onready var central_roxctl_to_cluster = $"Paths/central-roxctl-to-cluster"
@onready var popup_menu = $PopupMenu
@onready var version_label = $VersionLabel
@onready var cluster_scenes = {
0: prod_cluster,
1: dev_cluster,
2: other_cluster
}
# paths from a secured cluster to central cluster
# TODO: make these dynamic and calculate the path
@onready var to_cluster_paths = {
0: central_to_c_0,
1: central_to_c_1,
2: central_to_c_2,
}
# paths from a secured cluster to central cluster
# TODO: make these dynamic and calculate the path
@onready var to_central_paths = {
0: c_0_to_central,
1: c_1_to_central,
2: c_2_to_central,
}
# any registries in this dict are cluster local, any others are assumed internet accessable
@onready var local_registries_animates = {
"prod.registry.io": _prodAnimateCB,
"dev.reg.local": _devAnimateCB,
}
# maps a cluster index (key) to the names of all the cluster local registries (val)
var cluster_registries = {
0: ["prod.registry.io"],
1: ["dev.reg.local"],
}
func get_text_file_content(filePath):
var file = FileAccess.open(filePath, FileAccess.READ)
var content = file.get_as_text()
return content
func _ready():
version_label.text = "v" + get_text_file_content(version_txt_path)
# The enum and list of clusters must be the same, otherwise the dropdowns will not match the output
assert(Global.CLUSTER.size() == Global.CLUSTERS.size())
SignalManager.log_entry_popped.connect(_on_log_entry_pop)
SignalManager.log_cleared.connect(_on_log_clear)
SignalManager.deploy_to_cluster.connect(_on_deploy_to_cluster)
SignalManager.context_menu.connect(_on_context_menu)
var apPath:String = "Registry/AnimationPlayer"
animationPlayers = [
null,
prod_cluster.get_node(apPath),
dev_cluster.get_node(apPath),
other_cluster.get_node(apPath),
]
pause_seg = PathSegment.new(pause)
pause.hide()
big_cloud.hide()
for c in paths.get_children():
c.show()
for c in c_paths.get_children():
c.show()
c1Paths = c_paths.duplicate()
c1Paths.name = "c1Paths"
c1Paths.position += dev_cluster.position - prod_cluster.position
paths.add_child(c1Paths)
c2Paths = c_paths.duplicate()
c2Paths.name = "c2Paths"
c2Paths.position += other_cluster.position - prod_cluster.position
paths.add_child(c2Paths)
cluster_cpaths = {
0: c_paths,
1: c1Paths,
2: c2Paths,
}
# Set the initial speed value to the slider set in the editor / scene
_on_speed_slider_value_changed(speed_slider.value)
#_on_save_test_code_edit_ready()
done_ready = true
_reset()
func _reset(soft:bool=false):
if !done_ready:
return
Config.set_moving(false)
cur_path_segment_idx = 0
have_metadata = false
have_index_report = false
have_vuln_report = false
have_signatures = false
have_sigverification = false
have_error = false
for segment in Config.active_path():
segment.reset()
for a in animationPlayers:
if a == null:
continue
a.stop()
_del_all_log_entry()
if !soft:
#print_tree_pretty()
Config.clear_active_path()
Config.reset_cluster_clicked()
big_cloud.hide()
big_cloud_label.text = ""
for c in cluster_scenes.values():
c.show_cloud = false
func _errorC(text:String, pos:Global.Pos=Global.Pos.BOT, offsetX:int=0) -> Callable:
return Callable(self, "_error").bind(text, pos, offsetX)
func _error(text:String="ERR", pos:Global.Pos=Global.Pos.BOT, offsetX:int=0) -> Node:
var err:ErrorPopup = error_scene.instantiate()
err.LabelText = text
err.LabelPosition = pos
err.LabelOffsetX = offsetX
err.z_index = MAX_ZINDEX
return err
func _rdot() -> Node:
var dot = Sprite2D.new()
dot.name = "_rdot"
dot.scale = Vector2(0.3, 0.3)
dot.modulate = Color(255, 0, 0, 1.0)
dot.texture = preload("res://assets/white-circle.png")
dot.z_index = MAX_ZINDEX
return dot
func _pillC(idx:int) -> Callable:
return Callable(self, "_pill").bind(idx)
func _pill(idx:int):
var pill:Node2D = Node2D.new()
pill.name = "pill" + str(idx)
var c = pill_scenes[idx].instantiate()
pill.add_child(c)
c.active=true
if idx == IR or idx == VR:
c.scale = Vector2(0.3, 0.5)
c.position = Vector2(-7, -6)
else:
c.scale = Vector2(0.5, 0.5)
c.position = Vector2(-12, -6)
c.z_index = MAX_ZINDEX
return pill
func _docker_icon() -> Sprite2D:
var end_icon = Sprite2D.new()
end_icon.name = "_docker_icon"
end_icon.scale = Vector2(0.2, 0.2)
end_icon.position = Vector2(0, -5)
end_icon.texture = preload("res://assets/docker-mark-blue.png")
end_icon.z_index = MAX_ZINDEX
return end_icon
func _dot() -> Node:
var dot = Sprite2D.new()
dot.name = "_dot"
dot.scale = Vector2(0.3, 0.3)
var lc:Color = Global.TRAIL_COLOR
dot.modulate = Color(lc.r, lc.g, lc.b, 1.0)
dot.texture = preload("res://assets/white-circle.png")
dot.z_index = MAX_ZINDEX
return dot
func _image_status() -> ImageStatusMini:
var dupe = image_status_mini.instantiate()
dupe.name = "_image_status"
dupe.have_metadata = have_metadata
dupe.have_index_report = have_index_report
dupe.have_vuln_report = have_vuln_report
dupe.have_signatures = have_signatures
dupe.have_sigverification = have_sigverification
dupe.have_error = have_error
dupe.position = Vector2(-13, -21)
dupe.show()
dupe.z_index = MAX_ZINDEX+1
return dupe
func _process(delta):
_sync_image_status()
_update_button_states()
if cur_path_segment_idx >= Config.active_path().size():
Config.set_moving(false)
return
if !Config.moving():
return
if !pausing_enabled || !pausing:
var seg:PathSegment = Config.active_path()[cur_path_segment_idx]
if seg.walk(delta):
pausing = true
cur_path_segment_idx += 1
else:
if pause_seg.walk(delta):
pausing = false
pause_seg.reset()
func _update_button_states():
if cur_path_segment_idx >= Config.active_path().size():
forward_step_button.disabled = true
else:
forward_step_button.disabled = false
if Config.active_path().size() > 0:
pause_play_button.disabled = false
if cur_path_segment_idx > 0:
back_step_button.disabled = false
else:
var seg = Config.active_path()[cur_path_segment_idx]
if seg.progress() == 0:
back_step_button.disabled = true
else:
back_step_button.disabled = false
else:
back_step_button.disabled = true
pause_play_button.disabled = true
if !Config.moving():
pause_play_button.icon = play_icon
else:
pause_play_button.icon = pause_icon
func _sync_image_status():
image_status_zoomed.have_metadata(have_metadata)
image_status_zoomed.have_index_report(have_index_report)
image_status_zoomed.have_vuln_report(have_vuln_report)
image_status_zoomed.have_signatures(have_signatures)
image_status_zoomed.have_sigverification(have_sigverification)
image_status_zoomed.have_error(have_error)
class SegCreator:
var base:Node
var dwicon:Callable
var deicon:Callable
var dsicon:Callable
var dtrail:bool = true
func _init(p_base:Node):
base = p_base
func c(p_name:String) -> PathSegment:
var n = base.get_node(p_name)
var ps = PathSegment.new(n)
ps.wicon(dwicon)
ps.eicon(deicon)
ps.sicon(dsicon)
ps.trail(dtrail)
return ps
func wicon(p_icon:Callable) -> SegCreator:
dwicon = p_icon
return self
func eicon(p_icon:Callable) -> SegCreator:
deicon = p_icon
return self
func sicon(p_icon:Callable) -> SegCreator:
dsicon = p_icon
return self
func trail(p_trail:bool) -> SegCreator:
dtrail = p_trail
return self
func _extract_registry(p_image:String) -> String:
return p_image.get_slice("/", 0)
@onready var central_roxctl_start_sc = SegCreator.new(central_roxctl_start).wicon(_dot).eicon(_dot)
@onready var central_to_central_start_sc = SegCreator.new(central_roxctl_to_central_scan).wicon(_dot).eicon(_dot).trail(false)
@onready var central_scan_cloud_sc = SegCreator.new(central_scan).wicon(_dot)
@onready var central_scan_error_network_sc = SegCreator.new(central_scan_error).wicon(_dot)
@onready var central_scan_error_no_cluster_sc = SegCreator.new(central_delegate_error).wicon(_dot)
@onready var central_passthrough_sc = SegCreator.new(central_roxctl_to_cluster).wicon(_dot).trail(false)
@onready var sensor_to_central_start_sc = SegCreator.new(central_from_sensor_start).wicon(_dot).trail(false)
@onready var central_match_sc = SegCreator.new(central_match).wicon(_dot)
@onready var central_save_error_sc = SegCreator.new(central_error_from_sensor).wicon(_dot)
func _A() -> Array[PathSegment]:
return [central_roxctl_start_sc.c("a1"),]
func _BQ() -> Array[PathSegment]:
var cPaths:Node2D = cluster_cpaths[Config.get_cluster_clicked()]
var sc = SegCreator.new(cPaths.get_node("c0-deploy")).wicon(_dot).eicon(_dot)
return [
sc.c("a1"),
sc.c("a2").trail(false).sicon(nil).eicon(nil),
]
func _C() -> Array[PathSegment]:
return [central_to_central_start_sc.c("a1"),]
func _D() -> Array[PathSegment]:
big_cloud_label.text = _extract_registry(Config.get_active_image())
big_cloud.show()
return [
central_scan_cloud_sc.c("a1").sicon(_dot),
central_scan_cloud_sc.c("a2").eicon(_pillC(MD)).micon(_midIconCBC("Get metadata from registry"), 40),
central_scan_cloud_sc.c("a2").reverse().eicon(_pillC(MD)).wicon(_pillC(MD)).onevent(_metadataCB).trail(false),
central_scan_cloud_sc.c("a3"),
central_scan_cloud_sc.c("a4").micon(_midIconCBC("Get index report from indexer"), 40),
central_scan_cloud_sc.c("a5").eicon(_docker_icon).micon(_midIconCBC("Get layers from registry"), 40),
central_scan_cloud_sc.c("a5").reverse().wicon(_docker_icon).eicon(_pillC(IR)).trail(false),
central_scan_cloud_sc.c("a4").reverse().wicon(_pillC(IR)).eicon(_pillC(IR)).onevent(_indexReportCB).trail(false),
central_scan_cloud_sc.c("a6"),
central_scan_cloud_sc.c("a7").micon(_midIconCBC("Get vuln report from matcher"), 30),
central_scan_cloud_sc.c("a7_1").micon(_midIconCBC("Get index report from indexer"), 30),
central_scan_cloud_sc.c("a7_1").reverse().sicon(_pillC(IR)).wicon(_pillC(IR)).trail(false),
central_scan_cloud_sc.c("a7").reverse().sicon(_pillC(VR)).wicon(_pillC(VR)).eicon(_pillC(VR)).onevent(_vulnReportCB).trail(false),
central_scan_cloud_sc.c("a8"),
central_scan_cloud_sc.c("a9").micon(_midIconCBC("Get image signature from registry"), 30),
central_scan_cloud_sc.c("a9").reverse().sicon(_pillC(SIG)).wicon(_pillC(SIG)).eicon(_pillC(SIG)).onevent(_signatureCB).trail(false),
central_scan_cloud_sc.c("a10"),
central_scan_cloud_sc.c("a10_1").eicon(_pillC(SIGV)).micon(_midIconCBC("Verify image signatures"), 20),
central_scan_cloud_sc.c("a10_1").reverse().eicon(_pillC(SIGV)).onevent(_signatureVerificationCB).trail(false),
central_scan_cloud_sc.c("a10_2"),
central_scan_cloud_sc.c("a11").wicon(_image_status).eicon(_image_status).micon(_midIconCBC("Store final image in DB"), 20),
central_scan_cloud_sc.c("a11").reverse().trail(false),
central_scan_cloud_sc.c("a12").wicon(_image_status).eicon(_dot),
]
func _E() -> Array[PathSegment]:
var reg = _extract_registry(Config.get_active_image())
return [
central_scan_error_network_sc.c("a1").sicon(_dot),
central_scan_error_network_sc.c("a2").eicon(_errorC("", Global.Pos.TOP)).onevent(local_registries_animates[reg]).micon(_midIconCBC("Fail to get metadata from registry - unreachable"), 20),
central_scan_error_network_sc.c("a2").wicon(_rdot).reverse().eicon(_rdot).onevent(_errorStatusCB).trail(false),
central_scan_error_network_sc.c("a3").eicon(_dot).wicon(_rdot),
central_scan_error_network_sc.c("a4").eicon(_image_status).wicon(_rdot).micon(_midIconCBC("Store scan with error in DB (if no existing image)"), 20),
central_scan_error_network_sc.c("a5").eicon(_dot),
]
func _F() -> Array[PathSegment]:
return [
central_scan_error_no_cluster_sc.c("a1").sicon(_dot),
central_scan_error_no_cluster_sc.c("a2").eicon(_errorC("", Global.Pos.TOP)).micon(_midIconCBC("Fail to delegate, no cluster specified"), 20).onevent(_errorStatusCB),
central_scan_error_no_cluster_sc.c("a3").wicon(_rdot).eicon(_dot),
]
func _G() -> Array[PathSegment]:
return [
central_passthrough_sc.c("a1"),
]
func _HQ() -> Array[PathSegment]:
var dst_cluster:int = _get_dst_cluster()
var cPaths:Node2D = to_cluster_paths[dst_cluster]
var sc = SegCreator.new(cPaths).wicon(_dot).eicon(_dot).sicon(_dot)
var offset:int = 50
if dst_cluster == 1: # middle cluster - shorter offset, assumes only 3 Clusters
offset = 25
return [
sc.c("a1").altcolor().micon(_midIconCBC("Delegate scan to sensor"), offset),
sc.c("a2").trail(false),
]
func _I() -> Array[PathSegment]:
var dst_cluster:int = _get_dst_cluster()
var cPaths:Node2D = cluster_cpaths[dst_cluster]
var sc = SegCreator.new(cPaths.get_node("c0-scan-cloud")).wicon(_dot)
var c = cluster_scenes[dst_cluster]
c.cloud_text = _extract_registry(Config.get_active_image())
c.show_cloud = true
return [
sc.c("a1").sicon(_dot).wicon(_dot),
sc.c("a2").eicon(_pillC(MD)).micon(_midIconCBC("Get metadata from registry"), 40),
sc.c("a2").wicon(_pillC(MD)).reverse().eicon(_pillC(MD)).onevent(_metadataCB).trail(false),
sc.c("a3"),
sc.c("a4").micon(_midIconCBC("Get index report from indexer"), 50),
sc.c("a5").eicon(_docker_icon).micon(_midIconCBC("Get layers from registry"), 40),
sc.c("a5").wicon(_docker_icon).eicon(_pillC(IR)).reverse().trail(false),
sc.c("a4").wicon(_pillC(IR)).eicon(_pillC(IR)).reverse().onevent(_indexReportCB).trail(false),
sc.c("a6"),
sc.c("a7").eicon(_pillC(SIG)).micon(_midIconCBC("Get image signature from registry"), 80),
sc.c("a7").wicon(_pillC(SIG)).eicon(_pillC(SIG)).reverse().onevent(_signatureCB).trail(false),
sc.c("a8").eicon(_dot).micon(_midIconCBC("Send match request to central"), 24),
]
func _J() -> Array[PathSegment]:
var dst_cluster:int = _get_dst_cluster()
var cPaths:Node2D = cluster_cpaths[dst_cluster]
var sc = SegCreator.new(cPaths.get_node("c0-scan-local")).wicon(_dot)
return [
sc.c("a1").sicon(_dot).wicon(_dot),
sc.c("a2").eicon(_pillC(MD)).micon(_midIconCBC("Get metadata from registry"), 30),
sc.c("a2").wicon(_pillC(MD)).reverse().eicon(_pillC(MD)).onevent(_metadataCB).trail(false),
sc.c("a3"),
sc.c("a4").micon(_midIconCBC("Get index report from indexer"), 60),
sc.c("a5").eicon(_docker_icon).micon(_midIconCBC("Get layers from registry"), 30),
sc.c("a5").wicon(_docker_icon).eicon(_pillC(IR)).reverse().trail(false),
sc.c("a4").wicon(_pillC(IR)).eicon(_pillC(IR)).reverse().onevent(_indexReportCB).trail(false),
sc.c("a6"),
sc.c("a7").eicon(_pillC(SIG)).micon(_midIconCBC("Get image signature from registry"), 70),
sc.c("a7").wicon(_pillC(SIG)).eicon(_pillC(SIG)).reverse().onevent(_signatureCB).trail(false),
sc.c("a8").eicon(_dot).micon(_midIconCBC("Send match request to central"), 24),
]
func _K() -> Array[PathSegment]:
var reg = _extract_registry(Config.get_active_image())
var dst_cluster:int = _get_dst_cluster()
var cPaths:Node2D = cluster_cpaths[dst_cluster]
var sc = SegCreator.new(cPaths.get_node("c0-scan-local-error")).wicon(_dot)
return [
sc.c("a1").sicon(_dot),
sc.c("a2").eicon(_errorC("", Global.Pos.TOP)).micon(_midIconCBC("Fail to get metadata from registry - unreachable"), 20),
sc.c("a2").reverse().onevent(local_registries_animates[reg]).eicon(_rdot).trail(false),
sc.c("a3").wicon(_rdot).eicon(_dot).micon(_midIconCBC("Send failure to central"), 100),
]
func _L() -> Array[PathSegment]:
var dst_cluster:int = _get_dst_cluster()
var cPaths:Node2D = cluster_cpaths[dst_cluster]
var sc = SegCreator.new(cPaths.get_node("c0-scan-central")).wicon(_dot)
return [
sc.c("a1").sicon(_dot).eicon(_dot).micon(_midIconCBC("Send scan request to central"), 140),
]
func _MC() -> Array[PathSegment]:
var dst_cluster:int = _get_dst_cluster()
var cPaths:Node2D = cluster_cpaths[ dst_cluster]
var toCentralPath:Node2D = to_central_paths[dst_cluster]
var sc = SegCreator.new(toCentralPath).wicon(_dot).eicon(_dot).sicon(_dot)
var scEnd = SegCreator.new(cPaths.get_node("c0-end")).wicon(_dot).trail(false)
return [
scEnd.c("a1"),
sc.c("a1").wicon(_dot),
sensor_to_central_start_sc.c("a1"),
]
func _N() -> Array[PathSegment]:
return [
central_match_sc.c("a1").sicon(_dot),
central_match_sc.c("a2").eicon(_pillC(VR)).micon(_midIconCBC("Get vuln report from matcher"), 30),
central_match_sc.c("a2").reverse().wicon(_pillC(VR)).eicon(_pillC(VR)).onevent(_vulnReportCB).trail(false),
central_match_sc.c("a3"),
central_match_sc.c("a3_1").eicon(_pillC(SIGV)).micon(_midIconCBC("Verify image signatures"), 20),
central_match_sc.c("a3_1").reverse().eicon(_pillC(SIGV)).onevent(_signatureVerificationCB).trail(false),
central_match_sc.c("a3_2"),
central_match_sc.c("a4").sicon(_dot).wicon(_image_status).eicon(_image_status).micon(_midIconCBC("Store final image in DB"), 20),
central_match_sc.c("a5").wicon(_dot).eicon(_dot),
]
func _O() -> Array[PathSegment]:
return [
central_save_error_sc.c("a1").wicon(_rdot).sicon(_dot),
central_save_error_sc.c("a2").wicon(_rdot).sicon(_dot).eicon(_image_status).micon(_midIconCBC("Store scan with error in DB (if no existing image)"), 20),
central_save_error_sc.c("a3").eicon(_dot),
]
func _P() -> Array[PathSegment]:
return [
central_to_central_start_sc.c("b1").wicon(_image_status).eicon(_image_status),
]
func _Q() -> Array[PathSegment]:
return [
central_to_central_start_sc.c("b1").wicon(_image_status).eicon(_image_status),
]
# The cluster returned is used depending on context to obtain the approprate cluster paths
# or the paths to route the from central to a secured cluster.
func _get_dst_cluster() -> int:
var r:Config.ShouldDelegateResult = Config.should_delegate(Config.get_active_image())
# If Central was clicked the dst cluster is what was returned.
if Config.get_cluster_clicked() == -1:
return r.dst_cluster()
# If a secured cluster was clicked, then the destination is the cluster itself.
return Config.get_cluster_clicked()
# See docs\research.md for meaning of A, B, C etc.
func _build_path(p_path_num:int) -> Array[PathSegment]:
var path:Array[PathSegment] = []
match p_path_num:
1: # scan central cloud
path.append_array(_A())
path.append_array(_C())
path.append_array(_D())
path.append_array(_P())
2: # scan central error - no network path
path.append_array(_A())
path.append_array(_C())
path.append_array(_E())
path.append_array(_P())
3: # scan central error - no cluster
path.append_array(_A())
path.append_array(_C())
path.append_array(_F())
path.append_array(_P())
4: # central to sensor - index via cloud
path.append_array(_A())
path.append_array(_G())
path.append_array(_HQ())
path.append_array(_I())
path.append_array(_MC())
path.append_array(_N())
path.append_array(_P())
5: # central to sensor - index via local
path.append_array(_A())
path.append_array(_G())
path.append_array(_HQ())
path.append_array(_J())
path.append_array(_MC())
path.append_array(_N())
path.append_array(_P())
6: # central to sensor - error - no network path
path.append_array(_A())
path.append_array(_G())
path.append_array(_HQ())
path.append_array(_K())
path.append_array(_MC())
path.append_array(_O())
path.append_array(_P())
7: # sensor deploy - index via cloud
path.append_array(_BQ())
path.append_array(_I())
path.append_array(_MC())
path.append_array(_N())
8: # sensor deploy - index via local
path.append_array(_BQ())
path.append_array(_J())
path.append_array(_MC())
path.append_array(_N())
9: # sensor deploy - index error - no network path
path.append_array(_BQ())
path.append_array(_K())
path.append_array(_MC())
path.append_array(_O())
10: # sensor deploy to central - scan via cloud
path.append_array(_BQ())
path.append_array(_L())
path.append_array(_MC())
path.append_array(_D())
11: # sensor deploy to central - scan error - no network path
path.append_array(_BQ())
path.append_array(_L())
path.append_array(_MC())
path.append_array(_E())
return path
func _get_path(p_src_cluster_idx:int, p_image:String) -> Array[PathSegment]:
if p_src_cluster_idx == Global.CENTRAL_CLUSTER_IDX:
return _get_path_central_start(p_image)
return _get_path_cluster_start(p_src_cluster_idx, p_image)
func _get_path_central_start(image:String) -> Array[PathSegment]:
var r:Config.ShouldDelegateResult = Config.should_delegate(image)
var reg:String = _extract_registry(image)
var reg_internet_accessable:bool = !local_registries_animates.has(reg)
if !r.should_delegate():
# 01 if reg_internet_accessable else 02
return _build_path(1) if reg_internet_accessable else _build_path(2)
if r.dst_cluster() == Global.CENTRAL_CLUSTER_IDX:
return _build_path(3)
if reg_internet_accessable:
return _build_path(4)
if cluster_registries.has(r.dst_cluster()) && cluster_registries[r.dst_cluster()].has(reg):
return _build_path(5)
return _build_path(6)
func _get_path_cluster_start(p_src_cluster_idx:int, image:String) -> Array[PathSegment]:
var r:Config.ShouldDelegateResult = Config.should_delegate(image)
var reg:String = _extract_registry(image)
var reg_internet_accessable:bool = !local_registries_animates.has(reg)
if !r.should_delegate():
# 10 if reg_internet_accessable else 11
return _build_path(10) if reg_internet_accessable else _build_path(11)
if reg_internet_accessable:
return _build_path(7)
if cluster_registries.has(p_src_cluster_idx) && cluster_registries[p_src_cluster_idx].has(reg):
return _build_path(8)
return _build_path(9)
func _metadataCB(p_event:Global.Event):
match p_event:
Global.Event.END:
have_metadata = true
Global.Event.RESET:
have_metadata = false
func _indexReportCB(p_event:Global.Event):
match p_event:
Global.Event.END:
have_index_report = true
Global.Event.RESET:
have_index_report = false
func _vulnReportCB(p_event:Global.Event):
match p_event:
Global.Event.END:
have_vuln_report = true
Global.Event.RESET:
have_vuln_report = false
func _signatureCB(p_event:Global.Event):
match p_event:
Global.Event.END:
have_signatures = true
Global.Event.RESET:
have_signatures = false
func _signatureVerificationCB(p_event:Global.Event):
match p_event:
Global.Event.END:
have_sigverification = true
Global.Event.RESET:
have_sigverification = false
func _errorStatusCB(p_event:Global.Event):
match p_event:
Global.Event.END:
have_error = true
Global.Event.RESET:
have_error = false
func _prodAnimateCB(p_event:Global.Event):
_clusterAnimate(p_event, Global.CLUSTER.PROD)
func _devAnimateCB(p_event:Global.Event):
_clusterAnimate(p_event, Global.CLUSTER.DEV)
func _otherAnimateCB(p_event:Global.Event):
_clusterAnimate(p_event, Global.CLUSTER.OTHER)
func _clusterAnimate(p_event:Global.Event, p_cluster:Global.CLUSTER=Global.CLUSTER.CENTRAL):
match p_event:
Global.Event.START:
animationPlayers[p_cluster].play(animationRegHighlight)
Global.Event.END:
have_error = true
Global.Event.RESET:
animationPlayers[p_cluster].stop()
have_error = false
func _add_log_entry(p_icon_text:String, p_text:String):
SignalManager.push_log_entry.emit(p_icon_text, p_text)
func _del_log_entry():
SignalManager.pop_log_entry.emit()
func _del_all_log_entry():
SignalManager.clear_log.emit()
# should be one entry here per step in the slider
var walk_speeds_px:Array[float] = [
10,
50,
100,
250,
400,
500,
600,
800,
1000,
2000,
10000,
]
func _on_speed_slider_value_changed(value:float):
Config.update_walk_speed_px(walk_speeds_px[value])
func _on_log_entry_pop():
last_log_letter -= 1
if last_log_letter < initial_log_letter:
last_log_letter = initial_log_letter
func _on_log_clear():
last_log_letter = initial_log_letter
func _get_next_log_letter() -> String:
last_log_letter += 1
return char(last_log_letter)
func _get_last_log_letter() -> String:
return char(last_log_letter)
func _midIconCBC(p_text:String) -> Callable:
return Callable(self, "_midIconCB").bind(p_text)
func _midIconCB(p_text:String) -> Node:
var s = preload("res://letter_icon.tscn")
var i = s.instantiate()
i.scale = Vector2(0.6, 0.6)
i.update_icon_text(_get_next_log_letter())
_add_log_entry(_get_last_log_letter(), p_text)
return i
func _config_updated():
# TODO: instead of doing a full reset, perhaps just change the behavior of the flow controls
_reset()
func _on_prod_config_updated():
_config_updated()
func _on_dev_config_updated():
_config_updated()
func _on_quay_config_updated():
_config_updated()
func _on_default_cluster_option_item_selected(_index):
# -1 = none/default
# 0 = prod, ..., etc. so that the index will map to a cluster in the clusters array
SignalManager.dele_scan_update_default_cluster.emit(_index-1)
_config_updated()
func _on_context_menu(_p_cluster:Global.CLUSTER):
# disabled in preference # buttons
#popup_menu.active_cluster = p_cluster
#popup_menu.position = get_viewport().get_mouse_position()
#popup_menu.show()
pass
func _on_none_radio_toggled(_toggled_on):
if !_toggled_on:
return
SignalManager.dele_scan_update_enabled_for.emit(Global.ENABLED_FOR.NONE)
func _on_all_registries_radio_toggled(_toggled_on):
if !_toggled_on:
return
SignalManager.dele_scan_update_enabled_for.emit(Global.ENABLED_FOR.ALL)
func _on_specific_registries_radio_toggled(_toggled_on):
if !_toggled_on:
return
SignalManager.dele_scan_update_enabled_for.emit(Global.ENABLED_FOR.SPECIFIC)
func _on_back_step_button_pressed():
Config.set_moving(false)
if cur_path_segment_idx >= Config.active_path().size():
cur_path_segment_idx = Config.active_path().size()-1
if Config.active_path().size() == 0:
return
var seg:PathSegment
seg = Config.active_path()[cur_path_segment_idx]
seg.reset()
if cur_path_segment_idx >= 1:
cur_path_segment_idx -= 1
func _on_deploy_to_cluster(p_cluster:Global.CLUSTER):
_reset()
if !Config.has_images():
print("ERROR: no images, cannot deploy")
return
# print("prepping path for image: ", Config.get_active_image())
Config.set_cluster_clicked(p_cluster-1)
# Config.set_active_path(_prep_path(p_cluster, Config.get_active_image()))
Config.set_active_path(_get_path(p_cluster-1, Config.get_active_image()))
Config.set_moving(true)
func _on_reset_button_pressed():
_reset()
func _on_pause_play_button_pressed():
if !Config.moving() && cur_path_segment_idx >= Config.active_path().size():
_reset(true)
Config.toggle_moving()
#
#@onready var save_test_code_edit = $SaveTestCodeEdit
#var path:String = "user://savegame.save"
#
#func _on_save_test_code_edit_ready():
#var file:FileAccess = FileAccess.open(path, FileAccess.READ)
#if file == null:
#print("WARN: Loading saved data ", path, ": ", error_string(FileAccess.get_open_error()))
#return
#
#var content = file.get_as_text()
#save_test_code_edit.text = content
#
#func _on_save_test_code_edit_text_changed():
#var file:FileAccess = FileAccess.open(path, FileAccess.WRITE)
#file.store_string(save_test_code_edit.text)
func _handle_background_input_event(event):
if event is InputEventMouseButton and event.pressed and event.button_index == 1: # left click
Config.clear_focus(get_viewport())
func _on_bottom_panel_bg_gui_input(event):
_handle_background_input_event(event)
func _on_top_panel_bg_gui_input(event):
_handle_background_input_event(event)
func _on_log_panel_gui_input(event):
_handle_background_input_event(event)