diff --git a/.pnp.cjs b/.pnp.cjs index 0ed5cb6df3..ad9b75528f 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -164,7 +164,7 @@ const RAW_RUNTIME_STATE = "packageDependencies": [\ ["@babel/code-frame", "npm:7.24.7"],\ ["@babel/highlight", "npm:7.24.7"],\ - ["picocolors", "npm:1.1.0"]\ + ["picocolors", "npm:1.1.1"]\ ],\ "linkType": "HARD"\ }]\ @@ -374,7 +374,7 @@ const RAW_RUNTIME_STATE = ["@babel/helper-validator-identifier", "npm:7.25.9"],\ ["chalk", "npm:2.4.2"],\ ["js-tokens", "npm:4.0.0"],\ - ["picocolors", "npm:1.1.0"]\ + ["picocolors", "npm:1.1.1"]\ ],\ "linkType": "HARD"\ }]\ @@ -1261,13 +1261,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@eslint-community/eslint-utils", [\ - ["npm:4.4.0", {\ - "packageLocation": "./.yarn/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-7e559c4ce5.zip/node_modules/@eslint-community/eslint-utils/",\ - "packageDependencies": [\ - ["@eslint-community/eslint-utils", "npm:4.4.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ ["npm:4.4.1", {\ "packageLocation": "./.yarn/cache/@eslint-community-eslint-utils-npm-4.4.1-c83a271e90-2aa0ac2fc5.zip/node_modules/@eslint-community/eslint-utils/",\ "packageDependencies": [\ @@ -1275,10 +1268,10 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ - ["virtual:1fec2585567df2baf4e6094c0c86eb9d84760be330b6fe6c669230e99e52c9f91ed9cf539f99613768b3d5b796d9537b3fcd8084459eb13edb773ff1a6ef7367#npm:4.4.1", {\ - "packageLocation": "./.yarn/__virtual__/@eslint-community-eslint-utils-virtual-e9b089131b/0/cache/@eslint-community-eslint-utils-npm-4.4.1-c83a271e90-2aa0ac2fc5.zip/node_modules/@eslint-community/eslint-utils/",\ + ["virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.1", {\ + "packageLocation": "./.yarn/__virtual__/@eslint-community-eslint-utils-virtual-94654cbedf/0/cache/@eslint-community-eslint-utils-npm-4.4.1-c83a271e90-2aa0ac2fc5.zip/node_modules/@eslint-community/eslint-utils/",\ "packageDependencies": [\ - ["@eslint-community/eslint-utils", "virtual:1fec2585567df2baf4e6094c0c86eb9d84760be330b6fe6c669230e99e52c9f91ed9cf539f99613768b3d5b796d9537b3fcd8084459eb13edb773ff1a6ef7367#npm:4.4.1"],\ + ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.1"],\ ["@types/eslint", null],\ ["eslint", "virtual:f3f18773c1f2811e8d448670abfc3fed18cdffc11b444f7cbc3548ae5868e74f3c4ee449327c1fc9c24ce0732ee02505411a07539789bec8257188d17bbada1f#npm:9.14.0"],\ ["eslint-visitor-keys", "npm:3.4.3"]\ @@ -1289,24 +1282,10 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ - ["virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.0", {\ - "packageLocation": "./.yarn/__virtual__/@eslint-community-eslint-utils-virtual-bd737af038/0/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-7e559c4ce5.zip/node_modules/@eslint-community/eslint-utils/",\ + ["virtual:d84daf63b75039f65e32d776091a5a95ab3e18242eb444be8889bbcb76b7a7d7508b5e670a8854278abbbed4908e5d0d13344665327911199da36bd456a270c0#npm:4.4.1", {\ + "packageLocation": "./.yarn/__virtual__/@eslint-community-eslint-utils-virtual-23e7a37212/0/cache/@eslint-community-eslint-utils-npm-4.4.1-c83a271e90-2aa0ac2fc5.zip/node_modules/@eslint-community/eslint-utils/",\ "packageDependencies": [\ - ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.0"],\ - ["@types/eslint", null],\ - ["eslint", "virtual:f3f18773c1f2811e8d448670abfc3fed18cdffc11b444f7cbc3548ae5868e74f3c4ee449327c1fc9c24ce0732ee02505411a07539789bec8257188d17bbada1f#npm:9.14.0"],\ - ["eslint-visitor-keys", "npm:3.4.3"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:d84daf63b75039f65e32d776091a5a95ab3e18242eb444be8889bbcb76b7a7d7508b5e670a8854278abbbed4908e5d0d13344665327911199da36bd456a270c0#npm:4.4.0", {\ - "packageLocation": "./.yarn/__virtual__/@eslint-community-eslint-utils-virtual-cc37cd0ab8/0/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-7e559c4ce5.zip/node_modules/@eslint-community/eslint-utils/",\ - "packageDependencies": [\ - ["@eslint-community/eslint-utils", "virtual:d84daf63b75039f65e32d776091a5a95ab3e18242eb444be8889bbcb76b7a7d7508b5e670a8854278abbbed4908e5d0d13344665327911199da36bd456a270c0#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:d84daf63b75039f65e32d776091a5a95ab3e18242eb444be8889bbcb76b7a7d7508b5e670a8854278abbbed4908e5d0d13344665327911199da36bd456a270c0#npm:4.4.1"],\ ["@types/eslint", null],\ ["eslint", null],\ ["eslint-visitor-keys", "npm:3.4.3"]\ @@ -1319,13 +1298,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@eslint-community/regexpp", [\ - ["npm:4.11.1", {\ - "packageLocation": "./.yarn/cache/@eslint-community-regexpp-npm-4.11.1-37bbb67aaa-fbcc1cb65e.zip/node_modules/@eslint-community/regexpp/",\ - "packageDependencies": [\ - ["@eslint-community/regexpp", "npm:4.11.1"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:4.12.1", {\ "packageLocation": "./.yarn/cache/@eslint-community-regexpp-npm-4.12.1-ef4ab5217e-a03d98c246.zip/node_modules/@eslint-community/regexpp/",\ "packageDependencies": [\ @@ -1638,7 +1610,6 @@ const RAW_RUNTIME_STATE = ["@gardener-dashboard/kube-config", "workspace:packages/kube-config"],\ ["@gardener-dashboard/logger", "workspace:packages/logger"],\ ["@gardener-dashboard/test-utils", "workspace:packages/test-utils"],\ - ["chokidar", "npm:4.0.1"],\ ["eslint", "virtual:f3f18773c1f2811e8d448670abfc3fed18cdffc11b444f7cbc3548ae5868e74f3c4ee449327c1fc9c24ce0732ee02505411a07539789bec8257188d17bbada1f#npm:9.14.0"],\ ["eslint-plugin-import", "virtual:feaa032e1ffbff8da5dad8429b8494744ade8373389ef8e26f3d1f1980ceff327ab996fdc7c1977df285edeb918372fa01d7c87d79c9d7218f8701c70203bfe5#npm:2.31.0"],\ ["eslint-plugin-jest", "virtual:feaa032e1ffbff8da5dad8429b8494744ade8373389ef8e26f3d1f1980ceff327ab996fdc7c1977df285edeb918372fa01d7c87d79c9d7218f8701c70203bfe5#npm:28.9.0"],\ @@ -3212,7 +3183,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/__virtual__/@typescript-eslint-eslint-plugin-virtual-7a127f53db/0/cache/@typescript-eslint-eslint-plugin-npm-8.14.0-55616f1385-46c82eb45b.zip/node_modules/@typescript-eslint/eslint-plugin/",\ "packageDependencies": [\ ["@typescript-eslint/eslint-plugin", "virtual:1a3693785837ec7f2b3cc8f1d7724e37322656cfdc683e756003f39dfab0e2a9ff106b99415234e4241ae19a32e068c991f260afda3f65e447a69b8107f42459#npm:8.14.0"],\ - ["@eslint-community/regexpp", "npm:4.11.1"],\ + ["@eslint-community/regexpp", "npm:4.12.1"],\ ["@types/eslint", null],\ ["@types/typescript", null],\ ["@types/typescript-eslint__parser", null],\ @@ -3358,7 +3329,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/__virtual__/@typescript-eslint-utils-virtual-d84daf63b7/0/cache/@typescript-eslint-utils-npm-8.14.0-4742a7bfab-1fcc2651d8.zip/node_modules/@typescript-eslint/utils/",\ "packageDependencies": [\ ["@typescript-eslint/utils", "virtual:1a3693785837ec7f2b3cc8f1d7724e37322656cfdc683e756003f39dfab0e2a9ff106b99415234e4241ae19a32e068c991f260afda3f65e447a69b8107f42459#npm:8.14.0"],\ - ["@eslint-community/eslint-utils", "virtual:d84daf63b75039f65e32d776091a5a95ab3e18242eb444be8889bbcb76b7a7d7508b5e670a8854278abbbed4908e5d0d13344665327911199da36bd456a270c0#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:d84daf63b75039f65e32d776091a5a95ab3e18242eb444be8889bbcb76b7a7d7508b5e670a8854278abbbed4908e5d0d13344665327911199da36bd456a270c0#npm:4.4.1"],\ ["@types/eslint", null],\ ["@typescript-eslint/scope-manager", "npm:8.14.0"],\ ["@typescript-eslint/types", "npm:8.14.0"],\ @@ -3375,7 +3346,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/__virtual__/@typescript-eslint-utils-virtual-66d8a63dd0/0/cache/@typescript-eslint-utils-npm-8.14.0-4742a7bfab-1fcc2651d8.zip/node_modules/@typescript-eslint/utils/",\ "packageDependencies": [\ ["@typescript-eslint/utils", "virtual:920265345ea4067faba4b79db8010284e5552da581ea1ebfc57c6b032c05d37984adc7407082d7cee117f52d1ce80786b7b4b16b270103e24f47bcc006895d57#npm:8.14.0"],\ - ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.1"],\ ["@types/eslint", null],\ ["@typescript-eslint/scope-manager", "npm:8.14.0"],\ ["@typescript-eslint/types", "npm:8.14.0"],\ @@ -3647,18 +3618,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@vue/compiler-core", [\ - ["npm:3.5.12", {\ - "packageLocation": "./.yarn/cache/@vue-compiler-core-npm-3.5.12-ec7e993ccc-7f004b9633.zip/node_modules/@vue/compiler-core/",\ - "packageDependencies": [\ - ["@vue/compiler-core", "npm:3.5.12"],\ - ["@babel/parser", "npm:7.26.2"],\ - ["@vue/shared", "npm:3.5.12"],\ - ["entities", "npm:4.5.0"],\ - ["estree-walker", "npm:2.0.2"],\ - ["source-map-js", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:3.5.13", {\ "packageLocation": "./.yarn/cache/@vue-compiler-core-npm-3.5.13-b0c91e9970-b89f3e3ca9.zip/node_modules/@vue/compiler-core/",\ "packageDependencies": [\ @@ -3673,15 +3632,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@vue/compiler-dom", [\ - ["npm:3.5.12", {\ - "packageLocation": "./.yarn/cache/@vue-compiler-dom-npm-3.5.12-2c6fcbab3c-48a67cd28c.zip/node_modules/@vue/compiler-dom/",\ - "packageDependencies": [\ - ["@vue/compiler-dom", "npm:3.5.12"],\ - ["@vue/compiler-core", "npm:3.5.12"],\ - ["@vue/shared", "npm:3.5.12"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:3.5.13", {\ "packageLocation": "./.yarn/cache/@vue-compiler-dom-npm-3.5.13-8785a9ba19-8f424a7188.zip/node_modules/@vue/compiler-dom/",\ "packageDependencies": [\ @@ -3711,15 +3661,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@vue/compiler-ssr", [\ - ["npm:3.5.12", {\ - "packageLocation": "./.yarn/cache/@vue-compiler-ssr-npm-3.5.12-e1e40560ca-8a8fc4e205.zip/node_modules/@vue/compiler-ssr/",\ - "packageDependencies": [\ - ["@vue/compiler-ssr", "npm:3.5.12"],\ - ["@vue/compiler-dom", "npm:3.5.12"],\ - ["@vue/shared", "npm:3.5.12"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:3.5.13", {\ "packageLocation": "./.yarn/cache/@vue-compiler-ssr-npm-3.5.13-e1cdeef007-67621337b1.zip/node_modules/@vue/compiler-ssr/",\ "packageDependencies": [\ @@ -3774,13 +3715,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@vue/server-renderer", [\ - ["npm:3.5.12", {\ - "packageLocation": "./.yarn/cache/@vue-server-renderer-npm-3.5.12-3ad333df56-d9f25f165c.zip/node_modules/@vue/server-renderer/",\ - "packageDependencies": [\ - ["@vue/server-renderer", "npm:3.5.12"]\ - ],\ - "linkType": "SOFT"\ - }],\ ["npm:3.5.13", {\ "packageLocation": "./.yarn/cache/@vue-server-renderer-npm-3.5.13-d23f3ccee8-f500bdabc1.zip/node_modules/@vue/server-renderer/",\ "packageDependencies": [\ @@ -3803,10 +3737,10 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ - ["virtual:33382e2c41b7662b4530f61f13128e650803dc0e0b463c70df98582286d9916aedcc1ddcea66f7173aeed4b6d89426fd18b06d214a5ba235ecd78137e9ea48dd#npm:3.5.13", {\ - "packageLocation": "./.yarn/__virtual__/@vue-server-renderer-virtual-a73fe6cbf9/0/cache/@vue-server-renderer-npm-3.5.13-d23f3ccee8-f500bdabc1.zip/node_modules/@vue/server-renderer/",\ + ["virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.13", {\ + "packageLocation": "./.yarn/__virtual__/@vue-server-renderer-virtual-fe338cb778/0/cache/@vue-server-renderer-npm-3.5.13-d23f3ccee8-f500bdabc1.zip/node_modules/@vue/server-renderer/",\ "packageDependencies": [\ - ["@vue/server-renderer", "virtual:33382e2c41b7662b4530f61f13128e650803dc0e0b463c70df98582286d9916aedcc1ddcea66f7173aeed4b6d89426fd18b06d214a5ba235ecd78137e9ea48dd#npm:3.5.13"],\ + ["@vue/server-renderer", "virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.13"],\ ["@types/vue", null],\ ["@vue/compiler-ssr", "npm:3.5.13"],\ ["@vue/shared", "npm:3.5.13"],\ @@ -3817,31 +3751,9 @@ const RAW_RUNTIME_STATE = "vue"\ ],\ "linkType": "HARD"\ - }],\ - ["virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.12", {\ - "packageLocation": "./.yarn/__virtual__/@vue-server-renderer-virtual-db0a4417ab/0/cache/@vue-server-renderer-npm-3.5.12-3ad333df56-d9f25f165c.zip/node_modules/@vue/server-renderer/",\ - "packageDependencies": [\ - ["@vue/server-renderer", "virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.12"],\ - ["@types/vue", null],\ - ["@vue/compiler-ssr", "npm:3.5.12"],\ - ["@vue/shared", "npm:3.5.12"],\ - ["vue", "virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.13"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ }]\ ]],\ ["@vue/shared", [\ - ["npm:3.5.12", {\ - "packageLocation": "./.yarn/cache/@vue-shared-npm-3.5.12-70fd2bd5d7-48f94406c4.zip/node_modules/@vue/shared/",\ - "packageDependencies": [\ - ["@vue/shared", "npm:3.5.12"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:3.5.13", {\ "packageLocation": "./.yarn/cache/@vue-shared-npm-3.5.13-519178ab33-2c940ef907.zip/node_modules/@vue/shared/",\ "packageDependencies": [\ @@ -3855,8 +3767,8 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/@vue-test-utils-npm-2.4.6-ec350e6321-37fa46cb6b.zip/node_modules/@vue/test-utils/",\ "packageDependencies": [\ ["@vue/test-utils", "npm:2.4.6"],\ - ["@vue/compiler-dom", "npm:3.5.12"],\ - ["@vue/server-renderer", "virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.12"],\ + ["@vue/compiler-dom", "npm:3.5.13"],\ + ["@vue/server-renderer", "virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.13"],\ ["js-beautify", "npm:1.15.1"],\ ["vue", "virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.13"],\ ["vue-component-type-helpers", "npm:2.0.6"]\ @@ -6290,7 +6202,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/__virtual__/eslint-virtual-75f5f3bd86/0/cache/eslint-npm-9.14.0-04ed57b338-e1cbf571b7.zip/node_modules/eslint/",\ "packageDependencies": [\ ["eslint", "virtual:f3f18773c1f2811e8d448670abfc3fed18cdffc11b444f7cbc3548ae5868e74f3c4ee449327c1fc9c24ce0732ee02505411a07539789bec8257188d17bbada1f#npm:9.14.0"],\ - ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.1"],\ ["@eslint-community/regexpp", "npm:4.12.1"],\ ["@eslint/config-array", "npm:0.18.0"],\ ["@eslint/core", "npm:0.7.0"],\ @@ -6457,8 +6369,8 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/__virtual__/eslint-plugin-es-x-virtual-1eb64f578a/0/cache/eslint-plugin-es-x-npm-7.8.0-8237bd972e-002fda8c02.zip/node_modules/eslint-plugin-es-x/",\ "packageDependencies": [\ ["eslint-plugin-es-x", "virtual:1fec2585567df2baf4e6094c0c86eb9d84760be330b6fe6c669230e99e52c9f91ed9cf539f99613768b3d5b796d9537b3fcd8084459eb13edb773ff1a6ef7367#npm:7.8.0"],\ - ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.0"],\ - ["@eslint-community/regexpp", "npm:4.11.1"],\ + ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.1"],\ + ["@eslint-community/regexpp", "npm:4.12.1"],\ ["@types/eslint", null],\ ["eslint", "virtual:f3f18773c1f2811e8d448670abfc3fed18cdffc11b444f7cbc3548ae5868e74f3c4ee449327c1fc9c24ce0732ee02505411a07539789bec8257188d17bbada1f#npm:9.14.0"],\ ["eslint-compat-utils", "virtual:1eb64f578a694bb7b24903a5d8a30b2c09b8577b88c07cc271fe2a6f5be87a0c1cc8a438aeba065b64e2663ecde98aa4a823cb56a89e3589bb9740964cf8beb1#npm:0.5.1"]\ @@ -6625,13 +6537,13 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/__virtual__/eslint-plugin-n-virtual-1fec258556/0/cache/eslint-plugin-n-npm-17.13.1-4ace11339b-025c41aec2.zip/node_modules/eslint-plugin-n/",\ "packageDependencies": [\ ["eslint-plugin-n", "virtual:2cd60cf0eaa713981ba4fa725786c0c033552df3256034933bfbc531f91f1e19a67d4585fd90dddd4cbfda26946bb4507e7bcd454aea524fed93c918b191ad1a#npm:17.13.1"],\ - ["@eslint-community/eslint-utils", "virtual:1fec2585567df2baf4e6094c0c86eb9d84760be330b6fe6c669230e99e52c9f91ed9cf539f99613768b3d5b796d9537b3fcd8084459eb13edb773ff1a6ef7367#npm:4.4.1"],\ + ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.1"],\ ["@types/eslint", null],\ ["enhanced-resolve", "npm:5.17.1"],\ ["eslint", "virtual:f3f18773c1f2811e8d448670abfc3fed18cdffc11b444f7cbc3548ae5868e74f3c4ee449327c1fc9c24ce0732ee02505411a07539789bec8257188d17bbada1f#npm:9.14.0"],\ ["eslint-plugin-es-x", "virtual:1fec2585567df2baf4e6094c0c86eb9d84760be330b6fe6c669230e99e52c9f91ed9cf539f99613768b3d5b796d9537b3fcd8084459eb13edb773ff1a6ef7367#npm:7.8.0"],\ ["get-tsconfig", "npm:4.8.1"],\ - ["globals", "npm:15.11.0"],\ + ["globals", "npm:15.12.0"],\ ["ignore", "npm:5.3.2"],\ ["minimatch", "npm:9.0.5"],\ ["semver", "npm:7.6.3"]\ @@ -6727,7 +6639,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/__virtual__/eslint-plugin-vue-virtual-a024ca6718/0/cache/eslint-plugin-vue-npm-9.31.0-a9853a4864-c87ab4d59b.zip/node_modules/eslint-plugin-vue/",\ "packageDependencies": [\ ["eslint-plugin-vue", "virtual:8d919ffb8fd728f827df3f6a566e8e923223ffcec68f7450d83bbbc2dc25d6b8c987e111cbab484b209f253bdf2f2e00663b01a986262c44511128466462a76f#npm:9.31.0"],\ - ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:75f5f3bd86269d2dc4c5703baddfa0e0101eb5fd5cc7cab281fcdcf59e171fcb1c408e97818b2d543266db7acec87b269c781eb32fa6a979e8d24ed6d42cf9dd#npm:4.4.1"],\ ["@types/eslint", null],\ ["eslint", "virtual:f3f18773c1f2811e8d448670abfc3fed18cdffc11b444f7cbc3548ae5868e74f3c4ee449327c1fc9c24ce0732ee02505411a07539789bec8257188d17bbada1f#npm:9.14.0"],\ ["globals", "npm:13.24.0"],\ @@ -6862,7 +6774,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/estree-walker-npm-3.0.3-0372979673-c12e3c2b26.zip/node_modules/estree-walker/",\ "packageDependencies": [\ ["estree-walker", "npm:3.0.3"],\ - ["@types/estree", "npm:1.0.5"]\ + ["@types/estree", "npm:1.0.6"]\ ],\ "linkType": "HARD"\ }]\ @@ -7585,13 +7497,6 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ - ["npm:15.11.0", {\ - "packageLocation": "./.yarn/cache/globals-npm-15.11.0-336de1c0c2-861e39bb6b.zip/node_modules/globals/",\ - "packageDependencies": [\ - ["globals", "npm:15.11.0"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:15.12.0", {\ "packageLocation": "./.yarn/cache/globals-npm-15.12.0-998488f877-f34e0a1845.zip/node_modules/globals/",\ "packageDependencies": [\ @@ -10581,13 +10486,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["picocolors", [\ - ["npm:1.1.0", {\ - "packageLocation": "./.yarn/cache/picocolors-npm-1.1.0-ea12a640bd-86946f6032.zip/node_modules/picocolors/",\ - "packageDependencies": [\ - ["picocolors", "npm:1.1.0"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:1.1.1", {\ "packageLocation": "./.yarn/cache/picocolors-npm-1.1.1-4fede47cf1-e2e3e8170a.zip/node_modules/picocolors/",\ "packageDependencies": [\ @@ -10673,16 +10571,6 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["postcss", [\ - ["npm:8.4.47", {\ - "packageLocation": "./.yarn/cache/postcss-npm-8.4.47-2f4d4be1fa-929f68b508.zip/node_modules/postcss/",\ - "packageDependencies": [\ - ["postcss", "npm:8.4.47"],\ - ["nanoid", "npm:3.3.7"],\ - ["picocolors", "npm:1.1.0"],\ - ["source-map-js", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:8.4.49", {\ "packageLocation": "./.yarn/cache/postcss-npm-8.4.49-1c13833dd1-f1b3f17aaf.zip/node_modules/postcss/",\ "packageDependencies": [\ @@ -11224,7 +11112,7 @@ const RAW_RUNTIME_STATE = ["htmlparser2", "npm:8.0.2"],\ ["is-plain-object", "npm:5.0.0"],\ ["parse-srcset", "npm:1.0.2"],\ - ["postcss", "npm:8.4.47"]\ + ["postcss", "npm:8.4.49"]\ ],\ "linkType": "HARD"\ }]\ @@ -12417,7 +12305,7 @@ const RAW_RUNTIME_STATE = ["@types/browserslist", null],\ ["browserslist", "npm:4.23.1"],\ ["escalade", "npm:3.1.2"],\ - ["picocolors", "npm:1.1.0"]\ + ["picocolors", "npm:1.1.1"]\ ],\ "packagePeers": [\ "@types/browserslist",\ @@ -12517,7 +12405,7 @@ const RAW_RUNTIME_STATE = ["fsevents", "patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"],\ ["less", null],\ ["lightningcss", null],\ - ["postcss", "npm:8.4.47"],\ + ["postcss", "npm:8.4.49"],\ ["rollup", "npm:4.22.4"],\ ["sass", "npm:1.79.6"],\ ["sass-embedded", null],\ @@ -12560,7 +12448,7 @@ const RAW_RUNTIME_STATE = ["fsevents", "patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"],\ ["less", null],\ ["lightningcss", null],\ - ["postcss", "npm:8.4.47"],\ + ["postcss", "npm:8.4.49"],\ ["rollup", "npm:4.22.4"],\ ["sass", null],\ ["sass-embedded", null],\ @@ -12795,7 +12683,7 @@ const RAW_RUNTIME_STATE = ["@vue/compiler-dom", "npm:3.5.13"],\ ["@vue/compiler-sfc", "npm:3.5.13"],\ ["@vue/runtime-dom", "npm:3.5.13"],\ - ["@vue/server-renderer", "virtual:33382e2c41b7662b4530f61f13128e650803dc0e0b463c70df98582286d9916aedcc1ddcea66f7173aeed4b6d89426fd18b06d214a5ba235ecd78137e9ea48dd#npm:3.5.13"],\ + ["@vue/server-renderer", "virtual:ec350e632119c2fa6aa4185d5fb2e6904d7c1f9cefb2603c234bc720b5a0490a22229e2320a7b46e1376c2f73972079ba6fa907f4b7e80df555b8cfccd6e5aa2#npm:3.5.13"],\ ["@vue/shared", "npm:3.5.13"],\ ["typescript", null]\ ],\ diff --git a/.yarn/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-7e559c4ce5.zip b/.yarn/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-7e559c4ce5.zip deleted file mode 100644 index 7199799572..0000000000 Binary files a/.yarn/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-7e559c4ce5.zip and /dev/null differ diff --git a/.yarn/cache/@eslint-community-regexpp-npm-4.11.1-37bbb67aaa-fbcc1cb65e.zip b/.yarn/cache/@eslint-community-regexpp-npm-4.11.1-37bbb67aaa-fbcc1cb65e.zip deleted file mode 100644 index 36e164eb58..0000000000 Binary files a/.yarn/cache/@eslint-community-regexpp-npm-4.11.1-37bbb67aaa-fbcc1cb65e.zip and /dev/null differ diff --git a/.yarn/cache/@vue-compiler-core-npm-3.5.12-ec7e993ccc-7f004b9633.zip b/.yarn/cache/@vue-compiler-core-npm-3.5.12-ec7e993ccc-7f004b9633.zip deleted file mode 100644 index 5a279fe261..0000000000 Binary files a/.yarn/cache/@vue-compiler-core-npm-3.5.12-ec7e993ccc-7f004b9633.zip and /dev/null differ diff --git a/.yarn/cache/@vue-compiler-dom-npm-3.5.12-2c6fcbab3c-48a67cd28c.zip b/.yarn/cache/@vue-compiler-dom-npm-3.5.12-2c6fcbab3c-48a67cd28c.zip deleted file mode 100644 index 196766c766..0000000000 Binary files a/.yarn/cache/@vue-compiler-dom-npm-3.5.12-2c6fcbab3c-48a67cd28c.zip and /dev/null differ diff --git a/.yarn/cache/@vue-compiler-ssr-npm-3.5.12-e1e40560ca-8a8fc4e205.zip b/.yarn/cache/@vue-compiler-ssr-npm-3.5.12-e1e40560ca-8a8fc4e205.zip deleted file mode 100644 index 7ca98b5d3b..0000000000 Binary files a/.yarn/cache/@vue-compiler-ssr-npm-3.5.12-e1e40560ca-8a8fc4e205.zip and /dev/null differ diff --git a/.yarn/cache/@vue-server-renderer-npm-3.5.12-3ad333df56-d9f25f165c.zip b/.yarn/cache/@vue-server-renderer-npm-3.5.12-3ad333df56-d9f25f165c.zip deleted file mode 100644 index 8016e34257..0000000000 Binary files a/.yarn/cache/@vue-server-renderer-npm-3.5.12-3ad333df56-d9f25f165c.zip and /dev/null differ diff --git a/.yarn/cache/@vue-shared-npm-3.5.12-70fd2bd5d7-48f94406c4.zip b/.yarn/cache/@vue-shared-npm-3.5.12-70fd2bd5d7-48f94406c4.zip deleted file mode 100644 index af6aac4c74..0000000000 Binary files a/.yarn/cache/@vue-shared-npm-3.5.12-70fd2bd5d7-48f94406c4.zip and /dev/null differ diff --git a/.yarn/cache/globals-npm-15.11.0-336de1c0c2-861e39bb6b.zip b/.yarn/cache/globals-npm-15.11.0-336de1c0c2-861e39bb6b.zip deleted file mode 100644 index f83de5055e..0000000000 Binary files a/.yarn/cache/globals-npm-15.11.0-336de1c0c2-861e39bb6b.zip and /dev/null differ diff --git a/.yarn/cache/picocolors-npm-1.1.0-ea12a640bd-86946f6032.zip b/.yarn/cache/picocolors-npm-1.1.0-ea12a640bd-86946f6032.zip deleted file mode 100644 index 47e319dd48..0000000000 Binary files a/.yarn/cache/picocolors-npm-1.1.0-ea12a640bd-86946f6032.zip and /dev/null differ diff --git a/.yarn/cache/postcss-npm-8.4.47-2f4d4be1fa-929f68b508.zip b/.yarn/cache/postcss-npm-8.4.47-2f4d4be1fa-929f68b508.zip deleted file mode 100644 index cdc69c9fde..0000000000 Binary files a/.yarn/cache/postcss-npm-8.4.47-2f4d4be1fa-929f68b508.zip and /dev/null differ diff --git a/packages/kube-config/__tests__/client-config.test.js b/packages/kube-config/__tests__/client-config.test.js index 12855b12f8..adb48fd357 100644 --- a/packages/kube-config/__tests__/client-config.test.js +++ b/packages/kube-config/__tests__/client-config.test.js @@ -23,7 +23,7 @@ describe('client-config', () => { const initClientConfig = signal => { const config = new Config(kubeconfig) const reactive = !!signal - clientConfig = new ClientConfig(config, { reactive, signal }) + clientConfig = new ClientConfig(config, { reactive, interval: 500, signal }) return reactive ? onceEvent(clientConfig.watcher, 'ready') : Promise.resolve() diff --git a/packages/kube-config/__tests__/kube-config.test.js b/packages/kube-config/__tests__/kube-config.test.js index 849986d2a2..c4ab4bc6b0 100644 --- a/packages/kube-config/__tests__/kube-config.test.js +++ b/packages/kube-config/__tests__/kube-config.test.js @@ -10,8 +10,6 @@ const fs = require('fs') const path = require('path') const os = require('os') const yaml = require('js-yaml') -const EventEmitter = require('events') -const chokidar = require('chokidar') const { mockGetToken } = require('gtoken') const { cloneDeep } = require('lodash') const Config = require('../lib/Config') @@ -33,17 +31,10 @@ describe('kube-config', () => { const accessToken = 'access-token' beforeEach(() => { - jest.spyOn(chokidar, 'watch').mockImplementationOnce(() => { - const emitter = new EventEmitter() - emitter.close = jest.fn().mockImplementation(() => Promise.resolve()) - process.nextTick(() => emitter.emit('ready')) - return emitter - }) jest.spyOn(fs, 'readFileSync') }) afterEach(() => { - chokidar.watch.mockRestore() fs.readFileSync.mockRestore() }) diff --git a/packages/kube-config/__tests__/polling-watcher.test.js b/packages/kube-config/__tests__/polling-watcher.test.js new file mode 100644 index 0000000000..aa34a28471 --- /dev/null +++ b/packages/kube-config/__tests__/polling-watcher.test.js @@ -0,0 +1,103 @@ +// +// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Gardener contributors +// +// SPDX-License-Identifier: Apache-2.0 +// + +'use strict' + +const fs = require('fs/promises') +const { globalLogger: logger } = require('@gardener-dashboard/logger') +const PollingWatcher = require('../lib/PollingWatcher') + +const actualNextTick = jest.requireActual('process').nextTick +const flushPromises = () => new Promise(actualNextTick) + +describe('polling-watcher', () => { + beforeAll(() => { + jest.useFakeTimers() + }) + + afterAll(() => { + jest.useRealTimers() + }) + + describe('#run', () => { + const filename = '/path/to/file' + const content = 'content' + const interval = 10 + let ac + let fn + + const createWatcher = (signal = ac.signal) => { + return new PollingWatcher([filename], { + interval, + signal, + }) + } + + const advanceTimersByOneInterval = async () => { + jest.advanceTimersByTime(interval + 1) + await flushPromises() + } + + beforeEach(() => { + ac = new AbortController() + fn = jest.fn() + jest.spyOn(fs, 'readFile').mockResolvedValue(content) + logger.info.mockClear() + logger.error.mockClear() + }) + + afterEach(() => { + fs.readFile.mockRestore() + ac.abort() + }) + + it('should read the file content and call the callback function', async () => { + createWatcher().run(fn) + expect(fn).toHaveBeenCalledTimes(0) + await advanceTimersByOneInterval() + expect(fn).toHaveBeenCalledTimes(1) + expect(fn.mock.calls[0]).toEqual([filename, content]) + expect(logger.info).toHaveBeenCalledTimes(1) + expect(logger.info.mock.calls[0]).toEqual(['[kube-config] updated content of file `%s`', filename]) + }) + + it('should fail to read file content and not call the callback function', async () => { + const error = new Error('no such file') + fs.readFile.mockRejectedValueOnce(error) + createWatcher().run(fn) + expect(fn).toHaveBeenCalledTimes(0) + await advanceTimersByOneInterval() + expect(fn).toHaveBeenCalledTimes(0) + expect(logger.error).toHaveBeenCalledTimes(1) + expect(logger.error.mock.calls[0]).toEqual(['[kube-config] failed to stat file `%s`: %s', filename, error.message]) + }) + + it('should do nothing if abortet before run', async () => { + const watcher = createWatcher() + ac.abort() + watcher.run(fn) + await advanceTimersByOneInterval() + expect(fn).toHaveBeenCalledTimes(0) + }) + + it('should do nothing if already abortet', async () => { + ac.abort() + const watcher = createWatcher() + watcher.run(fn) + await advanceTimersByOneInterval() + expect(fn).toHaveBeenCalledTimes(0) + }) + + it('should run a watcher without abort signal', async () => { + const watcher = createWatcher(null) + ac.abort() + watcher.run(fn) + await advanceTimersByOneInterval() + expect(fn).toHaveBeenCalledTimes(1) + watcher.abort() + }) + }) +}) diff --git a/packages/kube-config/__tests__/watcher.test.js b/packages/kube-config/__tests__/watcher.test.js deleted file mode 100644 index 0b9345bf52..0000000000 --- a/packages/kube-config/__tests__/watcher.test.js +++ /dev/null @@ -1,137 +0,0 @@ -// -// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 -// - -'use strict' - -const EventEmitter = require('events') -const { basename } = require('path') -const chokidar = require('chokidar') -const { globalLogger: logger } = require('@gardener-dashboard/logger') -const Watcher = require('../lib/Watcher') -const { onceEvent } = fixtures.helper - -describe('watcher', () => { - const paths = [ - '/path/to/ca.crt', - '/path/to/token', - ] - let mockWatch - let emitter - let ac - - const createWatcher = async options => { - const watcher = new Watcher(paths, options) - expect(mockWatch).toBeCalledTimes(1) - expect(mockWatch.mock.calls[0]).toEqual([ - paths, - { - persistent: true, - awaitWriteFinish: true, - ignoreInitial: true, - followSymlinks: true, - disableGlobbing: true, - }, - ]) - setImmediate(() => emitter.emit('ready')) - await onceEvent(watcher, 'ready') - return watcher - } - - beforeEach(() => { - ac = new AbortController() - emitter = new EventEmitter() - emitter.close = jest.fn().mockImplementation(() => Promise.resolve()) - mockWatch = jest.spyOn(chokidar, 'watch').mockReturnValueOnce(emitter) - }) - - afterEach(() => { - logger.error.mockReset() - ac.abort() - }) - - afterAll(() => { - mockWatch.mockRestore() - }) - - it('should create a watcher with defaults', async () => { - expect.assertions(2) - const watcher = await createWatcher() - watcher.destroy() - }) - - it('should run a watcher and log errors', async () => { - const watcher = await createWatcher({ - signal: ac.signal, - readFile: path => Promise.resolve(basename(path)), - }) - const mockHandler = jest.fn((key, value) => { - if (value === 'ca.crt') { - watcher.destroy() - } - }) - watcher.run(mockHandler) - emitter.emit('change', '/path/to/token') - emitter.emit('error', new Error('foo')) - emitter.emit('change', '/path/to/ca.crt') - emitter.emit('error', new Error('bar')) - await onceEvent(watcher, 'close') - expect(mockHandler).toBeCalledTimes(2) - expect(mockHandler.mock.calls).toEqual([ - ['/path/to/token', 'token'], - ['/path/to/ca.crt', 'ca.crt'], - ]) - expect(logger.error).toBeCalledTimes(2) - expect(logger.error.mock.calls).toEqual([ - ['[kube-config] watch files error: %s', 'foo'], - ['[kube-config] watch files error: %s', 'bar'], - ]) - }) - - it('should throw a timeout error when creating a watcher', async () => { - const milliseconds = 1 - const watcher = new Watcher(paths, { - signal: ac.signal, - readyTimeout: milliseconds, - }) - const err = await onceEvent(watcher, 'error') - expect(err).toBeInstanceOf(Error) - expect(err.message).toEqual(`FSWatcher timed out after ${milliseconds} milliseconds`) - }) - - it('should throw a close error when destroying a watcher', async () => { - const closeError = new Error('close error') - const watcher = await createWatcher() - emitter.close.mockImplementationOnce(() => Promise.reject(closeError)) - watcher.destroy() - const err = await onceEvent(watcher, 'error') - expect(err).toBe(closeError) - }) - - it('should log a read file error when running a watcher', async () => { - const readFileError = new Error('read file error') - readFileError.code = 'EREADFILE' - const watcher = await createWatcher({ - signal: ac.signal, - readFile: path => path === '/path/to/token' - ? Promise.resolve(basename(path)) - : Promise.reject(readFileError), - }) - const mockHandler = jest.fn(() => watcher.destroy()) - watcher.run(mockHandler) - emitter.emit('change', '/path/to/ca.crt') - emitter.emit('change', '/path/to/..data') - emitter.emit('change', '/path/to/token') - await onceEvent(watcher, 'close') - expect(mockHandler).toBeCalledTimes(1) - expect(mockHandler.mock.calls).toEqual([ - ['/path/to/token', 'token'], - ]) - expect(logger.error).toBeCalledTimes(1) - expect(logger.error.mock.calls).toEqual([ - ['[kube-config] read file error %s: %s', 'EREADFILE', 'read file error'], - ]) - }) -}) diff --git a/packages/kube-config/lib/ClientConfig.js b/packages/kube-config/lib/ClientConfig.js index 032ba300fc..05632ba00d 100644 --- a/packages/kube-config/lib/ClientConfig.js +++ b/packages/kube-config/lib/ClientConfig.js @@ -8,7 +8,7 @@ const assert = require('assert').strict const fs = require('fs') -const Watcher = require('./Watcher') +const Watcher = require('./PollingWatcher') function getCluster ({ currentCluster }, files) { const cluster = {} @@ -25,7 +25,8 @@ function getCluster ({ currentCluster }, files) { cluster.certificateAuthority = base64Decode(caData) } else if (caFile) { files.set(caFile, 'certificateAuthority') - cluster.certificateAuthority = fs.readFileSync(caFile, 'utf8') // eslint-disable-line security/detect-non-literal-fs-filename + // eslint-disable-next-line security/detect-non-literal-fs-filename -- caFile is not user input + cluster.certificateAuthority = fs.readFileSync(caFile, 'utf8') } if (typeof insecureSkipTlsVerify === 'boolean') { cluster.insecureSkipTlsVerify = insecureSkipTlsVerify @@ -55,14 +56,17 @@ function getUser ({ currentUser }, files) { user.clientKey = base64Decode(keyData) } else if (certFile && keyFile) { files.set(certFile, 'clientCert') - user.clientCert = fs.readFileSync(certFile, 'utf8') // eslint-disable-line security/detect-non-literal-fs-filename + // eslint-disable-next-line security/detect-non-literal-fs-filename -- certFile is not user input + user.clientCert = fs.readFileSync(certFile, 'utf8') files.set(keyFile, 'clientKey') - user.clientKey = fs.readFileSync(keyFile, 'utf8') // eslint-disable-line security/detect-non-literal-fs-filename + // eslint-disable-next-line security/detect-non-literal-fs-filename -- keyFile is not user input + user.clientKey = fs.readFileSync(keyFile, 'utf8') } else if (token) { user.token = token } else if (tokenFile) { files.set(tokenFile, 'token') - user.token = fs.readFileSync(tokenFile, 'utf8') // eslint-disable-line security/detect-non-literal-fs-filename + // eslint-disable-next-line security/detect-non-literal-fs-filename -- tokenFile is not user input + user.token = fs.readFileSync(tokenFile, 'utf8') } else if (username && password) { user.username = username user.password = password diff --git a/packages/kube-config/lib/PollingWatcher.js b/packages/kube-config/lib/PollingWatcher.js new file mode 100644 index 0000000000..e10a9b15bd --- /dev/null +++ b/packages/kube-config/lib/PollingWatcher.js @@ -0,0 +1,65 @@ +// +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors +// +// SPDX-License-Identifier: Apache-2.0 +// + +'use strict' + +const fs = require('fs/promises') +const EventEmitter = require('events') +const { globalLogger: logger } = require('@gardener-dashboard/logger') + +class PollingWatcher extends EventEmitter { + #paths + #interval + #intervalId + #state = 'initial' + + constructor (paths, options) { + super() + this.#paths = paths + this.#interval = options?.interval ?? 300_000 + process.nextTick(() => { + this.#state = 'ready' + logger.debug('[kube-config] watcher ready') + this.emit('ready') + }) + const signal = options?.signal + if (signal instanceof AbortSignal) { + if (!signal.aborted) { + signal.addEventListener('abort', () => this.abort(), { once: true }) + } else { + this.#state = 'aborted' + } + } + } + + run (fn) { + if (['initial', 'ready'].includes(this.#state)) { + const tryReadFile = async path => { + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename -- path is not user input + const value = await fs.readFile(path, 'utf8') + logger.info('[kube-config] updated content of file `%s`', path) + fn(path, value) + } catch (err) { + logger.error('[kube-config] failed to stat file `%s`: %s', path, err.message) + } + } + this.#state = 'running' + this.#intervalId = setInterval(() => { + for (const path of this.#paths) { + tryReadFile(path) + } + }, this.#interval) + } + } + + abort () { + this.#state = 'aborted' + clearInterval(this.#intervalId) + } +} + +module.exports = PollingWatcher diff --git a/packages/kube-config/lib/Watcher.js b/packages/kube-config/lib/Watcher.js deleted file mode 100644 index 07b387f8d9..0000000000 --- a/packages/kube-config/lib/Watcher.js +++ /dev/null @@ -1,93 +0,0 @@ -// -// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 -// - -'use strict' - -const fsPromises = require('fs/promises') -const { Readable } = require('stream') -const chokidar = require('chokidar') -const { globalLogger: logger } = require('@gardener-dashboard/logger') - -class Watcher extends Readable { - #paths - #timeout - #watching - #fsWatcher - #readFile - - constructor (paths, { readyTimeout = 15000, readFile = fsPromises.readFile, ...options } = {}) { - super({ - ...options, - objectMode: true, - }) - logger.debug('[kube-config] creating watcher for', paths) - this.#paths = paths - this.#timeout = readyTimeout - this.#readFile = readFile - this.#watching = false - this.#fsWatcher = chokidar.watch(this.#paths, { - persistent: true, - awaitWriteFinish: true, - ignoreInitial: true, - followSymlinks: true, - disableGlobbing: true, - }) - } - - _construct (callback) { - const timeoutID = setTimeout(() => { - const err = new Error(`FSWatcher timed out after ${this.#timeout} milliseconds`) - logger.error('[kube-config] creating watcher timed out: %s', err.message) - callback(err) - }, this.#timeout) - this.#fsWatcher - .once('ready', () => { - logger.debug('[kube-config] watcher ready') - this.emit('ready') - clearTimeout(timeoutID) - callback() - }) - .on('error', err => { - logger.error('[kube-config] watch files error: %s', err.message) - }) - } - - _read () { - if (this.#watching !== true) { - this.#watching = true - this.#fsWatcher.on('change', async path => { - logger.debug('[kube-config] file watcher received change event for %s', path) - if (this.#paths.includes(path)) { - try { - const value = await this.#readFile(path, 'utf8') - this.push([path, value]) - } catch (err) { - logger.error('[kube-config] read file error %s: %s', err.code, err.message) - } - } - }) - } - } - - _destroy (error, callback) { - const done = closeError => callback(closeError || error) - this.#fsWatcher.close().then(done, done) - } - - async run (fn) { - try { - for await (const args of this) { - fn(...args) - } - } catch (err) { - if (err.name !== 'AbortError') { - logger.error('[kube-config] watch files ended with error: %s', err.message) - } - } - } -} - -module.exports = Watcher diff --git a/packages/kube-config/package.json b/packages/kube-config/package.json index 5920ce855d..db122e5e29 100644 --- a/packages/kube-config/package.json +++ b/packages/kube-config/package.json @@ -26,7 +26,6 @@ "dependencies": { "@gardener-dashboard/logger": "workspace:^", "@gardener-dashboard/test-utils": "workspace:^", - "chokidar": "^4.0.0", "gtoken": "^7.1.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21" @@ -83,7 +82,7 @@ "testEnvironment": "node", "coverageThreshold": { "global": { - "branches": 98, + "branches": 100, "functions": 100, "lines": 100, "statements": 100 diff --git a/yarn.lock b/yarn.lock index 4ee873c678..22d853e211 100644 --- a/yarn.lock +++ b/yarn.lock @@ -721,18 +721,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.1.2, @eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.4.0 - resolution: "@eslint-community/eslint-utils@npm:4.4.0" - dependencies: - eslint-visitor-keys: "npm:^3.3.0" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/7e559c4ce59cd3a06b1b5a517b593912e680a7f981ae7affab0d01d709e99cd5647019be8fafa38c350305bc32f1f7d42c7073edde2ab536c745e365f37b607e - languageName: node - linkType: hard - -"@eslint-community/eslint-utils@npm:^4.4.1": +"@eslint-community/eslint-utils@npm:^4.1.2, @eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.4.1": version: 4.4.1 resolution: "@eslint-community/eslint-utils@npm:4.4.1" dependencies: @@ -743,14 +732,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0": - version: 4.11.1 - resolution: "@eslint-community/regexpp@npm:4.11.1" - checksum: 10c0/fbcc1cb65ef5ed5b92faa8dc542e035269065e7ebcc0b39c81a4fe98ad35cfff20b3c8df048641de15a7757e07d69f85e2579c1a5055f993413ba18c055654f8 - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.12.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0, @eslint-community/regexpp@npm:^4.12.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 @@ -1037,7 +1019,6 @@ __metadata: dependencies: "@gardener-dashboard/logger": "workspace:^" "@gardener-dashboard/test-utils": "workspace:^" - chokidar: "npm:^4.0.0" eslint: "npm:^9.11.0" eslint-plugin-import: "npm:^2.31.0" eslint-plugin-jest: "npm:^28.8.3" @@ -2208,14 +2189,14 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:1.0.5, @types/estree@npm:^1.0.0": +"@types/estree@npm:1.0.5": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d languageName: node linkType: hard -"@types/estree@npm:^1.0.6": +"@types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6": version: 1.0.6 resolution: "@types/estree@npm:1.0.6" checksum: 10c0/cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a @@ -2599,19 +2580,6 @@ __metadata: languageName: node linkType: hard -"@vue/compiler-core@npm:3.5.12": - version: 3.5.12 - resolution: "@vue/compiler-core@npm:3.5.12" - dependencies: - "@babel/parser": "npm:^7.25.3" - "@vue/shared": "npm:3.5.12" - entities: "npm:^4.5.0" - estree-walker: "npm:^2.0.2" - source-map-js: "npm:^1.2.0" - checksum: 10c0/7f004b96330c00dc5b94f436be05ce3b196818a8bb1bfeb8f137aba0691deedd20c53e4aa05de830150578af6106e9f306b1fdf973f2db8470e59e81f0fc3a0f - languageName: node - linkType: hard - "@vue/compiler-core@npm:3.5.13": version: 3.5.13 resolution: "@vue/compiler-core@npm:3.5.13" @@ -2625,17 +2593,7 @@ __metadata: languageName: node linkType: hard -"@vue/compiler-dom@npm:*, @vue/compiler-dom@npm:3.5.12": - version: 3.5.12 - resolution: "@vue/compiler-dom@npm:3.5.12" - dependencies: - "@vue/compiler-core": "npm:3.5.12" - "@vue/shared": "npm:3.5.12" - checksum: 10c0/48a67cd28c25e94dccff3c1e18bf2f79b073e486a856e5b30661e89e50d08cd49ababc43de94626c948da77c8dad859909e32d3ab678079e90dfa5d3e1ddc344 - languageName: node - linkType: hard - -"@vue/compiler-dom@npm:3.5.13": +"@vue/compiler-dom@npm:*, @vue/compiler-dom@npm:3.5.13": version: 3.5.13 resolution: "@vue/compiler-dom@npm:3.5.13" dependencies: @@ -2662,16 +2620,6 @@ __metadata: languageName: node linkType: hard -"@vue/compiler-ssr@npm:3.5.12": - version: 3.5.12 - resolution: "@vue/compiler-ssr@npm:3.5.12" - dependencies: - "@vue/compiler-dom": "npm:3.5.12" - "@vue/shared": "npm:3.5.12" - checksum: 10c0/8a8fc4e2057fa1292860ff8a53af04604dc70f72aa4dcc7136f1c697adca9bc511ba5ffeca0259b14cc6b18119be726cd784845a6669427774793625d6e953b7 - languageName: node - linkType: hard - "@vue/compiler-ssr@npm:3.5.13": version: 3.5.13 resolution: "@vue/compiler-ssr@npm:3.5.13" @@ -2720,19 +2668,7 @@ __metadata: languageName: node linkType: hard -"@vue/server-renderer@npm:*": - version: 3.5.12 - resolution: "@vue/server-renderer@npm:3.5.12" - dependencies: - "@vue/compiler-ssr": "npm:3.5.12" - "@vue/shared": "npm:3.5.12" - peerDependencies: - vue: 3.5.12 - checksum: 10c0/d9f25f165c7d8fd53773238bd53fce4621e61676bbec12a57cd5b29aa4f15d7a2b3e93777665b85666edda57ce7f7deb4504a4596822006684babe0f8d2b41f6 - languageName: node - linkType: hard - -"@vue/server-renderer@npm:3.5.13": +"@vue/server-renderer@npm:*, @vue/server-renderer@npm:3.5.13": version: 3.5.13 resolution: "@vue/server-renderer@npm:3.5.13" dependencies: @@ -2744,13 +2680,6 @@ __metadata: languageName: node linkType: hard -"@vue/shared@npm:3.5.12": - version: 3.5.12 - resolution: "@vue/shared@npm:3.5.12" - checksum: 10c0/48f94406c42921901b21a57a7ebb401bbceb497152baf0554e5d5a11cbaa79958f966042e9d95614c0b02e8681b7e1b6c010fcb8b28c6bda1b090f2ddd7540d8 - languageName: node - linkType: hard - "@vue/shared@npm:3.5.13": version: 3.5.13 resolution: "@vue/shared@npm:3.5.13" @@ -5760,14 +5689,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^15.11.0": - version: 15.11.0 - resolution: "globals@npm:15.11.0" - checksum: 10c0/861e39bb6bd9bd1b9f355c25c962e5eb4b3f0e1567cf60fa6c06e8c502b0ec8706b1cce055d69d84d0b7b8e028bec5418cf629a54e7047e116538d1c1c1a375c - languageName: node - linkType: hard - -"globals@npm:^15.12.0": +"globals@npm:^15.11.0, globals@npm:^15.12.0": version: 15.12.0 resolution: "globals@npm:15.12.0" checksum: 10c0/f34e0a1845b694f45188331742af9f488b07ba7440a06e9d2039fce0386fbbfc24afdbb9846ebdccd4092d03644e43081c49eb27b30f4b88e43af156e1c1dc34 @@ -8384,14 +8306,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0": - version: 1.1.0 - resolution: "picocolors@npm:1.1.0" - checksum: 10c0/86946f6032148801ef09c051c6fb13b5cf942eaf147e30ea79edb91dd32d700934edebe782a1078ff859fb2b816792e97ef4dab03d7f0b804f6b01a0df35e023 - languageName: node - linkType: hard - -"picocolors@npm:^1.1.1": +"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -8464,18 +8379,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.3.11, postcss@npm:^8.4.43": - version: 8.4.47 - resolution: "postcss@npm:8.4.47" - dependencies: - nanoid: "npm:^3.3.7" - picocolors: "npm:^1.1.0" - source-map-js: "npm:^1.2.1" - checksum: 10c0/929f68b5081b7202709456532cee2a145c1843d391508c5a09de2517e8c4791638f71dd63b1898dba6712f8839d7a6da046c72a5e44c162e908f5911f57b5f44 - languageName: node - linkType: hard - -"postcss@npm:^8.4.48": +"postcss@npm:^8.3.11, postcss@npm:^8.4.43, postcss@npm:^8.4.48": version: 8.4.49 resolution: "postcss@npm:8.4.49" dependencies: