diff --git a/.gitignore b/.gitignore index 2d32c47dd..eab1070b1 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,7 @@ test/system/generator/generator scripts/collectors/ # java -deployments/kubehound/kubegraph/dsl/kubehound/target \ No newline at end of file +deployments/kubehound/kubegraph/dsl/kubehound/target + +# personal settings +.vscode/settings.json \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 00890d87d..bca4771bb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,8 +1,6 @@ run: # Default: 1m timeout: 5m - # For now, don't block the test, only comment on the findings! - issues-exit-code: 0 linters: disable-all: true @@ -15,7 +13,7 @@ linters: - bodyclose - containedctx - contextcheck - - cyclop + # - cyclop - decorder - dogsled - dupword @@ -33,14 +31,14 @@ linters: # - gci - ginkgolinter - gocheckcompilerdirectives - - gochecknoglobals + # - gochecknoglobals - gocognit - goconst - gocritic - gocyclo # - goerr113 # Would probably be best. But lets ignore for now - gofmt - - gofumpt + # - gofumpt - goheader - goimports - gomnd @@ -54,7 +52,7 @@ linters: - importas - ineffassign - interfacebloat - - ireturn + # - ireturn - loggercheck - maintidx - makezero @@ -74,14 +72,14 @@ linters: - predeclared - promlinter - reassign - - revive + # - revive - rowserrcheck - sqlclosecheck - staticcheck - - stylecheck + # - stylecheck TODO reeanble - tenv - testableexamples - - testpackage + # - testpackage - thelper - tparallel - typecheck @@ -90,5 +88,5 @@ linters: - unused - usestdlibvars - wastedassign - - whitespace + # - whitespace # - wrapcheck #TODO: add it back later potentially? \ No newline at end of file diff --git a/docs/Architecture.excalidraw b/docs/Architecture.excalidraw index dc3276c0f..322ec4398 100644 --- a/docs/Architecture.excalidraw +++ b/docs/Architecture.excalidraw @@ -23,6 +23,7 @@ "height": 181, "seed": 447987029, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -60,6 +61,7 @@ "height": 67.2, "seed": 745802389, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653818, @@ -73,7 +75,7 @@ "containerId": "LU54UurC_Phu3QzkWJLwt", "originalText": "File\nCollector", "lineHeight": 1.2, - "baseline": 57 + "baseline": 59 }, { "type": "ellipse", @@ -95,6 +97,7 @@ "height": 170, "seed": 531061275, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -136,6 +139,7 @@ "height": 67.2, "seed": 346499349, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653818, @@ -149,7 +153,7 @@ "containerId": "up9asGqaQNg_0-iT7qusl", "originalText": "API\nCollector", "lineHeight": 1.2, - "baseline": 57 + "baseline": 59 }, { "type": "diamond", @@ -171,6 +175,7 @@ "height": 166.54296875, "seed": 1153555445, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -214,6 +219,7 @@ "groupIds": [ "MsCOWLjA3f17vjTs-z5QE" ], + "frameId": null, "roundness": { "type": 2 }, @@ -327,6 +333,7 @@ "groupIds": [ "MsCOWLjA3f17vjTs-z5QE" ], + "frameId": null, "roundness": { "type": 2 }, @@ -396,6 +403,7 @@ "groupIds": [ "MsCOWLjA3f17vjTs-z5QE" ], + "frameId": null, "roundness": { "type": 2 }, @@ -465,6 +473,7 @@ "groupIds": [ "MsCOWLjA3f17vjTs-z5QE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037459, @@ -493,6 +502,7 @@ "groupIds": [ "MsCOWLjA3f17vjTs-z5QE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037459, @@ -521,6 +531,7 @@ "groupIds": [ "MsCOWLjA3f17vjTs-z5QE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037459, @@ -549,6 +560,7 @@ "groupIds": [ "MsCOWLjA3f17vjTs-z5QE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037459, @@ -577,6 +589,7 @@ "groupIds": [ "e4FrEnpo-TbNU0N2m087M" ], + "frameId": null, "roundness": { "type": 2 }, @@ -690,6 +703,7 @@ "groupIds": [ "e4FrEnpo-TbNU0N2m087M" ], + "frameId": null, "roundness": { "type": 2 }, @@ -759,6 +773,7 @@ "groupIds": [ "e4FrEnpo-TbNU0N2m087M" ], + "frameId": null, "roundness": { "type": 2 }, @@ -828,6 +843,7 @@ "groupIds": [ "e4FrEnpo-TbNU0N2m087M" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -865,6 +881,7 @@ "groupIds": [ "e4FrEnpo-TbNU0N2m087M" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037459, @@ -893,6 +910,7 @@ "groupIds": [ "e4FrEnpo-TbNU0N2m087M" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037459, @@ -921,6 +939,7 @@ "groupIds": [ "e4FrEnpo-TbNU0N2m087M" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037459, @@ -947,6 +966,7 @@ "height": 192.24738166156362, "seed": 935377499, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -998,6 +1018,7 @@ "height": 187.09855578401914, "seed": 735264533, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1031,8 +1052,8 @@ }, { "type": "text", - "version": 116, - "versionNonce": 1097025187, + "version": 117, + "versionNonce": 1980260479, "isDeleted": false, "id": "sJO_ZmMepiyi06AHrKkQ9", "fillStyle": "hachure", @@ -1049,6 +1070,7 @@ "height": 33.6, "seed": 1267509045, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -1060,7 +1082,7 @@ "type": "arrow" } ], - "updated": 1691691653819, + "updated": 1696427296401, "link": null, "locked": false, "fontSize": 28, @@ -1093,6 +1115,7 @@ "height": 1.9702272019470684, "seed": 1943431253, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1144,6 +1167,7 @@ "height": 126.55859375, "seed": 1581772603, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1193,6 +1217,7 @@ "height": 67.2, "seed": 2111698421, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653819, @@ -1206,12 +1231,12 @@ "containerId": "xqKEV747tZVmcShapaHbi", "originalText": "NoSQL\nWriter", "lineHeight": 1.2, - "baseline": 57 + "baseline": 59 }, { "type": "text", - "version": 186, - "versionNonce": 1864923715, + "version": 187, + "versionNonce": 361442033, "isDeleted": false, "id": "MhOA3DvDyl9_PMA_eGylg", "fillStyle": "hachure", @@ -1228,9 +1253,10 @@ "height": 33.6, "seed": 172611189, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653819, + "updated": 1696427296402, "link": null, "locked": false, "fontSize": 28, @@ -1263,6 +1289,7 @@ "height": 389.4886715529009, "seed": 506798427, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1315,6 +1342,7 @@ "height": 67.2, "seed": 312892469, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653819, @@ -1328,7 +1356,7 @@ "containerId": "fd3Nh6znMVqF-cqr9mwue", "originalText": "Write K8s objects", "lineHeight": 1.2, - "baseline": 57 + "baseline": 59 }, { "type": "arrow", @@ -1350,6 +1378,7 @@ "height": 1.8165751130919716, "seed": 1806709883, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1383,8 +1412,8 @@ }, { "type": "text", - "version": 101, - "versionNonce": 21379555, + "version": 102, + "versionNonce": 1011218591, "isDeleted": false, "id": "GTnv7qVfRupMg-qr0ON_9", "fillStyle": "hachure", @@ -1401,9 +1430,10 @@ "height": 33.6, "seed": 314961467, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653819, + "updated": 1696427296402, "link": null, "locked": false, "fontSize": 28, @@ -1436,6 +1466,7 @@ "height": 230.36699969117603, "seed": 1071347899, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1492,6 +1523,7 @@ "height": 33.6, "seed": 1788939739, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653819, @@ -1505,7 +1537,7 @@ "containerId": "n7WWKTxMSsvg3nwhmBDzJ", "originalText": "Write nodes", "lineHeight": 1.2, - "baseline": 23 + "baseline": 26 }, { "type": "arrow", @@ -1527,6 +1559,7 @@ "height": 3.7815459414130146, "seed": 1537295067, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1574,6 +1607,7 @@ "height": 223.8946525810136, "seed": 1976967413, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1630,6 +1664,7 @@ "height": 33.6, "seed": 1031015669, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653820, @@ -1643,7 +1678,7 @@ "containerId": "yCYW8mGk_9pzn4GQ_vZud", "originalText": "Write edges", "lineHeight": 1.2, - "baseline": 23 + "baseline": 26 }, { "type": "arrow", @@ -1665,6 +1700,7 @@ "height": 272.75491949539605, "seed": 1675107515, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1717,6 +1753,7 @@ "height": 33.6, "seed": 1340923291, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653820, @@ -1730,7 +1767,7 @@ "containerId": "UCintRLDih6wWQ6TibA03", "originalText": "Query store", "lineHeight": 1.2, - "baseline": 23 + "baseline": 26 }, { "type": "arrow", @@ -1752,6 +1789,7 @@ "height": 315.57325098876, "seed": 6284725, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1804,6 +1842,7 @@ "height": 33.6, "seed": 1714101819, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653820, @@ -1817,7 +1856,7 @@ "containerId": "yBfm8b0ilCWkAVtvbZAZR", "originalText": "Query store", "lineHeight": 1.2, - "baseline": 23 + "baseline": 26 }, { "type": "ellipse", @@ -1839,6 +1878,7 @@ "height": 169, "seed": 1635554101, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1880,6 +1920,7 @@ "height": 67.2, "seed": 1890657947, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653820, @@ -1893,7 +1934,7 @@ "containerId": "P8g7HFZhogpHXbo5Pcm6j", "originalText": "ETCD\nCollector", "lineHeight": 1.2, - "baseline": 57 + "baseline": 59 }, { "type": "arrow", @@ -1915,6 +1956,7 @@ "height": 422.7772450469131, "seed": 644078971, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -1966,6 +2008,7 @@ "height": 1728.9095269753611, "seed": 1285558005, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -1976,8 +2019,8 @@ }, { "type": "text", - "version": 130, - "versionNonce": 1899217091, + "version": 131, + "versionNonce": 229287121, "isDeleted": false, "id": "uJatiRDv4sNvMEWLmFCZs", "fillStyle": "hachure", @@ -1994,9 +2037,10 @@ "height": 33.6, "seed": 1739640981, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653820, + "updated": 1696427296402, "link": null, "locked": false, "fontSize": 28, @@ -2031,6 +2075,7 @@ "groupIds": [ "Q8J9alxDkAkYgdJR6PAp4" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -2064,6 +2109,7 @@ "groupIds": [ "Q8J9alxDkAkYgdJR6PAp4" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -2097,6 +2143,7 @@ "groupIds": [ "Q8J9alxDkAkYgdJR6PAp4" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2125,6 +2172,7 @@ "groupIds": [ "Q8J9alxDkAkYgdJR6PAp4" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2133,8 +2181,8 @@ }, { "type": "text", - "version": 118, - "versionNonce": 1031266541, + "version": 119, + "versionNonce": 1935379647, "isDeleted": false, "id": "qsY95SxOH_-1MsBxffwR8", "fillStyle": "hachure", @@ -2151,9 +2199,10 @@ "height": 35, "seed": 1958913958, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653820, + "updated": 1696427296402, "link": null, "locked": false, "fontSize": 28, @@ -2186,6 +2235,7 @@ "height": 410.7630774889635, "seed": 332990778, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -2233,6 +2283,7 @@ "height": 364.59330438082543, "seed": 1935244346, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -2270,6 +2321,7 @@ "height": 55.51727849608153, "seed": 965828602, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2313,8 +2365,8 @@ }, { "type": "text", - "version": 325, - "versionNonce": 1596239971, + "version": 326, + "versionNonce": 729801393, "isDeleted": false, "id": "xj-u_gjSnmn3GDxyNR2d8", "fillStyle": "hachure", @@ -2331,9 +2383,10 @@ "height": 35, "seed": 1421565370, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653820, + "updated": 1696427296402, "link": null, "locked": false, "fontSize": 28, @@ -2348,8 +2401,8 @@ }, { "type": "text", - "version": 298, - "versionNonce": 386349901, + "version": 299, + "versionNonce": 921279711, "isDeleted": false, "id": "5RMFef4-FX4TQRA_fiGXq", "fillStyle": "hachure", @@ -2366,9 +2419,10 @@ "height": 35, "seed": 408101882, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653820, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -2401,6 +2455,7 @@ "height": 55.51727849608153, "seed": 12824122, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2444,8 +2499,8 @@ }, { "type": "text", - "version": 315, - "versionNonce": 748071939, + "version": 316, + "versionNonce": 1001546897, "isDeleted": false, "id": "Q8HFSir8MT7mNfc1xSlP0", "fillStyle": "hachure", @@ -2462,9 +2517,10 @@ "height": 35, "seed": 557902438, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -2497,6 +2553,7 @@ "height": 55.51727849608153, "seed": 1558159782, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2540,8 +2597,8 @@ }, { "type": "text", - "version": 329, - "versionNonce": 243026349, + "version": 330, + "versionNonce": 1518381311, "isDeleted": false, "id": "Xx8EMOQ-0nia17TSOBruD", "fillStyle": "hachure", @@ -2558,9 +2615,10 @@ "height": 35, "seed": 463549370, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -2593,6 +2651,7 @@ "height": 55.51727849608153, "seed": 285740966, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2636,8 +2695,8 @@ }, { "type": "text", - "version": 349, - "versionNonce": 1569207203, + "version": 350, + "versionNonce": 167357041, "isDeleted": false, "id": "OYk4eZYTSZz7Z8N1q51Im", "fillStyle": "hachure", @@ -2654,9 +2713,10 @@ "height": 35, "seed": 1862182330, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -2689,6 +2749,7 @@ "height": 55.51727849608153, "seed": 2017465062, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2732,8 +2793,8 @@ }, { "type": "text", - "version": 336, - "versionNonce": 1157663757, + "version": 337, + "versionNonce": 1805725983, "isDeleted": false, "id": "THQTcyKGefUDkWgebQCI_", "fillStyle": "hachure", @@ -2750,9 +2811,10 @@ "height": 35, "seed": 967538298, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -2785,6 +2847,7 @@ "height": 55.51727849608153, "seed": 544487162, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2828,8 +2891,8 @@ }, { "type": "text", - "version": 328, - "versionNonce": 1915209539, + "version": 329, + "versionNonce": 2132620369, "isDeleted": false, "id": "eRAlYYwrSvaomNqigGNo_", "fillStyle": "hachure", @@ -2846,9 +2909,10 @@ "height": 35, "seed": 2034912678, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -2881,6 +2945,7 @@ "height": 55.51727849608153, "seed": 761333178, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -2924,8 +2989,8 @@ }, { "type": "text", - "version": 349, - "versionNonce": 2056094317, + "version": 350, + "versionNonce": 1941681471, "isDeleted": false, "id": "ae6RAopSKrGrhlpEiBhp9", "fillStyle": "hachure", @@ -2942,9 +3007,10 @@ "height": 35, "seed": 426167014, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -2977,6 +3043,7 @@ "height": 365.1629600443216, "seed": 2103890790, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -3022,6 +3089,7 @@ "height": 55.51727849608153, "seed": 263126522, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -3065,8 +3133,8 @@ }, { "type": "text", - "version": 400, - "versionNonce": 1624499939, + "version": 401, + "versionNonce": 2129953329, "isDeleted": false, "id": "2Qvkr2NhtfGOcw3dpgKc-", "fillStyle": "hachure", @@ -3083,9 +3151,10 @@ "height": 35, "seed": 1162049190, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -3100,8 +3169,8 @@ }, { "type": "text", - "version": 366, - "versionNonce": 871148749, + "version": 367, + "versionNonce": 2050012511, "isDeleted": false, "id": "uIC8FEvSKMfK2mGhnRdDZ", "fillStyle": "hachure", @@ -3118,9 +3187,10 @@ "height": 35, "seed": 1003564730, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296403, "link": null, "locked": false, "fontSize": 28, @@ -3153,6 +3223,7 @@ "height": 55.51727849608153, "seed": 136950246, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -3196,8 +3267,8 @@ }, { "type": "text", - "version": 401, - "versionNonce": 1343951491, + "version": 402, + "versionNonce": 107418641, "isDeleted": false, "id": "X1YLHU7ohQU4sOcnHA0qv", "fillStyle": "hachure", @@ -3214,9 +3285,10 @@ "height": 35, "seed": 770656122, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653821, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -3249,6 +3321,7 @@ "height": 55.51727849608153, "seed": 1629914406, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -3292,8 +3365,8 @@ }, { "type": "text", - "version": 516, - "versionNonce": 1126939501, + "version": 517, + "versionNonce": 1179693439, "isDeleted": false, "id": "jeCM6c0i4Y4GPlsfWd4VP", "fillStyle": "hachure", @@ -3310,9 +3383,10 @@ "height": 35, "seed": 239880250, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691683212, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -3345,6 +3419,7 @@ "height": 55.51727849608153, "seed": 27717734, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -3388,8 +3463,8 @@ }, { "type": "text", - "version": 403, - "versionNonce": 280742435, + "version": 404, + "versionNonce": 158099953, "isDeleted": false, "id": "vy6xQkiQNebtwi6MR1KA6", "fillStyle": "hachure", @@ -3406,6 +3481,7 @@ "height": 35, "seed": 80425210, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -3413,7 +3489,7 @@ "type": "arrow" } ], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -3446,6 +3522,7 @@ "height": 55.51727849608153, "seed": 1702359974, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -3489,8 +3566,8 @@ }, { "type": "text", - "version": 400, - "versionNonce": 1096261005, + "version": 401, + "versionNonce": 1633429919, "isDeleted": false, "id": "9o8Nx_3Aqci2cLWRVw73U", "fillStyle": "hachure", @@ -3507,9 +3584,10 @@ "height": 35, "seed": 1156514234, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -3542,6 +3620,7 @@ "height": 55.51727849608153, "seed": 113676006, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -3585,8 +3664,8 @@ }, { "type": "text", - "version": 419, - "versionNonce": 1470401987, + "version": 420, + "versionNonce": 286000081, "isDeleted": false, "id": "62qOOnavk9Qc0c1Qulbt9", "fillStyle": "hachure", @@ -3603,9 +3682,10 @@ "height": 35, "seed": 433764986, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -3638,6 +3718,7 @@ "height": 55.51727849608153, "seed": 304071206, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -3681,8 +3762,8 @@ }, { "type": "text", - "version": 415, - "versionNonce": 1292264429, + "version": 416, + "versionNonce": 1485020607, "isDeleted": false, "id": "J24wke_9NjpUX88qpjt2a", "fillStyle": "hachure", @@ -3699,9 +3780,10 @@ "height": 35, "seed": 1917934394, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -3736,6 +3818,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 1 }, @@ -3766,6 +3849,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -3796,6 +3880,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -3826,6 +3911,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -3856,6 +3942,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -3886,6 +3973,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -3916,6 +4004,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -3946,6 +4035,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 1 }, @@ -3976,6 +4066,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -4049,6 +4140,7 @@ "groupIds": [ "mMtLjAXY6JHnYGLWaVSlB" ], + "frameId": null, "roundness": { "type": 2 }, @@ -4120,6 +4212,7 @@ "height": 80.86674614073786, "seed": 1508484922, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -4169,6 +4262,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -4202,6 +4296,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": { "type": 2 }, @@ -4247,6 +4342,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -4275,6 +4371,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -4303,6 +4400,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -4331,6 +4429,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -4359,6 +4458,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": { "type": 2 }, @@ -4484,6 +4584,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": { "type": 2 }, @@ -4529,6 +4630,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": { "type": 2 }, @@ -4598,6 +4700,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, @@ -4626,6 +4729,7 @@ "groupIds": [ "iRSPwZklM-rZSUxJP0McP" ], + "frameId": null, "roundness": { "type": 2 }, @@ -4671,8 +4775,8 @@ }, { "type": "text", - "version": 106, - "versionNonce": 938728803, + "version": 107, + "versionNonce": 425550257, "isDeleted": false, "id": "HapGfrQFrDl5KE-Oby23Z", "fillStyle": "hachure", @@ -4689,6 +4793,7 @@ "height": 35, "seed": 1296390010, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -4696,7 +4801,7 @@ "type": "arrow" } ], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -4711,8 +4816,8 @@ }, { "type": "text", - "version": 151, - "versionNonce": 1473076813, + "version": 152, + "versionNonce": 1055362527, "isDeleted": false, "id": "Yq7rXU67DrJQRiPk7DO4o", "fillStyle": "hachure", @@ -4729,9 +4834,10 @@ "height": 35, "seed": 811089402, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -4764,6 +4870,7 @@ "height": 1.498914138905036, "seed": 1532855290, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -4789,8 +4896,8 @@ }, { "type": "text", - "version": 101, - "versionNonce": 1559771395, + "version": 102, + "versionNonce": 797442961, "isDeleted": false, "id": "cLd1O2Lwxzt4GEBAr_K4R", "fillStyle": "hachure", @@ -4807,9 +4914,10 @@ "height": 35, "seed": 132432998, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -4842,6 +4950,7 @@ "height": 1.498914138905036, "seed": 155202810, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -4867,8 +4976,8 @@ }, { "type": "text", - "version": 154, - "versionNonce": 948309165, + "version": 155, + "versionNonce": 1872263679, "isDeleted": false, "id": "7W32qHrGktfKhsDLb5QvA", "fillStyle": "hachure", @@ -4885,9 +4994,10 @@ "height": 35, "seed": 1371877286, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -4920,6 +5030,7 @@ "height": 1.498914138905036, "seed": 258607206, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -4945,8 +5056,8 @@ }, { "type": "text", - "version": 152, - "versionNonce": 70262947, + "version": 153, + "versionNonce": 1338206577, "isDeleted": false, "id": "dni7LEI81rGkEtw9q3eZN", "fillStyle": "hachure", @@ -4963,9 +5074,10 @@ "height": 35, "seed": 2053478650, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296404, "link": null, "locked": false, "fontSize": 28, @@ -4998,6 +5110,7 @@ "height": 1.498914138905036, "seed": 1041875494, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -5023,8 +5136,8 @@ }, { "type": "text", - "version": 146, - "versionNonce": 786034445, + "version": 147, + "versionNonce": 261546527, "isDeleted": false, "id": "rvw_FkiMnZ6xfJUCssEnW", "fillStyle": "hachure", @@ -5041,9 +5154,10 @@ "height": 35, "seed": 452418362, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653822, + "updated": 1696427296405, "link": null, "locked": false, "fontSize": 28, @@ -5076,6 +5190,7 @@ "height": 206.86063434769946, "seed": 1488310630, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -5104,6 +5219,7 @@ "height": 1267.6589402563484, "seed": 327107834, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -5114,8 +5230,8 @@ }, { "type": "text", - "version": 115, - "versionNonce": 927601731, + "version": 116, + "versionNonce": 56038225, "isDeleted": false, "id": "v63LJ3Vzev4f3cKRNbejM", "fillStyle": "hachure", @@ -5132,9 +5248,10 @@ "height": 35, "seed": 387890042, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653823, + "updated": 1696427296405, "link": null, "locked": false, "fontSize": 28, @@ -5167,6 +5284,7 @@ "height": 1011.3646259529033, "seed": 244157030, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -5177,8 +5295,8 @@ }, { "type": "text", - "version": 125, - "versionNonce": 1229096301, + "version": 126, + "versionNonce": 1339246143, "isDeleted": false, "id": "YeBADWHp2vZRmKb-TD44J", "fillStyle": "hachure", @@ -5195,9 +5313,10 @@ "height": 35, "seed": 1147259770, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653823, + "updated": 1696427296405, "link": null, "locked": false, "fontSize": 28, @@ -5230,6 +5349,7 @@ "height": 1.5712624387106189, "seed": 2000812730, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -5281,6 +5401,7 @@ "height": 326.974734576527, "seed": 389899578, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -5296,8 +5417,8 @@ }, { "type": "text", - "version": 460, - "versionNonce": 1176802275, + "version": 461, + "versionNonce": 1050313009, "isDeleted": false, "id": "0nXep7d3EFLCFaHLDUSx_", "fillStyle": "hachure", @@ -5314,9 +5435,10 @@ "height": 250, "seed": 61552186, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653823, + "updated": 1696427296405, "link": null, "locked": false, "fontSize": 20, @@ -5353,11 +5475,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -5879,8 +6004,8 @@ 7.598623012178745 ], [ - 25.175730140559015, - 6.024997325587149 + 25.17573014055902, + 6.024997325587147 ], [ 26.71194997066622, @@ -5951,11 +6076,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6009,11 +6137,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6067,11 +6198,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6125,11 +6259,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6183,11 +6320,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6241,11 +6381,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6300,11 +6443,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6438,11 +6584,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6496,11 +6645,14 @@ "AFAWSl1Crf0qSnXYVpXrz", "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -6553,11 +6705,14 @@ "groupIds": [ "_FV4vHIrmSht7toI9PovA" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -7002,8 +7157,8 @@ }, { "type": "text", - "version": 154, - "versionNonce": 185159629, + "version": 155, + "versionNonce": 1865295455, "isDeleted": false, "id": "6Su8vpgYUqsmtknzq5VDS", "fillStyle": "hachure", @@ -7020,9 +7175,10 @@ "height": 25, "seed": 233961978, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653823, + "updated": 1696427296405, "link": null, "locked": false, "fontSize": 20, @@ -7059,11 +7215,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -7585,8 +7744,8 @@ 7.598623012178745 ], [ - 25.17573014055902, - 6.024997325587147 + 25.175730140559015, + 6.024997325587149 ], [ 26.71194997066622, @@ -7657,11 +7816,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037460, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -7715,11 +7877,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -7773,11 +7938,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -7831,11 +7999,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -7889,11 +8060,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -7947,11 +8121,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -8006,11 +8183,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -8144,11 +8324,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -8202,11 +8385,14 @@ "FmTfJw8OCenf2_wWZq_nw", "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -8259,11 +8445,14 @@ "groupIds": [ "f80WnfxVQW6a-j7Srrwcr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -8708,8 +8897,8 @@ }, { "type": "text", - "version": 209, - "versionNonce": 13508483, + "version": 210, + "versionNonce": 2129998609, "isDeleted": false, "id": "zZPs1bg4kgerfBJZlmBts", "fillStyle": "hachure", @@ -8726,9 +8915,10 @@ "height": 25, "seed": 2130884966, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653823, + "updated": 1696427296405, "link": null, "locked": false, "fontSize": 20, @@ -8765,11 +8955,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9291,8 +9484,8 @@ 7.598623012178745 ], [ - 25.175730140559015, - 6.024997325587149 + 25.17573014055902, + 6.024997325587147 ], [ 26.71194997066622, @@ -9363,11 +9556,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9421,11 +9617,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9479,11 +9678,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9537,11 +9739,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9595,11 +9800,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9653,11 +9861,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9712,11 +9923,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9850,11 +10064,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9908,11 +10125,14 @@ "8KjcBEaqUAkN7PP6IjVkm", "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -9965,11 +10185,14 @@ "groupIds": [ "Kd39_VA_rsGjvFw6G6CMx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -10414,8 +10637,8 @@ }, { "type": "text", - "version": 317, - "versionNonce": 1380437549, + "version": 318, + "versionNonce": 2088239743, "isDeleted": false, "id": "h749tTzy4MnTdUx-ebPlM", "fillStyle": "hachure", @@ -10432,9 +10655,10 @@ "height": 75, "seed": 1726685434, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653823, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -10471,11 +10695,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -10997,8 +11224,8 @@ 7.598623012178745 ], [ - 25.17573014055902, - 6.024997325587147 + 25.175730140559015, + 6.024997325587149 ], [ 26.71194997066622, @@ -11069,11 +11296,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11127,11 +11357,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11185,11 +11418,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11243,11 +11479,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11301,11 +11540,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11359,11 +11601,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11418,11 +11663,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11556,11 +11804,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11614,11 +11865,14 @@ "66rp4gj3iM9UMv2b87AVE", "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -11671,11 +11925,14 @@ "groupIds": [ "6C179SeBHKCZuhPS5g3XJ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12120,8 +12377,8 @@ }, { "type": "text", - "version": 331, - "versionNonce": 830813987, + "version": 332, + "versionNonce": 685680881, "isDeleted": false, "id": "_IkzPk-IXZOv1AkhgTZlJ", "fillStyle": "hachure", @@ -12138,9 +12395,10 @@ "height": 50, "seed": 1741861946, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -12173,6 +12431,7 @@ "height": 893.3840847083609, "seed": 43931494, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -12192,8 +12451,8 @@ }, { "type": "text", - "version": 125, - "versionNonce": 2112323725, + "version": 126, + "versionNonce": 1483823775, "isDeleted": false, "id": "fhtnQZ7xkE4vZzHVHaQXd", "fillStyle": "hachure", @@ -12210,9 +12469,10 @@ "height": 25, "seed": 326573114, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -12227,8 +12487,8 @@ }, { "type": "text", - "version": 197, - "versionNonce": 1454922435, + "version": 198, + "versionNonce": 635331281, "isDeleted": false, "id": "_awvnh49jf-mf_Dz4IlKh", "fillStyle": "hachure", @@ -12245,9 +12505,10 @@ "height": 50, "seed": 2099728058, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -12280,6 +12541,7 @@ "height": 1043.1659775546364, "seed": 485762918, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -12310,6 +12572,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, @@ -12339,6 +12602,7 @@ "AA1i379KzLFvdRJIuu8vn", "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -12372,6 +12636,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, @@ -12400,6 +12665,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12407,6 +12673,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12447,6 +12715,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12454,6 +12723,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12494,6 +12765,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12501,6 +12773,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12545,6 +12819,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12552,6 +12827,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12600,6 +12877,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12607,6 +12885,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12647,6 +12927,7 @@ "groupIds": [ "EFpZ1qJJCWd1pAEFha0a6" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12654,6 +12935,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12678,8 +12961,8 @@ }, { "type": "text", - "version": 55, - "versionNonce": 1403119341, + "version": 56, + "versionNonce": 2009771711, "isDeleted": false, "id": "-GHqS8t7mzHIfqTsZnevk", "fillStyle": "hachure", @@ -12696,6 +12979,7 @@ "height": 25, "seed": 1785066214, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -12703,7 +12987,7 @@ "type": "arrow" } ], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -12738,6 +13022,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, @@ -12767,6 +13052,7 @@ "efVzV0UcTYyIVEHyUsWDd", "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, @@ -12795,6 +13081,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -12828,6 +13115,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12835,6 +13123,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12875,6 +13165,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12882,6 +13173,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12922,6 +13215,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12929,6 +13223,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -12973,6 +13269,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": { "type": 2 }, @@ -12980,6 +13277,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -13028,6 +13327,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13035,6 +13335,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -13075,6 +13377,7 @@ "groupIds": [ "kHmGzmh9FpRvDJ8I-pfq1" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13082,6 +13385,8 @@ "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -13106,8 +13411,8 @@ }, { "type": "text", - "version": 127, - "versionNonce": 486935139, + "version": 128, + "versionNonce": 1116463281, "isDeleted": false, "id": "CvDdQVlqAFXOuaA4tKvyT", "fillStyle": "hachure", @@ -13124,9 +13429,10 @@ "height": 25, "seed": 93885626, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -13141,8 +13447,8 @@ }, { "type": "text", - "version": 146, - "versionNonce": 637567309, + "version": 147, + "versionNonce": 1696890591, "isDeleted": false, "id": "XbeLWyVem7v6CSSyR3WKn", "fillStyle": "hachure", @@ -13159,9 +13465,10 @@ "height": 25, "seed": 1861795770, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -13194,6 +13501,7 @@ "height": 252.21274360903317, "seed": 78104058, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -13221,8 +13529,8 @@ }, { "type": "text", - "version": 89, - "versionNonce": 423413251, + "version": 90, + "versionNonce": 1284416145, "isDeleted": false, "id": "EO8bRIiEmk7DWH7DzMvej", "fillStyle": "hachure", @@ -13239,9 +13547,10 @@ "height": 25, "seed": 1093487142, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -13274,6 +13583,7 @@ "height": 180.0499431583786, "seed": 1045348858, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -13325,6 +13635,7 @@ "height": 155.47601557537837, "seed": 657704230, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -13376,6 +13687,7 @@ "height": 2.2117220564423405, "seed": 2031747174, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -13429,6 +13741,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 1 }, @@ -13464,6 +13777,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13494,6 +13808,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13524,6 +13839,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13554,6 +13870,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13584,6 +13901,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13614,6 +13932,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13644,6 +13963,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 1 }, @@ -13674,6 +13994,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13747,6 +14068,7 @@ "groupIds": [ "sqBfVZi-1ITceqOuhqcRh" ], + "frameId": null, "roundness": { "type": 2 }, @@ -13818,6 +14140,7 @@ "height": 194.74853571306028, "seed": 42381670, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -13851,8 +14174,8 @@ }, { "type": "text", - "version": 100, - "versionNonce": 979161005, + "version": 101, + "versionNonce": 51333887, "isDeleted": false, "id": "uAQf51mOXJz4uyUjWoj55", "fillStyle": "hachure", @@ -13869,9 +14192,10 @@ "height": 50, "seed": 488649190, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296406, "link": null, "locked": false, "fontSize": 20, @@ -13904,6 +14228,7 @@ "height": 302.6062188464276, "seed": 310212922, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -13914,8 +14239,8 @@ }, { "type": "text", - "version": 57, - "versionNonce": 1113263523, + "version": 58, + "versionNonce": 1889413233, "isDeleted": false, "id": "zEuehdc3bMVftmIh2a_Lj", "fillStyle": "hachure", @@ -13932,9 +14257,10 @@ "height": 25, "seed": 1384808166, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 20, @@ -13967,6 +14293,7 @@ "height": 302.6062188464276, "seed": 1280254842, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -13977,8 +14304,8 @@ }, { "type": "text", - "version": 41, - "versionNonce": 1860194829, + "version": 42, + "versionNonce": 235639583, "isDeleted": false, "id": "-NowFvWoyGBcG4bE3Eoe3", "fillStyle": "hachure", @@ -13995,9 +14322,10 @@ "height": 25, "seed": 1826353018, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 20, @@ -14030,6 +14358,7 @@ "height": 302.6062188464276, "seed": 364230118, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -14045,8 +14374,8 @@ }, { "type": "text", - "version": 107, - "versionNonce": 730816835, + "version": 108, + "versionNonce": 1484911185, "isDeleted": false, "id": "KZiBuznSWGBjrOkeluaJh", "fillStyle": "hachure", @@ -14063,9 +14392,10 @@ "height": 25, "seed": 1856184358, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653824, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 20, @@ -14098,6 +14428,7 @@ "height": 302.6062188464276, "seed": 1730307558, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -14113,8 +14444,8 @@ }, { "type": "text", - "version": 101, - "versionNonce": 545556589, + "version": 102, + "versionNonce": 1586091839, "isDeleted": false, "id": "Cz3o8zCBmAKr3xDGJhqB2", "fillStyle": "hachure", @@ -14131,9 +14462,10 @@ "height": 25, "seed": 1043241958, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 20, @@ -14166,6 +14498,7 @@ "height": 0.4774337933606603, "seed": 1057679802, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -14217,6 +14550,7 @@ "height": 7.774575294157557, "seed": 370307258, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -14267,11 +14601,14 @@ "myUiR6TwqHj9b2H8J_H6T", "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -14428,11 +14765,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15149,11 +15489,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15230,11 +15573,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15303,11 +15649,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15384,11 +15733,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15461,11 +15813,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15526,11 +15881,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15615,11 +15973,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15700,11 +16061,14 @@ "groupIds": [ "cDPrx6GGUhAN6L_YMHbOQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -15769,8 +16133,8 @@ }, { "type": "text", - "version": 82, - "versionNonce": 2117615843, + "version": 83, + "versionNonce": 152141873, "isDeleted": false, "id": "TUqxZ7SnpcRy9MvMax_BO", "fillStyle": "hachure", @@ -15787,9 +16151,10 @@ "height": 25, "seed": 1774165606, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 20, @@ -15804,8 +16169,8 @@ }, { "type": "text", - "version": 116, - "versionNonce": 1360196301, + "version": 117, + "versionNonce": 1793759071, "isDeleted": false, "id": "6xdRAgKtKnk3_eGkmo0jO", "fillStyle": "hachure", @@ -15822,9 +16187,10 @@ "height": 25, "seed": 73954790, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 20, @@ -15857,6 +16223,7 @@ "height": 194, "seed": 1741804193, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -15898,6 +16265,7 @@ "height": 67.2, "seed": 350413807, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653825, @@ -15911,7 +16279,7 @@ "containerId": "fKtJuxG78iy1w9dvjHWb9", "originalText": "Datadog\nCollector", "lineHeight": 1.2, - "baseline": 57 + "baseline": 59 }, { "type": "arrow", @@ -15933,6 +16301,7 @@ "height": 36.44921148713752, "seed": 1042619215, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -15984,6 +16353,7 @@ "height": 1079.9125171659634, "seed": 620026918, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037461, @@ -16012,6 +16382,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 1 }, @@ -16047,6 +16418,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16077,6 +16449,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16107,6 +16480,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16137,6 +16511,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16167,6 +16542,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16197,6 +16573,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16227,6 +16604,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 1 }, @@ -16257,6 +16635,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16330,6 +16709,7 @@ "groupIds": [ "ZavMkdmJkaLIHy-PgP5MZ" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16383,8 +16763,8 @@ }, { "type": "text", - "version": 269, - "versionNonce": 220533037, + "version": 270, + "versionNonce": 3428881, "isDeleted": false, "id": "Howa8TQy9WlNeQY7IFhdI", "fillStyle": "hachure", @@ -16401,9 +16781,10 @@ "height": 35, "seed": 1953839654, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 28, @@ -16418,8 +16799,8 @@ }, { "type": "text", - "version": 207, - "versionNonce": 273785891, + "version": 208, + "versionNonce": 159273855, "isDeleted": false, "id": "-kMNckUw3lQqSqTjAISxd", "fillStyle": "hachure", @@ -16436,9 +16817,10 @@ "height": 35, "seed": 1737536294, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 28, @@ -16471,6 +16853,7 @@ "height": 108.64961090483712, "seed": 29356474, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -16518,6 +16901,7 @@ "height": 151.12964752555854, "seed": 481476646, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -16547,8 +16931,8 @@ }, { "type": "text", - "version": 240, - "versionNonce": 304374669, + "version": 241, + "versionNonce": 316794865, "isDeleted": false, "id": "YPYEjVuQFyVe2PI-WkEpo", "fillStyle": "hachure", @@ -16565,6 +16949,7 @@ "height": 35, "seed": 967865466, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -16572,7 +16957,7 @@ "type": "arrow" } ], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 28, @@ -16605,6 +16990,7 @@ "height": 160.7731041147449, "seed": 1258393830, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -16634,8 +17020,8 @@ }, { "type": "text", - "version": 167, - "versionNonce": 1534011331, + "version": 168, + "versionNonce": 1921354655, "isDeleted": false, "id": "xBqw9q_jDO4kcgiPZ-6nK", "fillStyle": "hachure", @@ -16652,6 +17038,7 @@ "height": 35, "seed": 532862586, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -16663,7 +17050,7 @@ "type": "arrow" } ], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 28, @@ -16696,6 +17083,7 @@ "height": 5.2992232275960305, "seed": 179686138, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -16729,8 +17117,8 @@ }, { "type": "text", - "version": 171, - "versionNonce": 877292013, + "version": 172, + "versionNonce": 186761681, "isDeleted": false, "id": "aC1hBzszkK5enBuqWlkCK", "fillStyle": "hachure", @@ -16747,6 +17135,7 @@ "height": 35, "seed": 894126330, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -16758,7 +17147,7 @@ "type": "arrow" } ], - "updated": 1691691653825, + "updated": 1696427296407, "link": null, "locked": false, "fontSize": 28, @@ -16791,6 +17180,7 @@ "height": 3.523747459875949, "seed": 1056523322, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -16820,8 +17210,8 @@ }, { "type": "text", - "version": 130, - "versionNonce": 1532704611, + "version": 131, + "versionNonce": 36749247, "isDeleted": false, "id": "2SRBMgGBS9HO5oBhmR1Pm", "fillStyle": "hachure", @@ -16838,6 +17228,7 @@ "height": 35, "seed": 1945303590, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -16849,7 +17240,7 @@ "type": "arrow" } ], - "updated": 1691691653825, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -16884,6 +17275,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 1 }, @@ -16914,6 +17306,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16944,6 +17337,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -16974,6 +17368,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17004,6 +17399,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17034,6 +17430,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17064,6 +17461,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17094,6 +17492,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 1 }, @@ -17124,6 +17523,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17197,6 +17597,7 @@ "groupIds": [ "bXSKP-aOdbFMZHhRQPDxv" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17250,8 +17651,8 @@ }, { "type": "text", - "version": 192, - "versionNonce": 77636685, + "version": 193, + "versionNonce": 101408689, "isDeleted": false, "id": "AjyE3hskerq5S0alAsJLS", "fillStyle": "hachure", @@ -17268,9 +17669,10 @@ "height": 35, "seed": 1931060902, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653826, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -17303,6 +17705,7 @@ "height": 197.59243707361998, "seed": 2044902522, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -17350,6 +17753,7 @@ "height": 225.68129800111888, "seed": 34775718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -17383,8 +17787,8 @@ }, { "type": "text", - "version": 214, - "versionNonce": 241455875, + "version": 215, + "versionNonce": 983592927, "isDeleted": false, "id": "2ImcFmDw5TePp9f6hhi4A", "fillStyle": "hachure", @@ -17401,6 +17805,7 @@ "height": 35, "seed": 582531558, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -17416,7 +17821,7 @@ "type": "arrow" } ], - "updated": 1691691653826, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -17451,6 +17856,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 1 }, @@ -17486,6 +17892,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17516,6 +17923,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17546,6 +17954,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17576,6 +17985,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17606,6 +18016,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17636,6 +18047,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17666,6 +18078,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 1 }, @@ -17696,6 +18109,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17769,6 +18183,7 @@ "groupIds": [ "yoXO3GP4TgDaaMhEdvp9D" ], + "frameId": null, "roundness": { "type": 2 }, @@ -17822,8 +18237,8 @@ }, { "type": "text", - "version": 352, - "versionNonce": 922784429, + "version": 353, + "versionNonce": 298205585, "isDeleted": false, "id": "ri5yBasROMNLv3BqfTkFY", "fillStyle": "hachure", @@ -17840,9 +18255,10 @@ "height": 35, "seed": 218931450, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653826, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -17875,6 +18291,7 @@ "height": 151.06454402115833, "seed": 1454803066, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -17904,8 +18321,8 @@ }, { "type": "text", - "version": 91, - "versionNonce": 621345443, + "version": 92, + "versionNonce": 98900991, "isDeleted": false, "id": "ZIXo5j24FVchmuML-JqrO", "fillStyle": "hachure", @@ -17922,9 +18339,10 @@ "height": 35, "seed": 853337082, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653826, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -17957,6 +18375,7 @@ "height": 287.96093789736005, "seed": 441492070, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -18008,6 +18427,7 @@ "height": 668.2569377000852, "seed": 1669656662, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -18039,11 +18459,14 @@ "RLsv6qsAHmsxKzOTqJPvX", "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -18200,11 +18623,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -18921,11 +19347,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19002,11 +19431,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19075,11 +19507,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19156,11 +19591,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19233,11 +19671,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19298,11 +19739,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19387,11 +19831,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19472,11 +19919,14 @@ "groupIds": [ "FuSiCIM0do_H5amjSjXpE" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, "link": null, "locked": false, + "startBinding": null, + "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": null, @@ -19541,8 +19991,8 @@ }, { "type": "text", - "version": 430, - "versionNonce": 1209251085, + "version": 431, + "versionNonce": 193587057, "isDeleted": false, "id": "XTD_gXU_gSq9V87gFisld", "fillStyle": "hachure", @@ -19559,9 +20009,10 @@ "height": 35, "seed": 984612234, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653826, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -19594,6 +20045,7 @@ "height": 1.1891362203846256, "seed": 325230806, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -19646,6 +20098,7 @@ "height": 201.37494798168973, "seed": 226890826, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -19665,8 +20118,8 @@ }, { "type": "text", - "version": 449, - "versionNonce": 1006087747, + "version": 450, + "versionNonce": 939475999, "isDeleted": false, "id": "z34KgsXM2TscgIAB9ooPf", "fillStyle": "hachure", @@ -19683,9 +20136,10 @@ "height": 35, "seed": 269154122, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653826, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -19718,6 +20172,7 @@ "height": 1.372148871639638, "seed": 544839754, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -19774,6 +20229,7 @@ "height": 35, "seed": 176083990, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653827, @@ -19787,7 +20243,7 @@ "containerId": "4Fh2Ss8xQJCv3DVjUDUG9", "originalText": "store.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "text", @@ -19809,6 +20265,7 @@ "height": 35, "seed": 1964980118, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653827, @@ -19822,7 +20279,7 @@ "containerId": "VTgefUfszNcvznfTtdYCL", "originalText": "corev1.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "line", @@ -19846,6 +20303,7 @@ "groupIds": [ "kcs2Nt0poVny1cFEAC4RX" ], + "frameId": null, "roundness": { "type": 2 }, @@ -19959,6 +20417,7 @@ "groupIds": [ "kcs2Nt0poVny1cFEAC4RX" ], + "frameId": null, "roundness": { "type": 2 }, @@ -20028,6 +20487,7 @@ "groupIds": [ "kcs2Nt0poVny1cFEAC4RX" ], + "frameId": null, "roundness": { "type": 2 }, @@ -20097,6 +20557,7 @@ "groupIds": [ "kcs2Nt0poVny1cFEAC4RX" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -20123,6 +20584,7 @@ "height": 201.37494798168973, "seed": 852585098, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -20142,8 +20604,8 @@ }, { "type": "text", - "version": 358, - "versionNonce": 151623117, + "version": 359, + "versionNonce": 1033752913, "isDeleted": false, "id": "N9DAmwkBPCqomDAqz73Da", "fillStyle": "hachure", @@ -20160,9 +20622,10 @@ "height": 70, "seed": 55961430, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653827, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -20177,8 +20640,8 @@ }, { "type": "text", - "version": 281, - "versionNonce": 375208323, + "version": 282, + "versionNonce": 1356818495, "isDeleted": false, "id": "nac6VXoUQeADi7V2tIAyL", "fillStyle": "hachure", @@ -20195,9 +20658,10 @@ "height": 35, "seed": 417962186, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653827, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -20232,6 +20696,7 @@ "groupIds": [ "0-WKuMlz2CLhZK2z483_S" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -20260,6 +20725,7 @@ "groupIds": [ "0-WKuMlz2CLhZK2z483_S" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -20293,6 +20759,7 @@ "groupIds": [ "0-WKuMlz2CLhZK2z483_S" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -20321,6 +20788,7 @@ "groupIds": [ "0-WKuMlz2CLhZK2z483_S" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -20347,6 +20815,7 @@ "height": 132.8245958797488, "seed": 118556310, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -20395,6 +20864,7 @@ "height": 35, "seed": 855176202, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653827, @@ -20408,7 +20878,7 @@ "containerId": "5jInW3sEr1ZzjC6Gy_FD3", "originalText": "name:id", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "arrow", @@ -20430,6 +20900,7 @@ "height": 55.64934330989945, "seed": 626431766, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -20459,8 +20930,8 @@ }, { "type": "text", - "version": 224, - "versionNonce": 975245603, + "version": 225, + "versionNonce": 1029275441, "isDeleted": false, "id": "x4RtzbNrw0yT8GxZc_4P0", "fillStyle": "hachure", @@ -20477,9 +20948,10 @@ "height": 35, "seed": 1892403030, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653827, + "updated": 1696427296408, "link": null, "locked": false, "fontSize": 28, @@ -20512,6 +20984,7 @@ "height": 2.8250612418105447, "seed": 1402264778, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -20568,6 +21041,7 @@ "height": 35, "seed": 1530049418, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653827, @@ -20581,7 +21055,7 @@ "containerId": "2lFwazCPxIDa9_4trJef8", "originalText": "store.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "line", @@ -20605,6 +21079,7 @@ "groupIds": [ "A42y0PW7RefzsRzDq9gz8" ], + "frameId": null, "roundness": { "type": 2 }, @@ -20718,6 +21193,7 @@ "groupIds": [ "A42y0PW7RefzsRzDq9gz8" ], + "frameId": null, "roundness": { "type": 2 }, @@ -20787,6 +21263,7 @@ "groupIds": [ "A42y0PW7RefzsRzDq9gz8" ], + "frameId": null, "roundness": { "type": 2 }, @@ -20856,6 +21333,7 @@ "groupIds": [ "A42y0PW7RefzsRzDq9gz8" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -20882,6 +21360,7 @@ "height": 201.37494798168973, "seed": 899628362, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -20901,8 +21380,8 @@ }, { "type": "text", - "version": 397, - "versionNonce": 1388901571, + "version": 398, + "versionNonce": 2120616031, "isDeleted": false, "id": "xwwPm3GU_sRzaHk1Dnh99", "fillStyle": "hachure", @@ -20919,6 +21398,7 @@ "height": 70, "seed": 1042088970, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -20926,7 +21406,7 @@ "type": "arrow" } ], - "updated": 1691691653827, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -20941,8 +21421,8 @@ }, { "type": "text", - "version": 353, - "versionNonce": 1375726829, + "version": 354, + "versionNonce": 153383185, "isDeleted": false, "id": "F5igZKg0oi_RRfvl45Vf8", "fillStyle": "hachure", @@ -20959,9 +21439,10 @@ "height": 35, "seed": 1756623562, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653827, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -20994,6 +21475,7 @@ "height": 139.41632570020556, "seed": 1982919818, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -21046,6 +21528,7 @@ "height": 35, "seed": 1240847178, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653828, @@ -21059,7 +21542,7 @@ "containerId": "icUWPHatVQkIaB0tC61U1", "originalText": "store.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "arrow", @@ -21081,6 +21564,7 @@ "height": 55.64934330989945, "seed": 1999690250, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -21106,8 +21590,8 @@ }, { "type": "text", - "version": 327, - "versionNonce": 1991100237, + "version": 328, + "versionNonce": 1583588479, "isDeleted": false, "id": "Okv5hntUC3DyIfWDsFiqX", "fillStyle": "hachure", @@ -21124,9 +21608,10 @@ "height": 35, "seed": 1021118666, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653828, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -21159,6 +21644,7 @@ "height": 3.121775740976773, "seed": 1973578, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -21215,6 +21701,7 @@ "height": 35, "seed": 364897290, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653828, @@ -21228,7 +21715,7 @@ "containerId": "vmtLBKnXfJe1HuWYuR4_D", "originalText": "store.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "line", @@ -21252,6 +21739,7 @@ "groupIds": [ "a4C0JWkFHBweS1FI371Fr" ], + "frameId": null, "roundness": { "type": 2 }, @@ -21365,6 +21853,7 @@ "groupIds": [ "a4C0JWkFHBweS1FI371Fr" ], + "frameId": null, "roundness": { "type": 2 }, @@ -21434,6 +21923,7 @@ "groupIds": [ "a4C0JWkFHBweS1FI371Fr" ], + "frameId": null, "roundness": { "type": 2 }, @@ -21503,6 +21993,7 @@ "groupIds": [ "a4C0JWkFHBweS1FI371Fr" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -21529,6 +22020,7 @@ "height": 201.37494798168973, "seed": 257826250, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -21552,8 +22044,8 @@ }, { "type": "text", - "version": 564, - "versionNonce": 1366381997, + "version": 565, + "versionNonce": 1719019249, "isDeleted": false, "id": "E1sVYxk44xwhXS_sP4oVn", "fillStyle": "hachure", @@ -21570,9 +22062,10 @@ "height": 35, "seed": 2140451658, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653828, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -21605,6 +22098,7 @@ "height": 139.41632570020556, "seed": 906585354, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -21653,6 +22147,7 @@ "height": 35, "seed": 1181496266, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653828, @@ -21666,7 +22161,7 @@ "containerId": "rzHlGyMqcjK9XN3eKMiF8", "originalText": "graph.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "arrow", @@ -21688,6 +22183,7 @@ "height": 56.67851831248299, "seed": 1191651978, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -21717,8 +22213,8 @@ }, { "type": "text", - "version": 534, - "versionNonce": 2104760333, + "version": 535, + "versionNonce": 10009759, "isDeleted": false, "id": "JGiYtNmfw8M5Qu-vkVmHh", "fillStyle": "hachure", @@ -21735,9 +22231,10 @@ "height": 35, "seed": 1318406474, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653828, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -21772,6 +22269,7 @@ "groupIds": [ "eieTRpPLRHdIvDyYTPvzW" ], + "frameId": null, "roundness": { "type": 2 }, @@ -21885,6 +22383,7 @@ "groupIds": [ "eieTRpPLRHdIvDyYTPvzW" ], + "frameId": null, "roundness": { "type": 2 }, @@ -21954,6 +22453,7 @@ "groupIds": [ "eieTRpPLRHdIvDyYTPvzW" ], + "frameId": null, "roundness": { "type": 2 }, @@ -22023,6 +22523,7 @@ "groupIds": [ "eieTRpPLRHdIvDyYTPvzW" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -22051,6 +22552,7 @@ "groupIds": [ "eieTRpPLRHdIvDyYTPvzW" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -22079,6 +22581,7 @@ "groupIds": [ "eieTRpPLRHdIvDyYTPvzW" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -22107,6 +22610,7 @@ "groupIds": [ "eieTRpPLRHdIvDyYTPvzW" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -22133,6 +22637,7 @@ "height": 201.37494798168973, "seed": 672108682, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -22166,6 +22671,7 @@ "height": 4.451117066666484, "seed": 1066418250, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -22218,6 +22724,7 @@ "height": 35, "seed": 150316810, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653828, @@ -22231,7 +22738,7 @@ "containerId": "YWqAKxWXpqJONUQtqnpXX", "originalText": "graph.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "line", @@ -22255,6 +22762,7 @@ "groupIds": [ "TfkYGXD9O-Slr1WG1W-PL" ], + "frameId": null, "roundness": { "type": 2 }, @@ -22368,6 +22876,7 @@ "groupIds": [ "TfkYGXD9O-Slr1WG1W-PL" ], + "frameId": null, "roundness": { "type": 2 }, @@ -22437,6 +22946,7 @@ "groupIds": [ "TfkYGXD9O-Slr1WG1W-PL" ], + "frameId": null, "roundness": { "type": 2 }, @@ -22506,6 +23016,7 @@ "groupIds": [ "TfkYGXD9O-Slr1WG1W-PL" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -22534,6 +23045,7 @@ "groupIds": [ "TfkYGXD9O-Slr1WG1W-PL" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -22562,6 +23074,7 @@ "groupIds": [ "TfkYGXD9O-Slr1WG1W-PL" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -22595,6 +23108,7 @@ "groupIds": [ "TfkYGXD9O-Slr1WG1W-PL" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037462, @@ -22603,8 +23117,8 @@ }, { "type": "text", - "version": 524, - "versionNonce": 1957662317, + "version": 525, + "versionNonce": 2144739537, "isDeleted": false, "id": "hGRMhsF2Lt6tSi54-rnM5", "fillStyle": "hachure", @@ -22621,9 +23135,10 @@ "height": 35, "seed": 965073866, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653828, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -22638,8 +23153,8 @@ }, { "type": "text", - "version": 541, - "versionNonce": 447257315, + "version": 542, + "versionNonce": 683004095, "isDeleted": false, "id": "Z87U81mHKsNQZGda8v-5z", "fillStyle": "hachure", @@ -22656,9 +23171,10 @@ "height": 70, "seed": 53590422, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653828, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -22691,6 +23207,7 @@ "height": 0.024308695209583675, "seed": 1016795414, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -22720,8 +23237,8 @@ }, { "type": "text", - "version": 323, - "versionNonce": 904739021, + "version": 324, + "versionNonce": 1121705649, "isDeleted": false, "id": "75MkHAs2PaKs_YExiQaNq", "fillStyle": "hachure", @@ -22738,9 +23255,10 @@ "height": 35, "seed": 1458498122, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653828, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -22755,8 +23273,8 @@ }, { "type": "text", - "version": 518, - "versionNonce": 1217291971, + "version": 519, + "versionNonce": 1348165855, "isDeleted": false, "id": "eXXqVLxMZ-SINaZWEK6vz", "fillStyle": "hachure", @@ -22773,9 +23291,10 @@ "height": 35, "seed": 2122638422, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691788521, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -22810,6 +23329,7 @@ "groupIds": [ "e6FoFyDfx3cjwWTKdghlT" ], + "frameId": null, "roundness": { "type": 2 }, @@ -22923,6 +23443,7 @@ "groupIds": [ "e6FoFyDfx3cjwWTKdghlT" ], + "frameId": null, "roundness": { "type": 2 }, @@ -22992,6 +23513,7 @@ "groupIds": [ "e6FoFyDfx3cjwWTKdghlT" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23061,6 +23583,7 @@ "groupIds": [ "e6FoFyDfx3cjwWTKdghlT" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691788521, @@ -23069,8 +23592,8 @@ }, { "type": "text", - "version": 471, - "versionNonce": 1005813283, + "version": 472, + "versionNonce": 2117001361, "isDeleted": false, "id": "eJdETe_wMa0w2MxgbDDoe", "fillStyle": "hachure", @@ -23087,9 +23610,10 @@ "height": 35, "seed": 1215124618, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653829, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -23124,6 +23648,7 @@ "groupIds": [ "yNoD_vbAE9rZgHbQslQR3" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23237,6 +23762,7 @@ "groupIds": [ "yNoD_vbAE9rZgHbQslQR3" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23306,6 +23832,7 @@ "groupIds": [ "yNoD_vbAE9rZgHbQslQR3" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23375,6 +23902,7 @@ "groupIds": [ "yNoD_vbAE9rZgHbQslQR3" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037463, @@ -23383,8 +23911,8 @@ }, { "type": "text", - "version": 529, - "versionNonce": 1302669709, + "version": 530, + "versionNonce": 1763306751, "isDeleted": false, "id": "l_FDOh7PwBZ_RnXBuq1rf", "fillStyle": "hachure", @@ -23401,9 +23929,10 @@ "height": 35, "seed": 17606090, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653829, + "updated": 1696427296409, "link": null, "locked": false, "fontSize": 28, @@ -23438,6 +23967,7 @@ "groupIds": [ "bVvyoBcpxVzk9UfyRTbx2" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23551,6 +24081,7 @@ "groupIds": [ "bVvyoBcpxVzk9UfyRTbx2" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23620,6 +24151,7 @@ "groupIds": [ "bVvyoBcpxVzk9UfyRTbx2" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23689,6 +24221,7 @@ "groupIds": [ "bVvyoBcpxVzk9UfyRTbx2" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037463, @@ -23697,8 +24230,8 @@ }, { "type": "text", - "version": 540, - "versionNonce": 1579282541, + "version": 541, + "versionNonce": 1065789041, "isDeleted": false, "id": "jU6YsQJXfXX8LMOST6zpc", "fillStyle": "hachure", @@ -23715,9 +24248,10 @@ "height": 35, "seed": 578299862, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691834388, + "updated": 1696427296410, "link": null, "locked": false, "fontSize": 28, @@ -23752,6 +24286,7 @@ "groupIds": [ "TpkKZeq-1XqQDmplvCTKx" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23865,6 +24400,7 @@ "groupIds": [ "TpkKZeq-1XqQDmplvCTKx" ], + "frameId": null, "roundness": { "type": 2 }, @@ -23934,6 +24470,7 @@ "groupIds": [ "TpkKZeq-1XqQDmplvCTKx" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24003,6 +24540,7 @@ "groupIds": [ "TpkKZeq-1XqQDmplvCTKx" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691834388, @@ -24011,8 +24549,8 @@ }, { "type": "text", - "version": 598, - "versionNonce": 1161346083, + "version": 599, + "versionNonce": 1584526623, "isDeleted": false, "id": "JofDC9OYeEb-ry7vn6txt", "fillStyle": "hachure", @@ -24029,9 +24567,10 @@ "height": 35, "seed": 1962312214, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691834388, + "updated": 1696427296410, "link": null, "locked": false, "fontSize": 28, @@ -24066,6 +24605,7 @@ "groupIds": [ "gBLPhjimqekqu_zI1jMBp" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24179,6 +24719,7 @@ "groupIds": [ "gBLPhjimqekqu_zI1jMBp" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24248,6 +24789,7 @@ "groupIds": [ "gBLPhjimqekqu_zI1jMBp" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24317,6 +24859,7 @@ "groupIds": [ "gBLPhjimqekqu_zI1jMBp" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691834388, @@ -24343,6 +24886,7 @@ "height": 203, "seed": 932261014, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -24376,6 +24920,7 @@ "height": 70, "seed": 1548388950, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653829, @@ -24389,7 +24934,7 @@ "containerId": "envPvqHYosj6jgpA5j2y8", "originalText": "Ingestor start", "lineHeight": 1.25, - "baseline": 59 + "baseline": 61 }, { "type": "rectangle", @@ -24411,6 +24956,7 @@ "height": 178.22213825875951, "seed": 564950282, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -24452,6 +24998,7 @@ "height": 386.58741807507334, "seed": 569604362, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -24489,6 +25036,7 @@ "height": 1.7813219189458778, "seed": 2073345814, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -24540,6 +25088,7 @@ "height": 4.853974902052869, "seed": 491457686, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -24587,6 +25136,7 @@ "height": 203, "seed": 836886346, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -24624,6 +25174,7 @@ "height": 70, "seed": 498820618, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691788521, @@ -24637,7 +25188,7 @@ "containerId": "XBSyQ1XwWklNIKPPVHqfH", "originalText": "Ingestor complete", "lineHeight": 1.25, - "baseline": 59 + "baseline": 61 }, { "type": "arrow", @@ -24659,6 +25210,7 @@ "height": 1.0848629661159066, "seed": 1553461066, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -24710,6 +25262,7 @@ "height": 712.7734827095996, "seed": 1135082506, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -24720,8 +25273,8 @@ }, { "type": "text", - "version": 345, - "versionNonce": 1465675011, + "version": 346, + "versionNonce": 1907011665, "isDeleted": false, "id": "DgCGpzLU9rBvN5xs2dtna", "fillStyle": "hachure", @@ -24738,9 +25291,10 @@ "height": 35, "seed": 1127374230, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653829, + "updated": 1696427296410, "link": null, "locked": false, "fontSize": 28, @@ -24773,6 +25327,7 @@ "height": 2491.996381917053, "seed": 1504131722, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -24803,6 +25358,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 1 }, @@ -24838,6 +25394,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24868,6 +25425,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24898,6 +25456,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24928,6 +25487,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24958,6 +25518,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -24988,6 +25549,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -25018,6 +25580,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 1 }, @@ -25048,6 +25611,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -25121,6 +25685,7 @@ "groupIds": [ "CMUmtUGtXn4T6azbNTCty" ], + "frameId": null, "roundness": { "type": 2 }, @@ -25192,6 +25757,7 @@ "height": 130.05330604970732, "seed": 2092836042, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25243,6 +25809,7 @@ "height": 90.50540536418102, "seed": 536017802, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -25270,8 +25837,8 @@ }, { "type": "text", - "version": 393, - "versionNonce": 749672621, + "version": 394, + "versionNonce": 1473509695, "isDeleted": false, "id": "opI1A3GHk-glrkVHWtnzm", "fillStyle": "hachure", @@ -25288,9 +25855,10 @@ "height": 49.98417280508089, "seed": 467597898, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653830, + "updated": 1696427296410, "link": null, "locked": false, "fontSize": 19.993669122032355, @@ -25323,6 +25891,7 @@ "height": 127.82352476276401, "seed": 526197002, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25374,6 +25943,7 @@ "height": 85.19912398369183, "seed": 1172860874, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -25393,8 +25963,8 @@ }, { "type": "text", - "version": 427, - "versionNonce": 200135843, + "version": 428, + "versionNonce": 980581937, "isDeleted": false, "id": "YeZy94byHPYDUDPEghHwz", "fillStyle": "hachure", @@ -25411,9 +25981,10 @@ "height": 24.992086402540444, "seed": 60548746, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653830, + "updated": 1696427296411, "link": null, "locked": false, "fontSize": 19.993669122032355, @@ -25446,6 +26017,7 @@ "height": 85.19912398369183, "seed": 288523594, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -25465,8 +26037,8 @@ }, { "type": "text", - "version": 458, - "versionNonce": 1375828749, + "version": 459, + "versionNonce": 983595359, "isDeleted": false, "id": "oywRGTc7Qk21fMO5m7ipR", "fillStyle": "hachure", @@ -25483,9 +26055,10 @@ "height": 24.992086402540437, "seed": 1476873226, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653830, + "updated": 1696427296411, "link": null, "locked": false, "fontSize": 19.99366912203235, @@ -25518,6 +26091,7 @@ "height": 127.79868597553751, "seed": 1578449610, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25569,6 +26143,7 @@ "height": 85.18189579739149, "seed": 838291850, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -25588,8 +26163,8 @@ }, { "type": "text", - "version": 490, - "versionNonce": 1697728579, + "version": 491, + "versionNonce": 415600657, "isDeleted": false, "id": "aKLeLpuGjjphQKAjHsJjd", "fillStyle": "hachure", @@ -25606,9 +26181,10 @@ "height": 24.992086402540444, "seed": 1458081866, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653830, + "updated": 1696427296411, "link": null, "locked": false, "fontSize": 19.993669122032355, @@ -25641,6 +26217,7 @@ "height": 136.5401312566355, "seed": 818149130, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25692,6 +26269,7 @@ "height": 144.169951803329, "seed": 1879344586, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25743,6 +26321,7 @@ "height": 133.30558153297534, "seed": 2110078090, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25794,6 +26373,7 @@ "height": 143.84774119078224, "seed": 1740708682, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25845,6 +26425,7 @@ "height": 116.60610760911699, "seed": 1280516618, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -25872,8 +26453,8 @@ }, { "type": "text", - "version": 410, - "versionNonce": 932745581, + "version": 411, + "versionNonce": 1814558079, "isDeleted": false, "id": "-LC6sWVh5jazUS4DtR93c", "fillStyle": "hachure", @@ -25890,9 +26471,10 @@ "height": 49.98417280508089, "seed": 1182159050, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653830, + "updated": 1696427296411, "link": null, "locked": false, "fontSize": 19.993669122032355, @@ -25925,6 +26507,7 @@ "height": 108.82728112004406, "seed": 1506125706, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -25958,8 +26541,8 @@ }, { "type": "text", - "version": 345, - "versionNonce": 419776483, + "version": 346, + "versionNonce": 1117480433, "isDeleted": false, "id": "2Y2E7wJPH9_gmr4i3S7pg", "fillStyle": "hachure", @@ -25976,9 +26559,10 @@ "height": 24.992086402540444, "seed": 1585194570, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653830, + "updated": 1696427296411, "link": null, "locked": false, "fontSize": 19.993669122032355, @@ -26011,6 +26595,7 @@ "height": 112.7272827789352, "seed": 1836371210, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26058,6 +26643,7 @@ "height": 97.80441362673582, "seed": 1277860810, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -26089,8 +26675,8 @@ }, { "type": "text", - "version": 501, - "versionNonce": 1522392013, + "version": 502, + "versionNonce": 1403710879, "isDeleted": false, "id": "wR0GHC010wmNgfVtTA0EH", "fillStyle": "hachure", @@ -26107,6 +26693,7 @@ "height": 49.98417280508089, "seed": 1488491146, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -26114,7 +26701,7 @@ "type": "arrow" } ], - "updated": 1691691653830, + "updated": 1696427296411, "link": null, "locked": false, "fontSize": 19.993669122032355, @@ -26147,6 +26734,7 @@ "height": 6.33093387399208, "seed": 1977200970, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26194,6 +26782,7 @@ "height": 97.80441362673582, "seed": 72776906, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -26229,8 +26818,8 @@ }, { "type": "text", - "version": 797, - "versionNonce": 494424963, + "version": 798, + "versionNonce": 1123778513, "isDeleted": false, "id": "ZR7FlVxJKJhypbs2k28RF", "fillStyle": "hachure", @@ -26247,6 +26836,7 @@ "height": 49.98417280508089, "seed": 1119900554, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -26266,7 +26856,7 @@ "type": "arrow" } ], - "updated": 1691691653830, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 19.993669122032355, @@ -26299,6 +26889,7 @@ "height": 99.35846347974962, "seed": 804039050, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26350,6 +26941,7 @@ "height": 524.8499884213486, "seed": 54742794, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26397,6 +26989,7 @@ "height": 97.80441362673582, "seed": 595061898, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -26428,8 +27021,8 @@ }, { "type": "text", - "version": 489, - "versionNonce": 1401608749, + "version": 490, + "versionNonce": 475652543, "isDeleted": false, "id": "KrxqLrVYs9q4JJfaCjd4e", "fillStyle": "hachure", @@ -26446,6 +27039,7 @@ "height": 50, "seed": 597543754, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -26457,7 +27051,7 @@ "type": "arrow" } ], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -26490,6 +27084,7 @@ "height": 1377.6147890514992, "seed": 113462218, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -26500,8 +27095,8 @@ }, { "type": "text", - "version": 257, - "versionNonce": 583592739, + "version": 258, + "versionNonce": 1476222385, "isDeleted": false, "id": "h3exS8HSaQTUutxxP5KUd", "fillStyle": "hachure", @@ -26518,9 +27113,10 @@ "height": 25, "seed": 482034314, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -26553,6 +27149,7 @@ "height": 664.4354998350377, "seed": 101081418, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -26568,8 +27165,8 @@ }, { "type": "text", - "version": 285, - "versionNonce": 2062093453, + "version": 286, + "versionNonce": 928338399, "isDeleted": false, "id": "sZwffdBtAx5k-pfeeH9pz", "fillStyle": "hachure", @@ -26586,9 +27183,10 @@ "height": 25, "seed": 1040164874, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -26603,8 +27201,8 @@ }, { "type": "text", - "version": 218, - "versionNonce": 1298501315, + "version": 219, + "versionNonce": 281575313, "isDeleted": false, "id": "8VlmUF_Qt4ApUNPz0uyu9", "fillStyle": "hachure", @@ -26621,9 +27219,10 @@ "height": 25, "seed": 480384714, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -26656,6 +27255,7 @@ "height": 137.15506991788163, "seed": 1116253578, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26707,6 +27307,7 @@ "height": 170, "seed": 82734154, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26752,6 +27353,7 @@ "height": 50, "seed": 1504596746, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653831, @@ -26765,7 +27367,7 @@ "containerId": "j4cwbMzY4NsJefmBYH5X9", "originalText": "Consistency \nChecks", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "arrow", @@ -26787,6 +27389,7 @@ "height": 11.483730848594973, "seed": 1128489418, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26838,6 +27441,7 @@ "height": 158.17354008578013, "seed": 1019779210, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26871,6 +27475,7 @@ "height": 158.17354008578013, "seed": 637073226, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -26904,6 +27509,7 @@ "height": 1111.7188674874449, "seed": 791641610, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -26914,8 +27520,8 @@ }, { "type": "text", - "version": 368, - "versionNonce": 804044387, + "version": 369, + "versionNonce": 497925631, "isDeleted": false, "id": "uCzkLthQbcSGl2d6NC343", "fillStyle": "hachure", @@ -26932,9 +27538,10 @@ "height": 25, "seed": 1164389578, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -26949,8 +27556,8 @@ }, { "type": "text", - "version": 414, - "versionNonce": 554634573, + "version": 415, + "versionNonce": 731145585, "isDeleted": false, "id": "DuEE3eExprGc4nGfb45In", "fillStyle": "hachure", @@ -26967,9 +27574,10 @@ "height": 50, "seed": 2117796746, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -27002,6 +27610,7 @@ "height": 158.17354008578013, "seed": 620733386, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27012,8 +27621,8 @@ }, { "type": "text", - "version": 485, - "versionNonce": 86833667, + "version": 486, + "versionNonce": 1382262303, "isDeleted": false, "id": "tUM3WeCUqPHDKsr80vNyx", "fillStyle": "hachure", @@ -27030,9 +27639,10 @@ "height": 25, "seed": 1638701706, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -27065,6 +27675,7 @@ "height": 170, "seed": 2028073098, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27098,6 +27709,7 @@ "height": 50, "seed": 1160204106, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653831, @@ -27111,7 +27723,7 @@ "containerId": "Xw6yMFH8A3b4PSNT3SBS1", "originalText": "Consistency \nChecks", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "rectangle", @@ -27133,6 +27745,7 @@ "height": 286.7472395488016, "seed": 2128577738, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27172,8 +27785,8 @@ }, { "type": "text", - "version": 400, - "versionNonce": 707051939, + "version": 401, + "versionNonce": 866684753, "isDeleted": false, "id": "_m86-4rF1_MnbU0EYK2qV", "fillStyle": "hachure", @@ -27190,9 +27803,10 @@ "height": 50, "seed": 618743434, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653831, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -27225,6 +27839,7 @@ "height": 79.7674392151348, "seed": 796175370, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27268,6 +27883,7 @@ "height": 75.44648386296194, "seed": 387311050, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27315,6 +27931,7 @@ "height": 78.99213425916082, "seed": 737244362, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27366,6 +27983,7 @@ "height": 74.09520580987555, "seed": 1542912906, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27403,6 +28021,7 @@ "height": 25, "seed": 1858360202, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -27416,7 +28035,7 @@ "containerId": "k49IU2JpQlMRPTHn8q4aq", "originalText": "graph.Node", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -27438,6 +28057,7 @@ "height": 74.09520580987555, "seed": 468716566, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27471,6 +28091,7 @@ "height": 25, "seed": 696392022, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -27484,7 +28105,7 @@ "containerId": "XgqD_O7wJTgYbbilX_2TB", "originalText": "store.Node", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -27506,6 +28127,7 @@ "height": 74.09520580987555, "seed": 489035466, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27543,6 +28165,7 @@ "height": 25, "seed": 311209354, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -27556,7 +28179,7 @@ "containerId": "sZdlu9CbzbocolRQuWxZB", "originalText": "node name -> id", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -27578,6 +28201,7 @@ "height": 11.54342758770997, "seed": 675241034, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27629,6 +28253,7 @@ "height": 261.5385039229774, "seed": 1164002058, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27680,6 +28305,7 @@ "height": 244.23279989191587, "seed": 454578634, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -27731,6 +28357,7 @@ "height": 74.09520580987555, "seed": 746555530, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27768,6 +28395,7 @@ "height": 25, "seed": 1632757578, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -27781,7 +28409,7 @@ "containerId": "OvjODYiyUqvphGNiQUDEI", "originalText": "graph.Pod", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -27803,6 +28431,7 @@ "height": 74.09520580987555, "seed": 1911189002, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27840,6 +28469,7 @@ "height": 25, "seed": 1396972746, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -27853,7 +28483,7 @@ "containerId": "FZ1_Y3WMrhxJRLXHK46Gm", "originalText": "store.Pod", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -27875,6 +28505,7 @@ "height": 74.09520580987555, "seed": 586806154, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27912,6 +28543,7 @@ "height": 25, "seed": 323416650, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -27925,7 +28557,7 @@ "containerId": "_Faj1VlWH6veCRp3PGpn1", "originalText": "node -> volume", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -27947,6 +28579,7 @@ "height": 74.09520580987555, "seed": 431337878, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -27980,6 +28613,7 @@ "height": 25, "seed": 2054622934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -27993,7 +28627,7 @@ "containerId": "ULy667cTN29KFwP8z4MVL", "originalText": "volume -> node", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -28015,6 +28649,7 @@ "height": 74.09520580987555, "seed": 1624921418, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28048,6 +28683,7 @@ "height": 50, "seed": 37035018, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -28061,7 +28697,7 @@ "containerId": "0FTBBCFkcwBpkOM8UXAeX", "originalText": "container \nname -> id", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "rectangle", @@ -28083,6 +28719,7 @@ "height": 74.09520580987555, "seed": 1043415318, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28116,6 +28753,7 @@ "height": 25, "seed": 936685142, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653832, @@ -28129,7 +28767,7 @@ "containerId": "dfWfuCqtwTA8pLlFr_F_e", "originalText": "store.Container", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -28151,6 +28789,7 @@ "height": 74.09520580987555, "seed": 433802262, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28184,6 +28823,7 @@ "height": 25, "seed": 1208310102, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -28197,7 +28837,7 @@ "containerId": "bQE5a6tsjCSJv49bbhHqD", "originalText": "store.Volume", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -28219,6 +28859,7 @@ "height": 74.09520580987555, "seed": 213115478, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28252,6 +28893,7 @@ "height": 25, "seed": 2012293014, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -28265,7 +28907,7 @@ "containerId": "GTpL94XSOArP3YnCASPQS", "originalText": "graph.Container", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -28287,6 +28929,7 @@ "height": 74.09520580987555, "seed": 208704330, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28320,6 +28963,7 @@ "height": 25, "seed": 475240970, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -28333,7 +28977,7 @@ "containerId": "Q5t1ppg2EtnIAwKTHHjHP", "originalText": "graph.Volume", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -28355,6 +28999,7 @@ "height": 84.4599915876613, "seed": 112787018, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -28406,6 +29051,7 @@ "height": 117.98996097080726, "seed": 386781910, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -28449,6 +29095,7 @@ "height": 97.80441362673582, "seed": 2145547222, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28476,8 +29123,8 @@ }, { "type": "text", - "version": 336, - "versionNonce": 1600335949, + "version": 337, + "versionNonce": 610765375, "isDeleted": false, "id": "YZ9v3JHi75hcJXtdWoC80", "fillStyle": "hachure", @@ -28494,9 +29141,10 @@ "height": 50, "seed": 1616502922, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653833, + "updated": 1696427296412, "link": null, "locked": false, "fontSize": 20, @@ -28529,6 +29177,7 @@ "height": 277.03702285629856, "seed": 784707018, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -28580,6 +29229,7 @@ "height": 74.09520580987555, "seed": 144295062, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28617,6 +29267,7 @@ "height": 25, "seed": 962642390, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -28630,7 +29281,7 @@ "containerId": "k-f0FTXNiF_sYXQIRnCm6", "originalText": "graph.Role", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -28652,6 +29303,7 @@ "height": 74.09520580987555, "seed": 1255544598, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28689,6 +29341,7 @@ "height": 25, "seed": 1164887126, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -28702,7 +29355,7 @@ "containerId": "1w7d_3zbkhF27cUmYQPWl", "originalText": "store.Role", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -28724,6 +29377,7 @@ "height": 74.09520580987555, "seed": 1526712726, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28757,6 +29411,7 @@ "height": 25, "seed": 985540310, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -28770,7 +29425,7 @@ "containerId": "SYU-YUftKCSYzNVZ4ViNm", "originalText": "role name -> id", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -28792,6 +29447,7 @@ "height": 99.77020174017707, "seed": 1095904074, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -28839,6 +29495,7 @@ "height": 4.651922473860395, "seed": 1433770902, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -28890,6 +29547,7 @@ "height": 94.1329238635144, "seed": 490482762, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -28941,6 +29599,7 @@ "height": 74.09520580987555, "seed": 1510148630, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -28978,6 +29637,7 @@ "height": 25, "seed": 1753569110, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -28991,7 +29651,7 @@ "containerId": "YWLtu6UnUp51LqQDMqzou", "originalText": "graph.Identity", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -29013,6 +29673,7 @@ "height": 74.09520580987555, "seed": 600571030, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29050,6 +29711,7 @@ "height": 25, "seed": 562821590, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -29063,7 +29725,7 @@ "containerId": "ma4rSkeIgcLv4bhV0rsiv", "originalText": "store.Identity", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -29085,6 +29747,7 @@ "height": 97.45137370043108, "seed": 2005753558, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -29136,6 +29799,7 @@ "height": 212.13222413830783, "seed": 862393366, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -29187,6 +29851,7 @@ "height": 74.09520580987555, "seed": 814339210, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29220,6 +29885,7 @@ "height": 25, "seed": 103985994, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653833, @@ -29233,7 +29899,7 @@ "containerId": "fQIXFStXxbvA4CXzH-6YY", "originalText": "store.RoleBinding", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -29255,6 +29921,7 @@ "height": 74.09520580987555, "seed": 141490186, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29288,6 +29955,7 @@ "height": 25, "seed": 2091345610, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653834, @@ -29301,7 +29969,7 @@ "containerId": "9gXiM6GZy5kN3A6I7Q1OW", "originalText": "store.VolumeMount", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -29323,6 +29991,7 @@ "height": 74.09520580987555, "seed": 868080842, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29356,6 +30025,7 @@ "height": 25, "seed": 1312535434, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653834, @@ -29369,7 +30039,7 @@ "containerId": "4IEwuekveam7ZkJLV6FPV", "originalText": "graph.Group", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -29391,6 +30061,7 @@ "height": 74.09520580987555, "seed": 1844902934, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29424,6 +30095,7 @@ "height": 25, "seed": 2099972438, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653834, @@ -29437,7 +30109,7 @@ "containerId": "KAAPfGTVxVxfqhAGcJh_M", "originalText": "graph.Token", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -29459,6 +30131,7 @@ "height": 53.93863411415373, "seed": 564973206, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29469,8 +30142,8 @@ }, { "type": "text", - "version": 476, - "versionNonce": 133849133, + "version": 477, + "versionNonce": 1599896881, "isDeleted": false, "id": "K63fthKq1zDCMVb_JfTxI", "fillStyle": "hachure", @@ -29487,9 +30160,10 @@ "height": 25, "seed": 260213718, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653834, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -29522,6 +30196,7 @@ "height": 53.93863411415373, "seed": 272451210, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29532,8 +30207,8 @@ }, { "type": "text", - "version": 482, - "versionNonce": 1400685859, + "version": 483, + "versionNonce": 815393375, "isDeleted": false, "id": "SZx434IEAyN8u9Iok9wKs", "fillStyle": "hachure", @@ -29550,9 +30225,10 @@ "height": 25, "seed": 1118299466, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653834, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -29585,6 +30261,7 @@ "height": 53.93863411415373, "seed": 1988072598, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29595,8 +30272,8 @@ }, { "type": "text", - "version": 475, - "versionNonce": 1131926157, + "version": 476, + "versionNonce": 773304081, "isDeleted": false, "id": "PXg6Txuhjr9XnACRPA3o1", "fillStyle": "hachure", @@ -29613,9 +30290,10 @@ "height": 25, "seed": 168595926, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653834, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -29648,6 +30326,7 @@ "height": 318.3199609190659, "seed": 199636554, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29658,8 +30337,8 @@ }, { "type": "text", - "version": 157, - "versionNonce": 781068483, + "version": 158, + "versionNonce": 600524415, "isDeleted": false, "id": "PsCFAZngKhjlM8aBiROp_", "fillStyle": "hachure", @@ -29676,9 +30355,10 @@ "height": 25, "seed": 830212566, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653834, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -29711,6 +30391,7 @@ "height": 77.12426382400918, "seed": 1574784470, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -29754,6 +30435,7 @@ "height": 557.6045839637931, "seed": 140422422, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -29782,6 +30464,7 @@ "height": 88.8271872740422, "seed": 829725270, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -29819,6 +30502,7 @@ "height": 140.36153289949334, "seed": 869982102, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -29861,8 +30545,8 @@ }, { "type": "text", - "version": 433, - "versionNonce": 1733818605, + "version": 434, + "versionNonce": 1179755761, "isDeleted": false, "id": "I3IyBpdIHc46DQR-k_9ug", "fillStyle": "hachure", @@ -29879,9 +30563,10 @@ "height": 50, "seed": 868646102, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653834, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -29914,6 +30599,7 @@ "height": 2.0422468642314016, "seed": 114061846, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -29970,6 +30656,7 @@ "height": 25, "seed": 132235094, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653834, @@ -29983,7 +30670,7 @@ "containerId": "LawSMKqcvSl6E--hLA2Z8", "originalText": "ResultBatch[i]", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "text", @@ -30005,6 +30692,7 @@ "height": 25, "seed": 1801151638, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653835, @@ -30018,7 +30706,7 @@ "containerId": "UkB9MesYQKDf4g1G-8K3A", "originalText": "fetch i+1", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "ellipse", @@ -30040,6 +30728,7 @@ "height": 118, "seed": 317612502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30089,6 +30778,7 @@ "height": 25, "seed": 1638905622, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653835, @@ -30102,7 +30792,7 @@ "containerId": "VfjBxVkGiPZGXIez8Ol-Y", "originalText": "Process", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -30124,6 +30814,7 @@ "height": 2.0708604483011186, "seed": 269771862, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30176,6 +30867,7 @@ "height": 25, "seed": 2146527638, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653835, @@ -30189,7 +30881,7 @@ "containerId": "eumZ1ZWYV6vpUD_mZl9Ao", "originalText": "InsertBatch[i]", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "ellipse", @@ -30211,6 +30903,7 @@ "height": 88.8271872740422, "seed": 276547286, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30221,8 +30914,8 @@ }, { "type": "text", - "version": 403, - "versionNonce": 2098961315, + "version": 404, + "versionNonce": 1018961567, "isDeleted": false, "id": "cwQfv7ctKwc9rzmOEdeLR", "fillStyle": "hachure", @@ -30239,9 +30932,10 @@ "height": 25, "seed": 1917352982, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653835, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -30276,6 +30970,7 @@ "groupIds": [ "kphomEQ9vHcBubnpI6ne5" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -30309,6 +31004,7 @@ "groupIds": [ "kphomEQ9vHcBubnpI6ne5" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -30337,6 +31033,7 @@ "groupIds": [ "kphomEQ9vHcBubnpI6ne5" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -30365,6 +31062,7 @@ "groupIds": [ "kphomEQ9vHcBubnpI6ne5" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -30391,6 +31089,7 @@ "height": 91.65097232021844, "seed": 1523199574, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30424,8 +31123,8 @@ }, { "type": "text", - "version": 359, - "versionNonce": 683123725, + "version": 360, + "versionNonce": 328326865, "isDeleted": false, "id": "rCH1-6E8SS-myByDCU3hi", "fillStyle": "hachure", @@ -30442,9 +31141,10 @@ "height": 25, "seed": 1163785110, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653835, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -30459,8 +31159,8 @@ }, { "type": "text", - "version": 280, - "versionNonce": 453914435, + "version": 281, + "versionNonce": 236778175, "isDeleted": false, "id": "sIQsIbPKVe0sTNSdQqzJp", "fillStyle": "hachure", @@ -30477,9 +31177,10 @@ "height": 25, "seed": 436710858, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653835, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -30512,6 +31213,7 @@ "height": 97.30111962286378, "seed": 389921930, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30545,6 +31247,7 @@ "height": 50, "seed": 1646349834, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653835, @@ -30558,7 +31261,7 @@ "containerId": "VSMDmxXgN_-j6rmfPqbZx", "originalText": "Edge\nbuilder", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -30580,6 +31283,7 @@ "height": 97.30111962286378, "seed": 1435011402, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30613,6 +31317,7 @@ "height": 50, "seed": 721211402, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653835, @@ -30626,7 +31331,7 @@ "containerId": "V8U2TLLYSbd6LrAr16Qj2", "originalText": "Edge\nbuilder", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -30648,6 +31353,7 @@ "height": 97.30111962286378, "seed": 1555596298, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30681,6 +31387,7 @@ "height": 50, "seed": 668955338, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653835, @@ -30694,7 +31401,7 @@ "containerId": "AceyeqkbsBmQ5Cavzom0T", "originalText": "Edge\nbuilder", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -30716,6 +31423,7 @@ "height": 97.30111962286378, "seed": 1086311114, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30749,6 +31457,7 @@ "height": 50, "seed": 13623690, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653835, @@ -30762,7 +31471,7 @@ "containerId": "3JGtfCHPvCCdOFBkZooZ1", "originalText": "Edge\nbuilder", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -30784,6 +31493,7 @@ "height": 97.30111962286378, "seed": 838404362, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30817,6 +31527,7 @@ "height": 50, "seed": 1825003466, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653836, @@ -30830,7 +31541,7 @@ "containerId": "gyZMZrL-hRVdN_ViK8VXb", "originalText": "Edge\nbuilder", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -30852,6 +31563,7 @@ "height": 97.30111962286378, "seed": 1463858442, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -30885,6 +31597,7 @@ "height": 50, "seed": 1681490890, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653836, @@ -30898,7 +31611,7 @@ "containerId": "8Iwb2bt9XhlPOZetGviqC", "originalText": "Edge\nbuilder", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "rectangle", @@ -30920,6 +31633,7 @@ "height": 74.09520580987555, "seed": 1195919946, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -30957,6 +31671,7 @@ "height": 25, "seed": 823947530, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691888380, @@ -30970,7 +31685,7 @@ "containerId": "GpHnm8DCAEMOHSuzDt32M", "originalText": "VOLUME_ACCESS", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -30992,6 +31707,7 @@ "height": 74.09520580987555, "seed": 664706058, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -31025,6 +31741,7 @@ "height": 25, "seed": 1581419210, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653836, @@ -31038,7 +31755,7 @@ "containerId": "NW6ZZ__qXVWXozWRbPqyh", "originalText": "POD_EXEC", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -31060,6 +31777,7 @@ "height": 74.09520580987555, "seed": 1085284246, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -31097,6 +31815,7 @@ "height": 25, "seed": 1945353430, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653836, @@ -31110,7 +31829,7 @@ "containerId": "0J9zsTBrj6dd1vnUIDsc2", "originalText": "POD_ATTACH", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -31132,6 +31851,7 @@ "height": 74.09520580987555, "seed": 178543050, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -31169,6 +31889,7 @@ "height": 25, "seed": 1565167754, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653836, @@ -31182,7 +31903,7 @@ "containerId": "s-JaVwRj6FhhviSYLnUlq", "originalText": "TOKEN_STEAL", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -31204,6 +31925,7 @@ "height": 74.09520580987555, "seed": 972354506, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -31237,6 +31959,7 @@ "height": 25, "seed": 1266150026, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653836, @@ -31250,7 +31973,7 @@ "containerId": "BcIo4f60xGhusk_SEvOwj", "originalText": "MEMBER_OF", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -31272,6 +31995,7 @@ "height": 156.35756170361196, "seed": 703314826, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -31323,6 +32047,7 @@ "height": 74.09520580987555, "seed": 1969047382, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -31360,6 +32085,7 @@ "height": 25, "seed": 807791766, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653837, @@ -31373,7 +32099,7 @@ "containerId": "uhk7ByG30kD4HTyhMDv8G", "originalText": "EDGE...", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -31395,6 +32121,7 @@ "height": 71.73311536022857, "seed": 1388364374, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -31442,6 +32169,7 @@ "height": 113.4505667546041, "seed": 912743242, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -31493,6 +32221,7 @@ "height": 23.220989547952513, "seed": 865409942, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -31544,6 +32273,7 @@ "height": 209.3385502793817, "seed": 1192486794, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -31591,6 +32321,7 @@ "height": 276.4061938992993, "seed": 1472325718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -31640,6 +32371,7 @@ "groupIds": [ "GwViHflIy-bXq9umJcth7" ], + "frameId": null, "roundness": { "type": 2 }, @@ -31753,6 +32485,7 @@ "groupIds": [ "GwViHflIy-bXq9umJcth7" ], + "frameId": null, "roundness": { "type": 2 }, @@ -31822,6 +32555,7 @@ "groupIds": [ "GwViHflIy-bXq9umJcth7" ], + "frameId": null, "roundness": { "type": 2 }, @@ -31891,6 +32625,7 @@ "groupIds": [ "GwViHflIy-bXq9umJcth7" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -31919,6 +32654,7 @@ "groupIds": [ "GwViHflIy-bXq9umJcth7" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -31947,6 +32683,7 @@ "groupIds": [ "GwViHflIy-bXq9umJcth7" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -31980,6 +32717,7 @@ "groupIds": [ "GwViHflIy-bXq9umJcth7" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -31988,8 +32726,8 @@ }, { "type": "text", - "version": 80, - "versionNonce": 1571300525, + "version": 81, + "versionNonce": 611310769, "isDeleted": false, "id": "IZmYbAvhwLOI-Fvyn9Eea", "fillStyle": "hachure", @@ -32006,9 +32744,10 @@ "height": 25, "seed": 1073407766, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653837, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -32041,6 +32780,7 @@ "height": 0.4986898695981381, "seed": 2106067286, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32094,6 +32834,7 @@ "groupIds": [ "yD1wSwWC_94Z-Gb_R3gvT" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -32122,6 +32863,7 @@ "groupIds": [ "yD1wSwWC_94Z-Gb_R3gvT" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -32150,6 +32892,7 @@ "groupIds": [ "yD1wSwWC_94Z-Gb_R3gvT" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037464, @@ -32178,6 +32921,7 @@ "groupIds": [ "yD1wSwWC_94Z-Gb_R3gvT" ], + "frameId": null, "roundness": null, "boundElements": [ { @@ -32195,8 +32939,8 @@ }, { "type": "text", - "version": 168, - "versionNonce": 1272678563, + "version": 169, + "versionNonce": 9323231, "isDeleted": false, "id": "60rTmjiMEDvJ_9hKBmY8v", "fillStyle": "hachure", @@ -32213,9 +32957,10 @@ "height": 25, "seed": 586961546, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653837, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 20, @@ -32248,6 +32993,7 @@ "height": 366.64275267728294, "seed": 2060732566, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32299,6 +33045,7 @@ "height": 120.63070923576538, "seed": 1224534166, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32350,6 +33097,7 @@ "height": 3.416503609414349, "seed": 726564118, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32398,6 +33146,7 @@ "height": 201.37494798168973, "seed": 99248726, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32426,6 +33175,7 @@ "height": 35, "seed": 420917142, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653837, @@ -32439,12 +33189,12 @@ "containerId": "MQciJSE3dzcwxnMArhF9s", "originalText": "corev1.Node", "lineHeight": 1.25, - "baseline": 24 + "baseline": 26 }, { "type": "text", - "version": 633, - "versionNonce": 1162378307, + "version": 634, + "versionNonce": 1217601169, "isDeleted": false, "id": "c6ZdG-H-hh_aHr6l1y-JA", "fillStyle": "hachure", @@ -32461,9 +33211,10 @@ "height": 70, "seed": 554192086, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653837, + "updated": 1696427296413, "link": null, "locked": false, "fontSize": 28, @@ -32496,6 +33247,7 @@ "height": 0.06957818749424405, "seed": 1553461066, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32547,6 +33299,7 @@ "height": 1254.6012291473467, "seed": 140422422, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -32575,6 +33328,7 @@ "height": 88.8271872740422, "seed": 829725270, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32602,8 +33356,8 @@ }, { "type": "text", - "version": 519, - "versionNonce": 1857985901, + "version": 520, + "versionNonce": 346066687, "isDeleted": false, "id": "nC5afePC_WoGOZEuB2_DM", "fillStyle": "hachure", @@ -32620,6 +33374,7 @@ "height": 50, "seed": 868646102, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -32627,7 +33382,7 @@ "type": "arrow" } ], - "updated": 1691691653837, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 20, @@ -32660,6 +33415,7 @@ "height": 85.88815748807656, "seed": 114061846, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32716,6 +33472,7 @@ "height": 25, "seed": 132235094, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653837, @@ -32729,7 +33486,7 @@ "containerId": "TYFMB33UzQQs4xJVqLvtF", "originalText": "convert.Identity", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "ellipse", @@ -32751,6 +33508,7 @@ "height": 118, "seed": 317612502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -32792,6 +33550,7 @@ "height": 25, "seed": 1638905622, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653838, @@ -32805,7 +33564,7 @@ "containerId": "liHn3Jrx6sebH-YWri_2o", "originalText": "Identity", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "diamond", @@ -32829,6 +33588,7 @@ "groupIds": [ "d3ckQbsjRowbVBBeyAcIQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -32857,6 +33617,7 @@ "groupIds": [ "d3ckQbsjRowbVBBeyAcIQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -32885,6 +33646,7 @@ "groupIds": [ "d3ckQbsjRowbVBBeyAcIQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -32913,6 +33675,7 @@ "groupIds": [ "d3ckQbsjRowbVBBeyAcIQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -32921,8 +33684,8 @@ }, { "type": "text", - "version": 329, - "versionNonce": 542279555, + "version": 330, + "versionNonce": 1857234033, "isDeleted": false, "id": "944be9DVdoDP1qmUSQ59m", "fillStyle": "hachure", @@ -32939,9 +33702,10 @@ "height": 25, "seed": 436710858, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653838, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 20, @@ -32974,6 +33738,7 @@ "height": 125, "seed": 317612502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33023,6 +33788,7 @@ "height": 50, "seed": 1638905622, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653838, @@ -33036,7 +33802,7 @@ "containerId": "JvGcp_NbeszpPuw7d9U5R", "originalText": "PermissionSet", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "arrow", @@ -33058,6 +33824,7 @@ "height": 275.4586719211925, "seed": 114061846, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33110,6 +33877,7 @@ "height": 25, "seed": 132235094, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653838, @@ -33123,7 +33891,7 @@ "containerId": "6dPfsW2thYB9nfbs1U7sh", "originalText": "convert.PermissionSet", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -33145,6 +33913,7 @@ "height": 5.540488171682227, "seed": 1500306918, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33196,6 +33965,7 @@ "height": 290.05518568176194, "seed": 949820026, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -33229,6 +33999,7 @@ "height": 0.42547009971940497, "seed": 772951162, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33280,6 +34051,7 @@ "height": 232.66950410536182, "seed": 949820026, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -33313,6 +34085,7 @@ "height": 0.7856551427153136, "seed": 393361210, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33342,8 +34115,8 @@ }, { "type": "text", - "version": 50, - "versionNonce": 851089549, + "version": 51, + "versionNonce": 1691637535, "isDeleted": false, "id": "WG4oyhU-1p0gKRoDxmUKT", "fillStyle": "hachure", @@ -33360,9 +34133,10 @@ "height": 35, "seed": 29306426, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653838, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 28, @@ -33377,8 +34151,8 @@ }, { "type": "text", - "version": 153, - "versionNonce": 1581433539, + "version": 154, + "versionNonce": 1117220433, "isDeleted": false, "id": "NWyEiRRktVlteGkjN1DUO", "fillStyle": "hachure", @@ -33395,9 +34169,10 @@ "height": 125, "seed": 1535124582, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653838, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 20, @@ -33412,8 +34187,8 @@ }, { "type": "text", - "version": 95, - "versionNonce": 777125613, + "version": 96, + "versionNonce": 1738152767, "isDeleted": false, "id": "PWAFoR0ONAwARI9lv6fZi", "fillStyle": "hachure", @@ -33430,9 +34205,10 @@ "height": 35, "seed": 834182374, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653838, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 28, @@ -33447,8 +34223,8 @@ }, { "type": "text", - "version": 291, - "versionNonce": 386101859, + "version": 292, + "versionNonce": 186088497, "isDeleted": false, "id": "naYXCEyAtglpnFE1iFeW8", "fillStyle": "hachure", @@ -33465,9 +34241,10 @@ "height": 225, "seed": 1535124582, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653838, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 20, @@ -33500,6 +34277,7 @@ "height": 486.2047689650153, "seed": 1849021670, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33556,6 +34334,7 @@ "height": 25, "seed": 1915007142, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653839, @@ -33569,7 +34348,7 @@ "containerId": "IyYc0fMNj-4kLzbJkXHe_", "originalText": "convert.RoleBinding", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "ellipse", @@ -33591,6 +34370,7 @@ "height": 125, "seed": 317612502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33632,6 +34412,7 @@ "height": 25, "seed": 1638905622, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653839, @@ -33645,7 +34426,7 @@ "containerId": "xnm78Vztn4hyJGr5rG3gv", "originalText": "RoleBinding", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -33667,6 +34448,7 @@ "height": 3.2284154418821345, "seed": 1500306918, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33718,6 +34500,7 @@ "height": 262.5277956623513, "seed": 949820026, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -33733,8 +34516,8 @@ }, { "type": "text", - "version": 92, - "versionNonce": 166127533, + "version": 93, + "versionNonce": 1901222751, "isDeleted": false, "id": "-jHwBLdCc-wyPpCHePRzN", "fillStyle": "hachure", @@ -33751,9 +34534,10 @@ "height": 35, "seed": 29306426, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653839, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 28, @@ -33768,8 +34552,8 @@ }, { "type": "text", - "version": 188, - "versionNonce": 438203811, + "version": 189, + "versionNonce": 1209716241, "isDeleted": false, "id": "teLU9J9uK3obJhfHwG_0O", "fillStyle": "hachure", @@ -33786,9 +34570,10 @@ "height": 150, "seed": 1535124582, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653839, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 20, @@ -33821,6 +34606,7 @@ "height": 337.19929782268446, "seed": 1074047098, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -33872,6 +34658,7 @@ "height": 934.1652337294311, "seed": 2051889574, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -33887,8 +34674,8 @@ }, { "type": "text", - "version": 73, - "versionNonce": 1969711629, + "version": 74, + "versionNonce": 1984796543, "isDeleted": false, "id": "xZ9iEMva-bcaVH1BW0yM_", "fillStyle": "hachure", @@ -33905,6 +34692,7 @@ "height": 25, "seed": 1196184678, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -33912,7 +34700,7 @@ "type": "arrow" } ], - "updated": 1691691653839, + "updated": 1696427296414, "link": null, "locked": false, "fontSize": 20, @@ -33947,6 +34735,7 @@ "groupIds": [ "Ej87vWW4gBvbiGq5H6fNQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -33975,6 +34764,7 @@ "groupIds": [ "Ej87vWW4gBvbiGq5H6fNQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -34003,6 +34793,7 @@ "groupIds": [ "Ej87vWW4gBvbiGq5H6fNQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -34031,6 +34822,7 @@ "groupIds": [ "Ej87vWW4gBvbiGq5H6fNQ" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1690798037465, @@ -34039,8 +34831,8 @@ }, { "type": "text", - "version": 119, - "versionNonce": 111528259, + "version": 120, + "versionNonce": 278455281, "isDeleted": false, "id": "5rFVQmM8KYHOhTyQTnUOj", "fillStyle": "hachure", @@ -34057,6 +34849,7 @@ "height": 25, "seed": 1196184678, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -34064,7 +34857,7 @@ "type": "arrow" } ], - "updated": 1691691653839, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 20, @@ -34097,6 +34890,7 @@ "height": 123.66342881591027, "seed": 1838006694, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34148,6 +34942,7 @@ "height": 127.30058848696626, "seed": 1838006694, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34181,8 +34976,8 @@ }, { "type": "text", - "version": 64, - "versionNonce": 1986568301, + "version": 65, + "versionNonce": 214716319, "isDeleted": false, "id": "xp5RuGA6ZiZFGhVA4aOdw", "fillStyle": "hachure", @@ -34199,9 +34994,10 @@ "height": 35, "seed": 1349140538, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653839, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 28, @@ -34234,6 +35030,7 @@ "height": 81.8716635377159, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34271,6 +35068,7 @@ "height": 25, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653839, @@ -34284,7 +35082,7 @@ "containerId": "CB292a5h2OfJqxtREz7_l", "originalText": "CR", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "ellipse", @@ -34306,6 +35104,7 @@ "height": 81.8716635377159, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34339,6 +35138,7 @@ "height": 25, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653839, @@ -34352,7 +35152,7 @@ "containerId": "hGgXR4-bgng7r-_Qt5kpo", "originalText": "CRB", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "rectangle", @@ -34374,6 +35174,7 @@ "height": 202.25413609582537, "seed": 1741272678, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -34384,8 +35185,8 @@ }, { "type": "text", - "version": 116, - "versionNonce": 981505155, + "version": 117, + "versionNonce": 815349201, "isDeleted": false, "id": "BK9llMbWheyXF5BFMMfI-", "fillStyle": "hachure", @@ -34402,6 +35203,7 @@ "height": 35, "seed": 1112993190, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -34413,7 +35215,7 @@ "type": "arrow" } ], - "updated": 1691691653839, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 28, @@ -34428,8 +35230,8 @@ }, { "type": "text", - "version": 169, - "versionNonce": 451094829, + "version": 170, + "versionNonce": 788464575, "isDeleted": false, "id": "u3V4iaPha06p_gH0O3qcZ", "fillStyle": "hachure", @@ -34446,9 +35248,10 @@ "height": 25, "seed": 934109926, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653840, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 20, @@ -34481,6 +35284,7 @@ "height": 63.77447884768162, "seed": 1289128998, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34532,6 +35336,7 @@ "height": 68.06768789260968, "seed": 23414502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34579,6 +35384,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34612,6 +35418,7 @@ "height": 50, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653840, @@ -34625,7 +35432,7 @@ "containerId": "TtbdYcec7-cKrscMMG9Zk", "originalText": "R\nNS1", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -34647,6 +35454,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34680,6 +35488,7 @@ "height": 50, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653840, @@ -34693,7 +35502,7 @@ "containerId": "b5DtTGl8OTMGrDoOphUmM", "originalText": "RB\nNS1", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "rectangle", @@ -34715,6 +35524,7 @@ "height": 202.25413609582537, "seed": 1741272678, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -34725,8 +35535,8 @@ }, { "type": "text", - "version": 252, - "versionNonce": 1678872515, + "version": 253, + "versionNonce": 120806321, "isDeleted": false, "id": "GT3BpJMY46LwoRlz2Q4pa", "fillStyle": "hachure", @@ -34743,6 +35553,7 @@ "height": 35, "seed": 1112993190, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -34754,7 +35565,7 @@ "type": "arrow" } ], - "updated": 1691691653840, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 28, @@ -34787,6 +35598,7 @@ "height": 63.77447884768162, "seed": 1289128998, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34834,6 +35646,7 @@ "height": 68.06768789260968, "seed": 23414502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34881,6 +35694,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34914,6 +35728,7 @@ "height": 50, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653840, @@ -34927,7 +35742,7 @@ "containerId": "qlyTIVCPlvklxme25qfIX", "originalText": "R\nNS1", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -34949,6 +35764,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -34982,6 +35798,7 @@ "height": 50, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653840, @@ -34995,7 +35812,7 @@ "containerId": "KqQSYrxtwdB6-hqSLJTLa", "originalText": "RB\nNS2", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "arrow", @@ -35017,6 +35834,7 @@ "height": 68.52974340149603, "seed": 1289128998, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35064,6 +35882,7 @@ "height": 71.94248520843848, "seed": 23414502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35111,6 +35930,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35144,6 +35964,7 @@ "height": 25, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653840, @@ -35157,7 +35978,7 @@ "containerId": "Ohu49jihzZlVJbG7CPeMT", "originalText": "CR", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "ellipse", @@ -35179,6 +36000,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35212,6 +36034,7 @@ "height": 50, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653840, @@ -35225,7 +36048,7 @@ "containerId": "cFwmTPKcWmeguPp1TF2wj", "originalText": "RB\nNS1", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "rectangle", @@ -35247,6 +36070,7 @@ "height": 202.25413609582537, "seed": 1741272678, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -35257,8 +36081,8 @@ }, { "type": "text", - "version": 279, - "versionNonce": 1223862957, + "version": 280, + "versionNonce": 1023816671, "isDeleted": false, "id": "vjU5mGB6m4JGkVNpNNuvJ", "fillStyle": "hachure", @@ -35275,6 +36099,7 @@ "height": 35, "seed": 1112993190, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -35286,7 +36111,7 @@ "type": "arrow" } ], - "updated": 1691691653840, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 28, @@ -35319,6 +36144,7 @@ "height": 63.77447884768162, "seed": 1289128998, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35366,6 +36192,7 @@ "height": 68.06768789260968, "seed": 23414502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35413,6 +36240,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35446,6 +36274,7 @@ "height": 50, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653840, @@ -35459,7 +36288,7 @@ "containerId": "nsLbApqy2waVjFeh8SOO1", "originalText": "R\nNS1", "lineHeight": 1.25, - "baseline": 43 + "baseline": 44 }, { "type": "ellipse", @@ -35481,6 +36310,7 @@ "height": 85, "seed": 1637391718, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35514,6 +36344,7 @@ "height": 25, "seed": 696872934, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653841, @@ -35527,7 +36358,7 @@ "containerId": "vdopcd6ueG7Cuh-ESQrre", "originalText": "CRB", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -35549,6 +36380,7 @@ "height": 63.77447884768162, "seed": 1289128998, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35596,6 +36428,7 @@ "height": 68.06768789260968, "seed": 23414502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -35625,8 +36458,8 @@ }, { "type": "text", - "version": 71, - "versionNonce": 1277564483, + "version": 72, + "versionNonce": 613334417, "isDeleted": false, "id": "TQdPnFA8cvQ3ceam-sLvc", "fillStyle": "hachure", @@ -35643,9 +36476,10 @@ "height": 25, "seed": 755707366, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 20, @@ -35660,8 +36494,8 @@ }, { "type": "text", - "version": 68, - "versionNonce": 27239277, + "version": 69, + "versionNonce": 1056071679, "isDeleted": false, "id": "uJ9sLSzwi234RYNdJF4C_", "fillStyle": "hachure", @@ -35678,9 +36512,10 @@ "height": 25, "seed": 1124006138, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 20, @@ -35695,8 +36530,8 @@ }, { "type": "text", - "version": 68, - "versionNonce": 607147491, + "version": 69, + "versionNonce": 669180785, "isDeleted": false, "id": "AQJC6-WKMIMjExjCql-tv", "fillStyle": "hachure", @@ -35713,9 +36548,10 @@ "height": 25, "seed": 725920678, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 20, @@ -35730,8 +36566,8 @@ }, { "type": "text", - "version": 66, - "versionNonce": 907193805, + "version": 67, + "versionNonce": 1724123167, "isDeleted": false, "id": "oIgrnnwsPHeKvY9Znhkhk", "fillStyle": "hachure", @@ -35748,9 +36584,10 @@ "height": 25, "seed": 426363322, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 20, @@ -35765,8 +36602,8 @@ }, { "type": "text", - "version": 201, - "versionNonce": 1813094787, + "version": 202, + "versionNonce": 1568099665, "isDeleted": false, "id": "GiECrqsWtMc7YBX7TQXj9", "fillStyle": "hachure", @@ -35783,9 +36620,10 @@ "height": 25, "seed": 934109926, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296415, "link": null, "locked": false, "fontSize": 20, @@ -35800,8 +36638,8 @@ }, { "type": "text", - "version": 105, - "versionNonce": 1349872685, + "version": 106, + "versionNonce": 1382788159, "isDeleted": false, "id": "l82lHezNr7rBdUPYIY6lC", "fillStyle": "hachure", @@ -35818,9 +36656,10 @@ "height": 25, "seed": 1124006138, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -35835,8 +36674,8 @@ }, { "type": "text", - "version": 101, - "versionNonce": 755530019, + "version": 102, + "versionNonce": 480475953, "isDeleted": false, "id": "_e0jvtDX1g5qBGA_m6Tdt", "fillStyle": "hachure", @@ -35853,9 +36692,10 @@ "height": 25, "seed": 725920678, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -35870,8 +36710,8 @@ }, { "type": "text", - "version": 98, - "versionNonce": 1622236813, + "version": 99, + "versionNonce": 231328863, "isDeleted": false, "id": "7Yy76wraDR8OeKf7GUId0", "fillStyle": "hachure", @@ -35888,9 +36728,10 @@ "height": 25, "seed": 426363322, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -35905,8 +36746,8 @@ }, { "type": "text", - "version": 196, - "versionNonce": 1149459651, + "version": 197, + "versionNonce": 1708059921, "isDeleted": false, "id": "Sk0DFnPwXzqPssasM_enB", "fillStyle": "hachure", @@ -35923,9 +36764,10 @@ "height": 25, "seed": 934109926, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -35940,8 +36782,8 @@ }, { "type": "text", - "version": 100, - "versionNonce": 1031800045, + "version": 101, + "versionNonce": 1420748927, "isDeleted": false, "id": "tGgqSQu5udJDTSdL421b0", "fillStyle": "hachure", @@ -35958,9 +36800,10 @@ "height": 25, "seed": 1124006138, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653841, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -35975,8 +36818,8 @@ }, { "type": "text", - "version": 99, - "versionNonce": 1579207779, + "version": 100, + "versionNonce": 1081156337, "isDeleted": false, "id": "Tn6ktXLiaZCstCZsdtbRR", "fillStyle": "hachure", @@ -35993,9 +36836,10 @@ "height": 25, "seed": 725920678, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653842, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -36010,8 +36854,8 @@ }, { "type": "text", - "version": 93, - "versionNonce": 711647053, + "version": 94, + "versionNonce": 349929631, "isDeleted": false, "id": "OdmD68wjP_SeEpVxuZdB1", "fillStyle": "hachure", @@ -36028,9 +36872,10 @@ "height": 25, "seed": 426363322, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653842, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -36063,6 +36908,7 @@ "height": 235, "seed": 1926638566, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -36104,6 +36950,7 @@ "height": 225, "seed": 1093888742, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653842, @@ -36117,7 +36964,7 @@ "containerId": "vgJkokd_URCeGvumsOLYC", "originalText": "RoleBinding roleRef property does not have a namespace field. \n\nThe implication here is that a role binding can only reference a role in the same namespace.\n", "lineHeight": 1.25, - "baseline": 218 + "baseline": 219 }, { "type": "rectangle", @@ -36139,6 +36986,7 @@ "height": 235, "seed": 1926638566, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -36180,6 +37028,7 @@ "height": 75, "seed": 1093888742, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653842, @@ -36193,12 +37042,12 @@ "containerId": "5b-cH59bTBcvHB_BNzXNi", "originalText": "Cluster role bindings can not reference roles\n", "lineHeight": 1.25, - "baseline": 68 + "baseline": 69 }, { "type": "text", - "version": 322, - "versionNonce": 1764577187, + "version": 323, + "versionNonce": 1494326481, "isDeleted": false, "id": "v4V7UB5vr1cfdDv8LMUdW", "fillStyle": "hachure", @@ -36215,9 +37064,10 @@ "height": 51.56417306393979, "seed": 2092692006, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653842, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20.625669225575916, @@ -36250,6 +37100,7 @@ "height": 88.8271872740422, "seed": 829725270, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -36269,8 +37120,8 @@ }, { "type": "text", - "version": 611, - "versionNonce": 113979405, + "version": 612, + "versionNonce": 805311679, "isDeleted": false, "id": "aEjjK2Bpe7tF3MVW-245J", "fillStyle": "hachure", @@ -36287,6 +37138,7 @@ "height": 50, "seed": 868646102, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [ { @@ -36294,7 +37146,7 @@ "type": "arrow" } ], - "updated": 1691691653842, + "updated": 1696427296416, "link": null, "locked": false, "fontSize": 20, @@ -36327,6 +37179,7 @@ "height": 2.0082136291989627, "seed": 393361210, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -36374,6 +37227,7 @@ "height": 0.81834423033024, "seed": 1849021670, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -36430,6 +37284,7 @@ "height": 25, "seed": 1915007142, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653842, @@ -36443,7 +37298,7 @@ "containerId": "7r6wSyK-2IlRNgibwSdMa", "originalText": "convert.Role", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "ellipse", @@ -36465,6 +37320,7 @@ "height": 125, "seed": 317612502, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -36506,6 +37362,7 @@ "height": 25, "seed": 1638905622, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691653843, @@ -36519,7 +37376,7 @@ "containerId": "Rqcs5DYGRNVwXBqZWZcoz", "originalText": "Role", "lineHeight": 1.25, - "baseline": 18 + "baseline": 19 }, { "type": "arrow", @@ -36541,6 +37398,7 @@ "height": 5.430317324080534, "seed": 1500306918, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -36592,6 +37450,7 @@ "height": 262.5277956623513, "seed": 949820026, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -36607,8 +37466,8 @@ }, { "type": "text", - "version": 203, - "versionNonce": 585237219, + "version": 204, + "versionNonce": 1598544561, "isDeleted": false, "id": "Pqjfq6ESjYNJY2LwSjUUx", "fillStyle": "hachure", @@ -36625,9 +37484,10 @@ "height": 35, "seed": 29306426, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653843, + "updated": 1696427296417, "link": null, "locked": false, "fontSize": 28, @@ -36642,8 +37502,8 @@ }, { "type": "text", - "version": 308, - "versionNonce": 1985892557, + "version": 309, + "versionNonce": 2109547743, "isDeleted": false, "id": "GU8ODILn2LtYkITW8XY3w", "fillStyle": "hachure", @@ -36660,9 +37520,10 @@ "height": 150, "seed": 1535124582, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691653843, + "updated": 1696427296417, "link": null, "locked": false, "fontSize": 20, @@ -36677,8 +37538,8 @@ }, { "type": "text", - "version": 500, - "versionNonce": 1282901101, + "version": 501, + "versionNonce": 599481489, "isDeleted": false, "id": "bKJ-SIITDhp53QZH3jU1d", "fillStyle": "hachure", @@ -36695,9 +37556,10 @@ "height": 35, "seed": 1215124618, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691808899, + "updated": 1696427296417, "link": null, "locked": false, "fontSize": 28, @@ -36732,6 +37594,7 @@ "groupIds": [ "yzIWJ07uyfMJu-_eSwtAn" ], + "frameId": null, "roundness": { "type": 2 }, @@ -36845,6 +37708,7 @@ "groupIds": [ "yzIWJ07uyfMJu-_eSwtAn" ], + "frameId": null, "roundness": { "type": 2 }, @@ -36914,6 +37778,7 @@ "groupIds": [ "yzIWJ07uyfMJu-_eSwtAn" ], + "frameId": null, "roundness": { "type": 2 }, @@ -36983,6 +37848,7 @@ "groupIds": [ "yzIWJ07uyfMJu-_eSwtAn" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691794843, @@ -36991,8 +37857,8 @@ }, { "type": "text", - "version": 579, - "versionNonce": 343614467, + "version": 580, + "versionNonce": 228798719, "isDeleted": false, "id": "fRZUAtibbT04Fhhlgr0qA", "fillStyle": "hachure", @@ -37009,9 +37875,10 @@ "height": 35, "seed": 17606090, "groupIds": [], + "frameId": null, "roundness": null, "boundElements": [], - "updated": 1691691816497, + "updated": 1696427296417, "link": null, "locked": false, "fontSize": 28, @@ -37046,6 +37913,7 @@ "groupIds": [ "wNS-qryqZPDRgHZuc-ES5" ], + "frameId": null, "roundness": { "type": 2 }, @@ -37159,6 +38027,7 @@ "groupIds": [ "wNS-qryqZPDRgHZuc-ES5" ], + "frameId": null, "roundness": { "type": 2 }, @@ -37228,6 +38097,7 @@ "groupIds": [ "wNS-qryqZPDRgHZuc-ES5" ], + "frameId": null, "roundness": { "type": 2 }, @@ -37297,6 +38167,7 @@ "groupIds": [ "wNS-qryqZPDRgHZuc-ES5" ], + "frameId": null, "roundness": null, "boundElements": [], "updated": 1691691794843, @@ -37323,6 +38194,7 @@ "height": 386.58741807507334, "seed": 569604362, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, @@ -37360,6 +38232,7 @@ "height": 0.2914422932533398, "seed": 1553461066, "groupIds": [], + "frameId": null, "roundness": { "type": 2 }, @@ -37411,6 +38284,7 @@ "height": 386.58741807507334, "seed": 569604362, "groupIds": [], + "frameId": null, "roundness": { "type": 3 }, diff --git a/pkg/collector/file.go b/pkg/collector/file.go index 0b860603c..40f51453f 100644 --- a/pkg/collector/file.go +++ b/pkg/collector/file.go @@ -58,7 +58,8 @@ type FileCollector struct { // NewFileCollector creates a new instance of the file collector from the provided application config. func NewFileCollector(ctx context.Context, cfg *config.KubehoundConfig) (CollectorClient, error) { - baseTags := append(telemetry.BaseTags, telemetry.TagCollectorTypeFile) + tags := telemetry.BaseTags + tags = append(tags, telemetry.TagCollectorTypeFile) if cfg.Collector.Type != config.CollectorTypeFile { return nil, fmt.Errorf("invalid collector type in config: %s", cfg.Collector.Type) } @@ -73,7 +74,7 @@ func NewFileCollector(ctx context.Context, cfg *config.KubehoundConfig) (Collect return &FileCollector{ cfg: cfg.Collector.File, log: l, - tags: baseTags, + tags: tags, }, nil } @@ -81,7 +82,7 @@ func (c *FileCollector) Name() string { return FileCollectorName } -func (c *FileCollector) HealthCheck(ctx context.Context) (bool, error) { +func (c *FileCollector) HealthCheck(_ context.Context) (bool, error) { file, err := os.Stat(c.cfg.Directory) if err != nil { return false, fmt.Errorf("file collector base path: %w", err) @@ -94,7 +95,7 @@ func (c *FileCollector) HealthCheck(ctx context.Context) (bool, error) { return true, nil } -func (c *FileCollector) Close(ctx context.Context) error { +func (c *FileCollector) Close(_ context.Context) error { // NOP for this implementation return nil } @@ -108,8 +109,8 @@ func (c *FileCollector) streamPodsNamespace(ctx context.Context, fp string, inge for _, item := range list.Items { _ = statsd.Incr(telemetry.MetricCollectorPodsCount, c.tags, 1) - i := types.PodType(&item) - err = ingestor.IngestPod(ctx, i) + i := item + err = ingestor.IngestPod(ctx, &i) if err != nil { return fmt.Errorf("processing K8s pod %s: %w", i.Name, err) } @@ -151,8 +152,8 @@ func (c *FileCollector) streamRolesNamespace(ctx context.Context, fp string, ing for _, item := range list.Items { _ = statsd.Incr(telemetry.MetricCollectorRolesCount, c.tags, 1) - i := types.RoleType(&item) - err = ingestor.IngestRole(ctx, i) + i := item + err = ingestor.IngestRole(ctx, &i) if err != nil { return fmt.Errorf("processing K8s role %s: %w", i.Name, err) } @@ -194,8 +195,8 @@ func (c *FileCollector) streamRoleBindingsNamespace(ctx context.Context, fp stri for _, item := range list.Items { _ = statsd.Incr(telemetry.MetricCollectorRoleBindingsCount, c.tags, 1) - i := types.RoleBindingType(&item) - err = ingestor.IngestRoleBinding(ctx, i) + i := item + err = ingestor.IngestRoleBinding(ctx, &i) if err != nil { return fmt.Errorf("processing K8s role binding %s: %w", i.Name, err) } @@ -237,8 +238,8 @@ func (c *FileCollector) streamEndpointsNamespace(ctx context.Context, fp string, for _, item := range list.Items { _ = statsd.Incr(telemetry.MetricCollectorEndpointCount, c.tags, 1) - i := types.EndpointType(&item) - err = ingestor.IngestEndpoint(ctx, i) + i := item + err = ingestor.IngestEndpoint(ctx, &i) if err != nil { return fmt.Errorf("processing K8s endpoint slice %s: %w", i.Name, err) } @@ -286,8 +287,8 @@ func (c *FileCollector) StreamNodes(ctx context.Context, ingestor NodeIngestor) for _, item := range list.Items { _ = statsd.Incr(telemetry.MetricCollectorNodesCount, c.tags, 1) - i := types.NodeType(&item) - err = ingestor.IngestNode(ctx, i) + i := item + err = ingestor.IngestNode(ctx, &i) if err != nil { return fmt.Errorf("processing K8s node %s::%s: %w", i.Namespace, i.Name, err) } @@ -311,8 +312,8 @@ func (c *FileCollector) StreamClusterRoles(ctx context.Context, ingestor Cluster for _, item := range list.Items { _ = statsd.Incr(telemetry.MetricCollectorClusterRolesCount, c.tags, 1) - i := types.ClusterRoleType(&item) - err = ingestor.IngestClusterRole(ctx, i) + i := item + err = ingestor.IngestClusterRole(ctx, &i) if err != nil { return fmt.Errorf("processing k8s cluster role %s: %w", i.Name, err) } @@ -336,8 +337,8 @@ func (c *FileCollector) StreamClusterRoleBindings(ctx context.Context, ingestor for _, item := range list.Items { _ = statsd.Incr(telemetry.MetricCollectorClusterRoleBindingsCount, c.tags, 1) - i := types.ClusterRoleBindingType(&item) - err = ingestor.IngestClusterRoleBinding(ctx, i) + i := item + err = ingestor.IngestClusterRoleBinding(ctx, &i) if err != nil { return fmt.Errorf("processing K8s cluster role binding %s: %w", i.Name, err) } @@ -355,7 +356,7 @@ func readList[Tl types.ListInputType](ctx context.Context, inputPath string) (Tl var inputList Tl bytes, err := os.ReadFile(inputPath) if err != nil { - return inputList, fmt.Errorf("read file %s: %v", inputPath, err) + return inputList, fmt.Errorf("read file %s: %w", inputPath, err) } if len(bytes) == 0 { diff --git a/pkg/collector/file_test.go b/pkg/collector/file_test.go index 27b58d470..44c3ee51c 100644 --- a/pkg/collector/file_test.go +++ b/pkg/collector/file_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package collector import ( @@ -11,6 +12,8 @@ import ( ) func TestFileCollector_Constructor(t *testing.T) { + t.Parallel() + cfg, err := config.NewConfig("testdata/kubehound-test.yaml") assert.NoError(t, err) @@ -21,6 +24,8 @@ func TestFileCollector_Constructor(t *testing.T) { } func TestFileCollector_HealthCheck(t *testing.T) { + t.Parallel() + c := &FileCollector{ cfg: &config.FileCollectorConfig{ Directory: "does-not-exist/", @@ -53,6 +58,8 @@ func TestFileCollector_HealthCheck(t *testing.T) { } func NewTestFileCollector(t *testing.T) *FileCollector { + t.Helper() + cfg, err := config.NewConfig("testdata/kubehound-test.yaml") assert.NoError(t, err) @@ -63,6 +70,8 @@ func NewTestFileCollector(t *testing.T) *FileCollector { } func TestFileCollector_StreamNodes(t *testing.T) { + t.Parallel() + c := NewTestFileCollector(t) ctx := context.Background() i := mocks.NewNodeIngestor(t) @@ -75,6 +84,8 @@ func TestFileCollector_StreamNodes(t *testing.T) { } func TestFileCollector_StreamPods(t *testing.T) { + t.Parallel() + c := NewTestFileCollector(t) ctx := context.Background() i := mocks.NewPodIngestor(t) @@ -87,6 +98,8 @@ func TestFileCollector_StreamPods(t *testing.T) { } func TestFileCollector_StreamRoles(t *testing.T) { + t.Parallel() + c := NewTestFileCollector(t) ctx := context.Background() i := mocks.NewRoleIngestor(t) @@ -99,6 +112,8 @@ func TestFileCollector_StreamRoles(t *testing.T) { } func TestFileCollector_StreamRoleBindings(t *testing.T) { + t.Parallel() + c := NewTestFileCollector(t) ctx := context.Background() i := mocks.NewRoleBindingIngestor(t) @@ -111,6 +126,8 @@ func TestFileCollector_StreamRoleBindings(t *testing.T) { } func TestFileCollector_StreamClusterRoles(t *testing.T) { + t.Parallel() + c := NewTestFileCollector(t) ctx := context.Background() i := mocks.NewClusterRoleIngestor(t) @@ -123,6 +140,8 @@ func TestFileCollector_StreamClusterRoles(t *testing.T) { } func TestFileCollector_StreamClusterRoleBindings(t *testing.T) { + t.Parallel() + c := NewTestFileCollector(t) ctx := context.Background() i := mocks.NewClusterRoleBindingIngestor(t) @@ -135,6 +154,8 @@ func TestFileCollector_StreamClusterRoleBindings(t *testing.T) { } func TestFileCollector_StreamEndpoints(t *testing.T) { + t.Parallel() + c := NewTestFileCollector(t) ctx := context.Background() i := mocks.NewEndpointIngestor(t) diff --git a/pkg/collector/k8s_api.go b/pkg/collector/k8s_api.go index 2a9c076e8..b80758f05 100644 --- a/pkg/collector/k8s_api.go +++ b/pkg/collector/k8s_api.go @@ -40,12 +40,14 @@ func checkK8sAPICollectorConfig(collectorType string) error { if collectorType != config.CollectorTypeK8sAPI { return fmt.Errorf("invalid collector type in config: %s", collectorType) } + return nil } // NewK8sAPICollector creates a new instance of the k8s live API collector from the provided application config. func NewK8sAPICollector(ctx context.Context, cfg *config.KubehoundConfig) (CollectorClient, error) { - baseTags := append(telemetry.BaseTags, telemetry.TagCollectorTypeK8sApi) + tags := telemetry.BaseTags + tags = append(tags, telemetry.TagCollectorTypeK8sApi) l := log.Trace(ctx, log.WithComponent(K8sAPICollectorName)) err := checkK8sAPICollectorConfig(cfg.Collector.Type) @@ -68,7 +70,7 @@ func NewK8sAPICollector(ctx context.Context, cfg *config.KubehoundConfig) (Colle clientset: clientset, log: l, rl: ratelimit.New(cfg.Collector.Live.RateLimitPerSecond), // per second - tags: baseTags, + tags: tags, }, nil } @@ -92,7 +94,7 @@ func (c *k8sAPICollector) HealthCheck(ctx context.Context) (bool, error) { return true, nil } -func (c *k8sAPICollector) Close(ctx context.Context) error { +func (c *k8sAPICollector) Close(_ context.Context) error { return nil } @@ -130,6 +132,7 @@ func (c *k8sAPICollector) streamPodsNamespace(ctx context.Context, namespace str if err != nil { return nil, fmt.Errorf("getting K8s pods for namespace %s: %w", namespace, err) } + return entries, err })) @@ -138,11 +141,16 @@ func (c *k8sAPICollector) streamPodsNamespace(ctx context.Context, namespace str return pager.EachListItem(ctx, opts, func(obj runtime.Object) error { _ = statsd.Incr(telemetry.MetricCollectorPodsCount, c.tags, 1) c.rl.Take() - item := obj.(*corev1.Pod) + item, ok := obj.(*corev1.Pod) + if !ok { + return fmt.Errorf("pod stream type conversion error: %T", obj) + } + err := ingestor.IngestPod(ctx, item) if err != nil { return fmt.Errorf("processing K8s pod %s for namespace %s: %w", item.Name, namespace, err) } + return nil }) } @@ -157,6 +165,7 @@ func (c *k8sAPICollector) StreamPods(ctx context.Context, ingestor PodIngestor) if err != nil { return err } + return ingestor.Complete(ctx) } @@ -174,6 +183,7 @@ func (c *k8sAPICollector) streamRolesNamespace(ctx context.Context, namespace st if err != nil { return nil, fmt.Errorf("getting K8s roles for namespace %s: %w", namespace, err) } + return entries, err })) @@ -182,11 +192,16 @@ func (c *k8sAPICollector) streamRolesNamespace(ctx context.Context, namespace st return pager.EachListItem(ctx, opts, func(obj runtime.Object) error { _ = statsd.Incr(telemetry.MetricCollectorRolesCount, c.tags, 1) c.rl.Take() - item := obj.(*rbacv1.Role) + item, ok := obj.(*rbacv1.Role) + if !ok { + return fmt.Errorf("role stream type conversion error: %T", obj) + } + err := ingestor.IngestRole(ctx, item) if err != nil { return fmt.Errorf("processing K8s roles %s for namespace %s: %w", item.Name, namespace, err) } + return nil }) } @@ -201,6 +216,7 @@ func (c *k8sAPICollector) StreamRoles(ctx context.Context, ingestor RoleIngestor if err != nil { return err } + return ingestor.Complete(ctx) } @@ -218,6 +234,7 @@ func (c *k8sAPICollector) streamRoleBindingsNamespace(ctx context.Context, names if err != nil { return nil, fmt.Errorf("getting K8s rolebinding for namespace %s: %w", namespace, err) } + return entries, err })) @@ -226,11 +243,16 @@ func (c *k8sAPICollector) streamRoleBindingsNamespace(ctx context.Context, names return pager.EachListItem(ctx, opts, func(obj runtime.Object) error { _ = statsd.Incr(telemetry.MetricCollectorRoleBindingsCount, c.tags, 1) c.rl.Take() - item := obj.(*rbacv1.RoleBinding) + item, ok := obj.(*rbacv1.RoleBinding) + if !ok { + return fmt.Errorf("role binding stream type conversion error: %T", obj) + } + err := ingestor.IngestRoleBinding(ctx, item) if err != nil { return fmt.Errorf("processing K8s rolebinding %s for namespace %s: %w", item.Name, namespace, err) } + return nil }) } @@ -245,6 +267,7 @@ func (c *k8sAPICollector) StreamRoleBindings(ctx context.Context, ingestor RoleB if err != nil { return err } + return ingestor.Complete(ctx) } @@ -262,6 +285,7 @@ func (c *k8sAPICollector) streamEndpointsNamespace(ctx context.Context, namespac if err != nil { return nil, fmt.Errorf("getting K8s endpoint slices for namespace %s: %w", namespace, err) } + return entries, err })) @@ -270,11 +294,16 @@ func (c *k8sAPICollector) streamEndpointsNamespace(ctx context.Context, namespac return pager.EachListItem(ctx, opts, func(obj runtime.Object) error { _ = statsd.Incr(telemetry.MetricCollectorEndpointCount, c.tags, 1) c.rl.Take() - item := obj.(*discoveryv1.EndpointSlice) + item, ok := obj.(*discoveryv1.EndpointSlice) + if !ok { + return fmt.Errorf("endpoint stream type conversion error: %T", obj) + } + err := ingestor.IngestEndpoint(ctx, item) if err != nil { return fmt.Errorf("processing K8s endpoint slice %s for namespace %s: %w", item.Name, namespace, err) } + return nil }) } @@ -305,6 +334,7 @@ func (c *k8sAPICollector) StreamNodes(ctx context.Context, ingestor NodeIngestor if err != nil { return nil, fmt.Errorf("getting K8s nodes: %w", err) } + return entries, err })) @@ -313,16 +343,22 @@ func (c *k8sAPICollector) StreamNodes(ctx context.Context, ingestor NodeIngestor err := pager.EachListItem(ctx, opts, func(obj runtime.Object) error { _ = statsd.Incr(telemetry.MetricCollectorNodesCount, c.tags, 1) c.rl.Take() - item := obj.(*corev1.Node) + item, ok := obj.(*corev1.Node) + if !ok { + return fmt.Errorf("node stream type conversion error: %T", obj) + } + err := ingestor.IngestNode(ctx, item) if err != nil { return fmt.Errorf("processing K8s node %s: %w", item.Name, err) } + return nil }) if err != nil { return err } + return ingestor.Complete(ctx) } @@ -338,6 +374,7 @@ func (c *k8sAPICollector) StreamClusterRoles(ctx context.Context, ingestor Clust if err != nil { return nil, fmt.Errorf("getting K8s cluster roles: %w", err) } + return entries, err })) @@ -346,16 +383,22 @@ func (c *k8sAPICollector) StreamClusterRoles(ctx context.Context, ingestor Clust err := pager.EachListItem(ctx, opts, func(obj runtime.Object) error { _ = statsd.Incr(telemetry.MetricCollectorClusterRolesCount, c.tags, 1) c.rl.Take() - item := obj.(*rbacv1.ClusterRole) + item, ok := obj.(*rbacv1.ClusterRole) + if !ok { + return fmt.Errorf("cluster role stream type conversion error: %T", obj) + } + err := ingestor.IngestClusterRole(ctx, item) if err != nil { return fmt.Errorf("processing K8s cluster role %s: %w", item.Name, err) } + return nil }) if err != nil { return err } + return ingestor.Complete(ctx) } @@ -371,6 +414,7 @@ func (c *k8sAPICollector) StreamClusterRoleBindings(ctx context.Context, ingesto if err != nil { return nil, fmt.Errorf("getting K8s cluster roles: %w", err) } + return entries, err })) @@ -379,15 +423,21 @@ func (c *k8sAPICollector) StreamClusterRoleBindings(ctx context.Context, ingesto err := pager.EachListItem(ctx, opts, func(obj runtime.Object) error { _ = statsd.Incr(telemetry.MetricCollectorClusterRoleBindingsCount, c.tags, 1) c.rl.Take() - item := obj.(*rbacv1.ClusterRoleBinding) - err := ingestor.IngestClusterRoleBinding(ctx, obj.(*rbacv1.ClusterRoleBinding)) + item, ok := obj.(*rbacv1.ClusterRoleBinding) + if !ok { + return fmt.Errorf("cluster role binding stream type conversion error: %T", obj) + } + + err := ingestor.IngestClusterRoleBinding(ctx, item) if err != nil { return fmt.Errorf("processing K8s cluster role binding %s: %w", item.Name, err) } + return nil }) if err != nil { return err } + return ingestor.Complete(ctx) } diff --git a/pkg/collector/k8s_api_test.go b/pkg/collector/k8s_api_test.go index 93161280f..1257215a2 100644 --- a/pkg/collector/k8s_api_test.go +++ b/pkg/collector/k8s_api_test.go @@ -1,3 +1,4 @@ +//nolint:containedctx package collector import ( @@ -105,6 +106,7 @@ func TestNewK8sAPICollectorConfig(t *testing.T) { err = checkK8sAPICollectorConfig(cfg.Collector.Type) if (err != nil) != tt.wantErr { t.Errorf("NewK8sAPICollectorConfig() error = %v, wantErr %v", err, tt.wantErr) + return } @@ -140,14 +142,17 @@ func Test_k8sAPICollector_streamPodsNamespace(t *testing.T) { // 0 pod found test1 := func(t *testing.T) (*fake.Clientset, *mocks.PodIngestor) { + t.Helper() clientset := fake.NewSimpleClientset() m := mocks.NewPodIngestor(t) m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clientset, m } // Listing pods from all namespaces test2 := func(t *testing.T) (*fake.Clientset, *mocks.PodIngestor) { + t.Helper() clienset := fake.NewSimpleClientset( []runtime.Object{ fakePod("namespace1", "iamge1"), @@ -157,6 +162,7 @@ func Test_k8sAPICollector_streamPodsNamespace(t *testing.T) { m := mocks.NewPodIngestor(t) m.EXPECT().IngestPod(mock.Anything, mock.AnythingOfType("types.PodType")).Return(nil).Twice() m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clienset, m } @@ -221,14 +227,17 @@ func Test_k8sAPICollector_StreamRoles(t *testing.T) { // 0 roles test1 := func(t *testing.T) (*fake.Clientset, *mocks.RoleIngestor) { + t.Helper() clientset := fake.NewSimpleClientset() m := mocks.NewRoleIngestor(t) m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clientset, m } // Listing all the roles from all namespaces test2 := func(t *testing.T) (*fake.Clientset, *mocks.RoleIngestor) { + t.Helper() clienset := fake.NewSimpleClientset( []runtime.Object{ fakeRole("namespace1", "name1"), @@ -238,6 +247,7 @@ func Test_k8sAPICollector_StreamRoles(t *testing.T) { m := mocks.NewRoleIngestor(t) m.EXPECT().IngestRole(mock.Anything, mock.AnythingOfType("types.RoleType")).Return(nil).Twice() m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clienset, m } @@ -307,14 +317,17 @@ func Test_k8sAPICollector_StreamRoleBindings(t *testing.T) { // 0 role bindings found test1 := func(t *testing.T) (*fake.Clientset, *mocks.RoleBindingIngestor) { + t.Helper() clientset := fake.NewSimpleClientset() m := mocks.NewRoleBindingIngestor(t) m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clientset, m } // Listing all the roles bindings from all namespaces test2 := func(t *testing.T) (*fake.Clientset, *mocks.RoleBindingIngestor) { + t.Helper() clienset := fake.NewSimpleClientset( []runtime.Object{ fakeRoleBinding("namespace1", "name1"), @@ -324,6 +337,7 @@ func Test_k8sAPICollector_StreamRoleBindings(t *testing.T) { m := mocks.NewRoleBindingIngestor(t) m.EXPECT().IngestRoleBinding(mock.Anything, mock.AnythingOfType("types.RoleBindingType")).Return(nil).Twice() m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clienset, m } @@ -383,14 +397,17 @@ func Test_k8sAPICollector_StreamNodes(t *testing.T) { // 0 nodes found test1 := func(t *testing.T) (*fake.Clientset, *mocks.NodeIngestor) { + t.Helper() clientset := fake.NewSimpleClientset() m := mocks.NewNodeIngestor(t) m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clientset, m } // Listing all the nodes in the cluster test2 := func(t *testing.T) (*fake.Clientset, *mocks.NodeIngestor) { + t.Helper() clienset := fake.NewSimpleClientset( []runtime.Object{ fakeNode("name1", "uid1"), @@ -400,6 +417,7 @@ func Test_k8sAPICollector_StreamNodes(t *testing.T) { m := mocks.NewNodeIngestor(t) m.EXPECT().IngestNode(mock.Anything, mock.AnythingOfType("types.NodeType")).Return(nil).Twice() m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clienset, m } @@ -463,14 +481,17 @@ func Test_k8sAPICollector_StreamClusterRoles(t *testing.T) { // 0 cluster roles found test1 := func(t *testing.T) (*fake.Clientset, *mocks.ClusterRoleIngestor) { + t.Helper() clientset := fake.NewSimpleClientset() m := mocks.NewClusterRoleIngestor(t) m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clientset, m } // Listing all the cluster roles test2 := func(t *testing.T) (*fake.Clientset, *mocks.ClusterRoleIngestor) { + t.Helper() clienset := fake.NewSimpleClientset( []runtime.Object{ fakeClusterRole("name1"), @@ -480,6 +501,7 @@ func Test_k8sAPICollector_StreamClusterRoles(t *testing.T) { m := mocks.NewClusterRoleIngestor(t) m.EXPECT().IngestClusterRole(mock.Anything, mock.AnythingOfType("types.ClusterRoleType")).Return(nil).Twice() m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clienset, m } @@ -547,14 +569,17 @@ func Test_k8sAPICollector_StreamClusterRoleBindings(t *testing.T) { // 0 cluster role bindings found test1 := func(t *testing.T) (*fake.Clientset, *mocks.ClusterRoleBindingIngestor) { + t.Helper() clientset := fake.NewSimpleClientset() m := mocks.NewClusterRoleBindingIngestor(t) m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clientset, m } // Listing all the cluster roles bindings test2 := func(t *testing.T) (*fake.Clientset, *mocks.ClusterRoleBindingIngestor) { + t.Helper() clienset := fake.NewSimpleClientset( []runtime.Object{ fakeClusterRoleBinding("name1"), @@ -564,6 +589,7 @@ func Test_k8sAPICollector_StreamClusterRoleBindings(t *testing.T) { m := mocks.NewClusterRoleBindingIngestor(t) m.EXPECT().IngestClusterRoleBinding(mock.Anything, mock.AnythingOfType("types.ClusterRoleBindingType")).Return(nil).Twice() m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clienset, m } @@ -621,14 +647,17 @@ func Test_k8sAPICollector_StreamEndpoints(t *testing.T) { // 0 endpoints found test1 := func(t *testing.T) (*fake.Clientset, *mocks.EndpointIngestor) { + t.Helper() clientset := fake.NewSimpleClientset() m := mocks.NewEndpointIngestor(t) m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clientset, m } // Listing all the endpoints bindings from all namespaces test2 := func(t *testing.T) (*fake.Clientset, *mocks.EndpointIngestor) { + t.Helper() clienset := fake.NewSimpleClientset( []runtime.Object{ fakeEndpoint("namespace1", "name1"), @@ -638,6 +667,7 @@ func Test_k8sAPICollector_StreamEndpoints(t *testing.T) { m := mocks.NewEndpointIngestor(t) m.EXPECT().IngestEndpoint(mock.Anything, mock.AnythingOfType("types.EndpointType")).Return(nil).Twice() m.EXPECT().Complete(mock.Anything).Return(nil).Once() + return clienset, m } diff --git a/pkg/config/collector.go b/pkg/config/collector.go index 989d6dc0f..b855ed06c 100644 --- a/pkg/config/collector.go +++ b/pkg/config/collector.go @@ -22,7 +22,7 @@ type CollectorConfig struct { type K8SAPICollectorConfig struct { PageSize int64 `mapstructure:"page_size"` // Number of entry being retrieving by each call on the API (same for all Kubernetes entry types) PageBufferSize int32 `mapstructure:"page_buffer_size"` // Number of pages to buffer - RateLimitPerSecond int `mapstructure:"rate_limit_per_second"` // Rate limiting per second accross all calls (same for all kubernetes entry types) against the Kubernetes API + RateLimitPerSecond int `mapstructure:"rate_limit_per_second"` // Rate limiting per second across all calls (same for all kubernetes entry types) against the Kubernetes API } // FileCollectorConfig configures the file collector. diff --git a/pkg/kubehound/core/core.go b/pkg/kubehound/core/core.go index aa37c1a91..533ab61e8 100644 --- a/pkg/kubehound/core/core.go +++ b/pkg/kubehound/core/core.go @@ -50,6 +50,7 @@ func ingestData(ctx context.Context, cfg *config.KubehoundConfig, cache cache.Ca } log.I.Info("Completed data ingest and normalization") + return nil } @@ -83,6 +84,7 @@ func buildGraph(ctx context.Context, cfg *config.KubehoundConfig, storedb stored } log.I.Info("Completed graph construction") + return nil } @@ -181,5 +183,6 @@ func Launch(ctx context.Context, opts ...LaunchOption) error { } log.I.Infof("Attack graph generation complete in %s", time.Since(start)) + return nil } diff --git a/pkg/kubehound/graph/adapter/gremlin.go b/pkg/kubehound/graph/adapter/gremlin.go index bd93cc8e7..6cbd386d1 100644 --- a/pkg/kubehound/graph/adapter/gremlin.go +++ b/pkg/kubehound/graph/adapter/gremlin.go @@ -73,6 +73,7 @@ func GremlinEdgeProcessor(ctx context.Context, oic *converter.ObjectIDConverter, func DefaultEdgeTraversal() types.EdgeTraversal { return func(source *gremlin.GraphTraversalSource, inserts []any) *gremlin.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("em"). MergeE(__.Select("em")). diff --git a/pkg/kubehound/graph/builder.go b/pkg/kubehound/graph/builder.go index 78e0f83d9..bbea3f89d 100644 --- a/pkg/kubehound/graph/builder.go +++ b/pkg/kubehound/graph/builder.go @@ -60,7 +60,8 @@ func (b *Builder) buildEdge(ctx context.Context, label string, e edge.Builder, o return err } - tags := append(telemetry.BaseTags, telemetry.TagTypeJanusGraph) + tags := telemetry.BaseTags + tags = append(tags, telemetry.TagTypeJanusGraph) w, err := b.graphdb.EdgeWriter(ctx, e, graphdb.WithTags(tags)) if err != nil { return err @@ -127,6 +128,7 @@ func (b *Builder) Run(ctx context.Context) error { err := b.buildEdge(workCtx, label, e, oic, l) if err != nil { l.Errorf("building simple edge %s: %v", label, err) + return err } @@ -149,5 +151,6 @@ func (b *Builder) Run(ctx context.Context) error { } l.Info("Completed edge construction") + return nil } diff --git a/pkg/kubehound/graph/edge/base.go b/pkg/kubehound/graph/edge/base.go index c6850323e..88c8f3ec9 100644 --- a/pkg/kubehound/graph/edge/base.go +++ b/pkg/kubehound/graph/edge/base.go @@ -12,6 +12,7 @@ type BaseEdge struct { func (e *BaseEdge) Initialize(cfg *config.EdgeBuilderConfig) error { e.cfg = cfg + return nil } diff --git a/pkg/kubehound/graph/edge/container_attach.go b/pkg/kubehound/graph/edge/container_attach.go index 2c61697a5..f6f036892 100644 --- a/pkg/kubehound/graph/edge/container_attach.go +++ b/pkg/kubehound/graph/edge/container_attach.go @@ -57,7 +57,7 @@ func (e *ContainerAttach) Stream(ctx context.Context, store storedb.Provider, _ // We just need a 1:1 mapping of the container and pod to create this edge projection := bson.M{"_id": 1, "pod_id": 1} - cur, err := containers.Find(context.Background(), bson.M{}, options.Find().SetProjection(projection)) + cur, err := containers.Find(ctx, bson.M{}, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/endpoint_exploit_external.go b/pkg/kubehound/graph/edge/endpoint_exploit_external.go index e0e894ddb..4dd5e3248 100644 --- a/pkg/kubehound/graph/edge/endpoint_exploit_external.go +++ b/pkg/kubehound/graph/edge/endpoint_exploit_external.go @@ -123,7 +123,7 @@ func (e *EndpointExploitExternal) Stream(ctx context.Context, store storedb.Prov }, } - cur, err := endpoints.Aggregate(context.Background(), pipeline) + cur, err := endpoints.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/endpoint_exploit_internal.go b/pkg/kubehound/graph/edge/endpoint_exploit_internal.go index bf71dc44b..aea1b208d 100644 --- a/pkg/kubehound/graph/edge/endpoint_exploit_internal.go +++ b/pkg/kubehound/graph/edge/endpoint_exploit_internal.go @@ -59,7 +59,7 @@ func (e *EndpointExploitInternal) Stream(ctx context.Context, store storedb.Prov // We just need a 1:1 mapping of the (private) endpoint and container to create this edge projection := bson.M{"_id": 1, "container_id": 1} - cur, err := endpoints.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := endpoints.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/escape_module_load.go b/pkg/kubehound/graph/edge/escape_module_load.go index 6b32a0b27..1cc1bede2 100644 --- a/pkg/kubehound/graph/edge/escape_module_load.go +++ b/pkg/kubehound/graph/edge/escape_module_load.go @@ -29,7 +29,7 @@ func (e *EscapeModuleLoad) Name() string { return "ContainerEscapeModuleLoad" } -// Processor delegates the processing tasks to to the generic containerEscapeProcessor. +// Processor delegates the processing tasks to the generic containerEscapeProcessor. func (e *EscapeModuleLoad) Processor(ctx context.Context, oic *converter.ObjectIDConverter, entry any) (any, error) { return containerEscapeProcessor(ctx, oic, e.Label(), entry) } @@ -49,7 +49,7 @@ func (e *EscapeModuleLoad) Stream(ctx context.Context, store storedb.Provider, _ // We just need a 1:1 mapping of the node and container to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := containers.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := containers.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/escape_nsenter.go b/pkg/kubehound/graph/edge/escape_nsenter.go index bb4ff4e59..29b1f9e7f 100644 --- a/pkg/kubehound/graph/edge/escape_nsenter.go +++ b/pkg/kubehound/graph/edge/escape_nsenter.go @@ -29,7 +29,7 @@ func (e *EscapeNsenter) Name() string { return "ContainerEscapeNsenter" } -// Processor delegates the processing tasks to to the generic containerEscapeProcessor. +// Processor delegates the processing tasks to the generic containerEscapeProcessor. func (e *EscapeNsenter) Processor(ctx context.Context, oic *converter.ObjectIDConverter, entry any) (any, error) { return containerEscapeProcessor(ctx, oic, e.Label(), entry) } @@ -48,7 +48,7 @@ func (e *EscapeNsenter) Stream(ctx context.Context, store storedb.Provider, _ ca // We just need a 1:1 mapping of the node and container to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := containers.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := containers.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/escape_priv_mount.go b/pkg/kubehound/graph/edge/escape_priv_mount.go index f9268c931..55b1f6e5d 100644 --- a/pkg/kubehound/graph/edge/escape_priv_mount.go +++ b/pkg/kubehound/graph/edge/escape_priv_mount.go @@ -29,7 +29,7 @@ func (e *EscapePrivMount) Name() string { return "ContainerEscapePrivilegedMount" } -// Processor delegates the processing tasks to to the generic containerEscapeProcessor. +// Processor delegates the processing tasks to the generic containerEscapeProcessor. func (e *EscapePrivMount) Processor(ctx context.Context, oic *converter.ObjectIDConverter, entry any) (any, error) { return containerEscapeProcessor(ctx, oic, e.Label(), entry) } @@ -48,7 +48,7 @@ func (e *EscapePrivMount) Stream(ctx context.Context, store storedb.Provider, _ // We just need a 1:1 mapping of the node and container to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := containers.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := containers.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/escape_sys_ptrace.go b/pkg/kubehound/graph/edge/escape_sys_ptrace.go index 0b67e4502..50ead1a94 100644 --- a/pkg/kubehound/graph/edge/escape_sys_ptrace.go +++ b/pkg/kubehound/graph/edge/escape_sys_ptrace.go @@ -29,7 +29,7 @@ func (e *EscapeSysPtrace) Name() string { return "ContainerEscapeSysPtrace" } -// Processor delegates the processing tasks to to the generic containerEscapeProcessor. +// Processor delegates the processing tasks to the generic containerEscapeProcessor. func (e *EscapeSysPtrace) Processor(ctx context.Context, oic *converter.ObjectIDConverter, entry any) (any, error) { return containerEscapeProcessor(ctx, oic, e.Label(), entry) } @@ -50,7 +50,7 @@ func (e *EscapeSysPtrace) Stream(ctx context.Context, store storedb.Provider, _ // We just need a 1:1 mapping of the node and container to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := containers.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := containers.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/exploit_host_read.go b/pkg/kubehound/graph/edge/exploit_host_read.go index f0758029a..0bd5acfbb 100644 --- a/pkg/kubehound/graph/edge/exploit_host_read.go +++ b/pkg/kubehound/graph/edge/exploit_host_read.go @@ -16,7 +16,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -// Dangerous mounts that can be abused to read secrets granting execution on the host +// UnsafeReadMountlist represents dangerous mounts that can be abused to read secrets granting execution on the host var UnsafeReadMountlist = []primitive.Regex{ {Pattern: "^/$"}, {Pattern: "^/home$"}, @@ -73,7 +73,7 @@ func (e *ExploitHostRead) Stream(ctx context.Context, store storedb.Provider, _ // We just need a 1:1 mapping of the node and container to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := volumes.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := volumes.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/exploit_host_traverse_token.go b/pkg/kubehound/graph/edge/exploit_host_traverse_token.go index a9a2c8d76..4a99d0ef2 100644 --- a/pkg/kubehound/graph/edge/exploit_host_traverse_token.go +++ b/pkg/kubehound/graph/edge/exploit_host_traverse_token.go @@ -15,7 +15,8 @@ import ( "go.mongodb.org/mongo-driver/bson/primitive" ) -// Mounts that grant access to the pod service account tokens that reside in /var/lib/kubelet/pods//volumes/kubernetes.io~projected// +// TokenMountList represent ounts that grant access to the pod service account tokens that reside +// in /var/lib/kubelet/pods//volumes/kubernetes.io~projected// var TokenMountList = []primitive.Regex{ {Pattern: "^/$"}, {Pattern: "^/var$"}, @@ -113,7 +114,7 @@ func (e *ExploitHostTraverse) Stream(ctx context.Context, store storedb.Provider }, } - cur, err := volumes.Aggregate(context.Background(), pipeline) + cur, err := volumes.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/exploit_host_write.go b/pkg/kubehound/graph/edge/exploit_host_write.go index 09c2be0db..5bd524a9e 100644 --- a/pkg/kubehound/graph/edge/exploit_host_write.go +++ b/pkg/kubehound/graph/edge/exploit_host_write.go @@ -16,7 +16,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -// Common safe mounts that are deemed not exploitable +// SafeWriteMountList represent common safe mounts that are deemed not exploitable var SafeWriteMountList = []primitive.Regex{ {Pattern: "^/var/run/datadog-agent$"}, {Pattern: "^/etc/datadog-agent$"}, @@ -29,7 +29,6 @@ var SafeWriteMountList = []primitive.Regex{ {Pattern: "^/tmp?.*"}, {Pattern: "^/var/run/.*"}, {Pattern: "^/mnt/.*"}, - {Pattern: "^/mnt/.*"}, {Pattern: "^/var/lib/datadog-agent/.*"}, {Pattern: "^/var/tmp/datadog-agent/.*"}, {Pattern: "^/run/udev"}, @@ -90,7 +89,7 @@ func (e *ExploitHostWrite) Stream(ctx context.Context, store storedb.Provider, _ // We just need a 1:1 mapping of the node and container to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := volumes.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := volumes.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/identity_assume_container.go b/pkg/kubehound/graph/edge/identity_assume_container.go index c0380c93e..9d3afc24b 100644 --- a/pkg/kubehound/graph/edge/identity_assume_container.go +++ b/pkg/kubehound/graph/edge/identity_assume_container.go @@ -72,7 +72,7 @@ func (e *IdentityAssumeContainer) Stream(ctx context.Context, store storedb.Prov }, }, } - cur, err := containers.Aggregate(context.Background(), pipeline) + cur, err := containers.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/identity_assume_node.go b/pkg/kubehound/graph/edge/identity_assume_node.go index 5a93abd6f..d1937fb49 100644 --- a/pkg/kubehound/graph/edge/identity_assume_node.go +++ b/pkg/kubehound/graph/edge/identity_assume_node.go @@ -57,7 +57,7 @@ func (e *IdentityAssumeNode) Stream(ctx context.Context, store storedb.Provider, // If the default node group has no permissions, we do not set a user id filter := bson.M{"user_id": bson.M{"$ne": primitive.NilObjectID}} - cur, err := nodes.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := nodes.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/permission_discover.go b/pkg/kubehound/graph/edge/permission_discover.go index 670585692..ad85c92df 100644 --- a/pkg/kubehound/graph/edge/permission_discover.go +++ b/pkg/kubehound/graph/edge/permission_discover.go @@ -131,7 +131,7 @@ func (e *PermissionDiscover) Stream(ctx context.Context, store storedb.Provider, }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/pod_attach.go b/pkg/kubehound/graph/edge/pod_attach.go index 9345aed88..d17cd1da8 100644 --- a/pkg/kubehound/graph/edge/pod_attach.go +++ b/pkg/kubehound/graph/edge/pod_attach.go @@ -53,7 +53,7 @@ func (e *PodAttach) Stream(ctx context.Context, store storedb.Provider, _ cache. // We just need a 1:1 mapping of the node and pod to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := pods.Find(context.Background(), bson.M{}, options.Find().SetProjection(projection)) + cur, err := pods.Find(ctx, bson.M{}, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/pod_create.go b/pkg/kubehound/graph/edge/pod_create.go index 7d598fc38..5347128e8 100644 --- a/pkg/kubehound/graph/edge/pod_create.go +++ b/pkg/kubehound/graph/edge/pod_create.go @@ -72,6 +72,7 @@ func (e *PodCreate) Traversal() types.EdgeTraversal { if e.cfg.LargeClusterOptimizations { // In large clusters this can explode the number of edges and we can safely assume this is a critical issue g. + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold(). As("rpc"). @@ -142,7 +143,7 @@ func (e *PodCreate) Stream(ctx context.Context, store storedb.Provider, _ cache. }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/pod_exec.go b/pkg/kubehound/graph/edge/pod_exec.go index ce1f8dc73..d7ba29c59 100644 --- a/pkg/kubehound/graph/edge/pod_exec.go +++ b/pkg/kubehound/graph/edge/pod_exec.go @@ -72,6 +72,7 @@ func (e *PodExec) Traversal() types.EdgeTraversal { if e.cfg.LargeClusterOptimizations { // In large clusters this can explode the number of edges and we can safely assume this is a critical issue g. + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold(). As("rpe"). @@ -137,7 +138,7 @@ func (e *PodExec) Stream(ctx context.Context, store storedb.Provider, _ cache.Ca }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/pod_exec_namespace.go b/pkg/kubehound/graph/edge/pod_exec_namespace.go index 1d0f1e083..48e8066db 100644 --- a/pkg/kubehound/graph/edge/pod_exec_namespace.go +++ b/pkg/kubehound/graph/edge/pod_exec_namespace.go @@ -113,7 +113,7 @@ func (e *PodExecNamespace) Stream(ctx context.Context, store storedb.Provider, _ }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/pod_patch.go b/pkg/kubehound/graph/edge/pod_patch.go index 60f21d354..4f4429113 100644 --- a/pkg/kubehound/graph/edge/pod_patch.go +++ b/pkg/kubehound/graph/edge/pod_patch.go @@ -72,6 +72,7 @@ func (e *PodPatch) Traversal() types.EdgeTraversal { if e.cfg.LargeClusterOptimizations { // In large clusters this can explode the number of edges and we can safely assume this is a critical issue g. + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold(). As("rpp"). @@ -144,7 +145,7 @@ func (e *PodPatch) Stream(ctx context.Context, store storedb.Provider, _ cache.C }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/pod_patch_namespace.go b/pkg/kubehound/graph/edge/pod_patch_namespace.go index ab798b433..f59a5bf52 100644 --- a/pkg/kubehound/graph/edge/pod_patch_namespace.go +++ b/pkg/kubehound/graph/edge/pod_patch_namespace.go @@ -120,7 +120,7 @@ func (e *PodPatchNamespace) Stream(ctx context.Context, store storedb.Provider, }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/share_ps_namespace.go b/pkg/kubehound/graph/edge/share_ps_namespace.go index 6e7e5a9ff..8a73ec541 100644 --- a/pkg/kubehound/graph/edge/share_ps_namespace.go +++ b/pkg/kubehound/graph/edge/share_ps_namespace.go @@ -38,7 +38,7 @@ func (e *SharePSNamespace) Name() string { return "SharePSNamespace" } -// Processor delegates the processing tasks to to the generic containerEscapeProcessor. +// Processor delegates the processing tasks to the generic containerEscapeProcessor. func (e *SharePSNamespace) Processor(ctx context.Context, oic *converter.ObjectIDConverter, entry any) (any, error) { typed, ok := entry.(*sharedPsNamespaceGroupPair) if !ok { @@ -52,32 +52,30 @@ func (e *SharePSNamespace) Stream(ctx context.Context, store storedb.Provider, _ callback types.ProcessEntryCallback, complete types.CompleteQueryCallback) error { coll := adapter.MongoDB(store).Collection(collections.PodName) - pipeline := bson.A{ - bson.D{{"$match", bson.D{{"k8.spec.shareprocessnamespace", true}}}}, - bson.D{ - {"$lookup", - bson.D{ - {"from", "containers"}, - {"localField", "_id"}, - {"foreignField", "pod_id"}, - {"as", "containers_with_shared_ns"}, - }, + pipeline := []bson.M{ + { + "$match": bson.M{ + "k8.spec.shareprocessnamespace": true, }, }, - bson.D{ - {"$project", - bson.D{ - {"_id", 1}, - {"containers_with_shared_ns", bson.D{{"_id", 1}}}, - }, + { + "$lookup": bson.M{ + "as": "containers_with_shared_ns", + "from": "containers", + "localField": "_id", + "foreignField": "pod_id", }, }, - bson.D{ - {"$project", - bson.D{ - {"_id", 0}, - {"container_ids", "$containers_with_shared_ns._id"}, - }, + { + "$project": bson.M{ + "_id": 1, + "containers_with_shared_ns": bson.M{"_id": 1}, + }, + }, + { + "$project": bson.M{ + "_id": 0, + "container_ids": "$containers_with_shared_ns._id", }, }, } diff --git a/pkg/kubehound/graph/edge/token_bruteforce.go b/pkg/kubehound/graph/edge/token_bruteforce.go index 0d5b54a83..0b1b6efea 100644 --- a/pkg/kubehound/graph/edge/token_bruteforce.go +++ b/pkg/kubehound/graph/edge/token_bruteforce.go @@ -126,7 +126,7 @@ func (e *TokenBruteforce) Stream(ctx context.Context, store storedb.Provider, _ }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/token_bruteforce_namespace.go b/pkg/kubehound/graph/edge/token_bruteforce_namespace.go index f922372ba..9f38e22ef 100644 --- a/pkg/kubehound/graph/edge/token_bruteforce_namespace.go +++ b/pkg/kubehound/graph/edge/token_bruteforce_namespace.go @@ -123,7 +123,7 @@ func (e *TokenBruteforceNamespace) Stream(ctx context.Context, store storedb.Pro }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/token_list.go b/pkg/kubehound/graph/edge/token_list.go index 23e53232e..b486f012c 100644 --- a/pkg/kubehound/graph/edge/token_list.go +++ b/pkg/kubehound/graph/edge/token_list.go @@ -126,7 +126,7 @@ func (e *TokenList) Stream(ctx context.Context, store storedb.Provider, _ cache. }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/token_list_namespace.go b/pkg/kubehound/graph/edge/token_list_namespace.go index 50a0da252..0e398eb90 100644 --- a/pkg/kubehound/graph/edge/token_list_namespace.go +++ b/pkg/kubehound/graph/edge/token_list_namespace.go @@ -115,7 +115,7 @@ func (e *TokenListNamespace) Stream(ctx context.Context, store storedb.Provider, }, } - cur, err := permissionSets.Aggregate(context.Background(), pipeline) + cur, err := permissionSets.Aggregate(ctx, pipeline) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/token_steal.go b/pkg/kubehound/graph/edge/token_steal.go index abd09b9a2..96d3c6bf6 100644 --- a/pkg/kubehound/graph/edge/token_steal.go +++ b/pkg/kubehound/graph/edge/token_steal.go @@ -59,7 +59,7 @@ func (e *TokenSteal) Stream(ctx context.Context, sdb storedb.Provider, c cache.C // We just need a 1:1 mapping of the volume and projected service account to create this edge projection := bson.M{"_id": 1, "projected_id": 1} - cur, err := volumes.Find(context.Background(), filter, options.Find().SetProjection(projection)) + cur, err := volumes.Find(ctx, filter, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/volume_access.go b/pkg/kubehound/graph/edge/volume_access.go index 1be1c1ee9..d2745d490 100644 --- a/pkg/kubehound/graph/edge/volume_access.go +++ b/pkg/kubehound/graph/edge/volume_access.go @@ -53,7 +53,7 @@ func (e *VolumeAccess) Stream(ctx context.Context, store storedb.Provider, _ cac // We just need a 1:1 mapping of the node and volume to create this edge projection := bson.M{"_id": 1, "node_id": 1} - cur, err := volumes.Find(context.Background(), bson.M{}, options.Find().SetProjection(projection)) + cur, err := volumes.Find(ctx, bson.M{}, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/edge/volume_discover.go b/pkg/kubehound/graph/edge/volume_discover.go index 4e18743d5..a52611782 100644 --- a/pkg/kubehound/graph/edge/volume_discover.go +++ b/pkg/kubehound/graph/edge/volume_discover.go @@ -53,7 +53,7 @@ func (e *VolumeDiscover) Stream(ctx context.Context, store storedb.Provider, _ c // We just need a 1:1 mapping of the container and volume to create this edge projection := bson.M{"_id": 1, "container_id": 1} - cur, err := volumes.Find(context.Background(), bson.M{}, options.Find().SetProjection(projection)) + cur, err := volumes.Find(ctx, bson.M{}, options.Find().SetProjection(projection)) if err != nil { return err } diff --git a/pkg/kubehound/graph/types/data.go b/pkg/kubehound/graph/types/data.go index 34bab4c30..05a58d764 100644 --- a/pkg/kubehound/graph/types/data.go +++ b/pkg/kubehound/graph/types/data.go @@ -7,8 +7,8 @@ import ( // An object to encapsulate the raw data required to create one or more edges. For example a pod id and a node id. type DataContainer any -// ProcessEntryCallback is a callback provided by the the edge builder that will convert edge query results into graph database writes. +// ProcessEntryCallback is a callback provided by the edge builder that will convert edge query results into graph database writes. type ProcessEntryCallback func(ctx context.Context, model DataContainer) error -// CompleteQueryCallback is a callback provided by the the edge builder that will flush any outstanding graph database writes. +// CompleteQueryCallback is a callback provided by the edge builder that will flush any outstanding graph database writes. type CompleteQueryCallback func(ctx context.Context) error diff --git a/pkg/kubehound/graph/vertex/base_vertex.go b/pkg/kubehound/graph/vertex/base_vertex.go index be21bc084..53ce246b1 100644 --- a/pkg/kubehound/graph/vertex/base_vertex.go +++ b/pkg/kubehound/graph/vertex/base_vertex.go @@ -10,6 +10,7 @@ type BaseVertex struct { func (v *BaseVertex) Initialize(cfg *config.VertexBuilderConfig) error { v.cfg = cfg + return nil } diff --git a/pkg/kubehound/graph/vertex/container.go b/pkg/kubehound/graph/vertex/container.go index 6fa2f18e0..8b92d48b6 100644 --- a/pkg/kubehound/graph/vertex/container.go +++ b/pkg/kubehound/graph/vertex/container.go @@ -30,6 +30,7 @@ func (v *Container) Processor(ctx context.Context, entry any) (any, error) { func (v *Container) Traversal() types.VertexTraversal { return func(source *gremlingo.GraphTraversalSource, inserts []any) *gremlingo.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("containers"). AddV(v.Label()).As("containerVtx"). diff --git a/pkg/kubehound/graph/vertex/container_test.go b/pkg/kubehound/graph/vertex/container_test.go index 307fc8f6a..7e9096581 100644 --- a/pkg/kubehound/graph/vertex/container_test.go +++ b/pkg/kubehound/graph/vertex/container_test.go @@ -46,6 +46,7 @@ func TestContainer_Traversal(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() v := Container{} g := gremlingo.GraphTraversalSource{} diff --git a/pkg/kubehound/graph/vertex/endpoint.go b/pkg/kubehound/graph/vertex/endpoint.go index da38f6cbd..1454fb284 100644 --- a/pkg/kubehound/graph/vertex/endpoint.go +++ b/pkg/kubehound/graph/vertex/endpoint.go @@ -30,6 +30,7 @@ func (v *Endpoint) Processor(ctx context.Context, entry any) (any, error) { func (v *Endpoint) Traversal() types.VertexTraversal { return func(source *gremlin.GraphTraversalSource, inserts []any) *gremlin.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("endpoints"). AddV(v.Label()).As("epVtx"). diff --git a/pkg/kubehound/graph/vertex/identity.go b/pkg/kubehound/graph/vertex/identity.go index 21066f17a..db7355980 100644 --- a/pkg/kubehound/graph/vertex/identity.go +++ b/pkg/kubehound/graph/vertex/identity.go @@ -30,6 +30,7 @@ func (v *Identity) Processor(ctx context.Context, entry any) (any, error) { func (v *Identity) Traversal() types.VertexTraversal { return func(source *gremlin.GraphTraversalSource, inserts []any) *gremlin.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("ids"). AddV(v.Label()).As("idVtx"). diff --git a/pkg/kubehound/graph/vertex/identity_test.go b/pkg/kubehound/graph/vertex/identity_test.go index 432526e4a..03fd664c6 100644 --- a/pkg/kubehound/graph/vertex/identity_test.go +++ b/pkg/kubehound/graph/vertex/identity_test.go @@ -35,6 +35,7 @@ func TestIdentity_Traversal(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() v := Identity{} g := gremlingo.GraphTraversalSource{} diff --git a/pkg/kubehound/graph/vertex/node.go b/pkg/kubehound/graph/vertex/node.go index 5082d40be..59f71fafc 100644 --- a/pkg/kubehound/graph/vertex/node.go +++ b/pkg/kubehound/graph/vertex/node.go @@ -30,6 +30,7 @@ func (v *Node) Processor(ctx context.Context, entry any) (any, error) { func (v *Node) Traversal() types.VertexTraversal { return func(source *gremlin.GraphTraversalSource, inserts []any) *gremlin.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("nodes"). AddV(v.Label()).As("nodeVtx"). diff --git a/pkg/kubehound/graph/vertex/node_test.go b/pkg/kubehound/graph/vertex/node_test.go index 2ebf8debb..2cecd75af 100644 --- a/pkg/kubehound/graph/vertex/node_test.go +++ b/pkg/kubehound/graph/vertex/node_test.go @@ -36,6 +36,7 @@ func TestNode_Traversal(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() v := Node{} g := gremlingo.GraphTraversalSource{} diff --git a/pkg/kubehound/graph/vertex/permission_set.go b/pkg/kubehound/graph/vertex/permission_set.go index d5f11ee78..4b719adc2 100644 --- a/pkg/kubehound/graph/vertex/permission_set.go +++ b/pkg/kubehound/graph/vertex/permission_set.go @@ -35,6 +35,7 @@ func (v *PermissionSet) Processor(ctx context.Context, entry any) (any, error) { func (v *PermissionSet) Traversal() types.VertexTraversal { return func(source *gremlin.GraphTraversalSource, inserts []any) *gremlin.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("roles"). AddV(v.Label()).As("roleVtx"). diff --git a/pkg/kubehound/graph/vertex/permission_set_test.go b/pkg/kubehound/graph/vertex/permission_set_test.go index f44b7722b..e29200781 100644 --- a/pkg/kubehound/graph/vertex/permission_set_test.go +++ b/pkg/kubehound/graph/vertex/permission_set_test.go @@ -35,6 +35,7 @@ func TestPermissionSet_Traversal(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() v := PermissionSet{} g := gremlingo.GraphTraversalSource{} diff --git a/pkg/kubehound/graph/vertex/pod.go b/pkg/kubehound/graph/vertex/pod.go index 829f154fa..61a4c2892 100644 --- a/pkg/kubehound/graph/vertex/pod.go +++ b/pkg/kubehound/graph/vertex/pod.go @@ -30,6 +30,7 @@ func (v *Pod) Processor(ctx context.Context, entry any) (any, error) { func (v *Pod) Traversal() types.VertexTraversal { return func(source *gremlin.GraphTraversalSource, inserts []any) *gremlin.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("pods"). AddV(v.Label()).As("podVtx"). diff --git a/pkg/kubehound/graph/vertex/pod_test.go b/pkg/kubehound/graph/vertex/pod_test.go index 3bd61f953..fa22a9832 100644 --- a/pkg/kubehound/graph/vertex/pod_test.go +++ b/pkg/kubehound/graph/vertex/pod_test.go @@ -39,6 +39,7 @@ func TestPod_Traversal(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() v := Pod{} g := gremlingo.GraphTraversalSource{} diff --git a/pkg/kubehound/graph/vertex/volume.go b/pkg/kubehound/graph/vertex/volume.go index 11926111d..333177add 100644 --- a/pkg/kubehound/graph/vertex/volume.go +++ b/pkg/kubehound/graph/vertex/volume.go @@ -30,6 +30,7 @@ func (v *Volume) Processor(ctx context.Context, entry any) (any, error) { func (v *Volume) Traversal() types.VertexTraversal { return func(source *gremlin.GraphTraversalSource, inserts []any) *gremlin.GraphTraversal { g := source.GetGraphTraversal(). + //nolint:asasalint // required due to constraints in the gremlin API Inject(inserts). Unfold().As("volumes"). AddV(v.Label()).As("volVtx"). diff --git a/pkg/kubehound/graph/vertex/volume_test.go b/pkg/kubehound/graph/vertex/volume_test.go index b72daf504..fe971ab54 100644 --- a/pkg/kubehound/graph/vertex/volume_test.go +++ b/pkg/kubehound/graph/vertex/volume_test.go @@ -34,6 +34,7 @@ func TestVolume_Traversal(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() v := Volume{} g := gremlingo.GraphTraversalSource{} diff --git a/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest.go b/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest.go index 6af4c1c02..c63504a4f 100644 --- a/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest.go +++ b/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "errors" "github.com/DataDog/KubeHound/pkg/globals/types" "github.com/DataDog/KubeHound/pkg/kubehound/graph/vertex" @@ -74,13 +75,14 @@ func (i *ClusterRoleBindingIngest) processSubject(ctx context.Context, subj *sto ck := cachekey.Identity(sid.Name, sid.Namespace) err = i.r.writeCache(ctx, ck, sid.Id.Hex()) if err != nil { - switch e := err.(type) { - case *cache.OverwriteError: + var errOverwrite *cache.OverwriteError + if errors.As(err, &errOverwrite) { log.Trace(ctx).Debugf("identity cache entry %#v already exists, skipping inserts", ck) + return nil - default: - return e } + + return err } // Async write identity to store @@ -148,8 +150,9 @@ func (i *ClusterRoleBindingIngest) IngestClusterRoleBinding(ctx context.Context, // Normalize K8s cluster role binding to store object format o, err := i.r.storeConvert.ClusterRoleBinding(ctx, crb) if err != nil { - if err == converter.ErrDanglingRoleBinding { + if errors.Is(err, converter.ErrDanglingRoleBinding) { log.Trace(ctx).Warnf("Cluster role binding dropped: %s: %s", err.Error(), crb.Name) + return nil } @@ -173,9 +176,12 @@ func (i *ClusterRoleBindingIngest) IngestClusterRoleBinding(ctx context.Context, // Create permission from Rolebinding entry err = i.createPermissionSet(ctx, o) - switch err { - case nil: - case converter.ErrRoleCacheMiss, converter.ErrRoleBindProperties: + switch { + case err == nil: + // NOP + case errors.Is(err, converter.ErrRoleCacheMiss): + fallthrough + case errors.Is(err, converter.ErrRoleBindProperties): log.Trace(ctx).Warnf("Permission set dropped (%s::%s): %v", crb.Namespace, crb.Name, err) default: return err diff --git a/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest_test.go b/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest_test.go index 6701ca7ae..945391924 100644 --- a/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest_test.go +++ b/pkg/kubehound/ingestor/pipeline/cluster_role_binding_ingest_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package pipeline import ( @@ -21,6 +22,8 @@ import ( ) func TestClusterRoleBindingIngest_Pipeline(t *testing.T) { + t.Parallel() + crbi := &ClusterRoleBindingIngest{} ctx := context.Background() @@ -72,10 +75,11 @@ func TestClusterRoleBindingIngest_Pipeline(t *testing.T) { // Store setup - identities isw := storedb.NewAsyncWriter(t) identities := collections.Identity{} - storeId := store.ObjectID() + storeID := store.ObjectID() isw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Identity")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.Identity).Id = storeId + i.(*store.Identity).Id = storeID + return nil }).Once() isw.EXPECT().Flush(ctx).Return(nil) @@ -85,10 +89,11 @@ func TestClusterRoleBindingIngest_Pipeline(t *testing.T) { // Store setup - permissionsets pssw := storedb.NewAsyncWriter(t) psbs := collections.PermissionSet{} - psStoreId := store.ObjectID() + psStoreID := store.ObjectID() pssw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.PermissionSet")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.PermissionSet).Id = psStoreId + i.(*store.PermissionSet).Id = psStoreID + return nil }).Once() pssw.EXPECT().Flush(ctx).Return(nil) @@ -101,7 +106,7 @@ func TestClusterRoleBindingIngest_Pipeline(t *testing.T) { "isNamespaced": false, "name": "app-monitors-cluster", "namespace": "", - "storeID": storeId.Hex(), + "storeID": storeID.Hex(), "type": "ServiceAccount", "team": "test-team", "app": "test-app", @@ -121,7 +126,7 @@ func TestClusterRoleBindingIngest_Pipeline(t *testing.T) { "namespace": "", "role": "test-reader", "roleBinding": "app-monitors-read", - "storeID": psStoreId.Hex(), + "storeID": psStoreID.Hex(), "team": "test-team", "app": "test-app", "service": "test-service", diff --git a/pkg/kubehound/ingestor/pipeline/cluster_role_ingest.go b/pkg/kubehound/ingestor/pipeline/cluster_role_ingest.go index b8a67cabd..d2905ecd0 100644 --- a/pkg/kubehound/ingestor/pipeline/cluster_role_ingest.go +++ b/pkg/kubehound/ingestor/pipeline/cluster_role_ingest.go @@ -59,11 +59,7 @@ func (i *ClusterRoleIngest) IngestClusterRole(ctx context.Context, role types.Cl } // Async write to cache - if err := i.r.writeCache(ctx, cachekey.Role(o.Name, o.Namespace), *o); err != nil { - return err - } - - return nil + return i.r.writeCache(ctx, cachekey.Role(o.Name, o.Namespace), *o) } // completeCallback is invoked by the collector when all cluster roles have been streamed. diff --git a/pkg/kubehound/ingestor/pipeline/cluster_role_ingest_test.go b/pkg/kubehound/ingestor/pipeline/cluster_role_ingest_test.go index 8576323fd..e542e463d 100644 --- a/pkg/kubehound/ingestor/pipeline/cluster_role_ingest_test.go +++ b/pkg/kubehound/ingestor/pipeline/cluster_role_ingest_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package pipeline import ( @@ -18,6 +19,8 @@ import ( ) func TestClusterRoleIngest_Pipeline(t *testing.T) { + t.Parallel() + cri := &ClusterRoleIngest{} ctx := context.Background() @@ -48,10 +51,11 @@ func TestClusterRoleIngest_Pipeline(t *testing.T) { sdb := storedb.NewProvider(t) sw := storedb.NewAsyncWriter(t) roles := collections.Role{} - storeId := store.ObjectID() + storeID := store.ObjectID() sw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Role")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.Role).Id = storeId + i.(*store.Role).Id = storeID + return nil }).Once() sw.EXPECT().Flush(ctx).Return(nil) diff --git a/pkg/kubehound/ingestor/pipeline/endpoint_ingest.go b/pkg/kubehound/ingestor/pipeline/endpoint_ingest.go index d5b6736e8..208a0f1f3 100644 --- a/pkg/kubehound/ingestor/pipeline/endpoint_ingest.go +++ b/pkg/kubehound/ingestor/pipeline/endpoint_ingest.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "errors" "github.com/DataDog/KubeHound/pkg/globals/types" "github.com/DataDog/KubeHound/pkg/kubehound/graph/vertex" @@ -60,8 +61,9 @@ func (i *EndpointIngest) IngestEndpoint(ctx context.Context, eps types.EndpointT // Normalize endpoint to store object format o, err := i.r.storeConvert.Endpoint(ctx, addr, port, eps) if err != nil { - if err == converter.ErrEndpointTarget { + if errors.Is(err, converter.ErrEndpointTarget) { log.Trace(ctx).Warnf("Endpoint dropped: %s: %s", err.Error(), addr.TargetRef) + return nil } @@ -91,7 +93,6 @@ func (i *EndpointIngest) IngestEndpoint(ctx context.Context, eps types.EndpointT return err } } - } return nil diff --git a/pkg/kubehound/ingestor/pipeline/endpoint_ingest_test.go b/pkg/kubehound/ingestor/pipeline/endpoint_ingest_test.go index 1873df170..807aaf83c 100644 --- a/pkg/kubehound/ingestor/pipeline/endpoint_ingest_test.go +++ b/pkg/kubehound/ingestor/pipeline/endpoint_ingest_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package pipeline import ( @@ -19,6 +20,8 @@ import ( ) func TestEndpointSlice_Pipeline(t *testing.T) { + t.Parallel() + ei := &EndpointIngest{} ctx := context.Background() @@ -49,10 +52,11 @@ func TestEndpointSlice_Pipeline(t *testing.T) { sdb := storedb.NewProvider(t) sw := storedb.NewAsyncWriter(t) endpoints := collections.Endpoint{} - storeId := store.ObjectID() + storeID := store.ObjectID() sw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Endpoint")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.Endpoint).Id = storeId + i.(*store.Endpoint).Id = storeID + return nil }).Times(2) @@ -76,7 +80,7 @@ func TestEndpointSlice_Pipeline(t *testing.T) { "service": "cassandra", "serviceDns": "cassandra-temporal-dev.cassandra-temporal-dev", "serviceEndpoint": "cassandra-temporal-dev", - "storeID": storeId.Hex(), + "storeID": storeID.Hex(), "team": "workflow-engine", } vtx2 := map[string]interface{}{ @@ -94,7 +98,7 @@ func TestEndpointSlice_Pipeline(t *testing.T) { "service": "cassandra", "serviceDns": "cassandra-temporal-dev.cassandra-temporal-dev", "serviceEndpoint": "cassandra-temporal-dev", - "storeID": storeId.Hex(), + "storeID": storeID.Hex(), "team": "workflow-engine", } diff --git a/pkg/kubehound/ingestor/pipeline/group.go b/pkg/kubehound/ingestor/pipeline/group.go index 04b931e71..2fcc22e47 100644 --- a/pkg/kubehound/ingestor/pipeline/group.go +++ b/pkg/kubehound/ingestor/pipeline/group.go @@ -28,11 +28,12 @@ func (g *Group) Run(outer context.Context, deps *Dependencies) error { for _, ingest := range g.Ingests { i := ingest - // Don't spin off a goroutine until we initalize successfully + // Don't spin off a goroutine until we initialize successfully err := i.Initialize(ctx, deps) if err != nil { l.Errorf("%s initialization: %v", i.Name(), err) cancelGroup(err) + break } @@ -59,5 +60,6 @@ func (g *Group) Run(outer context.Context, deps *Dependencies) error { } l.Infof("Completed %s ingest", g.Name) + return nil } diff --git a/pkg/kubehound/ingestor/pipeline/ingest_resources.go b/pkg/kubehound/ingestor/pipeline/ingest_resources.go index ff7de9a0c..46809d1aa 100644 --- a/pkg/kubehound/ingestor/pipeline/ingest_resources.go +++ b/pkg/kubehound/ingestor/pipeline/ingest_resources.go @@ -13,6 +13,7 @@ import ( "github.com/DataDog/KubeHound/pkg/kubehound/storage/storedb" "github.com/DataDog/KubeHound/pkg/kubehound/store/collections" "github.com/DataDog/KubeHound/pkg/telemetry" + "github.com/DataDog/KubeHound/pkg/telemetry/log" "github.com/hashicorp/go-multierror" ) @@ -62,6 +63,7 @@ func WithCacheWriter(opts ...cache.WriterOption) IngestResourceOption { func WithCacheReader() IngestResourceOption { return func(ctx context.Context, rOpts *resourceOptions, deps *Dependencies) error { rOpts.cacheReader = deps.Cache + return nil } } @@ -70,6 +72,7 @@ func WithCacheReader() IngestResourceOption { func WithConverterCache() IngestResourceOption { return func(_ context.Context, rOpts *resourceOptions, deps *Dependencies) error { rOpts.storeConvert = converter.NewStoreWithCache(deps.Cache) + return nil } } @@ -78,7 +81,8 @@ func WithConverterCache() IngestResourceOption { // To access the writer use the storeWriter(c collections.Collection) function. func WithStoreWriter[T collections.Collection](c T) IngestResourceOption { return func(ctx context.Context, rOpts *resourceOptions, deps *Dependencies) error { - tags := append(telemetry.BaseTags, telemetry.TagTypeMongodb) + tags := telemetry.BaseTags + tags = append(tags, telemetry.TagTypeMongodb) w, err := deps.StoreDB.BulkWriter(ctx, c, storedb.WithTags(tags)) if err != nil { @@ -116,6 +120,7 @@ func WithGraphWriter(v vertex.Builder) IngestResourceOption { }) rOpts.flush = append(rOpts.flush, w.Flush) + return nil } } @@ -172,7 +177,10 @@ func CreateResources(ctx context.Context, deps *Dependencies, opts ...IngestReso // Do a cleanup of whatever has been registered in the case of a partial success defer func() { if err != nil { - i.cleanupAll(ctx) + err := i.cleanupAll(ctx) + if err != nil { + log.Trace(ctx).Errorf("Ingestor cleanup failure: %v", err) + } } }() diff --git a/pkg/kubehound/ingestor/pipeline/ingest_resources_test.go b/pkg/kubehound/ingestor/pipeline/ingest_resources_test.go index 855cf92f2..248411ee9 100644 --- a/pkg/kubehound/ingestor/pipeline/ingest_resources_test.go +++ b/pkg/kubehound/ingestor/pipeline/ingest_resources_test.go @@ -71,7 +71,6 @@ func TestIngestResources_Initializer(t *testing.T) { assert.Equal(t, 0, len(oi.flush)) // Test cache writer mechanics - oi = &IngestResources{} cw := cache.NewAsyncWriter(t) cw.EXPECT().Flush(ctx).Return(nil) cw.EXPECT().Close(ctx).Return(nil) @@ -85,7 +84,6 @@ func TestIngestResources_Initializer(t *testing.T) { assert.NoError(t, oi.cleanupAll(ctx)) // Test store writer mechanics - oi = &IngestResources{} sw := storedb.NewAsyncWriter(t) sw.EXPECT().Flush(ctx).Return(nil) sw.EXPECT().Close(ctx).Return(nil) @@ -100,7 +98,6 @@ func TestIngestResources_Initializer(t *testing.T) { assert.NoError(t, oi.cleanupAll(ctx)) // Test graph writer mechanics - oi = &IngestResources{} gw := graphdb.NewAsyncVertexWriter(t) gw.EXPECT().Flush(ctx).Return(nil) gw.EXPECT().Close(ctx).Return(nil) @@ -119,8 +116,6 @@ func TestIngestResources_FlushErrors(t *testing.T) { t.Parallel() ctx := context.Background() - oi := &IngestResources{} - client := collector.NewCollectorClient(t) c := cache.NewCacheProvider(t) gdb := graphdb.NewProvider(t) @@ -153,8 +148,6 @@ func TestIngestResources_CloseErrors(t *testing.T) { t.Parallel() ctx := context.Background() - oi := &IngestResources{} - client := collector.NewCollectorClient(t) c := cache.NewCacheProvider(t) gdb := graphdb.NewProvider(t) @@ -192,8 +185,6 @@ func TestIngestResources_CloseIdempotent(t *testing.T) { t.Parallel() ctx := context.Background() - oi := &IngestResources{} - client := collector.NewCollectorClient(t) c := cache.NewCacheProvider(t) gdb := graphdb.NewProvider(t) diff --git a/pkg/kubehound/ingestor/pipeline/node_ingest.go b/pkg/kubehound/ingestor/pipeline/node_ingest.go index f76654f01..499947d6d 100644 --- a/pkg/kubehound/ingestor/pipeline/node_ingest.go +++ b/pkg/kubehound/ingestor/pipeline/node_ingest.go @@ -73,11 +73,7 @@ func (i *NodeIngest) IngestNode(ctx context.Context, node types.NodeType) error } // Aysnc write to graph - if err := i.r.writeVertex(ctx, i.vertex, insert); err != nil { - return err - } - - return nil + return i.r.writeVertex(ctx, i.vertex, insert) } // completeCallback is invoked by the collector when all nodes have been streamed. diff --git a/pkg/kubehound/ingestor/pipeline/node_ingest_test.go b/pkg/kubehound/ingestor/pipeline/node_ingest_test.go index 48a9cfc30..3ffe9d8fc 100644 --- a/pkg/kubehound/ingestor/pipeline/node_ingest_test.go +++ b/pkg/kubehound/ingestor/pipeline/node_ingest_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package pipeline import ( @@ -20,6 +21,7 @@ import ( ) func TestNodeIngest_Pipeline(t *testing.T) { + t.Parallel() ni := &NodeIngest{} ctx := context.Background() @@ -58,10 +60,11 @@ func TestNodeIngest_Pipeline(t *testing.T) { sdb := storedb.NewProvider(t) sw := storedb.NewAsyncWriter(t) nodes := collections.Node{} - storeId := store.ObjectID() + storeID := store.ObjectID() sw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Node")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.Node).Id = storeId + i.(*store.Node).Id = storeID + return nil }).Once() sw.EXPECT().Flush(ctx).Return(nil) @@ -75,7 +78,7 @@ func TestNodeIngest_Pipeline(t *testing.T) { "isNamespaced": false, "name": "node-1", "namespace": "", - "storeID": storeId.Hex(), + "storeID": storeID.Hex(), "app": "", "service": "", "team": "test-team", diff --git a/pkg/kubehound/ingestor/pipeline/pod_ingest.go b/pkg/kubehound/ingestor/pipeline/pod_ingest.go index 18251d25f..cce13afff 100644 --- a/pkg/kubehound/ingestor/pipeline/pod_ingest.go +++ b/pkg/kubehound/ingestor/pipeline/pod_ingest.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "errors" "github.com/DataDog/KubeHound/pkg/globals/types" "github.com/DataDog/KubeHound/pkg/kubehound/graph/vertex" @@ -45,7 +46,7 @@ func (i *PodIngest) Initialize(ctx context.Context, deps *Dependencies) error { // // Pods will create other objects such as volumes (from the pod volume mount list) and containers - // from the (container/init container lists). As such we need to intialize a list of the writers we need. + // from the (container/init container lists). As such we need to initialize a list of the writers we need. // i.v = []vertex.Builder{ @@ -80,9 +81,7 @@ func (i *PodIngest) Initialize(ctx context.Context, deps *Dependencies) error { } // processEndpoints will handle the ingestion pipeline for a endpoints belonging to a processed K8s pod input. -func (i *PodIngest) processEndpoints(ctx context.Context, port *corev1.ContainerPort, - pod *store.Pod, container *store.Container) error { - +func (i *PodIngest) processEndpoints(ctx context.Context, port *corev1.ContainerPort, pod *store.Pod, container *store.Container) error { // Normalize endpoint to temporary store object format tmp, err := i.r.storeConvert.EndpointPrivate(ctx, port, pod, container) if err != nil { @@ -93,10 +92,10 @@ func (i *PodIngest) processEndpoints(ctx context.Context, port *corev1.Container // further. However if it does NOT we write the details of the container port as a private endpoint entry. ck := cachekey.Endpoint(tmp.Namespace, tmp.PodName, tmp.SafeProtocol(), tmp.SafePort()) _, err = i.r.readCache(ctx, ck).Bool() - switch err { - case cache.ErrNoEntry: + switch { + case errors.Is(err, cache.ErrNoEntry): // No associated endpoint slice, create the endpoint from container parameters - case nil: + case err == nil: // Validate our assumptions - the below not be possible in our data model and will result in missing edges if port.HostPort != 0 && port.ContainerPort != port.HostPort { log.Trace(ctx).Warnf("assumption failure: host port set on container with associated endpoint slice (%s)", ck.Key()) @@ -187,9 +186,7 @@ func (i *PodIngest) processContainer(ctx context.Context, parent *store.Pod, con } // processVolumeMount will handle the ingestion pipeline for a volume belonging to a processed K8s pod input. -func (i *PodIngest) processVolumeMount(ctx context.Context, volumeMount types.VolumeMountType, - pod *store.Pod, container *store.Container) error { - +func (i *PodIngest) processVolumeMount(ctx context.Context, volumeMount types.VolumeMountType, pod *store.Pod, container *store.Container) error { // TODO can we skip known good e.g agent here to cuyt down the volume?? if ok, err := preflight.CheckVolume(volumeMount); !ok { return err @@ -199,6 +196,7 @@ func (i *PodIngest) processVolumeMount(ctx context.Context, volumeMount types.Vo sv, err := i.r.storeConvert.Volume(ctx, volumeMount, pod, container) if err != nil { log.Trace(ctx).Debugf("process volume type: %v (continuing)", err) + return nil } @@ -214,11 +212,7 @@ func (i *PodIngest) processVolumeMount(ctx context.Context, volumeMount types.Vo } // Aysnc write to graph - if err := i.r.writeVertex(ctx, i.v[volumeIndex], insert); err != nil { - return err - } - - return nil + return i.r.writeVertex(ctx, i.v[volumeIndex], insert) } // streamCallback is invoked by the collector for each pod collected. @@ -233,6 +227,7 @@ func (i *PodIngest) IngestPod(ctx context.Context, pod types.PodType) error { sp, err := i.r.storeConvert.Pod(ctx, pod) if err != nil { log.Trace(ctx).Warnf("process pod %s error (continuing): %v", pod.Name, err) + return nil } diff --git a/pkg/kubehound/ingestor/pipeline/pod_ingest_test.go b/pkg/kubehound/ingestor/pipeline/pod_ingest_test.go index 61cae906e..37c088474 100644 --- a/pkg/kubehound/ingestor/pipeline/pod_ingest_test.go +++ b/pkg/kubehound/ingestor/pipeline/pod_ingest_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package pipeline import ( @@ -20,8 +21,9 @@ import ( ) func TestPodIngest_Pipeline(t *testing.T) { - pi := &PodIngest{} + t.Parallel() + pi := &PodIngest{} ctx := context.Background() fakePod, err := loadTestObject[types.PodType]("testdata/pod.json") assert.NoError(t, err) @@ -67,6 +69,7 @@ func TestPodIngest_Pipeline(t *testing.T) { psw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Pod")). RunAndReturn(func(ctx context.Context, i any) error { i.(*store.Pod).Id = pid + return nil }).Once() psw.EXPECT().Flush(ctx).Return(nil) @@ -79,6 +82,7 @@ func TestPodIngest_Pipeline(t *testing.T) { csw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Container")). RunAndReturn(func(ctx context.Context, i any) error { i.(*store.Container).Id = cid + return nil }).Once() csw.EXPECT().Flush(ctx).Return(nil) @@ -91,6 +95,7 @@ func TestPodIngest_Pipeline(t *testing.T) { vsw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Volume")). RunAndReturn(func(ctx context.Context, i any) error { i.(*store.Volume).Id = vid + return nil }).Once() @@ -104,6 +109,7 @@ func TestPodIngest_Pipeline(t *testing.T) { esw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Endpoint")). RunAndReturn(func(ctx context.Context, i any) error { i.(*store.Endpoint).Id = eid + return nil }).Once() diff --git a/pkg/kubehound/ingestor/pipeline/role_binding_ingest.go b/pkg/kubehound/ingestor/pipeline/role_binding_ingest.go index b5589defa..4b6576f07 100644 --- a/pkg/kubehound/ingestor/pipeline/role_binding_ingest.go +++ b/pkg/kubehound/ingestor/pipeline/role_binding_ingest.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "errors" "github.com/DataDog/KubeHound/pkg/globals/types" "github.com/DataDog/KubeHound/pkg/kubehound/graph/vertex" @@ -74,13 +75,14 @@ func (i *RoleBindingIngest) processSubject(ctx context.Context, subj *store.Bind ck := cachekey.Identity(sid.Name, sid.Namespace) err = i.r.writeCache(ctx, ck, sid.Id.Hex()) if err != nil { - switch e := err.(type) { - case *cache.OverwriteError: + var errOverwrite *cache.OverwriteError + if errors.As(err, &errOverwrite) { log.Trace(ctx).Debugf("identity cache entry %#v already exists, skipping inserts", ck) + return nil - default: - return e } + + return err } // Async write identity to store @@ -95,11 +97,7 @@ func (i *RoleBindingIngest) processSubject(ctx context.Context, subj *store.Bind } // Aysnc write to graph - if err := i.r.writeVertex(ctx, i.vertexIdentity, insert); err != nil { - return err - } - - return nil + return i.r.writeVertex(ctx, i.vertexIdentity, insert) } // createPermissionSet creates a permission set from an input store role binding. @@ -125,11 +123,7 @@ func (i *RoleBindingIngest) createPermissionSet(ctx context.Context, rb *store.R } // // Aysnc write to graph - if err := i.r.writeVertex(ctx, i.vertexPermissionSet, insert); err != nil { - return err - } - - return nil + return i.r.writeVertex(ctx, i.vertexPermissionSet, insert) } // streamCallback is invoked by the collector for each role binding collected. @@ -143,8 +137,9 @@ func (i *RoleBindingIngest) IngestRoleBinding(ctx context.Context, rb types.Role // Normalize K8s role binding to store object format o, err := i.r.storeConvert.RoleBinding(ctx, rb) if err != nil { - if err == converter.ErrDanglingRoleBinding { + if errors.Is(err, converter.ErrDanglingRoleBinding) { log.Trace(ctx).Warnf("Role binding dropped (%s::%s): %s", rb.Namespace, rb.Name, err.Error()) + return nil } @@ -168,9 +163,12 @@ func (i *RoleBindingIngest) IngestRoleBinding(ctx context.Context, rb types.Role // Create permission from Rolebinding entry err = i.createPermissionSet(ctx, o) - switch err { - case nil: - case converter.ErrRoleCacheMiss, converter.ErrRoleBindProperties: + switch { + case err == nil: + // NOP + case errors.Is(err, converter.ErrRoleCacheMiss): + fallthrough + case errors.Is(err, converter.ErrRoleBindProperties): log.Trace(ctx).Warnf("Permission set dropped (%s::%s): %v", rb.Namespace, rb.Name, err) default: return err diff --git a/pkg/kubehound/ingestor/pipeline/role_binding_ingest_test.go b/pkg/kubehound/ingestor/pipeline/role_binding_ingest_test.go index 5f344b4be..5179a2505 100644 --- a/pkg/kubehound/ingestor/pipeline/role_binding_ingest_test.go +++ b/pkg/kubehound/ingestor/pipeline/role_binding_ingest_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package pipeline import ( @@ -21,8 +22,9 @@ import ( ) func TestRoleBindingIngest_Pipeline(t *testing.T) { - ri := &RoleBindingIngest{} + t.Parallel() + ri := &RoleBindingIngest{} ctx := context.Background() fakeRb, err := loadTestObject[types.RoleBindingType]("testdata/rolebinding.json") assert.NoError(t, err) @@ -76,10 +78,11 @@ func TestRoleBindingIngest_Pipeline(t *testing.T) { // Store setup - permissionsets pssw := storedb.NewAsyncWriter(t) psbs := collections.PermissionSet{} - psStoreId := store.ObjectID() + psStoreID := store.ObjectID() pssw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.PermissionSet")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.PermissionSet).Id = psStoreId + i.(*store.PermissionSet).Id = psStoreID + return nil }).Once() pssw.EXPECT().Flush(ctx).Return(nil) @@ -87,10 +90,11 @@ func TestRoleBindingIngest_Pipeline(t *testing.T) { sdb.EXPECT().BulkWriter(ctx, psbs, mock.Anything).Return(pssw, nil) identities := collections.Identity{} - storeId := store.ObjectID() + storeID := store.ObjectID() isw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Identity")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.Identity).Id = storeId + i.(*store.Identity).Id = storeID + return nil }).Once() isw.EXPECT().Flush(ctx).Return(nil) @@ -104,7 +108,7 @@ func TestRoleBindingIngest_Pipeline(t *testing.T) { "critical": false, "name": "app-monitors", "namespace": "test-app", - "storeID": storeId.Hex(), + "storeID": storeID.Hex(), "type": "ServiceAccount", "team": "test-team", "app": "test-app", @@ -124,7 +128,7 @@ func TestRoleBindingIngest_Pipeline(t *testing.T) { "role": "test-reader", "roleBinding": "app-monitors-read", "namespace": "test-app", - "storeID": psStoreId.Hex(), + "storeID": psStoreID.Hex(), "team": "test-team", "app": "test-app", "service": "test-service", diff --git a/pkg/kubehound/ingestor/pipeline/role_ingest.go b/pkg/kubehound/ingestor/pipeline/role_ingest.go index ce369e143..6a874c6d5 100644 --- a/pkg/kubehound/ingestor/pipeline/role_ingest.go +++ b/pkg/kubehound/ingestor/pipeline/role_ingest.go @@ -58,11 +58,7 @@ func (i *RoleIngest) IngestRole(ctx context.Context, role types.RoleType) error } // Async write to cache - if err := i.r.writeCache(ctx, cachekey.Role(o.Name, o.Namespace), *o); err != nil { - return err - } - - return nil + return i.r.writeCache(ctx, cachekey.Role(o.Name, o.Namespace), *o) } // completeCallback is invoked by the collector when all roles have been streamed. diff --git a/pkg/kubehound/ingestor/pipeline/role_ingest_test.go b/pkg/kubehound/ingestor/pipeline/role_ingest_test.go index b31236da7..e0a78b64b 100644 --- a/pkg/kubehound/ingestor/pipeline/role_ingest_test.go +++ b/pkg/kubehound/ingestor/pipeline/role_ingest_test.go @@ -1,3 +1,4 @@ +//nolint:forcetypeassert package pipeline import ( @@ -17,8 +18,9 @@ import ( ) func TestRoleIngest_Pipeline(t *testing.T) { - ri := &RoleIngest{} + t.Parallel() + ri := &RoleIngest{} ctx := context.Background() fakeRole, err := loadTestObject[types.RoleType]("testdata/role.json") assert.NoError(t, err) @@ -48,10 +50,11 @@ func TestRoleIngest_Pipeline(t *testing.T) { sdb := storedb.NewProvider(t) sw := storedb.NewAsyncWriter(t) roles := collections.Role{} - storeId := store.ObjectID() + storeID := store.ObjectID() sw.EXPECT().Queue(ctx, mock.AnythingOfType("*store.Role")). RunAndReturn(func(ctx context.Context, i any) error { - i.(*store.Role).Id = storeId + i.(*store.Role).Id = storeID + return nil }).Once() sw.EXPECT().Flush(ctx).Return(nil) diff --git a/pkg/kubehound/ingestor/pipeline/sequence.go b/pkg/kubehound/ingestor/pipeline/sequence.go index 0315810da..9594884f5 100644 --- a/pkg/kubehound/ingestor/pipeline/sequence.go +++ b/pkg/kubehound/ingestor/pipeline/sequence.go @@ -29,5 +29,6 @@ func (s *Sequence) Run(ctx context.Context, deps *Dependencies) error { } l.Infof("Completed ingest sequence %s", s.Name) + return nil } diff --git a/pkg/kubehound/ingestor/pipeline_ingestor.go b/pkg/kubehound/ingestor/pipeline_ingestor.go index 35a629892..1cefb5041 100644 --- a/pkg/kubehound/ingestor/pipeline_ingestor.go +++ b/pkg/kubehound/ingestor/pipeline_ingestor.go @@ -132,6 +132,7 @@ func (i PipelineIngestor) Run(outer context.Context) error { } l.Info("Completed pipeline ingest") + return nil } diff --git a/pkg/kubehound/ingestor/pipeline_ingestor_test.go b/pkg/kubehound/ingestor/pipeline_ingestor_test.go index 1e3c9d062..0d1568939 100644 --- a/pkg/kubehound/ingestor/pipeline_ingestor_test.go +++ b/pkg/kubehound/ingestor/pipeline_ingestor_test.go @@ -49,6 +49,8 @@ func TestPipelineIngestor_HealthCheck(t *testing.T) { } func createMockData(t *testing.T) (map[string]*mocks.ObjectIngest, *PipelineIngestor) { + t.Helper() + ingests := make(map[string]*mocks.ObjectIngest) ingests["nodes"] = mocks.NewObjectIngest(t) ingests["pods"] = mocks.NewObjectIngest(t) diff --git a/pkg/kubehound/ingestor/preflight/checks.go b/pkg/kubehound/ingestor/preflight/checks.go index 0ec2aa3ca..811baae0f 100644 --- a/pkg/kubehound/ingestor/preflight/checks.go +++ b/pkg/kubehound/ingestor/preflight/checks.go @@ -7,7 +7,7 @@ import ( "github.com/DataDog/KubeHound/pkg/telemetry/log" ) -// Volumes will not be ingested - use with caution! +// SkipVolumes represent a list of Volumes that will not be ingested - use with caution! var SkipVolumes = map[string]bool{ "/var/run/datadog-agent": true, } @@ -31,6 +31,7 @@ func CheckPod(pod types.PodType) (bool, error) { if pod.Status.Phase != "Running" { log.I.Debugf("pod %s::%s not running (status=%s), skipping ingest!", pod.Namespace, pod.Name, pod.Status.Phase) + return false, nil } @@ -104,6 +105,7 @@ func CheckEndpoint(ep types.EndpointType) (bool, error) { if len(ep.Ports) == 0 { log.I.Debugf("endpoint slice %s::%s not associated with any target, skipping ingest!", ep.Namespace, ep.Name) + return false, nil } diff --git a/pkg/kubehound/libkube/address_test.go b/pkg/kubehound/libkube/address_test.go index be0573ef2..b7a8fc1bd 100644 --- a/pkg/kubehound/libkube/address_test.go +++ b/pkg/kubehound/libkube/address_test.go @@ -8,6 +8,8 @@ import ( ) func TestAddressType(t *testing.T) { + t.Parallel() + type args struct { address string } @@ -43,12 +45,17 @@ func TestAddressType(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got, err := AddressType(tt.args.address) if (err != nil) != tt.wantErr { t.Errorf("AddressType() error = %v, wantErr %v", err, tt.wantErr) + return } + if !reflect.DeepEqual(got, tt.want) { t.Errorf("AddressType() = %v, want %v", got, tt.want) } diff --git a/pkg/kubehound/libkube/rbac.go b/pkg/kubehound/libkube/rbac.go index 40d624a0a..3ea4b21ab 100644 --- a/pkg/kubehound/libkube/rbac.go +++ b/pkg/kubehound/libkube/rbac.go @@ -23,7 +23,7 @@ var ( var ( lookupOnce sync.Once lookupNid primitive.ObjectID - lookupErr error + errLookup error ) // NodeUser will return the full name of the dedicated node user. @@ -40,17 +40,17 @@ func DefaultNodeIdentity(ctx context.Context, c cache.CacheReader) (primitive.Ob ck := cachekey.Identity(DefaultNodeGroup, DefaultNodeNamespace) lookupNid, err = c.Get(ctx, ck).ObjectID() - switch err { - case nil: + switch { + case err == nil: // NOP - case cache.ErrNoEntry: - lookupErr = ErrMissingNodeUser + case errors.Is(err, cache.ErrNoEntry): + errLookup = ErrMissingNodeUser default: - lookupErr = err + errLookup = err } }) - return lookupNid, lookupErr + return lookupNid, errLookup } // NodeIdentity will either return the store id of the dedicated node user or store id of the default system:nodes group if a dedicated user is not present. @@ -59,11 +59,11 @@ func NodeIdentity(ctx context.Context, c cache.CacheReader, nodeName string) (pr // Lookup whether the node has a dedicated user ck := cachekey.Identity(NodeUser(nodeName), DefaultNodeNamespace) nid, err := c.Get(ctx, ck).ObjectID() - switch err { - case nil: + switch { + case err == nil: // We have a dedicated user, return its id return nid, nil - case cache.ErrNoEntry: + case errors.Is(err, cache.ErrNoEntry): // Return the default user id return DefaultNodeIdentity(ctx, c) } diff --git a/pkg/kubehound/models/converter/store.go b/pkg/kubehound/models/converter/store.go index 89184a322..6650c8367 100644 --- a/pkg/kubehound/models/converter/store.go +++ b/pkg/kubehound/models/converter/store.go @@ -65,11 +65,11 @@ func (c *StoreConverter) Container(_ context.Context, input types.ContainerType, HostNetwork: parent.K8.Spec.HostNetwork, ServiceAccount: parent.K8.Spec.ServiceAccountName, }, - K8: corev1.Container(*input), + K8: *input, Ownership: store.ExtractOwnership(parent.K8.Labels), } - // Certain fields are set by the PodSecurityContext and overriden by the container's SecurityContext. + // Certain fields are set by the PodSecurityContext and overridden by the container's SecurityContext. // Currently we only consider the RunAsUser field. if input.SecurityContext != nil && input.SecurityContext.RunAsUser != nil { output.Inherited.RunAsUser = *input.SecurityContext.RunAsUser @@ -88,7 +88,7 @@ func (c *StoreConverter) Node(ctx context.Context, input types.NodeType) (*store output := &store.Node{ Id: store.ObjectID(), - K8: corev1.Node(*input), + K8: *input, Ownership: store.ExtractOwnership(input.ObjectMeta.Labels), } @@ -98,11 +98,11 @@ func (c *StoreConverter) Node(ctx context.Context, input types.NodeType) (*store // Retrieve the associated identity store ID from the cache uid, err := libkube.NodeIdentity(ctx, c.cache, input.Name) - switch err { - case nil: + switch { + case err == nil: // We have a matching node identity object in the store output.UserId = uid - case libkube.ErrMissingNodeUser: + case errors.Is(err, libkube.ErrMissingNodeUser): // This is completely fine. Most nodes will run under a default account with no permissions which we ignore. default: return nil, err @@ -126,7 +126,7 @@ func (c *StoreConverter) Pod(ctx context.Context, input types.PodType) (*store.P output := &store.Pod{ Id: store.ObjectID(), NodeId: nid, - K8: corev1.Pod(*input), + K8: *input, Ownership: store.ExtractOwnership(input.ObjectMeta.Labels), } @@ -143,10 +143,10 @@ func (c *StoreConverter) handleProjectedToken(ctx context.Context, input types.V // Retrieve the associated identity store ID from the cache said, err := c.cache.Get(ctx, cachekey.Identity(pod.K8.Spec.ServiceAccountName, pod.K8.Namespace)).ObjectID() - switch err { - case nil: + switch { + case err == nil: // We have a matching identity object in the store, continue to create a volume - case cache.ErrNoEntry: + case errors.Is(err, cache.ErrNoEntry): // This is completely fine. Most pods will run under a default account with no permissions which we ignore. return primitive.NilObjectID, "", ErrProjectedDefaultToken default: @@ -158,6 +158,7 @@ func (c *StoreConverter) handleProjectedToken(ctx context.Context, input types.V for _, proj := range volume.Projected.Sources { if proj.ServiceAccountToken != nil { sourcePath = libkube.ServiceAccountTokenPath(string(pod.K8.ObjectMeta.UID), input.Name) + break } } @@ -190,18 +191,19 @@ func (c *StoreConverter) Volume(ctx context.Context, input types.VolumeMountType // Expect a small size array so iterating through this is quicker than building up a map for lookup for _, volume := range pod.K8.Spec.Volumes { - if volume.Name == input.Name { + v := volume + if v.Name == input.Name { found = true // Only a subset of volumes are currently supported switch { - case volume.HostPath != nil: + case v.HostPath != nil: output.Type = shared.VolumeTypeHost - output.SourcePath = volume.HostPath.Path - case volume.Projected != nil: - said, source, err := c.handleProjectedToken(ctx, input, &volume, pod) + output.SourcePath = v.HostPath.Path + case v.Projected != nil: + said, source, err := c.handleProjectedToken(ctx, input, &v, pod) if err != nil { - return nil, fmt.Errorf("projected token volume (%s) processing: %w", volume.Name, err) + return nil, fmt.Errorf("projected token volume (%s) processing: %w", v.Name, err) } output.Type = shared.VolumeTypeProjected @@ -211,7 +213,7 @@ func (c *StoreConverter) Volume(ctx context.Context, input types.VolumeMountType return nil, ErrUnsupportedVolume } - output.K8 = volume + output.K8 = v } } @@ -249,10 +251,10 @@ func (c *StoreConverter) ClusterRole(_ context.Context, input types.ClusterRoleT func (c *StoreConverter) convertSubject(ctx context.Context, subj rbacv1.Subject) (store.BindSubject, error) { // Check if identity already exists and use that ID, otherwise generate a new one sid, err := c.cache.Get(ctx, cachekey.Identity(subj.Name, subj.Namespace)).ObjectID() - switch err { - case nil: + switch { + case err == nil: // Entry already exists, use the cached id value - case cache.ErrNoEntry: + case errors.Is(err, cache.ErrNoEntry): // Entry does not exist, create a new id value sid = store.ObjectID() default: @@ -399,6 +401,7 @@ func (c *StoreConverter) PermissionSet(ctx context.Context, roleBinding *store.R if roleBinding.Namespace != role.Namespace && role.Namespace != EmptyNamespace { log.Trace(ctx).Debugf("The role namespace (%s) does not match the rolebinding namespace (%s)", role.Namespace, roleBinding.Namespace) + return nil, ErrRoleBindProperties } @@ -416,6 +419,7 @@ func (c *StoreConverter) PermissionSet(ctx context.Context, roleBinding *store.R if !isEffective { log.Trace(ctx).Debugf("The rolebinding/subjects are ALL not in the same namespace: rb::%s/rb.sbj::%#v", roleBinding.Namespace, roleBinding.Subjects) + return nil, ErrRoleBindProperties } @@ -464,6 +468,7 @@ func (c *StoreConverter) PermissionSetCluster(ctx context.Context, clusterRoleBi if role.IsNamespaced { log.Trace(ctx).Debugf("The clusterrolebinding bind a role and not a clusterrole, skipping the permissionset: r::%s/cr::%s", role.Namespace, clusterRoleBinding.Namespace) + return nil, ErrRoleBindProperties } diff --git a/pkg/kubehound/models/store/endpoint.go b/pkg/kubehound/models/store/endpoint.go index 7db268af5..c709878e1 100644 --- a/pkg/kubehound/models/store/endpoint.go +++ b/pkg/kubehound/models/store/endpoint.go @@ -56,5 +56,5 @@ func (e *Endpoint) SafePortName() string { return DefaultPortName } - return string(*e.Port.Name) + return *e.Port.Name } diff --git a/pkg/kubehound/risk/engine.go b/pkg/kubehound/risk/engine.go index 9494701e3..aebe37e40 100644 --- a/pkg/kubehound/risk/engine.go +++ b/pkg/kubehound/risk/engine.go @@ -1,3 +1,4 @@ +//nolint:unparam,gocritic package risk import ( diff --git a/pkg/kubehound/risk/rules.go b/pkg/kubehound/risk/rules.go index c3c0f2c3c..79d52b74c 100644 --- a/pkg/kubehound/risk/rules.go +++ b/pkg/kubehound/risk/rules.go @@ -61,7 +61,7 @@ var CriticalRoleMap = map[string]bool{ "system:node-problem-detector": true, "system:node-proxier": true, "system:persistent-volume-provisioner": true, - "system:public-info-viewer ": true, + "system:public-info-viewer": true, "system:service-account-issuer-discovery": true, "system:volume-scheduler": true, "view": true, diff --git a/pkg/kubehound/services/dependency.go b/pkg/kubehound/services/dependency.go index a3b1571d0..1865d531e 100644 --- a/pkg/kubehound/services/dependency.go +++ b/pkg/kubehound/services/dependency.go @@ -25,6 +25,7 @@ func HealthCheck(ctx context.Context, deps []Dependency) error { ok, err := d.HealthCheck(ctx) if err != nil { res = multierror.Append(res, err) + continue } diff --git a/pkg/kubehound/storage/cache/memcache_bench_test.go b/pkg/kubehound/storage/cache/memcache_bench_test.go index e3b2b53d6..2b5e08a2a 100644 --- a/pkg/kubehound/storage/cache/memcache_bench_test.go +++ b/pkg/kubehound/storage/cache/memcache_bench_test.go @@ -35,7 +35,7 @@ func BenchmarkWrite(b *testing.B) { for i := 0; i < b.N*n; i++ { containerKey := cachekey.Container(fmt.Sprintf("%ftestPod%d", k, i), fmt.Sprintf("%ftestContainer%d", k, i), "test") - fakeCacheWriter.Queue(ctx, containerKey, fmt.Sprintf("%ftestContainerID%d", k, i)) + _ = fakeCacheWriter.Queue(ctx, containerKey, fmt.Sprintf("%ftestContainerID%d", k, i)) } fakeProvider.Close(ctx) }) @@ -64,7 +64,7 @@ func BenchmarkRead(b *testing.B) { n := int(math.Pow(2, k)) fakeProvider, fakeCache := fakeCacheBuilder(ctx, b.N*n) b.Run(fmt.Sprintf("%d", n), func(b *testing.B) { - for key, _ := range fakeCache { + for key := range fakeCache { fakeProvider.Get(ctx, key) } }) diff --git a/pkg/kubehound/storage/cache/memcache_provider.go b/pkg/kubehound/storage/cache/memcache_provider.go index ab54e294a..bb88de802 100644 --- a/pkg/kubehound/storage/cache/memcache_provider.go +++ b/pkg/kubehound/storage/cache/memcache_provider.go @@ -39,6 +39,7 @@ func (mp *MemCacheProvider) Name() string { func (m *MemCacheProvider) Close(ctx context.Context) error { // No data should be access after the Close(), this will create a crash on Get() access which will make debuging easier m.data = nil + return nil } diff --git a/pkg/kubehound/storage/cache/memcache_test.go b/pkg/kubehound/storage/cache/memcache_test.go index eba60f998..7106ecb99 100644 --- a/pkg/kubehound/storage/cache/memcache_test.go +++ b/pkg/kubehound/storage/cache/memcache_test.go @@ -1,3 +1,4 @@ +//nolint:containedctx package cache import ( @@ -20,7 +21,7 @@ func fakeCacheBuilder(ctx context.Context, cacheSize int) (*MemCacheProvider, ma fakeCacheWriter, _ := fakeProvider.BulkWriter(ctx) for key, val := range fakeCache { - fakeCacheWriter.Queue(ctx, key, val) + _ = fakeCacheWriter.Queue(ctx, key, val) } return fakeProvider, fakeCache @@ -62,6 +63,7 @@ func TestMemCacheProvider_Get(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() m := &MemCacheProvider{ data: tt.fields.data, mu: tt.fields.mu, @@ -71,6 +73,7 @@ func TestMemCacheProvider_Get(t *testing.T) { got, err := m.Get(tt.args.ctx, key).Text() if (err != nil) != tt.wantErr { t.Errorf("MemCacheProvider.Get() error = %v, wantErr %v", err, tt.wantErr) + return } if got != val { @@ -151,6 +154,7 @@ func TestMemCacheAsyncWriter_Queue(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() m := &MemCacheAsyncWriter{ data: tt.fields.MemCacheProvider.data, mu: tt.fields.MemCacheProvider.mu, @@ -165,6 +169,7 @@ func TestMemCacheAsyncWriter_Queue(t *testing.T) { got, err := tt.fields.MemCacheProvider.Get(tt.args.ctx, key).Text() if err != nil { t.Errorf("MemCacheProvider.Get() error = %v", err) + return } if got != val { diff --git a/pkg/kubehound/storage/cache/memcache_writer.go b/pkg/kubehound/storage/cache/memcache_writer.go index 1507b41e3..c01d991c7 100644 --- a/pkg/kubehound/storage/cache/memcache_writer.go +++ b/pkg/kubehound/storage/cache/memcache_writer.go @@ -38,14 +38,15 @@ func (m *MemCacheAsyncWriter) Queue(ctx context.Context, key cachekey.CacheKey, } m.data[keyId] = value + return nil } -func (m *MemCacheAsyncWriter) Flush(ctx context.Context) error { +func (m *MemCacheAsyncWriter) Flush(_ context.Context) error { return nil } -func (m *MemCacheAsyncWriter) Close(ctx context.Context) error { +func (m *MemCacheAsyncWriter) Close(_ context.Context) error { // Underlying data map is owned by the proviuder object return nil } diff --git a/pkg/kubehound/storage/cache/provider.go b/pkg/kubehound/storage/cache/provider.go index 5983e3df6..95326ccd5 100644 --- a/pkg/kubehound/storage/cache/provider.go +++ b/pkg/kubehound/storage/cache/provider.go @@ -56,5 +56,6 @@ func Factory(ctx context.Context, cfg *config.KubehoundConfig) (CacheProvider, e if err != nil { return nil, err } + return provider, nil } diff --git a/pkg/kubehound/storage/cache/result_test.go b/pkg/kubehound/storage/cache/result_test.go index 17a6fe5dd..7d54de853 100644 --- a/pkg/kubehound/storage/cache/result_test.go +++ b/pkg/kubehound/storage/cache/result_test.go @@ -10,6 +10,8 @@ import ( ) func TestCacheResult_ObjectID(t *testing.T) { + t.Parallel() + objectId := primitive.NewObjectID() type fields struct { Value any @@ -68,7 +70,9 @@ func TestCacheResult_ObjectID(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() r := &CacheResult{ Value: tt.fields.Value, Err: tt.fields.Err, @@ -76,8 +80,10 @@ func TestCacheResult_ObjectID(t *testing.T) { got, err := r.ObjectID() if (err != nil) != tt.wantErr { t.Errorf("CacheResult.ObjectID() error = %v, wantErr %v", err, tt.wantErr) + return } + if !reflect.DeepEqual(got, tt.want) { t.Errorf("CacheResult.ObjectID() = %v, want %v", got, tt.want) } @@ -86,6 +92,8 @@ func TestCacheResult_ObjectID(t *testing.T) { } func TestCacheResult_Int64(t *testing.T) { + t.Parallel() + type fields struct { Value any Err error @@ -134,7 +142,9 @@ func TestCacheResult_Int64(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() r := &CacheResult{ Value: tt.fields.Value, Err: tt.fields.Err, @@ -142,6 +152,7 @@ func TestCacheResult_Int64(t *testing.T) { got, err := r.Int64() if (err != nil) != tt.wantErr { t.Errorf("CacheResult.Int64() error = %v, wantErr %v", err, tt.wantErr) + return } if got != tt.want { @@ -152,6 +163,8 @@ func TestCacheResult_Int64(t *testing.T) { } func TestCacheResult_Text(t *testing.T) { + t.Parallel() + type fields struct { Value any Err error @@ -200,7 +213,9 @@ func TestCacheResult_Text(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() r := &CacheResult{ Value: tt.fields.Value, Err: tt.fields.Err, @@ -208,6 +223,7 @@ func TestCacheResult_Text(t *testing.T) { got, err := r.Text() if (err != nil) != tt.wantErr { t.Errorf("CacheResult.Text() error = %v, wantErr %v", err, tt.wantErr) + return } if got != tt.want { @@ -218,6 +234,8 @@ func TestCacheResult_Text(t *testing.T) { } func TestCacheResult_Bool(t *testing.T) { + t.Parallel() + type fields struct { Value any Err error @@ -266,7 +284,10 @@ func TestCacheResult_Bool(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + r := &CacheResult{ Value: tt.fields.Value, Err: tt.fields.Err, @@ -274,6 +295,7 @@ func TestCacheResult_Bool(t *testing.T) { got, err := r.Bool() if (err != nil) != tt.wantErr { t.Errorf("CacheResult.Bool() error = %v, wantErr %v", err, tt.wantErr) + return } if got != tt.want { @@ -284,6 +306,8 @@ func TestCacheResult_Bool(t *testing.T) { } func TestCacheResult_Role(t *testing.T) { + t.Parallel() + testOwnershipInfo := store.OwnershipInfo{ Application: "test-app", Team: "test-team", @@ -346,7 +370,9 @@ func TestCacheResult_Role(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() r := &CacheResult{ Value: tt.fields.Value, Err: tt.fields.Err, @@ -354,6 +380,7 @@ func TestCacheResult_Role(t *testing.T) { got, err := r.Role() if (err != nil) != tt.wantErr { t.Errorf("CacheResult.Role() error = %v, wantErr %v", err, tt.wantErr) + return } if !reflect.DeepEqual(got, tt.want) { diff --git a/pkg/kubehound/storage/graphdb/janusgraph_edge_writer.go b/pkg/kubehound/storage/graphdb/janusgraph_edge_writer.go index 66f4297eb..0005225a9 100644 --- a/pkg/kubehound/storage/graphdb/janusgraph_edge_writer.go +++ b/pkg/kubehound/storage/graphdb/janusgraph_edge_writer.go @@ -76,6 +76,7 @@ func (jgv *JanusGraphEdgeWriter) startBackgroundWriter(ctx context.Context) { } case <-ctx.Done(): log.Trace(ctx).Info("Closed background janusgraph worker on context cancel") + return } } @@ -114,6 +115,7 @@ func (jgv *JanusGraphEdgeWriter) batchWrite(ctx context.Context, data []any) err func (jgv *JanusGraphEdgeWriter) Close(ctx context.Context) error { close(jgv.consumerChan) + return nil } @@ -137,6 +139,7 @@ func (jgv *JanusGraphEdgeWriter) Flush(ctx context.Context) error { if err != nil { log.Trace(ctx).Errorf("batch write %s: %+v", jgv.builder, err) jgv.writingInFlight.Wait() + return err } @@ -148,6 +151,7 @@ func (jgv *JanusGraphEdgeWriter) Flush(ctx context.Context) error { log.Trace(ctx).Debugf("Edge writer %d %s queued", jgv.qcounter, jgv.builder) log.Trace(ctx).Infof("Edge writer %d %s written", jgv.wcounter, jgv.builder) + return nil } diff --git a/pkg/kubehound/storage/graphdb/janusgraph_provider.go b/pkg/kubehound/storage/graphdb/janusgraph_provider.go index 83d294a27..26fec5e00 100644 --- a/pkg/kubehound/storage/graphdb/janusgraph_provider.go +++ b/pkg/kubehound/storage/graphdb/janusgraph_provider.go @@ -94,11 +94,12 @@ func (jgp *JanusGraphProvider) HealthCheck(ctx context.Context) (bool, error) { value, err := one.GetInt() if err != nil { - return false, fmt.Errorf("get int value from healthcheck: %v", err) + return false, fmt.Errorf("get int value from healthcheck: %w", err) } if value != 1 { log.Trace(ctx).Errorf("healthcheck returned wrong value, got: %d wanted: %s", value, wantValue) + return false, nil } @@ -125,5 +126,6 @@ func (jgp *JanusGraphProvider) EdgeWriter(ctx context.Context, e edge.Builder, o // Close cleans up any resources used by the Provider implementation. Provider cannot be reused after this call. func (jgp *JanusGraphProvider) Close(ctx context.Context) error { jgp.drc.Close() + return nil } diff --git a/pkg/kubehound/storage/graphdb/janusgraph_vertex_writer.go b/pkg/kubehound/storage/graphdb/janusgraph_vertex_writer.go index 539337f2a..d63bb0814 100644 --- a/pkg/kubehound/storage/graphdb/janusgraph_vertex_writer.go +++ b/pkg/kubehound/storage/graphdb/janusgraph_vertex_writer.go @@ -85,6 +85,7 @@ func (jgv *JanusGraphVertexWriter) startBackgroundWriter(ctx context.Context) { } case <-ctx.Done(): log.Trace(ctx).Info("Closed background janusgraph worker on context cancel") + return } } @@ -98,8 +99,12 @@ func (jgv *JanusGraphVertexWriter) cacheIds(ctx context.Context, idMap []*gremli return fmt.Errorf("parsing vertex insert result map: %#v", r) } - storeID := idMap["storeID"].(string) - vertexId := idMap["id"].(int64) + storeID, sOk := idMap["storeID"].(string) + vertexId, vOk := idMap["id"].(int64) + + if !sOk || !vOk { + return errors.New("vertex id type conversion") + } err := jgv.cache.Queue(ctx, cachekey.ObjectID(storeID), vertexId) if err != nil { @@ -174,6 +179,7 @@ func (jgv *JanusGraphVertexWriter) Flush(ctx context.Context) error { if err != nil { log.Trace(ctx).Errorf("batch write %s: %+v", jgv.builder, err) jgv.writingInFlight.Wait() + return err } @@ -190,6 +196,7 @@ func (jgv *JanusGraphVertexWriter) Flush(ctx context.Context) error { log.Trace(ctx).Debugf("Batch writer %d %s queued", jgv.qcounter, jgv.builder) log.Trace(ctx).Infof("Batch writer %d %s written", jgv.wcounter, jgv.builder) + return nil } diff --git a/pkg/kubehound/storage/graphdb/provider.go b/pkg/kubehound/storage/graphdb/provider.go index b26d57dfa..61825d74e 100644 --- a/pkg/kubehound/storage/graphdb/provider.go +++ b/pkg/kubehound/storage/graphdb/provider.go @@ -76,5 +76,6 @@ type AsyncEdgeWriter interface { // Factory returns an initialized instance of a graphdb provider from the provided application config. func Factory(ctx context.Context, cfg *config.KubehoundConfig) (Provider, error) { r := storage.Retrier(NewGraphDriver, cfg.Storage.Retry, cfg.Storage.RetryDelay) + return r(ctx, cfg.JanusGraph.URL, cfg.JanusGraph.ConnectionTimeout) } diff --git a/pkg/kubehound/storage/retrier.go b/pkg/kubehound/storage/retrier.go index a1719da19..8495d0f0a 100644 --- a/pkg/kubehound/storage/retrier.go +++ b/pkg/kubehound/storage/retrier.go @@ -10,7 +10,7 @@ type Connector[T any] func(ctx context.Context, dbHost string, timeout time.Dura func Retrier[T any](connector Connector[T], retries int, delay time.Duration) Connector[T] { return func(ctx context.Context, dbHost string, timeout time.Duration) (T, error) { for r := 0; ; r++ { - var emtpy T + var empty T provider, err := connector(ctx, dbHost, timeout) if err == nil || r >= retries { return provider, err @@ -19,7 +19,7 @@ func Retrier[T any](connector Connector[T], retries int, delay time.Duration) Co select { case <-time.After(delay): case <-ctx.Done(): - return emtpy, ctx.Err() + return empty, ctx.Err() } } } diff --git a/pkg/kubehound/storage/storedb/mongo_provider.go b/pkg/kubehound/storage/storedb/mongo_provider.go index a91306159..a49ad2656 100644 --- a/pkg/kubehound/storage/storedb/mongo_provider.go +++ b/pkg/kubehound/storage/storedb/mongo_provider.go @@ -77,6 +77,7 @@ func (mp *MongoProvider) HealthCheck(ctx context.Context) (bool, error) { if err != nil { return false, err } + return true, nil } @@ -86,5 +87,6 @@ func (mp *MongoProvider) Close(ctx context.Context) error { func (mp *MongoProvider) BulkWriter(ctx context.Context, collection collections.Collection, opts ...WriterOption) (AsyncWriter, error) { writer := NewMongoAsyncWriter(ctx, mp, collection, opts...) + return writer, nil } diff --git a/pkg/kubehound/storage/storedb/mongo_provider_test.go b/pkg/kubehound/storage/storedb/mongo_provider_test.go index 1b551e2ef..c8555a883 100644 --- a/pkg/kubehound/storage/storedb/mongo_provider_test.go +++ b/pkg/kubehound/storage/storedb/mongo_provider_test.go @@ -1,3 +1,4 @@ +//nolint:containedctx,unused package storedb import ( @@ -11,17 +12,19 @@ import ( ) func TestMongoProvider_BulkWriter(t *testing.T) { + t.Parallel() // FIXME: we should probably setup a mongodb test server in CI for the system tests if config.IsCI() { t.Skip("Skip mongo tests in CI") } - t.Parallel() + ctx := context.Background() provider, err := NewMongoProvider(ctx, MongoLocalDatabaseURL, 1*time.Second) // TODO: add another check (env var maybe?) // "integration test checks" if err != nil { t.Error("FAILED TO CONNECT TO LOCAL MONGO DB DURING TESTS, SKIPPING") + return } @@ -68,8 +71,10 @@ func TestMongoProvider_BulkWriter(t *testing.T) { writer, err := mp.BulkWriter(tt.args.ctx, tt.args.collection, tt.args.opts...) if (err != nil) != tt.wantErr { t.Errorf("MongoProvider.BulkWriter() error = %v, wantErr %v", err, tt.wantErr) + return } + if writer == nil { t.Errorf("writer returned by BulkWriter is nil") } diff --git a/pkg/kubehound/storage/storedb/mongo_writer.go b/pkg/kubehound/storage/storedb/mongo_writer.go index 409629c37..fb6533f98 100644 --- a/pkg/kubehound/storage/storedb/mongo_writer.go +++ b/pkg/kubehound/storage/storedb/mongo_writer.go @@ -47,6 +47,7 @@ func NewMongoAsyncWriter(ctx context.Context, mp *MongoProvider, collection coll } maw.consumerChan = make(chan []mongo.WriteModel, consumerChanSize) maw.startBackgroundWriter(ctx) + return &maw } @@ -67,6 +68,7 @@ func (maw *MongoAsyncWriter) startBackgroundWriter(ctx context.Context) { } case <-ctx.Done(): log.Trace(ctx).Debug("Closed background mongodb worker") + return } } @@ -88,6 +90,7 @@ func (maw *MongoAsyncWriter) batchWrite(ctx context.Context, ops []mongo.WriteMo if err != nil { return fmt.Errorf("could not write in bulk to mongo: %w", err) } + return nil } @@ -102,6 +105,7 @@ func (maw *MongoAsyncWriter) Queue(ctx context.Context, model any) error { // cleanup the ops array after we have copied it to the channel maw.ops = nil } + return nil } @@ -125,16 +129,19 @@ func (maw *MongoAsyncWriter) Flush(ctx context.Context) error { // we cannot defer it because the go routine may last longer than the current function // the defer is going to be executed at the return time, whetever or not the inner go routine is processing data maw.writingInFlight.Wait() + return nil } err := maw.batchWrite(ctx, maw.ops) if err != nil { maw.writingInFlight.Wait() + return err } maw.ops = nil + return nil } @@ -145,5 +152,6 @@ func (maw *MongoAsyncWriter) Close(ctx context.Context) error { } maw.ops = nil + return nil } diff --git a/pkg/kubehound/storage/storedb/mongo_writer_test.go b/pkg/kubehound/storage/storedb/mongo_writer_test.go index 148ec8568..b2a4cb686 100644 --- a/pkg/kubehound/storage/storedb/mongo_writer_test.go +++ b/pkg/kubehound/storage/storedb/mongo_writer_test.go @@ -1,3 +1,4 @@ +//nolint:containedctx,contextcheck package storedb import ( @@ -17,12 +18,13 @@ type FakeElement struct { } func TestMongoAsyncWriter_Queue(t *testing.T) { + t.Parallel() + // FIXME: we should probably setup a mongodb test server in CI for the system tests if config.IsCI() { t.Skip("Skip mongo tests in CI") } - t.Parallel() fakeElem := FakeElement{ FieldA: 123, FieldB: "lol", @@ -35,6 +37,7 @@ func TestMongoAsyncWriter_Queue(t *testing.T) { // "integration test checks" if err != nil { t.Error("FAILED TO CONNECT TO LOCAL MONGO DB DURING TESTS, SKIPPING") + return } @@ -108,11 +111,12 @@ func TestMongoAsyncWriter_Queue(t *testing.T) { } func TestMongoAsyncWriter_Flush(t *testing.T) { + t.Parallel() + // FIXME: we should probably setup a mongodb test server in CI for the system tests if config.IsCI() { t.Skip("Skip mongo tests in CI") } - t.Parallel() fakeElem := FakeElement{ FieldA: 123, FieldB: "lol", @@ -208,6 +212,7 @@ func TestMongoAsyncWriter_Flush(t *testing.T) { // "integration test checks" if err != nil { t.Error("FAILED TO CONNECT TO LOCAL MONGO DB DURING TESTS, SKIPPING") + return } defer mongoProvider.Close(ctx) @@ -223,6 +228,7 @@ func TestMongoAsyncWriter_Flush(t *testing.T) { err = maw.Flush(tt.argsFlush.ctx) if (err != nil) != tt.wantErr { t.Errorf("MongoAsyncWriter.Flush() error = %v, wantErr %v", err, tt.wantErr) + return } diff --git a/pkg/kubehound/storage/storedb/provider.go b/pkg/kubehound/storage/storedb/provider.go index e15485c34..f5324b36f 100644 --- a/pkg/kubehound/storage/storedb/provider.go +++ b/pkg/kubehound/storage/storedb/provider.go @@ -57,5 +57,6 @@ type AsyncWriter interface { // Factory returns an initialized instance of a storedb provider from the provided application config. func Factory(ctx context.Context, cfg *config.KubehoundConfig) (Provider, error) { r := storage.Retrier(NewMongoProvider, cfg.Storage.Retry, cfg.Storage.RetryDelay) + return r(ctx, cfg.MongoDB.URL, cfg.MongoDB.ConnectionTimeout) } diff --git a/pkg/telemetry/log/logger.go b/pkg/telemetry/log/logger.go index 7ca381cc4..9ef249339 100644 --- a/pkg/telemetry/log/logger.go +++ b/pkg/telemetry/log/logger.go @@ -31,8 +31,8 @@ var globalConfig = LoggerConfig{ DD: true, } -// Global logger instance for use through the app -var I *KubehoundLogger = Base() +// I Global logger instance for use through the app +var I = Base() // Require our logger to append job or API related fields for easier filtering and parsing // of logs within custom dashboards. Sticking to the "structured" log types also enables @@ -45,12 +45,14 @@ type KubehoundLogger struct { // traceID retrieves the trace ID from the provided span. func traceID(span tracer.Span) string { traceID := span.Context().TraceID() + return strconv.FormatUint(traceID, 10) } // traceID retrieves the span ID from the provided span. func spanID(span tracer.Span) string { spanID := span.Context().SpanID() + return strconv.FormatUint(spanID, 10) } @@ -64,7 +66,7 @@ func Base() *KubehoundLogger { return &KubehoundLogger{logger} } -// SetDD enables/disbaled Datadog integration in the logger. +// SetDD enables/disabled Datadog integration in the logger. func SetDD(enabled bool) { globalConfig.Mu.Lock() defer globalConfig.Mu.Unlock() diff --git a/pkg/telemetry/statsd/statsd.go b/pkg/telemetry/statsd/statsd.go index f284f96b0..dd4fc8357 100644 --- a/pkg/telemetry/statsd/statsd.go +++ b/pkg/telemetry/statsd/statsd.go @@ -27,12 +27,15 @@ func Setup(statsdURL string) error { // In case we don't have a statsd url set, we just want to continue, but log that we aren't going to submit metrics. if statsdURL == "" { log.I.Warn("No metrics collector has been setup. All metrics submission are going to be NOOP.") + return nil } + statsdClient, err = statsd.New(statsdURL) if err != nil { return err } + return nil } @@ -41,6 +44,7 @@ func Count(name string, value int64, tags []string, rate float64) error { if statsdClient == nil { return nil } + return statsdClient.Count(name, value, tags, rate) } @@ -49,6 +53,7 @@ func Gauge(name string, value float64, tags []string, rate float64) error { if statsdClient == nil { return nil } + return statsdClient.Gauge(name, value, tags, rate) } @@ -57,6 +62,7 @@ func Incr(name string, tags []string, rate float64) error { if statsdClient == nil { return nil } + return statsdClient.Incr(name, tags, rate) } @@ -65,6 +71,7 @@ func Decr(name string, tags []string, rate float64) error { if statsdClient == nil { return nil } + return statsdClient.Decr(name, tags, rate) } @@ -73,6 +80,7 @@ func Histogram(name string, value float64, tags []string, rate float64) error { if statsdClient == nil { return nil } + return statsdClient.Histogram(name, value, tags, rate) } @@ -81,6 +89,7 @@ func Event(event *statsd.Event) error { if statsdClient == nil { return nil } + return statsdClient.Event(event) } @@ -89,6 +98,7 @@ func SimpleEvent(title string, text string) error { if statsdClient == nil { return nil } + return statsdClient.SimpleEvent(title, text) } @@ -97,6 +107,7 @@ func Set(name string, value string, tags []string, rate float64) error { if statsdClient == nil { return nil } + return statsdClient.Set(name, value, tags, rate) } @@ -105,6 +116,7 @@ func Timing(name string, value time.Duration, tags []string, rate float64) error if statsdClient == nil { return nil } + return statsdClient.Timing(name, value, tags, rate) } @@ -113,7 +125,10 @@ func TimingDist(name string, dt time.Duration, tags []string, rate float64) erro if statsdClient == nil { return nil } - return statsdClient.Distribution(name, dt.Seconds()*1000, tags, rate) + + const secToMillis = 1000 + + return statsdClient.Distribution(name, dt.Seconds()*secToMillis, tags, rate) } // TimeInMilliseconds sends timing information in milliseconds. @@ -121,6 +136,7 @@ func TimeInMilliseconds(name string, value float64, tags []string, rate float64) if statsdClient == nil { return nil } + return statsdClient.TimeInMilliseconds(name, value, tags, rate) } @@ -129,6 +145,7 @@ func Distribution(name string, value float64, tags []string, rate float64) error if statsdClient == nil { return nil } + return statsdClient.Distribution(name, value, tags, rate) } diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index 670d94c27..d6a938bb5 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -8,44 +8,47 @@ import ( "github.com/DataDog/KubeHound/pkg/telemetry/tracer" ) -type TelemetryState struct { +type State struct { Enabled bool } // Initialize all telemetry required // return client to enable clean shutdown -func Initialize(cfg *config.KubehoundConfig) (*TelemetryState, error) { +func Initialize(cfg *config.KubehoundConfig) (*State, error) { if !cfg.Telemetry.Enabled { - return &TelemetryState{}, nil + return &State{}, nil } - // profiling + // Profiling profiler.Initialize(cfg) - //Tracing + + // Tracing tracer.Initialize(cfg) + // Metrics err := statsd.Setup(cfg.Telemetry.Statsd.URL) if err != nil { - return &TelemetryState{ + return &State{ Enabled: true, }, err } - return &TelemetryState{ + return &State{ Enabled: true, }, nil } -func Shutdown(ts *TelemetryState) { +func Shutdown(ts *State) { if !ts.Enabled { return } - //Profiling + // Profiling profiler.Shutdown() - //Tracing + // Tracing tracer.Shutdown() + // Metrics err := statsd.Flush() if err != nil { diff --git a/pkg/worker/pond.go b/pkg/worker/pond.go index 0d0e2ae56..78b0b90e2 100644 --- a/pkg/worker/pond.go +++ b/pkg/worker/pond.go @@ -28,6 +28,7 @@ func newPond(size int, capacity int) WorkerPool { func (wp *PondWorkerPool) Start(parent context.Context) (context.Context, error) { group, ctx := wp.pool.GroupContext(parent) wp.group = group + return ctx, nil } diff --git a/test/system/generator/generator.go b/test/system/generator/generator.go index 21a806b70..5c199eb4d 100644 --- a/test/system/generator/generator.go +++ b/test/system/generator/generator.go @@ -1,3 +1,4 @@ +//nolint:all package main import ( diff --git a/test/system/graph_dsl_test.go b/test/system/graph_dsl_test.go index 08d8d1d51..2b2c183cf 100644 --- a/test/system/graph_dsl_test.go +++ b/test/system/graph_dsl_test.go @@ -1,3 +1,4 @@ +//nolint:all package system import ( diff --git a/test/system/graph_edge_test.go b/test/system/graph_edge_test.go index 62c0c4fc1..166a884d0 100644 --- a/test/system/graph_edge_test.go +++ b/test/system/graph_edge_test.go @@ -1,3 +1,4 @@ +//nolint:all package system import ( @@ -70,6 +71,7 @@ func (suite *EdgeTestSuite) _testContainerEscape(edgeLabel string, nodes map[str for _, r := range results { if nodes[r.GetString()] { matched = true + break } } @@ -89,6 +91,7 @@ func (suite *EdgeTestSuite) _testContainerEscape(edgeLabel string, nodes map[str for _, r := range results { if containers[r.GetString()] { matched = true + break } } diff --git a/test/system/graph_vertex_test.go b/test/system/graph_vertex_test.go index 54ca4703a..f784d7579 100644 --- a/test/system/graph_vertex_test.go +++ b/test/system/graph_vertex_test.go @@ -1,3 +1,4 @@ +//nolint:all package system import ( diff --git a/test/system/setup_test.go b/test/system/setup_test.go index f6e40fcb5..c7181deb4 100644 --- a/test/system/setup_test.go +++ b/test/system/setup_test.go @@ -1,3 +1,4 @@ +//nolint:all package system import (