openshift/api
GitHub: openshift/api
OpenShift API 类型定义和序列化代码的权威源码仓库,为客户端库和平台组件提供 CRD schema 及 FeatureGate 管理能力。
Stars: 113 | Forks: 794
# api
OpenShift API 定义的权威位置。
此仓库包含 [openshift/client-go](https://github.com/openshift/client-go) 使用的 API 类型定义和序列化代码。
此仓库中的 API 随 OCP 有效载荷(payload)一起发布。
## 添加新的 FeatureGate
将你的 FeatureGate 添加到 `features.go` 中。
合并完全禁用或处于 TechPreview 的 FeatureGate 的门槛是一个开放的 enhancement。
若要在任何 ClusterProfile 上将其提升至 Default,门槛是在所有平台上通过 99% 的测试,或获得 QE 的签字确认。
### 向所有 ClusterProfile 添加新的 TechPreview FeatureGate(Hypershift 和 SelfManaged)
```
FeatureGateMyFeatureName = newFeatureGate("MyFeatureName").
reportProblemsToJiraComponent("my-jira-component").
contactPerson("my-team-lead").
productScope(ocpSpecific).
enableIn(TechPreviewNoUpgrade).
mustRegister()
```
### 仅向所有 Hypershift 添加新的 TechPreview FeatureGate
这将在 Hypershift 的 TechPreview 中被启用,但绝不会在 SelfManaged 上启用
```
FeatureGateMyFeatureName = newFeatureGate("MyFeatureName").
reportProblemsToJiraComponent("my-jira-component").
contactPerson("my-team-lead").
productScope(ocpSpecific).
enableForClusterProfile(Hypershift, TechPreviewNoUpgrade).
mustRegister()
```
### 提升至 Default,但仅限于 Hypershift
这将在所有 ClusterProfile 的 TechPreview 中启用,同时也会在 Hypershift 上默认启用。
在 SelfManaged 上,它将不会在 Default 中启用。
```
FeatureGateMyFeatureName = newFeatureGate("MyFeatureName").
reportProblemsToJiraComponent("my-jira-component").
contactPerson("my-team-lead").
productScope([ocpSpecific|kubernetes]).
enableIn(TechPreviewNoUpgrade).
enableForClusterProfile(Hypershift, Default).
mustRegister()
```
### 在所有 ClusterProfile 上提升至 Default
```
FeatureGateMyFeatureName = newFeatureGate("MyFeatureName").
reportProblemsToJiraComponent("my-jira-component").
contactPerson("my-team-lead").
productScope([ocpSpecific|kubernetes]).
enableIn(Default, TechPreviewNoUpgrade).
mustRegister()
```
### 定义 API 验证测试
测试在逻辑上与 FeatureGate 相关联。
添加任何 FeatureGate 功能时,都需要一个新的测试文件。
测试文件位于 `//tests//FeatureGate.yaml`:
```
route/
v1/
tests/
routes.route.openshift.io/
AAA_ungated.yaml
RouteExternalCertificate.yaml
```
这是一个 `AAA_ungated.yaml` 的示例:
```
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this.
name: Route
crdName: routes.route.openshift.io
tests:
```
这是一个 `RouteExternalCertificate.yaml` 的示例:
```
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this.
name: Route
crdName: routes.route.openshift.io
featureGate: RouteExternalCertificate
tests:
```
集成测试使用 crdName 和 featureGate 来确定哪些测试适用于哪些清单(manifests),并在各种 FeatureSet 和 ClusterProfile 上启用/禁用 FeatureGate 时自动对更改做出反应。
如果你不想复制/粘贴现有文件,[`gen-minimal-test.sh`](tests/hack/gen-minimal-test.sh) 仍然可以用来生成文件占位符。
### 定义 FeatureGate e2e 测试
为了将 API 移入 `Default` FeatureSet,必须证明其完整性和可靠性。
E2E 测试是唯一一种能自动防止随着时间推移发生回归的测试类别:仓库的 presubmit 并不能提供同等的保护。
为了确认这一点,每次将 FeatureGate 添加到 `Default` FeatureSet 时,都会运行一个自动化的验证脚本。
该脚本会查询我们的 CI 系统(sippy/component readiness)以检索给定 FeatureGate 的所有自动化测试列表,
然后执行以下规则。
1. 测试必须包含 `[OCPFeatureGate:]` 或标准的上游标签 `[FeatureGate:]`。
2. 每个 FeatureGate 必须至少包含五个测试。
3. 每个测试必须在我们有对应作业的每一个 TechPreview 平台上运行。(如果你的功能不支持某个变体,请申请例外。)
4. 每个测试必须在每个平台/变体上至少运行 14 次。
5. 每个测试在每个平台/变体上的通过率必须至少达到 95%。
6. 如果测试在最近 7 天内运行了至少 14 次,则测试结果取自最近 7 天。否则,使用最近 14 天的数据。
7. 测试抖动(即使测试最终在重试时通过)也会被视为失败,并对通过率产生负面影响。
如果你的 FeatureGate 缺少自动化测试,可以通过例外流程让 QE 在 PR 上发表评论,从而签字确认该提升操作。
## 定义新的 API
新的 API(新的 CRD)必须首先作为不稳定 API (v1alpha1) 添加。
一旦功能开发得更成熟,并准备好提升为稳定版,API 就可以提升至 v1。
### 为什么我们从 v1alpha1 开始?
通过将 API 作为 v1alpha1 启动,我们可以对 API 进行迭代,并具备进行破坏性更改的能力。
我们可以更改 schema、更改验证、更改整个类型,甚至更改序列化方式,而无需担心。
当对 API 进行更改时,任何现有的客户端代码都需要进行更新以保持匹配。
如果存在破坏性更改(例如更改序列化),则需要使用新版本的 API。
如果我们不为每次破坏性更改提升 API 版本,那么在发生破坏性更改之前生成的客户端,
在尝试反序列化 API 的新序列化格式时就会崩溃(panic)。
如果在开发功能期间需要进行破坏性更改,我们应该将该功能转移到 v1alpha2(或 v1alpha3 等),
直到我们满意并可以将其提升至 v1 为止。
在将功能提升至 v1 时,请勿对 API 进行更改。
### 添加新的稳定 API (v1)
复制时,需要注意哪些 `// +foo` 标记位于上方两个注释块中,哪些位于上方一个注释块中。
```
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// the next line of whitespace matters
// MyAPI is amazing, let me describe it!
//
// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
// +openshift:compatibility-gen:level=1
// +openshift:file-pattern=cvoRunLevel=0000_50,operatorName=my-operator,operatorOrdering=01
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=myapis,scope=Cluster
// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/
// +openshift:capability=IfYouHaveOne
// +kubebuilder:printcolumn:name=Column Name,JSONPath=.status.something,type=string,description=how users should interpret this.
// +kubebuilder:metadata:annotations=key=value
// +kubebuilder:metadata:labels=key=value
// +kubebuilder:validation:XValidation:rule=
type MyAPI struct {
metav1.TypeMeta `json:",inline"`
// metadata is the standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec is the desired state of the cluster version - the operator will work
// to ensure that the desired version is applied to the cluster.
// +kubebuilder:validation:Required
Spec MyAPISpec `json:"spec"`
// status contains information about the available updates and any in-progress
// updates.
// +optional
Status MyAPIStatus `json:"status"`
}
```
### 添加新的不稳定 API (v1alpha)
首先,按照上述说明添加一个 FeatureGate。
与上面类似,但有一个额外的步骤
```
// +kubebuilder:validation:XValidation:rule=
// +openshift:enable:FeatureGate=MyFeatureGate
type MyAPI struct {
...
}
```
### 添加新字段
为了方便起见,这里列出了其他一些用例,但可以查看 `./example` 目录了解更多可能性。
```
// +openshift:validation:FeatureGateAwareXValidation:featureGate=MyFeatureGate,rule="has(oldSelf.coolNewField) ? has(self.coolNewField) : true",message="coolNewField may not be removed once set"
type MyAPI struct {
// +openshift:enable:FeatureGate=MyFeatureGate
// +optional
CoolNewField string `json:"coolNewField"`
}
// EvolvingDiscriminator defines the audit policy profile type.
// +openshift:validation:FeatureGateAwareEnum:featureGate="",enum="";StableValue
// +openshift:validation:FeatureGateAwareEnum:featureGate=MyFeatureGate,enum="";StableValue;TechPreviewOnlyValue
type EvolvingDiscriminator string
const (
// "StableValue" is always present.
StableValue EvolvingDiscriminator = "StableValue"
// "TechPreviewOnlyValue" should only be allowed when TechPreviewNoUpgrade is set in the cluster
TechPreviewOnlyValue EvolvingDiscriminator = "TechPreviewOnlyValue"
)
```
### 必需的标签
除了标准的 `lgtm` 和 `approved` 标签外,此仓库还需要以下标签之一:
`bugzilla/valid-bug` - 如果你的 PR 引用了一个有效的 bugzilla bug,则应用此标签
或者
`qe-approved`、`docs-approved` 和 `px-approved` - openshift 组织中的任何人都可以通过 `/label` 命令应用这些标签。
谁应该应用这些 qe/docs/px 标签?
- 对于在代码冻结前合并功能的 no-FF 团队,他们需要让相应的团队(即 qe、docs、px)将这些标签应用到他们的 api 仓库 PR 上
- 对于在 FF(传统)前合并功能的 FF 团队,他们可以自行应用标签(通过 /label 命令),这对这些团队来说基本无关紧要
- 对于在 FF 之后合并功能的 FF 团队,除非有特殊情况,否则该 PR 应该被拒绝
为什么需要这些标签?
我们需要一种方法,让 no-FF 团队能够在 FF 之后进行合并,而不需要 BZ。对于非共享仓库,该机制是
qe/docs/px-approved 标签。我们将此机制扩展到共享仓库,因为否则 no-FF 团队将
在其功能 PR 上放置一个虚拟的 `bugzilla/valid-bug` 标签,以便能够在功能冻结后合并它们。由于大多数
个人无法将 `bugzilla/valid-bug` 标签应用于 PR,这给这些 PR 带来了额外的障碍。相反,任何人
都可以应用 docs/qe/px-approved 标签,因此需要应用这些标签才能合并的 "FF" 团队可以这样做,而无需
额外的人员参与。
这是否意味着功能冻结团队可以使用 no-FF 流程来合并代码?
不,将一个团队注册为 no-FF 团队需要对该流程进行一些基本的教育,并确保相关的 QE+Docs
参与者了解该团队正在转向该模式。如果你想注册你的团队,请与 Gina Hargan 联系,她将
很乐意帮助你的团队完成入门。
## 将生成的清单 vendoring 到其他仓库
如果你的仓库依赖于 vendoring 和复制 CRD 清单(做得好!),你需要有一行 import 语句,
依赖于包含 CRD 清单的包。
例如,添加
```
import (
_ "github.com/openshift/api/operatoringress/v1/zz_generated.crd-manifests"
)
```
到任何 .go 文件都可以起作用,但通常会选择 `tools/tools.go` 或 `pkg/dependencymagnet/doc.go` 文件。
添加后,`go mod vendor` 将获取包含清单的包,以便你进行复制。
## 生成 CRD schema
自 Kubernetes 1.16 起,在 `apiextensions.k8s.io/v1` 中创建的每个 CRD 都必须具有 [结构化的 OpenAPIV3 schema](https://kubernetes.io/blog/2019/06/20/crd-structural-schema/)。这些 schema 为字段提供服务端验证,并为 `oc explain` 提供说明。此外,schema 还能确保 etcd 中数据的结构一致性。如果没有它,任何内容都可以存储在资源中,这可能会带来安全隐患。由于我们在本仓库中托管了许多 CRD 及其对应的 Go 类型,因此我们也要求它们具有 schema。但是,以下说明同样适用于未托管在此处的 CRD。
这些 schema 通常非常长且复杂,不应手动编写。对于 OpenShift,我们在 [build-machinery-go](https://github.com/openshift/build-machinery-go/) 中提供了 Makefile 目标,用于在上游的 [controller-gen](https://github.com/kubernetes-sigs/controller-tools) 工具基础上生成 schema。
如果你在此仓库中对 CRD 类型进行了更改,只需调用 `make update-codegen-crds` 即可重新生成所有 CRD 并更新清单。如果你的清单没有更新,请确保在我们的[调用 Makefile 目标](https://github.com/openshift/api/blob/release-4.5/Makefile#L17-L29)中包含了其 API 的路径;如果这没有帮助,请尝试调用 `make generate-with-container`,以便在受控环境中执行生成器。
要将此生成器添加到另一个仓库:
1. Vendoring `github.com/openshift/build-machinery-go`
2. 更新你的 `Makefile` 以包含以下内容:
```
include $(addprefix ./vendor/github.com/openshift/build-machinery-go/make/, \
targets/openshift/crd-schema-gen.mk \
)
$(call add-crd-gen,,,,)
```
调用的参数如下:
1. `TARGET_NAME`:生成的 Make 目标的名称。可以是任何内容,只要它不与另一个 make 目标冲突即可。建议使用你的 api 名称。
2. `API_DIRECTORY`:API 的位置。例如,如果你的 Go 类型位于 `pkg/apis/myoperator/v1/types.go` 下,则此项应为 `./pkg/apis/myoperator/v1`。
3. `CRD_MANIFESTS`:CRD 所在的目录。例如,如果是 `manifests/my_operator.crd.yaml`,则应为 `./manifests`
4. `MANIFEST_OUTPUT`:这很可能应该与 `CRD_MANIFESTS` 相同,提供此项只是为了灵活地将生成的代码输出到不同的目录。
你可以根据需要包含对多个不同 API 的调用,或者如果你在同一目录下有多个 API(例如 `v1` 和 `v2beta1`),你可以使用 1 次调用指向你的 API 的父目录。
完成此操作后,调用 `make update-codegen-crds` 应该会为你的 CRD 生成一个新的结构化 OpenAPIV3 schema。
**注意**
- 这不会生成整个 CRD,只会生成它们的 OpenAPIV3 schema。如果你还没有 CRD,生成器将不会有任何输出。
- 确保你的 API 声明正确,以便生成器能够识别它。这意味着,在你的 `doc.go` 中,包含以下内容:
1. `// +groupName=`,这应该与你的 CRD `spec` 中的 `group` 相匹配
2. `// +kubebuilder:validation:Optional`,这告诉操作者除非显式标记了 `// +kubebuilder:validation:Required`,否则字段应该是可选的
有关添加到你的 Go 类型的 API 标记的更多信息,请参阅 [Kubebuilder book](https://book.kubebuilder.io/reference/markers.html)
### 生成顺序
`make update-codegen-crds` 的执行流程大致如下:
1. 运行 `empty-partial-schema` 工具。这会为每个 FeatureGate 在 `zz_generated.featuregated-crd-manifests` 中创建空的 CRD 清单。
2. 运行 `schemapatch` 工具。这会为每个基于 FeatureGate 的 CRD 清单填充 schema。
3. 运行 `manifest-merge` 工具。这会合并所有基于 FeatureGate 的 CRD 清单和 `manual-overrides`
#### empty-partial-schema
该工具基于 gengo,并会扫描所有类型以查找 `// +kubebuilder:object:root=true` 标记。
对于每个匹配的类型,都会对其进行遍历,并跟踪所有包含 `featureGate` 的标签
(`// +openshift:enable:FeatureGate`、`// +openshift:validation:FeatureGateAwareEnum` 和 `// +openshift:validation:FeatureGateAwareXValidation`)。
对于每个类型和每个 FeatureGate,都会在 `zz_generated.featuregated-crd-manifests` 中创建一个文件形式的 CRD 清单。
此阶段重新实现了最常见的 kube-builder 标签,以填充 CRD 清单的非 schema 部分。
这包括诸如 metadata、resource 之类的内容,以及一些自定义的 openshift 标签。
生成器在进行验证时会忽略 schema,因此它不会因为需要运行 `schemapatch` 而失败。
当移除某个 gate 时,生成器应该会清理旧的 FeatureGated 清单。
对于有时会被取消 gating(ungated)的资源,会创建 Ungated 文件。
注入的注解用于指示某个清单属于哪个 FeatureGate:这随后会被 `schemapatch` 和 `manifest-merge` 读取。
#### schemapatch
该工具基于 kubebuilder,并进行了补丁修复以处理 FeatureGated 类型、成员和验证。
它读取由 `empty-partial-schema` 注入的注解,以决定在创建需要注入的 schema 时应将哪个 FeatureGate 视为已启用。
它对于 FeatureGate 在特定的 ClusterProfile、FeatureSet 元组中是启用还是禁用一无所知。
它只需要对所有 FeatureGated 部分清单进行一次遍历。
如果 schema 生成不能满足你的需求,`manual-override-crd-manifests` 允许对 CRD 清单的某些部分进行覆盖。
不再支持 `yamlpatch`。
其格式仅仅是“写出你想要的 CRD,并删除生成器已正确的内容”。
更具体地说,它是服务器端应用(结构化合并差异,structured merge diff)能够正确合并到
原本会生成的 CRD 之上的部分清单。
需要注意的是,你无法使用 kube-apiserver 对此进行测试,因为 CRD schema 使用的是原子列表(atomic lists),而我们不得不对该
schema 打补丁,以指示其为由版本作为键的 map 列表。
#### manifest-merge
该工具基于 gengo,它会在每个 ClusterProfile、FeatureSet 元组的基础上合并 `zz_generated.featuregated-crd-manifests` 和 `manual-override-crd-manifests` 中的文件。
该工具将所有可能的 ClusterProfile 和所有可能的 FeatureSet 作为输入。
然后,它会将 ClusterProfile、FeatureSet 元组映射到对应的已启用和已禁用的 FeatureGate 集合。
接着,对于每个 CRD、ClusterProfile、Feature 元组,它会基于 CRD schema 以及使原子字段成为 map 列表的补丁,使用结构化合并差异(SSA,structured-merge-diff)逻辑合并相关的输入。
关联性是根据以下条件确定的:
1. 此清单是否具有首选的 ClusterProfile 注解:如果有,则遵循它们;如果没有,则将其包含在所有地方。
2. 此清单是否具有 FeatureGate 注解:如果有,则与该 ClusterProfile、FeatureSet 元组的已启用集合进行匹配。
请注意,CustomNoUpgrade 会选择所有内容
一旦我们获得了每个 ClusterProfile、FeatureSet 元组对应的 CRD,我们就会选择要序列化的内容。
其遵循的大致流程如下:
1. 如果所有的 CRD 都相同,则写入单个文件,并使用没有 FeatureSet 和所有 ClusterProfile 进行注解。完成。
2. 如果对于每个 FeatureSet,所有 ClusterProfile 的所有 CRD 都相同,则为每个 FeatureSet 创建一个文件,并使用一个 FeatureSet 和所有 ClusterProfile 进行注解。完成。
3. 如果对于一个 ClusterProfile,所有 FeatureSet 的所有 CRD 都相同,则创建一个文件,并使用没有 FeatureSet 和一个 ClusterProfile 进行注解。继续执行 4。
4. 对于所有剩余的 ClusterProfile、FeatureSet 元组,序列化一个带有一个 FeatureSet 和一个 ClusterProfile 的文件。
标签:3D图, EVTX分析, 子域名突变, 日志审计