Skip to content

Commit

Permalink
chore: rename k8s to kubernetes
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Dec 31, 2023
1 parent e999afd commit 91a3f59
Show file tree
Hide file tree
Showing 33 changed files with 297 additions and 328 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ _Pvt_Extensions
**/appsettings.json
**/appsettings.*.json
!**/appsettings.Template.json
**/k8sconfig.yaml
**/kube-config.yaml

.VSCodeCounter/*
.idea/**
Expand All @@ -254,4 +254,3 @@ _Pvt_Extensions
**/files/**
**/uploads/**
**/.DS_Store

10 changes: 5 additions & 5 deletions docs/pages/config/appsettings.zh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ import { Callout } from "nextra-theme-docs";
"ChallengeNetwork": "",
"Uri": "unix:///var/run/docker.sock"
},
"K8sConfig": {
"KubernetesConfig": {
// optional
"Namespace": "gzctf-challenges",
"ConfigPath": "k8sconfig.yaml",
"ConfigPath": "kube-config.yaml",
"AllowCIDR": [
// allow the cluster CIDR for LB
"10.0.0.0/8"
Expand Down Expand Up @@ -174,15 +174,15 @@ GZCTF 仅支持 PostgreSQL 作为数据库,不支持 MySQL 等其他数据库
#### Kubernetes

- **Namespace:** Kubernetes 命名空间,用于创建题目实例的命名空间,默认为 `gzctf-challenges`
- **ConfigPath:** Kubernetes 配置文件路径,用于连接集群,默认为 `k8sconfig.yaml`
- **ConfigPath:** Kubernetes 配置文件路径,用于连接集群,默认为 `kube-config.yaml`
- **AllowCIDR:** 允许访问 Pod 的 CIDR 白名单
- **DNS:** 避免使用集群 DNS 的自定义 DNS 服务器列表

默认行为请将集群连接配置放入 `k8sconfig.yaml` 文件中,并将其挂载到 `/app` 目录下。实验功能若非了解行为请勿更改。
默认行为请将集群连接配置放入 `kube-config.yaml` 文件中,并将其挂载到 `/app` 目录下。实验功能若非了解行为请勿更改。

<Callout type="info">

请注意更改 `k8sconfig.yaml` 文件中的 `server` 字段,将其指向集群的 API Server 地址。集群默认地址一般为 `https://127.0.0.1:6443`,需要更改为集群实际地址。
请注意更改 `kube-config.yaml` 文件中的 `server` 字段,将其指向集群的 API Server 地址。集群默认地址一般为 `https://127.0.0.1:6443`,需要更改为集群实际地址。

</Callout>

Expand Down
6 changes: 3 additions & 3 deletions docs/pages/deployment/docker-k8s.zh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ sudo k3s kubectl cluster-info

</Callout>

将上述输出的内容保存为 `k8sconfig.yaml`,并更改 `server` 字段为 k3s control-panel 所在机器的 IP,例如
将上述输出的内容保存为 `kube-config.yaml`,并更改 `server` 字段为 k3s control-panel 所在机器的 IP,例如

```yaml
apiVersion: v1
Expand All @@ -90,7 +90,7 @@ clusters:
# ...
```

将其存储至部署 GZCTF 的机器上,和 `docker-compose.yml` 在一个文件夹内,例如 `k8sconfig.yaml`
将其存储至部署 GZCTF 的机器上,和 `docker-compose.yml` 在一个文件夹内,例如 `kube-config.yaml`
之后更改 `docker-compose.yml` 中的挂载信息:

```yaml
Expand All @@ -104,7 +104,7 @@ gzctf:
volumes:
- "./data/files:/app/files"
- "./appsettings.json:/app/appsettings.json:ro"
- "./k8sconfig.yaml:/app/k8sconfig.yaml:ro" # this is required for k8s deployment
- "./kube-config.yaml:/app/kube-config.yaml:ro" # this is required for k8s deployment
# - "/var/run/docker.sock:/var/run/docker.sock" # this is required for docker deployment
depends_on:
- db
Expand Down
14 changes: 7 additions & 7 deletions docs/pages/deployment/k8s-only.zh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ import { Callout } from "nextra-theme-docs";
apiVersion: v1
kind: Secret
metadata:
name: gzctf-k8sconfig
name: gzctf-kube-config
namespace: gzctf-server
type: Opaque
data:
k8sconfig: ... # base64 编码后的 k8s 连接文件
kube-config: ... # base64 编码后的 k8s 连接文件
---
apiVersion: v1
kind: Secret
Expand Down Expand Up @@ -152,9 +152,9 @@ import { Callout } from "nextra-theme-docs";
- name: gzctf-config
mountPath: /app/appsettings.json
subPath: appsettings.json
- name: gzctf-k8sconfig
mountPath: /app/k8sconfig.yaml
subPath: k8sconfig
- name: gzctf-kube-config
mountPath: /app/kube-config.yaml
subPath: kube-config
# 若需要持久化存储日志 .log 文件
# 请为每个 GZCTF 实例额外挂载一个卷至 /app/log
# GZCTF 会自动处理日志文件,并会自动 rotate 和 compress
Expand All @@ -169,9 +169,9 @@ import { Callout } from "nextra-theme-docs";
- name: gzctf-config
configMap:
name: gzctf-config
- name: gzctf-k8sconfig
- name: gzctf-kube-config
secret:
secretName: gzctf-k8sconfig
secretName: gzctf-kube-config
---
apiVersion: apps/v1
kind: Deployment
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/issue/qa.zh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Description of the challenge...

更一般的情况下最方便的部署方式为 Docker + K3s 分离部署,只需要执行 `docker-compose` 即可完成 GZCTF 平台的部署,而 K3s 的部署则只需要执行安装后导出 kubeconfig 挂载给 GZCTF 即可。

如果需要使用 K3s 集群内部署,需要提供两个 PVC(用于数据库及附件存储)、一个 ConfigMap(用于存储 `appsettings.json`)、一个 Secret(用于存储指向自己集群的 `k8sconfig.yaml`)。你可以按需进行数据库部署及 Redis 部署,如果只运行一个 GZCTF 实例,可以不部署 Redis。
如果需要使用 K3s 集群内部署,需要提供两个 PVC(用于数据库及附件存储)、一个 ConfigMap(用于存储 `appsettings.json`)、一个 Secret(用于存储指向自己集群的 `kube-config.yaml`)。你可以按需进行数据库部署及 Redis 部署,如果只运行一个 GZCTF 实例,可以不部署 Redis。

**经测试,出于数据库性能考量,暂不建议使用多实例分布部署,单实例多性能足以支持大多数比赛。**

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/quick-start.zh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ GZCTF 的安全性和前端功能(如操作剪贴板)依赖于 HTTPS,此
volumes:
- "./data/files:/app/files"
- "./appsettings.json:/app/appsettings.json:ro"
# - "./k8sconfig.yaml:/app/k8sconfig.yaml:ro" # this is required for k8s deployment
# - "./kube-config.yaml:/app/kube-config.yaml:ro" # this is required for k8s deployment
- "/var/run/docker.sock:/var/run/docker.sock" # this is required for docker deployment
depends_on:
- db
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/Controllers/AccountController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public async Task<IActionResult> Register([FromBody] RegisterModel model, Cancel
RegisterStatus.EmailConfirmationRequired, StatusCodes.Status200OK));
}

private bool VerifyEmailDomain(string email)
bool VerifyEmailDomain(string email)
{
var mailDomain = email.Split('@')[1];

Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/Controllers/AssetsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public async Task<IActionResult> Upload(List<IFormFile> files, [FromQuery] strin
try
{
List<LocalFile> results = new();
foreach (var file in files.Where(file => file.Length > 0))
foreach (IFormFile? file in files.Where(file => file.Length > 0))
{
LocalFile res = await fileService.CreateOrUpdateFile(file, filename, token);
logger.SystemLog(
Expand Down
27 changes: 12 additions & 15 deletions src/GZCTF/Controllers/GameController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -916,8 +916,7 @@ public async Task<IActionResult> CreateContainer([FromRoute] int id, [FromRoute]

if (DateTimeOffset.UtcNow - instance.LastContainerOperation < TimeSpan.FromSeconds(10))
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Game_OperationTooFrequent)],
StatusCodes.Status429TooManyRequests))
{ StatusCode = StatusCodes.Status429TooManyRequests };
StatusCodes.Status429TooManyRequests)) { StatusCode = StatusCodes.Status429TooManyRequests };

if (instance.Container is not null)
{
Expand All @@ -930,15 +929,15 @@ public async Task<IActionResult> CreateContainer([FromRoute] int id, [FromRoute]

return await gameInstanceRepository.CreateContainer(instance, context.Participation!.Team, context.User!,
context.Game!.ContainerCountLimit, token) switch
{
null or (TaskStatus.Failed, null) => BadRequest(
new RequestResponse(localizer[nameof(Resources.Program.Game_ContainerCreationFailed)])),
(TaskStatus.Denied, null) => BadRequest(
new RequestResponse(localizer[nameof(Resources.Program.Game_ContainerNumberLimitExceeded),
context.Game.ContainerCountLimit])),
(TaskStatus.Success, var x) => Ok(ContainerInfoModel.FromContainer(x!)),
_ => throw new UnreachableException()
};
{
null or (TaskStatus.Failed, null) => BadRequest(
new RequestResponse(localizer[nameof(Resources.Program.Game_ContainerCreationFailed)])),
(TaskStatus.Denied, null) => BadRequest(
new RequestResponse(localizer[nameof(Resources.Program.Game_ContainerNumberLimitExceeded),
context.Game.ContainerCountLimit])),
(TaskStatus.Success, var x) => Ok(ContainerInfoModel.FromContainer(x!)),
_ => throw new UnreachableException()
};
}

/// <summary>
Expand Down Expand Up @@ -1031,8 +1030,7 @@ public async Task<IActionResult> DeleteContainer([FromRoute] int id, [FromRoute]

if (DateTimeOffset.UtcNow - instance.LastContainerOperation < TimeSpan.FromSeconds(10))
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Game_OperationTooFrequent)],
StatusCodes.Status429TooManyRequests))
{ StatusCode = StatusCodes.Status429TooManyRequests };
StatusCodes.Status429TooManyRequests)) { StatusCode = StatusCodes.Status429TooManyRequests };

var destroyId = instance.Container.ContainerId;

Expand Down Expand Up @@ -1066,8 +1064,7 @@ async Task<ContextInfo> GetContextInfo(int id, int challengeId = 0, bool withFla
{
ContextInfo res = new()
{
User = await userManager.GetUserAsync(User),
Game = await gameRepository.GetGameById(id, token)
User = await userManager.GetUserAsync(User), Game = await gameRepository.GetGameById(id, token)
};

if (res.Game is null)
Expand Down
3 changes: 1 addition & 2 deletions src/GZCTF/Controllers/ProxyController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,7 @@ async Task<IActionResult> DoContainerProxy(Guid id, IPEndPoint client, IPEndPoin
TaskStatus.Failed, LogLevel.Debug);
return new JsonResult(new RequestResponse(
localizer[nameof(Resources.Program.Proxy_ContainerConnectionFailed), e.SocketErrorCode],
StatusCodes.Status418ImATeapot))
{ StatusCode = StatusCodes.Status418ImATeapot };
StatusCodes.Status418ImATeapot)) { StatusCode = StatusCodes.Status418ImATeapot };
}

using WebSocket ws = await HttpContext.WebSockets.AcceptWebSocketAsync();
Expand Down
21 changes: 7 additions & 14 deletions src/GZCTF/Controllers/TeamController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ public async Task<IActionResult> UpdateTeam([FromRoute] int id, [FromBody] TeamU

if (team.CaptainId != user!.Id)
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Auth_AccessForbidden)],
StatusCodes.Status403Forbidden))
{ StatusCode = StatusCodes.Status403Forbidden };
StatusCodes.Status403Forbidden)) { StatusCode = StatusCodes.Status403Forbidden };

team.UpdateInfo(model);

Expand Down Expand Up @@ -183,8 +182,7 @@ public async Task<IActionResult> Transfer([FromRoute] int id, [FromBody] TeamTra

if (team.CaptainId != user!.Id)
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Auth_AccessForbidden)],
StatusCodes.Status403Forbidden))
{ StatusCode = StatusCodes.Status403Forbidden };
StatusCodes.Status403Forbidden)) { StatusCode = StatusCodes.Status403Forbidden };

if (team.Locked && await teamRepository.AnyActiveGame(team, token))
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Team_Locked)]));
Expand Down Expand Up @@ -232,8 +230,7 @@ public async Task<IActionResult> InviteCode([FromRoute] int id, CancellationToke

if (team.CaptainId != user!.Id)
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Auth_AccessForbidden)],
StatusCodes.Status403Forbidden))
{ StatusCode = StatusCodes.Status403Forbidden };
StatusCodes.Status403Forbidden)) { StatusCode = StatusCodes.Status403Forbidden };

return Ok(team.InviteCode);
}
Expand Down Expand Up @@ -266,8 +263,7 @@ public async Task<IActionResult> UpdateInviteToken([FromRoute] int id, Cancellat

if (team.CaptainId != user!.Id)
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Auth_AccessForbidden)],
StatusCodes.Status403Forbidden))
{ StatusCode = StatusCodes.Status403Forbidden };
StatusCodes.Status403Forbidden)) { StatusCode = StatusCodes.Status403Forbidden };

team.UpdateInviteToken();

Expand Down Expand Up @@ -305,8 +301,7 @@ public async Task<IActionResult> KickUser([FromRoute] int id, [FromRoute] Guid u

if (team.CaptainId != user!.Id)
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Auth_AccessForbidden)],
StatusCodes.Status403Forbidden))
{ StatusCode = StatusCodes.Status403Forbidden };
StatusCodes.Status403Forbidden)) { StatusCode = StatusCodes.Status403Forbidden };

IDbContextTransaction trans = await teamRepository.BeginTransactionAsync(token);

Expand Down Expand Up @@ -492,8 +487,7 @@ public async Task<IActionResult> Avatar([FromRoute] int id, IFormFile file, Canc

if (team.CaptainId != user!.Id)
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Auth_AccessForbidden)],
StatusCodes.Status403Forbidden))
{ StatusCode = StatusCodes.Status403Forbidden };
StatusCodes.Status403Forbidden)) { StatusCode = StatusCodes.Status403Forbidden };

if (file.Length == 0)
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.File_SizeZero)]));
Expand Down Expand Up @@ -545,8 +539,7 @@ public async Task<IActionResult> DeleteTeam(int id, CancellationToken token)

if (team.CaptainId != user!.Id)
return new JsonResult(new RequestResponse(localizer[nameof(Resources.Program.Auth_AccessForbidden)],
StatusCodes.Status403Forbidden))
{ StatusCode = StatusCodes.Status403Forbidden };
StatusCodes.Status403Forbidden)) { StatusCode = StatusCodes.Status403Forbidden };

if (team.Locked && await teamRepository.AnyActiveGame(team, token))
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Team_Locked)]));
Expand Down
8 changes: 3 additions & 5 deletions src/GZCTF/Extensions/CaptchaExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public override async Task<bool> VerifyAsync(ModelWithCaptcha model, HttpContext
HttpResponseMessage result =
await _httpClient.GetAsync($"{api}?secret={Config.SecretKey}&response={model.Challenge}&remoteip={ip}",
token);
var res = await result.Content.ReadFromJsonAsync<RecaptchaResponseModel>(cancellationToken: token);
var res = await result.Content.ReadFromJsonAsync<RecaptchaResponseModel>(token);

return res is not null && res.Success && res.Score >= Config.GoogleRecaptcha.RecaptchaThreshold;
}
Expand All @@ -84,15 +84,13 @@ public override async Task<bool> VerifyAsync(ModelWithCaptcha model, HttpContext

TurnstileRequestModel req = new()
{
Secret = Config.SecretKey,
Response = model.Challenge,
RemoteIp = ip.ToString()
Secret = Config.SecretKey, Response = model.Challenge, RemoteIp = ip.ToString()
};

const string api = "https://challenges.cloudflare.com/turnstile/v0/siteverify";

HttpResponseMessage result = await _httpClient.PostAsJsonAsync(api, req, token);
var res = await result.Content.ReadFromJsonAsync<TurnstileResponseModel>(cancellationToken: token);
var res = await result.Content.ReadFromJsonAsync<TurnstileResponseModel>(token);

return res is not null && res.Success;
}
Expand Down
11 changes: 6 additions & 5 deletions src/GZCTF/Extensions/DatabaseSinkExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using Namotion.Reflection;
using Serilog;
using Serilog.Configuration;
using Serilog.Core;
Expand Down Expand Up @@ -45,10 +46,10 @@ public void Emit(LogEvent logEvent)
TimeUtc = logEvent.Timestamp.ToUniversalTime(),
Level = logEvent.Level.ToString(),
Message = logEvent.RenderMessage(),
UserName = logEvent.Properties["UserName"].ToString()[1..^1],
Logger = logEvent.Properties["SourceContext"].ToString()[1..^1],
RemoteIP = logEvent.Properties["IP"].ToString()[1..^1],
Status = logEvent.Properties["Status"].ToString(),
UserName = logEvent.TryGetPropertyValue<string>("UserName")?[1..^1],
Logger = logEvent.TryGetPropertyValue<string>("SourceContext")?[1..^1] ?? "",
RemoteIP = logEvent.TryGetPropertyValue<string>("IP")?[1..^1],
Status = logEvent.TryGetPropertyValue<TaskStatus>("Status").ToString(),
Exception = logEvent.Exception?.ToString()
};

Expand Down Expand Up @@ -89,4 +90,4 @@ async Task WriteToDatabase(CancellationToken token = default)
}
catch (TaskCanceledException) { }
}
}
}
2 changes: 1 addition & 1 deletion src/GZCTF/Extensions/SignalRSinkExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ public void Emit(LogEvent logEvent)
// ignored
}
}
}
}
2 changes: 1 addition & 1 deletion src/GZCTF/GZCTF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
</ItemGroup>

<ItemGroup>
<None Update="k8sconfig.yaml">
<None Update="kube-config.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
Expand Down
6 changes: 2 additions & 4 deletions src/GZCTF/Models/AppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,11 @@ public class AppDbContext(DbContextOptions<AppDbContext> options) :

internal static readonly JsonSerializerOptions _jsonOptions = new() { WriteIndented = false };

static ValueConverter<T?, string> GetJsonConverter<T>() where T : class, new()
{
return new ValueConverter<T?, string>(
static ValueConverter<T?, string> GetJsonConverter<T>() where T : class, new() =>
new(
v => JsonSerializer.Serialize(v ?? new(), _jsonOptions),
v => JsonSerializer.Deserialize<T>(v, _jsonOptions)
);
}

static ValueComparer<TList> GetEnumerableComparer<TList, T>()
where T : notnull
Expand Down
10 changes: 2 additions & 8 deletions src/GZCTF/Models/Data/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,8 @@ public class Game
[Required]
public BloodBonus BloodBonus
{
get
{
return BloodBonus.FromValue(BloodBonusValue);
}
set
{
BloodBonusValue = value.Val;
}
get => BloodBonus.FromValue(BloodBonusValue);
set => BloodBonusValue = value.Val;
}

[NotMapped]
Expand Down
Loading

0 comments on commit 91a3f59

Please sign in to comment.