我已经建立了一个开放api格式的模式:
type Test_manifest struct {
metav1.TypeMeta
metav1.ObjectMeta
Spec spec
}
type spec struct {
Policies []string
Resources resources
Results []results
Variables variables
}
这不是完整的模式,只是其中的一部分。下面是实际的yaml文件:
apiVersion: cli.kyverno.io/v1beta1
kind: kyvernotest
metadata:
name: test-check-nvidia-gpus
labels:
foolabel: foovalue
annotations:
fookey: foovalue
我想从用户验证传入的yaml文件,我可以把这个yaml json,然后验证字段的值,但我没有得到如何验证字段本身,我的意思是如果用户写name1
而不是name
然后如何显示错误。基本上是如何验证的关键。
下面是我为值验证所实现的:
test := "cmd/cli/kubectl-kyverno/test/test.yaml"
yamlFile, err := ioutil.ReadFile(test)
if err != nil {
fmt.Printf("Error: failed to read file %v", err)
}
policyBytes, err1 := yaml.ToJSON(yamlFile)
if err1 != nil {
fmt.Printf("failed to convert to JSON")
}
tests := &kyvernov1.Test_manifest{}
if err := json.Unmarshal(policyBytes, tests); err != nil {
fmt.Printf("failed to decode yaml")
}
if tests.TypeMeta.APIVersion == "" {
fmt.Printf("skipping file as tests.TypeMeta.APIVersion not found")
}
if tests.TypeMeta.Kind == "" {
fmt.Printf("skipping file as tests.TypeMeta.Kind not found")
} else if tests.TypeMeta.Kind != "KyvernoTest" {
fmt.Printf("skipping file as tests.TypeMeta.Kind is not `KyvernoTest`")
}
我们也希望这个验证发生在集群之外。
我想到了两件事:
- 我注意到你正试图手工构建一个k8s API扩展,这是很多的返工,我会建议你使用一个框架来处理这个问题。这是推荐的最佳实践,经常使用。这太复杂了,无法手工完成。这里有一些资源。(kube-builder operator-sdk)。这些解决方案也是基于Open-API的。它们可以让你在一个简单的模板中定义你的模式,并为你生成所有的验证和API +控制器代码。
- 如果您需要更多的验证和完整性测试,通常可以在集群中的允许控制器的帮助下完成。它拦截传入的请求,并在API服务器处理请求之前对其执行操作。(用于验证,遵从性,策略执行,身份验证等)您可以在这里阅读更多关于准入控制器的信息。