Reputation: 559
While defining a K8 CRD, I need a flexibility to pass any key/value pairs as input while submitting a resource object. https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
image:
type: string
replicas:
type: integer
From the link above, if you see properties can only hold cronSpec
, image
and/or replicas
. Can it be free-form? Meaning I can pass any key/value pairs and in my code I get a collection (may be a map) that can contain key/value pairs.
https://stackoverflow.com/users/14044/mike-bryant I tried with this CRD:
schema:
openAPIV3Schema:
type: object
properties:
apiVersion:
type: string
spec:
type: object
properties:
appProperties:
type: object
properties:
messages:
type: array
items:
type: object
properties:
key:
type: string
value:
type: string
with custom object having input like this:
messages:
- key: "server1"
value: "ping failed"
- key: "server2"
value: "abort"
- key: "server3"
value: "succes"
but when I patch the crd with some update status, k8 fails with below error:
kind=Status, message=the server rejected our request due to an error in our request, metadata=ListMeta(_continue=null, remainingItemCount=null, resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid, status=Failure, additionalProperties={}).:
Upvotes: 4
Views: 3891
Reputation: 47
I wanted to have arbitrarily nested json in my k8s custom resource definition. Unfortunately, while "addtionalProperties: true" seems to work, it only works for ONE LEVEL of specification (i.e. arbitrarily nested json is still not allowed). This DOES NOT agree with the OpenAPI v3 spec which Kubernetes is supposed to be following! I finally settled on the following solution:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: exampleconfigs.mycompany.com
spec:
group: mycompany.com
names:
kind: ExampleConfig
listKind: ExampleConfigList
plural: exampleconfigs
singular: exampleconfig
scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
x-kubernetes-preserve-unknown-fields: true
This solves, the problem completely, i.e., it allows json nested to an arbitrary degree, and is subtle, because you must put the x-kubernetes-preserve-unknown-fields in the 2nd level "object:" field for the tag to work properly, clarifying some of the previous suggestions.
Upvotes: 0
Reputation: 800
We can use additionalProperties
with type: string
for this.
additionalProperties:
type: string
For example, I'm adding customSelector
property to the spec. customSelector
is of type object (a map) with strings for key/values.
spec:
properties:
customSelector:
additionalProperties:
type: string
description: Free form key value pairs
type: object
type: object
Upvotes: 2
Reputation: 1112
I think you can use additionalProperties
for this.
x-kubernetes-preserve-unknown-fields
might also be useful: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#controlling-pruning
Upvotes: 0