From 31e177bd77e5133e72795e0108511df0fc5d2839 Mon Sep 17 00:00:00 2001 From: GZTime Date: Sun, 23 Jul 2023 16:16:35 +0800 Subject: [PATCH] feat(config): custom k8s config --- docs/pages/config/appsettings.zh.mdx | 21 +- src/GZCTF/ClientApp/package.json | 8 +- src/GZCTF/ClientApp/pnpm-lock.yaml | 277 ++++++++---------- src/GZCTF/Controllers/GameController.cs | 2 +- src/GZCTF/Models/Internal/Configs.cs | 14 + .../Request/Admin/ContainerInstanceModel.cs | 3 +- src/GZCTF/Services/DockerService.cs | 12 +- src/GZCTF/Services/K8sService.cs | 72 +++-- 8 files changed, 213 insertions(+), 196 deletions(-) diff --git a/docs/pages/config/appsettings.zh.mdx b/docs/pages/config/appsettings.zh.mdx index bdd0120df..606e14325 100644 --- a/docs/pages/config/appsettings.zh.mdx +++ b/docs/pages/config/appsettings.zh.mdx @@ -47,6 +47,20 @@ import { Callout } from "nextra-theme-docs"; SwarmMode: false, Uri: "unix:///var/run/docker.sock", }, + K8sConfig: { + // optional + Namespace: "gzctf-challenges", + ConfigPath: "k8sconfig.yaml", + AllowCIDR: [ + // allow the cluster CIDR for LB + "10.0.0.0/8", + ], + DNS: [ + // custom DNS to avoid cluster DNS + "8.8.8.8", + "223.5.5.5", + ], + }, }, RequestLogging: false, DisableRateLimit: false, @@ -121,7 +135,12 @@ GZCTF 仅支持 PostgreSQL 作为数据库,不支持 MySQL 等其他数据库 #### Kubernetes -请将集群连接配置放入 `k8sconfig.yaml` 文件中,并将其挂载到 `/app` 目录下 +- **Namespace:** Kubernetes 命名空间,用于创建题目实例的命名空间,默认为 `gzctf-challenges` +- **ConfigPath:** Kubernetes 配置文件路径,用于连接集群,默认为 `k8sconfig.yaml` +- **AllowCIDR:** [实验功能] 允许访问 Pod 的 CIDR 白名单 +- **DNS:** [实验功能] 避免使用集群 DNS 的自定义 DNS 服务器列表 + +默认行为请将集群连接配置放入 `k8sconfig.yaml` 文件中,并将其挂载到 `/app` 目录下。实验功能若非了解行为请勿更改。 diff --git a/src/GZCTF/ClientApp/package.json b/src/GZCTF/ClientApp/package.json index 84ae39e3a..76db7f743 100644 --- a/src/GZCTF/ClientApp/package.json +++ b/src/GZCTF/ClientApp/package.json @@ -37,7 +37,7 @@ "prismjs": "^1.29.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-pdf": "^7.1.3", + "react-pdf": "^7.2.0", "react-router": "^6.14.2", "react-router-dom": "^6.14.2", "swr": "^2.2.0", @@ -46,10 +46,10 @@ "devDependencies": { "@babel/eslint-parser": "^7.22.9", "@nabla/vite-plugin-eslint": "^1.5.0", - "@trivago/prettier-plugin-sort-imports": "^4.1.1", + "@trivago/prettier-plugin-sort-imports": "^4.2.0", "@types/katex": "^0.16.1", "@types/marked": "^5.0.1", - "@types/node": "20.4.2", + "@types/node": "20.4.4", "@types/prismjs": "^1.26.0", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", @@ -67,7 +67,7 @@ "swagger-typescript-api": "^13.0.0", "tslib": "^2.6.0", "typescript": "5.1.6", - "vite": "^4.4.4", + "vite": "^4.4.6", "vite-plugin-pages": "^0.31.0", "vite-plugin-prismjs": "^0.0.8", "vite-plugin-webfont-dl": "^3.7.6" diff --git a/src/GZCTF/ClientApp/pnpm-lock.yaml b/src/GZCTF/ClientApp/pnpm-lock.yaml index eaf2ea91a..6c4c1815e 100644 --- a/src/GZCTF/ClientApp/pnpm-lock.yaml +++ b/src/GZCTF/ClientApp/pnpm-lock.yaml @@ -84,8 +84,8 @@ dependencies: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) react-pdf: - specifier: ^7.1.3 - version: 7.1.3(react-dom@18.2.0)(react@18.2.0) + specifier: ^7.2.0 + version: 7.2.0(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) react-router: specifier: ^6.14.2 version: 6.14.2(react@18.2.0) @@ -97,7 +97,7 @@ dependencies: version: 2.2.0(react@18.2.0) vite-tsconfig-paths: specifier: ^4.2.0 - version: 4.2.0(typescript@5.1.6)(vite@4.4.4) + version: 4.2.0(typescript@5.1.6)(vite@4.4.6) devDependencies: '@babel/eslint-parser': @@ -105,10 +105,10 @@ devDependencies: version: 7.22.9(@babel/core@7.22.9)(eslint@8.45.0) '@nabla/vite-plugin-eslint': specifier: ^1.5.0 - version: 1.5.0(eslint@8.45.0)(vite@4.4.4) + version: 1.5.0(eslint@8.45.0)(vite@4.4.6) '@trivago/prettier-plugin-sort-imports': - specifier: ^4.1.1 - version: 4.1.1(prettier@3.0.0) + specifier: ^4.2.0 + version: 4.2.0(prettier@3.0.0) '@types/katex': specifier: ^0.16.1 version: 0.16.1 @@ -116,8 +116,8 @@ devDependencies: specifier: ^5.0.1 version: 5.0.1 '@types/node': - specifier: 20.4.2 - version: 20.4.2 + specifier: 20.4.4 + version: 20.4.4 '@types/prismjs': specifier: ^1.26.0 version: 1.26.0 @@ -135,7 +135,7 @@ devDependencies: version: 6.1.0(eslint@8.45.0)(typescript@5.1.6) '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.0.3(vite@4.4.4) + version: 4.0.3(vite@4.4.6) axios: specifier: ^1.4.0 version: 1.4.0 @@ -170,17 +170,17 @@ devDependencies: specifier: 5.1.6 version: 5.1.6 vite: - specifier: ^4.4.4 - version: 4.4.4(@types/node@20.4.2) + specifier: ^4.4.6 + version: 4.4.6(@types/node@20.4.4) vite-plugin-pages: specifier: ^0.31.0 - version: 0.31.0(vite@4.4.4) + version: 0.31.0(vite@4.4.6) vite-plugin-prismjs: specifier: ^0.0.8 version: 0.0.8(prismjs@1.29.0) vite-plugin-webfont-dl: specifier: ^3.7.6 - version: 3.7.6(vite@4.4.4) + version: 3.7.6(vite@4.4.6) packages: @@ -279,23 +279,10 @@ packages: lru-cache: 5.1.1 semver: 6.3.1 - /@babel/helper-environment-visitor@7.21.5: - resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==} - engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-environment-visitor@7.22.5: resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} engines: {node: '>=6.9.0'} - /@babel/helper-function-name@7.21.0: - resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.21.9 - '@babel/types': 7.21.5 - dev: true - /@babel/helper-function-name@7.22.5: resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} engines: {node: '>=6.9.0'} @@ -303,13 +290,6 @@ packages: '@babel/template': 7.22.5 '@babel/types': 7.22.5 - /@babel/helper-hoist-variables@7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.5 - dev: true - /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} @@ -353,13 +333,6 @@ packages: dependencies: '@babel/types': 7.22.5 - /@babel/helper-split-export-declaration@7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.5 - dev: true - /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} @@ -369,6 +342,7 @@ packages: /@babel/helper-string-parser@7.21.5: resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} engines: {node: '>=6.9.0'} + dev: false /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} @@ -412,14 +386,6 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.21.9: - resolution: {integrity: sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.17.0 - dev: true - /@babel/parser@7.22.7: resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==} engines: {node: '>=6.0.0'} @@ -461,15 +427,6 @@ packages: regenerator-runtime: 0.13.11 dev: false - /@babel/template@7.21.9: - resolution: {integrity: sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/parser': 7.21.9 - '@babel/types': 7.21.5 - dev: true - /@babel/template@7.22.5: resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} engines: {node: '>=6.9.0'} @@ -482,13 +439,13 @@ packages: resolution: {integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.22.5 '@babel/generator': 7.17.7 - '@babel/helper-environment-visitor': 7.21.5 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.7 '@babel/types': 7.17.0 debug: 4.3.4 globals: 11.12.0 @@ -517,7 +474,7 @@ packages: resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.19.1 + '@babel/helper-validator-identifier': 7.22.5 to-fast-properties: 2.0.0 dev: true @@ -528,6 +485,7 @@ packages: '@babel/helper-string-parser': 7.21.5 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 + dev: false /@babel/types@7.22.5: resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} @@ -626,176 +584,176 @@ packages: resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} dev: false - /@esbuild/android-arm64@0.18.13: - resolution: {integrity: sha512-j7NhycJUoUAG5kAzGf4fPWfd17N6SM3o1X6MlXVqfHvs2buFraCJzos9vbeWjLxOyBKHyPOnuCuipbhvbYtTAg==} + /@esbuild/android-arm64@0.18.15: + resolution: {integrity: sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==} engines: {node: '>=12'} cpu: [arm64] os: [android] requiresBuild: true optional: true - /@esbuild/android-arm@0.18.13: - resolution: {integrity: sha512-KwqFhxRFMKZINHzCqf8eKxE0XqWlAVPRxwy6rc7CbVFxzUWB2sA/s3hbMZeemPdhN3fKBkqOaFhTbS8xJXYIWQ==} + /@esbuild/android-arm@0.18.15: + resolution: {integrity: sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==} engines: {node: '>=12'} cpu: [arm] os: [android] requiresBuild: true optional: true - /@esbuild/android-x64@0.18.13: - resolution: {integrity: sha512-M2eZkRxR6WnWfVELHmv6MUoHbOqnzoTVSIxgtsyhm/NsgmL+uTmag/VVzdXvmahak1I6sOb1K/2movco5ikDJg==} + /@esbuild/android-x64@0.18.15: + resolution: {integrity: sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==} engines: {node: '>=12'} cpu: [x64] os: [android] requiresBuild: true optional: true - /@esbuild/darwin-arm64@0.18.13: - resolution: {integrity: sha512-f5goG30YgR1GU+fxtaBRdSW3SBG9pZW834Mmhxa6terzcboz7P2R0k4lDxlkP7NYRIIdBbWp+VgwQbmMH4yV7w==} + /@esbuild/darwin-arm64@0.18.15: + resolution: {integrity: sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@esbuild/darwin-x64@0.18.13: - resolution: {integrity: sha512-RIrxoKH5Eo+yE5BtaAIMZaiKutPhZjw+j0OCh8WdvKEKJQteacq0myZvBDLU+hOzQOZWJeDnuQ2xgSScKf1Ovw==} + /@esbuild/darwin-x64@0.18.15: + resolution: {integrity: sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==} engines: {node: '>=12'} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@esbuild/freebsd-arm64@0.18.13: - resolution: {integrity: sha512-AfRPhHWmj9jGyLgW/2FkYERKmYR+IjYxf2rtSLmhOrPGFh0KCETFzSjx/JX/HJnvIqHt/DRQD/KAaVsUKoI3Xg==} + /@esbuild/freebsd-arm64@0.18.15: + resolution: {integrity: sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] requiresBuild: true optional: true - /@esbuild/freebsd-x64@0.18.13: - resolution: {integrity: sha512-pGzWWZJBInhIgdEwzn8VHUBang8UvFKsvjDkeJ2oyY5gZtAM6BaxK0QLCuZY+qoj/nx/lIaItH425rm/hloETA==} + /@esbuild/freebsd-x64@0.18.15: + resolution: {integrity: sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] requiresBuild: true optional: true - /@esbuild/linux-arm64@0.18.13: - resolution: {integrity: sha512-hCzZbVJEHV7QM77fHPv2qgBcWxgglGFGCxk6KfQx6PsVIdi1u09X7IvgE9QKqm38OpkzaAkPnnPqwRsltvLkIQ==} + /@esbuild/linux-arm64@0.18.15: + resolution: {integrity: sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==} engines: {node: '>=12'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-arm@0.18.13: - resolution: {integrity: sha512-4iMxLRMCxGyk7lEvkkvrxw4aJeC93YIIrfbBlUJ062kilUUnAiMb81eEkVvCVoh3ON283ans7+OQkuy1uHW+Hw==} + /@esbuild/linux-arm@0.18.15: + resolution: {integrity: sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==} engines: {node: '>=12'} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-ia32@0.18.13: - resolution: {integrity: sha512-I3OKGbynl3AAIO6onXNrup/ttToE6Rv2XYfFgLK/wnr2J+1g+7k4asLrE+n7VMhaqX+BUnyWkCu27rl+62Adug==} + /@esbuild/linux-ia32@0.18.15: + resolution: {integrity: sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==} engines: {node: '>=12'} cpu: [ia32] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-loong64@0.18.13: - resolution: {integrity: sha512-8pcKDApAsKc6WW51ZEVidSGwGbebYw2qKnO1VyD8xd6JN0RN6EUXfhXmDk9Vc4/U3Y4AoFTexQewQDJGsBXBpg==} + /@esbuild/linux-loong64@0.18.15: + resolution: {integrity: sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-mips64el@0.18.13: - resolution: {integrity: sha512-6GU+J1PLiVqWx8yoCK4Z0GnfKyCGIH5L2KQipxOtbNPBs+qNDcMJr9euxnyJ6FkRPyMwaSkjejzPSISD9hb+gg==} + /@esbuild/linux-mips64el@0.18.15: + resolution: {integrity: sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-ppc64@0.18.13: - resolution: {integrity: sha512-pfn/OGZ8tyR8YCV7MlLl5hAit2cmS+j/ZZg9DdH0uxdCoJpV7+5DbuXrR+es4ayRVKIcfS9TTMCs60vqQDmh+w==} + /@esbuild/linux-ppc64@0.18.15: + resolution: {integrity: sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-riscv64@0.18.13: - resolution: {integrity: sha512-aIbhU3LPg0lOSCfVeGHbmGYIqOtW6+yzO+Nfv57YblEK01oj0mFMtvDJlOaeAZ6z0FZ9D13oahi5aIl9JFphGg==} + /@esbuild/linux-riscv64@0.18.15: + resolution: {integrity: sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-s390x@0.18.13: - resolution: {integrity: sha512-Pct1QwF2sp+5LVi4Iu5Y+6JsGaV2Z2vm4O9Dd7XZ5tKYxEHjFtb140fiMcl5HM1iuv6xXO8O1Vrb1iJxHlv8UA==} + /@esbuild/linux-s390x@0.18.15: + resolution: {integrity: sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==} engines: {node: '>=12'} cpu: [s390x] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-x64@0.18.13: - resolution: {integrity: sha512-zTrIP0KzYP7O0+3ZnmzvUKgGtUvf4+piY8PIO3V8/GfmVd3ZyHJGz7Ht0np3P1wz+I8qJ4rjwJKqqEAbIEPngA==} + /@esbuild/linux-x64@0.18.15: + resolution: {integrity: sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==} engines: {node: '>=12'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@esbuild/netbsd-x64@0.18.13: - resolution: {integrity: sha512-I6zs10TZeaHDYoGxENuksxE1sxqZpCp+agYeW039yqFwh3MgVvdmXL5NMveImOC6AtpLvE4xG5ujVic4NWFIDQ==} + /@esbuild/netbsd-x64@0.18.15: + resolution: {integrity: sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] requiresBuild: true optional: true - /@esbuild/openbsd-x64@0.18.13: - resolution: {integrity: sha512-W5C5nczhrt1y1xPG5bV+0M12p2vetOGlvs43LH8SopQ3z2AseIROu09VgRqydx5qFN7y9qCbpgHLx0kb0TcW7g==} + /@esbuild/openbsd-x64@0.18.15: + resolution: {integrity: sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] requiresBuild: true optional: true - /@esbuild/sunos-x64@0.18.13: - resolution: {integrity: sha512-X/xzuw4Hzpo/yq3YsfBbIsipNgmsm8mE/QeWbdGdTTeZ77fjxI2K0KP3AlhZ6gU3zKTw1bKoZTuKLnqcJ537qw==} + /@esbuild/sunos-x64@0.18.15: + resolution: {integrity: sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==} engines: {node: '>=12'} cpu: [x64] os: [sunos] requiresBuild: true optional: true - /@esbuild/win32-arm64@0.18.13: - resolution: {integrity: sha512-4CGYdRQT/ILd+yLLE5i4VApMPfGE0RPc/wFQhlluDQCK09+b4JDbxzzjpgQqTPrdnP7r5KUtGVGZYclYiPuHrw==} + /@esbuild/win32-arm64@0.18.15: + resolution: {integrity: sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@esbuild/win32-ia32@0.18.13: - resolution: {integrity: sha512-D+wKZaRhQI+MUGMH+DbEr4owC2D7XnF+uyGiZk38QbgzLcofFqIOwFs7ELmIeU45CQgfHNy9Q+LKW3cE8g37Kg==} + /@esbuild/win32-ia32@0.18.15: + resolution: {integrity: sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==} engines: {node: '>=12'} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@esbuild/win32-x64@0.18.13: - resolution: {integrity: sha512-iVl6lehAfJS+VmpF3exKpNQ8b0eucf5VWfzR8S7xFve64NBNz2jPUgx1X93/kfnkfgP737O+i1k54SVQS7uVZA==} + /@esbuild/win32-x64@0.18.15: + resolution: {integrity: sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -1106,7 +1064,7 @@ packages: - utf-8-validate dev: false - /@nabla/vite-plugin-eslint@1.5.0(eslint@8.45.0)(vite@4.4.4): + /@nabla/vite-plugin-eslint@1.5.0(eslint@8.45.0)(vite@4.4.6): resolution: {integrity: sha512-3NR+mHcW4lY9n1t+cqM8W1xM/UQXKpuDyaoJmPPQKoBCEjFoSvE4XcJwG86lk7K0AauqWwecsgEhmdZLDW07YQ==} peerDependencies: eslint: '*' @@ -1115,7 +1073,7 @@ packages: '@types/eslint': 8.40.0 chalk: 4.1.2 eslint: 8.45.0 - vite: 4.4.4(@types/node@20.4.2) + vite: 4.4.6(@types/node@20.4.4) dev: true /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: @@ -1267,17 +1225,17 @@ packages: engines: {node: '>=10'} dev: true - /@trivago/prettier-plugin-sort-imports@4.1.1(prettier@3.0.0): - resolution: {integrity: sha512-dQ2r2uzNr1x6pJsuh/8x0IRA3CBUB+pWEW3J/7N98axqt7SQSm+2fy0FLNXvXGg77xEDC7KHxJlHfLYyi7PDcw==} + /@trivago/prettier-plugin-sort-imports@4.2.0(prettier@3.0.0): + resolution: {integrity: sha512-YBepjbt+ZNBVmN3ev1amQH3lWCmHyt5qTbLCp/syXJRu/Kw2koXh44qayB1gMRxcL/gV8egmjN5xWSrYyfUtyw==} peerDependencies: '@vue/compiler-sfc': 3.x - prettier: 2.x + prettier: 2.x - 3.x peerDependenciesMeta: '@vue/compiler-sfc': optional: true dependencies: '@babel/generator': 7.17.7 - '@babel/parser': 7.21.9 + '@babel/parser': 7.22.7 '@babel/traverse': 7.17.3 '@babel/types': 7.17.0 javascript-natural-sort: 0.7.1 @@ -1324,8 +1282,8 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true - /@types/node@20.4.2: - resolution: {integrity: sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==} + /@types/node@20.4.4: + resolution: {integrity: sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==} /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} @@ -1494,7 +1452,7 @@ packages: eslint-visitor-keys: 3.4.1 dev: true - /@vitejs/plugin-react@4.0.3(vite@4.4.4): + /@vitejs/plugin-react@4.0.3(vite@4.4.6): resolution: {integrity: sha512-pwXDog5nwwvSIzwrvYYmA2Ljcd/ZNlcsSG2Q9CNDBwnsd55UGAyr2doXtB5j+2uymRCnCfExlznzzSFbBRcoCg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -1504,7 +1462,7 @@ packages: '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.9) react-refresh: 0.14.0 - vite: 4.4.4(@types/node@20.4.2) + vite: 4.4.6(@types/node@20.4.4) transitivePeerDependencies: - supports-color dev: true @@ -2026,34 +1984,34 @@ packages: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} dev: true - /esbuild@0.18.13: - resolution: {integrity: sha512-vhg/WR/Oiu4oUIkVhmfcc23G6/zWuEQKFS+yiosSHe4aN6+DQRXIfeloYGibIfVhkr4wyfuVsGNLr+sQU1rWWw==} + /esbuild@0.18.15: + resolution: {integrity: sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.13 - '@esbuild/android-arm64': 0.18.13 - '@esbuild/android-x64': 0.18.13 - '@esbuild/darwin-arm64': 0.18.13 - '@esbuild/darwin-x64': 0.18.13 - '@esbuild/freebsd-arm64': 0.18.13 - '@esbuild/freebsd-x64': 0.18.13 - '@esbuild/linux-arm': 0.18.13 - '@esbuild/linux-arm64': 0.18.13 - '@esbuild/linux-ia32': 0.18.13 - '@esbuild/linux-loong64': 0.18.13 - '@esbuild/linux-mips64el': 0.18.13 - '@esbuild/linux-ppc64': 0.18.13 - '@esbuild/linux-riscv64': 0.18.13 - '@esbuild/linux-s390x': 0.18.13 - '@esbuild/linux-x64': 0.18.13 - '@esbuild/netbsd-x64': 0.18.13 - '@esbuild/openbsd-x64': 0.18.13 - '@esbuild/sunos-x64': 0.18.13 - '@esbuild/win32-arm64': 0.18.13 - '@esbuild/win32-ia32': 0.18.13 - '@esbuild/win32-x64': 0.18.13 + '@esbuild/android-arm': 0.18.15 + '@esbuild/android-arm64': 0.18.15 + '@esbuild/android-x64': 0.18.15 + '@esbuild/darwin-arm64': 0.18.15 + '@esbuild/darwin-x64': 0.18.15 + '@esbuild/freebsd-arm64': 0.18.15 + '@esbuild/freebsd-x64': 0.18.15 + '@esbuild/linux-arm': 0.18.15 + '@esbuild/linux-arm64': 0.18.15 + '@esbuild/linux-ia32': 0.18.15 + '@esbuild/linux-loong64': 0.18.15 + '@esbuild/linux-mips64el': 0.18.15 + '@esbuild/linux-ppc64': 0.18.15 + '@esbuild/linux-riscv64': 0.18.15 + '@esbuild/linux-s390x': 0.18.15 + '@esbuild/linux-x64': 0.18.15 + '@esbuild/netbsd-x64': 0.18.15 + '@esbuild/openbsd-x64': 0.18.15 + '@esbuild/sunos-x64': 0.18.15 + '@esbuild/win32-arm64': 0.18.15 + '@esbuild/win32-ia32': 0.18.15 + '@esbuild/win32-x64': 0.18.15 /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -3206,8 +3164,8 @@ packages: engines: {node: '>=8.6'} dev: true - /postcss@8.4.26: - resolution: {integrity: sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==} + /postcss@8.4.27: + resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.6 @@ -3283,12 +3241,17 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: false - /react-pdf@7.1.3(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-6llkAHFVj24QhheAfB8FMKAlIDTuF2HUK7ULgLNDahJT2WYNvYc41hbHCSZ0DqI0jUtUxEkroq40iQuy0S+o8A==} + /react-pdf@7.2.0(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ZdPTauNSjIK61W3HtUO8eiRCrzDWGp8FF23g8UUtMbW+Fqgd+MsnmEiQBaBrhXpCSoJYHm80lMjVqk7vm+SEaA==} peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true dependencies: + '@types/react': 18.2.15 clsx: 2.0.0 make-cancellable-promise: 1.3.1 make-event-props: 1.6.1 @@ -3949,7 +3912,7 @@ packages: dev: false optional: true - /vite-plugin-pages@0.31.0(vite@4.4.4): + /vite-plugin-pages@0.31.0(vite@4.4.6): resolution: {integrity: sha512-fw3onBfVTXQI7rOzAbSZhmfwvk50+3qNnGZpERjmD93c8nEjrGLyd53eFXYMxcJV4KA1vzi4qIHt2+6tS4dEMw==} peerDependencies: '@vue/compiler-sfc': ^2.7.0 || ^3.0.0 @@ -3966,7 +3929,7 @@ packages: json5: 2.2.3 local-pkg: 0.4.3 picocolors: 1.0.0 - vite: 4.4.4(@types/node@20.4.2) + vite: 4.4.6(@types/node@20.4.4) yaml: 2.3.1 transitivePeerDependencies: - supports-color @@ -3983,7 +3946,7 @@ packages: - supports-color dev: true - /vite-plugin-webfont-dl@3.7.6(vite@4.4.4): + /vite-plugin-webfont-dl@3.7.6(vite@4.4.6): resolution: {integrity: sha512-mJJuMI8w6dOpiDZL1RqWh0nu0wLuWMfdw6UzedpuTHY/Th5LsY9wwT1YyW8FHjjAN3xta/3CapRvgmU4qvPOkQ==} peerDependencies: vite: ^2 || ^3 || ^4 @@ -3992,12 +3955,12 @@ packages: clean-css: 5.3.2 flat-cache: 3.0.4 picocolors: 1.0.0 - vite: 4.4.4(@types/node@20.4.2) + vite: 4.4.6(@types/node@20.4.4) transitivePeerDependencies: - debug dev: true - /vite-tsconfig-paths@4.2.0(typescript@5.1.6)(vite@4.4.4): + /vite-tsconfig-paths@4.2.0(typescript@5.1.6)(vite@4.4.6): resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==} peerDependencies: vite: '*' @@ -4008,14 +3971,14 @@ packages: debug: 4.3.4 globrex: 0.1.2 tsconfck: 2.1.1(typescript@5.1.6) - vite: 4.4.4(@types/node@20.4.2) + vite: 4.4.6(@types/node@20.4.4) transitivePeerDependencies: - supports-color - typescript dev: false - /vite@4.4.4(@types/node@20.4.2): - resolution: {integrity: sha512-4mvsTxjkveWrKDJI70QmelfVqTm+ihFAb6+xf4sjEU2TmUCTlVX87tmg/QooPEMQb/lM9qGHT99ebqPziEd3wg==} + /vite@4.4.6(@types/node@20.4.4): + resolution: {integrity: sha512-EY6Mm8vJ++S3D4tNAckaZfw3JwG3wa794Vt70M6cNJ6NxT87yhq7EC8Rcap3ahyHdo8AhCmV9PTk+vG1HiYn1A==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -4042,9 +4005,9 @@ packages: terser: optional: true dependencies: - '@types/node': 20.4.2 - esbuild: 0.18.13 - postcss: 8.4.26 + '@types/node': 20.4.4 + esbuild: 0.18.15 + postcss: 8.4.27 rollup: 3.26.3 optionalDependencies: fsevents: 2.3.2 diff --git a/src/GZCTF/Controllers/GameController.cs b/src/GZCTF/Controllers/GameController.cs index bf8b1156d..3fe8547c4 100644 --- a/src/GZCTF/Controllers/GameController.cs +++ b/src/GZCTF/Controllers/GameController.cs @@ -375,7 +375,7 @@ public async Task Submissions([FromRoute] int id, [FromQuery] Ans [HttpGet("{id}/CheatInfo")] [ProducesResponseType(typeof(CheatInfoModel[]), StatusCodes.Status200OK)] [ProducesResponseType(typeof(RequestResponse), StatusCodes.Status404NotFound)] - public async Task CheatInfo([FromRoute] int id,CancellationToken token = default) + public async Task CheatInfo([FromRoute] int id, CancellationToken token = default) { var game = await gameRepository.GetGameById(id, token); diff --git a/src/GZCTF/Models/Internal/Configs.cs b/src/GZCTF/Models/Internal/Configs.cs index 456ec18e7..78aed1d76 100644 --- a/src/GZCTF/Models/Internal/Configs.cs +++ b/src/GZCTF/Models/Internal/Configs.cs @@ -86,6 +86,7 @@ public class ContainerProvider public ContainerProviderType Type { get; set; } = ContainerProviderType.Docker; public string PublicEntry { get; set; } = string.Empty; + public K8sConfig? K8sConfig { get; set; } public DockerConfig? DockerConfig { get; set; } } @@ -95,6 +96,19 @@ public class DockerConfig public bool SwarmMode { get; set; } = false; } +public class K8sConfig +{ + public string Namespace { get; set; } = "gzctf-challenges"; + public string KubeConfig { get; set; } = "k8sconfig.yaml"; + + // TODO:wait for JsonObjectCreationHandling release + //public List AllowCIDR { get; set; } = new() { "10.0.0.0/8" }; + //public List DNS { get; set; } = new() { "8.8.8.8", "223.5.5.5", "114.114.114.114" }; + + public string[]? AllowCIDR { get; set; } + public string[]? DNS { get; set; } +} + public class RegistryConfig { public string? ServerAddress { get; set; } diff --git a/src/GZCTF/Models/Request/Admin/ContainerInstanceModel.cs b/src/GZCTF/Models/Request/Admin/ContainerInstanceModel.cs index daa3d1619..db1dde68e 100644 --- a/src/GZCTF/Models/Request/Admin/ContainerInstanceModel.cs +++ b/src/GZCTF/Models/Request/Admin/ContainerInstanceModel.cs @@ -57,7 +57,8 @@ internal static ContainerInstanceModel FromContainer(Container container) var team = container.Instance?.Participation?.Team; var chal = container.Instance?.Challenge; - var model = new ContainerInstanceModel() { + var model = new ContainerInstanceModel() + { Image = container.Image, ContainerGuid = container.Id, ContainerId = container.ContainerId, diff --git a/src/GZCTF/Services/DockerService.cs b/src/GZCTF/Services/DockerService.cs index 00d3a3b79..52b78172a 100644 --- a/src/GZCTF/Services/DockerService.cs +++ b/src/GZCTF/Services/DockerService.cs @@ -1,9 +1,9 @@ using System.Net; +using Docker.DotNet; +using Docker.DotNet.Models; using GZCTF.Models.Internal; using GZCTF.Services.Interface; using GZCTF.Utils; -using Docker.DotNet; -using Docker.DotNet.Models; using Microsoft.Extensions.Options; namespace GZCTF.Services; @@ -18,7 +18,7 @@ public class DockerService : IContainerService public DockerService(IOptions _options, IOptions _registry, ILogger _logger) { - options = _options.Value.DockerConfig ?? new DockerConfig(); + options = _options.Value.DockerConfig ?? new(); publicEntry = _options.Value.PublicEntry; logger = _logger; DockerClientConfiguration cfg = string.IsNullOrEmpty(options.Uri) ? new() : new(new Uri(options.Uri)); @@ -136,7 +136,7 @@ private ServiceCreateParameters GetServiceCreateParameters(ContainerConfig confi } }; - public async Task CreateContainerWithSwarm(ContainerConfig config, CancellationToken token = default) + private async Task CreateContainerWithSwarm(ContainerConfig config, CancellationToken token = default) { var parameters = GetServiceCreateParameters(config); int retry = 0; @@ -157,7 +157,7 @@ private ServiceCreateParameters GetServiceCreateParameters(ContainerConfig confi } else { - logger.SystemLog($"容器 {parameters.Service.Name} 创建失败, 状态:{e.StatusCode.ToString()}", TaskStatus.Failed, LogLevel.Warning); + logger.SystemLog($"容器 {parameters.Service.Name} 创建失败, 状态:{e.StatusCode}", TaskStatus.Failed, LogLevel.Warning); logger.SystemLog($"容器 {parameters.Service.Name} 创建失败, 响应:{e.ResponseBody}", TaskStatus.Failed, LogLevel.Error); return null; } @@ -203,7 +203,7 @@ private ServiceCreateParameters GetServiceCreateParameters(ContainerConfig confi return container; } - public async Task CreateContainerWithSingle(ContainerConfig config, CancellationToken token = default) + private async Task CreateContainerWithSingle(ContainerConfig config, CancellationToken token = default) { var parameters = GetCreateContainerParameters(config); CreateContainerResponse? containerRes = null; diff --git a/src/GZCTF/Services/K8sService.cs b/src/GZCTF/Services/K8sService.cs index a55b64f2b..190eb8c97 100644 --- a/src/GZCTF/Services/K8sService.cs +++ b/src/GZCTF/Services/K8sService.cs @@ -12,7 +12,6 @@ namespace GZCTF.Services; public class K8sService : IContainerService { - private const string Namespace = "gzctf-challenges"; private const string NetworkPolicy = "gzctf-policy"; private readonly ILogger logger; @@ -20,19 +19,21 @@ public class K8sService : IContainerService private readonly string hostIP; private readonly string publicEntry; private readonly string? AuthSecretName; + private readonly K8sConfig options; public K8sService(IOptions _registry, IOptions _provider, ILogger _logger) { logger = _logger; publicEntry = _provider.Value.PublicEntry; + options = _provider.Value.K8sConfig ?? new(); - if (!File.Exists("k8sconfig.yaml")) + if (!File.Exists(options.KubeConfig)) { - LogHelper.SystemLog(logger, "无法加载 K8s 配置文件,请确保挂载 /app/k8sconfig.yaml"); - throw new FileNotFoundException("k8sconfig.yaml"); + LogHelper.SystemLog(logger, $"无法加载 K8s 配置文件,请确保配置文件存在 {options.KubeConfig}"); + throw new FileNotFoundException(options.KubeConfig); } - var config = KubernetesClientConfiguration.BuildConfigFromConfigFile("k8sconfig.yaml"); + var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(options.KubeConfig); hostIP = config.Host[(config.Host.LastIndexOf('/') + 1)..config.Host.LastIndexOf(':')]; @@ -53,8 +54,9 @@ public K8sService(IOptions _registry, IOptions _registry, IOptions() { ["ctf.gzti.me/ResourceId"] = name, @@ -101,7 +103,8 @@ public K8sService(IOptions _registry, IOptions _registry, IOptions() { ["cpu"] = new ResourceQuantity("10m"), - ["memory"] = new ResourceQuantity("32Mi"), - ["ephemeral-storage"] = new ResourceQuantity("128Mi") + ["memory"] = new ResourceQuantity("32Mi") } } } @@ -140,7 +142,7 @@ public K8sService(IOptions _registry, IOptions _registry, IOptions() { ["ctf.gzti.me/ResourceId"] = name } }, Spec = new V1ServiceSpec() @@ -192,14 +194,14 @@ public K8sService(IOptions _registry, IOptions _registry, IOptions ns.Metadata.Name != Namespace)) - kubernetesClient.CoreV1.CreateNamespace(new() { Metadata = new() { Name = Namespace } }); + if (kubernetesClient.CoreV1.ListNamespace().Items.All(ns => ns.Metadata.Name != options.Namespace)) + kubernetesClient.CoreV1.CreateNamespace(new() { Metadata = new() { Name = options.Namespace } }); - if (kubernetesClient.NetworkingV1.ListNamespacedNetworkPolicy(Namespace).Items.All(np => np.Metadata.Name != NetworkPolicy)) + if (kubernetesClient.NetworkingV1.ListNamespacedNetworkPolicy(options.Namespace).Items.All(np => np.Metadata.Name != NetworkPolicy)) { + kubernetesClient.NetworkingV1.CreateNamespacedNetworkPolicy(new() { Metadata = new() { Name = NetworkPolicy }, @@ -272,17 +275,34 @@ private void InitK8s(bool withAuth, RegistryConfig? registry) { To = new[] { - new V1NetworkPolicyPeer() { IpBlock = new() { Cidr = "0.0.0.0/0", Except = new[] { "10.0.0.0/8" } } }, + new V1NetworkPolicyPeer() { + IpBlock = new() { + Cidr = "0.0.0.0/0", + // FIXME: remove nullable when JsonObjectCreationHandling release + Except = options.AllowCIDR ?? new[] { "10.0.0.0/8" } + } + }, } } } } - }, Namespace); + }, options.Namespace); } if (withAuth && registry is not null) { - var auth = Codec.Base64.Encode($"{registry.UserName}:{registry.Password}"); + // check if the UserName and UserName + // will inject the json and make it invalid + foreach (var chr in $"{registry.UserName}{registry.UserName}") + { + if (":@\"\\".Contains(chr)) + { + logger.SystemLog("Registry 用户名或密码中包含非法字符", TaskStatus.Failed, LogLevel.Error); + throw new ArgumentException("Registry 用户名或密码中包含非法字符"); + } + } + + var auth = Codec.Base64.Encode($"{registry.UserName}:{registry.UserName}"); var dockerjson = $"{{\"auths\":{{\"{registry.ServerAddress}\":{{\"auth\":\"{auth}\"," + $"\"username\":\"{registry.UserName}\",\"password\":\"{registry.Password}\"}}}}}}"; var dockerjsonBytes = Encoding.ASCII.GetBytes(dockerjson); @@ -291,7 +311,7 @@ private void InitK8s(bool withAuth, RegistryConfig? registry) Metadata = new V1ObjectMeta() { Name = AuthSecretName, - NamespaceProperty = Namespace, + NamespaceProperty = options.Namespace, }, Data = new Dictionary() { [".dockerconfigjson"] = dockerjsonBytes }, Type = "kubernetes.io/dockerconfigjson" @@ -299,11 +319,11 @@ private void InitK8s(bool withAuth, RegistryConfig? registry) try { - kubernetesClient.CoreV1.ReplaceNamespacedSecret(secret, AuthSecretName, Namespace); + kubernetesClient.CoreV1.ReplaceNamespacedSecret(secret, AuthSecretName, options.Namespace); } catch { - kubernetesClient.CoreV1.CreateNamespacedSecret(secret, Namespace); + kubernetesClient.CoreV1.CreateNamespacedSecret(secret, options.Namespace); } } }