I have created a CRD for a resource and currently unable to make them mutually exclusive and optional at the same time:
optionOne:
type: string
optionTwo:
type: string
optionThree:
type: string
optionFour:
type: string
How to combine exclusitivity and optionality of these fields?
I tried using
oneOf:
- not:
required: ["optionOne"]
But it didn't work.
I used Rust and kube-derive
to define a FourOption
type that takes an optional oneOf
value. It generated the following CRD:
fouroption.crd.yaml
:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: fouroptions.example.com
spec:
group: example.com
names:
categories: []
kind: FourOption
plural: fouroptions
shortNames: []
singular: fouroption
scope: Namespaced
versions:
- additionalPrinterColumns: []
name: v1alpha1
schema:
openAPIV3Schema:
description: Stackoverflow 78523396
properties:
spec:
properties:
foo:
nullable: true
oneOf:
- required:
- option_one
- required:
- option_two
- required:
- option_three
- required:
- option_four
properties:
option_four:
type: string
option_one:
type: string
option_three:
type: string
option_two:
type: string
type: object
type: object
required:
- spec
title: FourOption
type: object
served: true
storage: true
subresources: {}
NAMESPACE="78523396"
kubectl create namespace ${NAMESPACE}
kubectl apply --filename=./fouroption.crd.yaml
customresourcedefinition.apiextensions.k8s.io/fouroptions.example.com configured
Then I tested with none; oneof; and multiple:
kind: List
apiVersion: v1
metadata:
items:
# Expect: succeed
- kind: FourOption
apiVersion: example.com/v1alpha1
metadata:
name: none
spec:
foo: null
# Expect: succeed
- kind: FourOption
apiVersion: example.com/v1alpha1
metadata:
name: option-two
spec:
foo:
option_two: Hello Freddie
# Expect: fail
- kind: FourOption
apiVersion: example.com/v1alpha1
metadata:
name: multiple
spec:
foo:
option_two: Hello Freddie
option_four: Hello Freddie
Yields:
fouroption.example.com/none created
fouroption.example.com/option-two created
The FourOption "multiple" is invalid: <nil>: Invalid value: "": "spec.foo" must validate one and only one schema (oneOf). Found 2 valid alternatives