如何在Kubernetes CRD OpenAPI schema中正确使用oneOf
OpenAPI v3(Kubernetes CRD)互斥属性Schema实现
场景需求
需要为自定义资源的widget字段实现如下校验规则:
- 支持两类配置二选一:
widgetName:字符串类型,传入已有Widget资源的名称widgetDefinition:对象类型,内联定义Widget资源的完整配置
- 两个属性不可同时配置,允许二者均不配置
合法配置示例
- 引用已有Widget资源:
widget: widgetName: Foo
- 内联定义Widget资源:
widget: widgetDefinition: name: Foo size: large color: red
初始写法报错原因
直接在oneOf分支内定义字段类型、属性的写法不符合Kubernetes CRD的结构型Schema(Structural Schema) 强制要求:所有字段的结构定义(包括type、properties、additionalProperties等)必须声明在字段的顶层属性块中,oneOf/anyOf/allOf这类组合校验块内部仅能编写校验规则,不能重复定义字段结构,否则会抛出must be empty to be structural的校验错误。
正确Schema实现
先在widget对象的顶层properties块中完整声明两个字段的全量结构信息,再通过oneOf结合required、not规则实现互斥校验:
versions: - name: v1beta1 schema: openAPIV3Schema: type: object properties: spec: type: object properties: widget: type: object # 顶层定义所有字段结构,满足结构型Schema要求 properties: widgetName: type: string widgetDefinition: type: object properties: name: type: string size: type: string color: type: string # 组合校验块仅写约束规则,不定义结构 oneOf: # 合法场景1:两个字段均不配置 - not: anyOf: - required: ["widgetName"] - required: ["widgetDefinition"] # 合法场景2:仅配置widgetName - required: ["widgetName"] not: required: ["widgetDefinition"] # 合法场景3:仅配置widgetDefinition - required: ["widgetDefinition"] not: required: ["widgetName"]
提示:如果业务要求两个字段必须二选一、不允许都不配置,直接删除
oneOf下第一个场景分支即可。
内容的提问来源于stack exchange,提问作者larsks
相关产品推荐
相关产品推荐

