kubewarden/k8s-objects-generator
GitHub: kubewarden/k8s-objects-generator
从 Kubernetes 官方 OpenAPI 规范生成兼容 TinyGo 的 Go 类型定义,使开发者能够用 Go 编写可编译为 WebAssembly 的 Kubernetes 策略代码。
Stars: 8 | Forks: 5
[](https://github.com/kubewarden/community/blob/main/REPOSITORIES.md#stable)
本仓库提供了 CLI 工具 `k8s-objects-generator`。
该工具的目的是处理 Kubernetes 提供的 OpenAPI 文件,并为其中定义的所有类型生成模型。
本项目创建的 Go 模型兼容 [TinyGo](https://tinygo.org/),并且可以使用 JSON 格式进行序列化和反序列化。
## 背景信息
TinyGo 是一个替代性的 Go 编译器,它可以生成非浏览器目标的 WebAssembly 代码。官方的 Go 编译器尚不具备此能力。对于想要编写 Go 代码并将其构建为旨在浏览器之外运行的 WebAssembly 模块的开发者来说,TinyGo 是唯一的选择。
TinyGo 尚不支持完整的 Go 标准库,而且对 Go 反射的支持也有限。
正因如此,无法从上游(例如:`k8s.io/api/core/v1`)导入官方的 Kubernetes Go 库。
导入这些官方 Kubernetes 类型将导致编译失败。
## 技术细节
本节描述了 `k8s-objects-generator` 如何解决阻止在 TinyGo 中使用官方 Kubernetes Go 库的问题。
### 解决编译错误
官方 Kubernetes 库中定义的 Go 类型拥有一系列执行诸如对象验证等操作的方法。
这些方法依赖于 Go 标准库的某些部分以及与 WebAssembly 目标不兼容的第三方库。
好消息是,对于 Kubewarden 场景,我们并不关心这些额外的方法。我们只需要包含所有 Kubernetes 资源的纯 Go 类型。
`k8s-objects-generator` 利用 [go-swagger](https://goswagger.io/) 来处理 Kubernetes 提供的官方 `swagger.json` 文件,并创建其中定义的所有模型。
这些模型是使用 go-swagger 的自定义模板创建的,该模板仅写入对象定义。
然而,go-swagger 生成的模型包含一些 Go 标准库未定义的数据类型。这包括用于处理 base64 编码字节和 datetime 对象的类型。
所有这些自定义数据类型均由 [`github.com/go-openapi/strfmt`](https://github.com/go-openapi/strfmt) 模块提供。
不幸的是,该模块包含的一些依赖项在使用 TinyGo 编译时无法通过。
幸运的是,这些依赖项仅在实现我们不关心的验证方法时才需要。
为了解决这个问题,这里创建了一个精简版的 `github.com/go-openapi/strfmt` 库:
[`github.com/kubewarden/strfmt`](https://github.com/kubewarden/strfmt)。
由 `k8s-objects-generator` 生成的 `go.mod` 文件包含一个 `replace` 指令,该指令将 `github.com/go-openapi/strfmt` 替换为 `github.com/kubewarden/strfmt`。
### 解决“扁平”包问题
默认情况下,swagger 将所有 Kubernetes 对象生成在同一个 Go 包中。
这意味着你最终会在同一个目录下拥有超过 560 个 Go 类型定义,并且对象名称会像 `IoK8sAPICoreV1Pod` 或 `IoK8sApimachineryPkgApisMetaV1ObjectMeta` 这样。
`k8s-objects-generator` 通过将 Kubernetes 开发者提供的大型 swagger 文件拆分为较小的文件来解决这个问题。
该工具为每个包创建一个 swagger 文件。最终代码将具有与官方 Kubernetes Go 库相同的包结构。
在拆分操作期间,OpenAPI 定义会被部分重写,以确保最终对象可以相互解析。
## 需求
必须安装来自 [go-swagger](https://goswagger.io/install.html) 项目的 swagger CLI 工具。
使用此项目生成的类型需要 **TinyGo 0.28.1 或更高版本。**
应安装 swagger 0.29.0 或更高版本
## 用法
从 Kubernetes [upstream repository](https://github.com/kubernetes/kubernetes/tree/release-1.24/api/openapi-spec) 获取 [`swagger.json`](https://github.com/kubernetes/kubernetes/blob/release-1.24/api/openapi-spec/swagger.json) 文件
调用以下命令:
```
k8s-objects-generator -f swagger.json -o ~/k8s-data-types
```
此命令读取由 `-f` 标志引用的 swagger 文件,并在 `~/k8s-data-types` 目录中创建所有文件。
### 输出目录布局
通过 `-o` 标志提供的输出目录将具有以下结构:
```
~/k8s-data-types
|
\-- src
|
\-- github.com
|
\-- kubewarden
|
\-- k8s-objects
```
`k8s-objects-generator` 将使用 `~/k8s-data-types` 作为唯一的 `GOPATH` 调用 `go` 二进制文件。
这意味着,在过程结束时,输出目录还将包含 `pkg` 和其他 `src` 目录。
相关文件将存储在 `~/k8s-data-types/src/github.com/kubewarden/k8s-objects` 目录中。这是你需要保留的唯一目录。
### 将新版本推送到 kubewarden/k8s-objects
根据需要在 `mass-generate.sh` 中设置 `KUBERNETES_VERSION_MIN`、`KUBERNETES_VERSION_MAX`,在 `mass-push.sh` 中设置 `KUBEMINOR`。
删除并重新克隆 kubewarden/k8s-objects。以我为例:
```
cd suse/kw
rm k8s-objects; git clone git@github.com:kubewarden/k8s-objects.git
```
为所有 k8s 版本生成所有文件,每个版本位于其自己的分支上:
```
./mass-generate.sh -m commit.md --git-dir ~/suse/kw/k8s-objects
```
现在,根据需要推送到上游 kubewarden/k8s-objects。你可以推送新 k8s 版本(例如:1.30)的新分支:
```
cd ~/suse/kw/k8s-objects
git push origin release-1.30
git push origin v1.30.0-kw1
```
或者进行批量推送,这可能会覆盖旧分支:
```
mv ~/suse/kw/k8s-objects ~/hacking/kubernetes/kubewarden/k8s-objects
./mass-push.sh -m commit.md --git-dir ~/suse/kw/k8s-objects
```
标签:AI工具, API规范, Go语言, Kubewarden, OpenAPI, Swagger, TinyGo, WASM, WebAssembly, 代码生成器, 子域名突变, 序列化, 数据模型, 无反射, 日志审计, 替代编译器, 程序破解, 策略引擎, 类型定义, 网络安全挑战, 边缘计算