{
  "description": "A CompositeResourceDefinition defines the schema for a new custom Kubernetes\nAPI.\n\nRead the Crossplane documentation for\n[more information about CustomResourceDefinitions](https://docs.crossplane.io/latest/concepts/composite-resource-definitions).",
  "properties": {
    "apiVersion": {
      "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
      "type": "string"
    },
    "kind": {
      "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
      "type": "string"
    },
    "metadata": {
      "type": "object"
    },
    "spec": {
      "description": "CompositeResourceDefinitionSpec specifies the desired state of the definition.",
      "properties": {
        "claimNames": {
          "description": "ClaimNames specifies the names of an optional composite resource claim.\nWhen claim names are specified Crossplane will create a namespaced\n'composite resource claim' CRD that corresponds to the defined composite\nresource. This composite resource claim acts as a namespaced proxy for\nthe composite resource; creating, updating, or deleting the claim will\ncreate, update, or delete a corresponding composite resource. You may add\nclaim names to an existing CompositeResourceDefinition, but they cannot\nbe changed or removed once they have been set.\n\nDeprecated: Claims aren't supported in apiextensions.crossplane.io/v2.",
          "properties": {
            "categories": {
              "description": "categories is a list of grouped resources this custom resource belongs to (e.g. 'all').\nThis is published in API discovery documents, and used by clients to support invocations like\n`kubectl get all`.",
              "items": {
                "type": "string"
              },
              "type": "array",
              "x-kubernetes-list-type": "atomic"
            },
            "kind": {
              "description": "kind is the serialized kind of the resource. It is normally CamelCase and singular.\nCustom resource instances will use this value as the `kind` attribute in API calls.",
              "type": "string"
            },
            "listKind": {
              "description": "listKind is the serialized kind of the list for this resource. Defaults to \"`kind`List\".",
              "type": "string"
            },
            "plural": {
              "description": "plural is the plural name of the resource to serve.\nThe custom resources are served under `/apis/<group>/<version>/.../<plural>`.\nMust match the name of the CustomResourceDefinition (in the form `<names.plural>.<group>`).\nMust be all lowercase.",
              "type": "string"
            },
            "shortNames": {
              "description": "shortNames are short names for the resource, exposed in API discovery documents,\nand used by clients to support invocations like `kubectl get <shortname>`.\nIt must be all lowercase.",
              "items": {
                "type": "string"
              },
              "type": "array",
              "x-kubernetes-list-type": "atomic"
            },
            "singular": {
              "description": "singular is the singular name of the resource. It must be all lowercase. Defaults to lowercased `kind`.",
              "type": "string"
            }
          },
          "required": [
            "kind",
            "plural"
          ],
          "type": "object",
          "additionalProperties": false
        },
        "connectionSecretKeys": {
          "description": "ConnectionSecretKeys is the list of connection secret keys the\ndefined XR can publish. If the list is empty, all keys will be\npublished. If the list isn't empty, any connection secret keys that\ndon't appear in the list will be filtered out. Only LegacyCluster XRs\nsupport connection secrets.\n\nDeprecated: XR connection secrets aren't supported in\napiextensions.crossplane.io/v2. Compose a secret instead.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "conversion": {
          "description": "Conversion defines all conversion settings for the defined Composite resource.",
          "properties": {
            "strategy": {
              "description": "strategy specifies how custom resources are converted between versions. Allowed values are:\n- `\"None\"`: The converter only change the apiVersion and would not touch any other field in the custom resource.\n- `\"Webhook\"`: API Server will call to an external webhook to do the conversion. Additional information\n  is needed for this option. This requires spec.preserveUnknownFields to be false, and spec.conversion.webhook to be set.",
              "type": "string"
            },
            "webhook": {
              "description": "webhook describes how to call the conversion webhook. Required when `strategy` is set to `\"Webhook\"`.",
              "properties": {
                "clientConfig": {
                  "description": "clientConfig is the instructions for how to call the webhook if strategy is `Webhook`.",
                  "properties": {
                    "caBundle": {
                      "description": "caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.\nIf unspecified, system trust roots on the apiserver are used.",
                      "format": "byte",
                      "type": "string"
                    },
                    "service": {
                      "description": "service is a reference to the service for this webhook. Either\nservice or url must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.",
                      "properties": {
                        "name": {
                          "description": "name is the name of the service.\nRequired",
                          "type": "string"
                        },
                        "namespace": {
                          "description": "namespace is the namespace of the service.\nRequired",
                          "type": "string"
                        },
                        "path": {
                          "description": "path is an optional URL path at which the webhook will be contacted.",
                          "type": "string"
                        },
                        "port": {
                          "description": "port is an optional service port at which the webhook will be contacted.\n`port` should be a valid port number (1-65535, inclusive).\nDefaults to 443 for backward compatibility.",
                          "format": "int32",
                          "type": "integer"
                        }
                      },
                      "required": [
                        "name",
                        "namespace"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "url": {
                      "description": "url gives the location of the webhook, in standard URL form\n(`scheme://host:port/path`). Exactly one of `url` or `service`\nmust be specified.\n\nThe `host` should not refer to a service running in the cluster; use\nthe `service` field instead. The host might be resolved via external\nDNS in some apiservers (e.g., `kube-apiserver` cannot resolve\nin-cluster DNS as that would be a layering violation). `host` may\nalso be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is\nrisky unless you take great care to run this webhook on all hosts\nwhich run an apiserver which might need to make calls to this\nwebhook. Such installs are likely to be non-portable, i.e., not easy\nto turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in\na URL. You may use the path to pass an arbitrary string to the\nwebhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not\nallowed. Fragments (\"#...\") and query parameters (\"?...\") are not\nallowed, either.",
                      "type": "string"
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                },
                "conversionReviewVersions": {
                  "description": "conversionReviewVersions is an ordered list of preferred `ConversionReview`\nversions the Webhook expects. The API server will use the first version in\nthe list which it supports. If none of the versions specified in this list\nare supported by API server, conversion will fail for the custom resource.\nIf a persisted Webhook configuration specifies allowed versions and does not\ninclude any versions known to the API Server, calls to the webhook will fail.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array",
                  "x-kubernetes-list-type": "atomic"
                }
              },
              "required": [
                "conversionReviewVersions"
              ],
              "type": "object",
              "additionalProperties": false
            }
          },
          "required": [
            "strategy"
          ],
          "type": "object",
          "additionalProperties": false
        },
        "defaultCompositeDeletePolicy": {
          "description": "DefaultCompositeDeletePolicy is the policy used when deleting the Composite\nthat is associated with the Claim if no policy has been specified.\n\nDeprecated: Claims aren't supported in apiextensions.crossplane.io/v2.",
          "enum": [
            "Background",
            "Foreground"
          ],
          "type": "string"
        },
        "defaultCompositionRef": {
          "description": "DefaultCompositionRef refers to the Composition resource that will be used\nin case no composition selector is given.",
          "properties": {
            "name": {
              "description": "Name of the Composition.",
              "type": "string"
            }
          },
          "required": [
            "name"
          ],
          "type": "object",
          "additionalProperties": false
        },
        "defaultCompositionUpdatePolicy": {
          "default": "Automatic",
          "description": "DefaultCompositionUpdatePolicy is the policy used when updating composites after a new\nComposition Revision has been created if no policy has been specified on the composite.",
          "enum": [
            "Automatic",
            "Manual"
          ],
          "type": "string"
        },
        "enforcedCompositionRef": {
          "description": "EnforcedCompositionRef refers to the Composition resource that will be used\nby all composite instances whose schema is defined by this definition.",
          "properties": {
            "name": {
              "description": "Name of the Composition.",
              "type": "string"
            }
          },
          "required": [
            "name"
          ],
          "type": "object",
          "x-kubernetes-validations": [
            {
              "message": "Value is immutable",
              "rule": "self == oldSelf"
            }
          ],
          "additionalProperties": false
        },
        "group": {
          "description": "Group specifies the API group of the defined composite resource.\nComposite resources are served under `/apis/<group>/...`. Must match the\nname of the XRD (in the form `<names.plural>.<group>`).",
          "type": "string",
          "x-kubernetes-validations": [
            {
              "message": "Value is immutable",
              "rule": "self == oldSelf"
            }
          ]
        },
        "metadata": {
          "description": "Metadata specifies the desired metadata for the defined composite resource and claim CRD's.",
          "properties": {
            "annotations": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Annotations is an unstructured key value map stored with a resource that may be\nset by external tools to store and retrieve arbitrary metadata. They are not\nqueryable and should be preserved when modifying objects.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations",
              "type": "object"
            },
            "labels": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Map of string keys and values that can be used to organize and categorize\n(scope and select) objects. May match selectors of replication controllers\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels\nand services.\nThese labels are added to the composite resource and claim CRD's in addition\nto any labels defined by `CompositionResourceDefinition` `metadata.labels`.",
              "type": "object"
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "names": {
          "description": "Names specifies the resource and kind names of the defined composite\nresource.",
          "properties": {
            "categories": {
              "description": "categories is a list of grouped resources this custom resource belongs to (e.g. 'all').\nThis is published in API discovery documents, and used by clients to support invocations like\n`kubectl get all`.",
              "items": {
                "type": "string"
              },
              "type": "array",
              "x-kubernetes-list-type": "atomic"
            },
            "kind": {
              "description": "kind is the serialized kind of the resource. It is normally CamelCase and singular.\nCustom resource instances will use this value as the `kind` attribute in API calls.",
              "type": "string"
            },
            "listKind": {
              "description": "listKind is the serialized kind of the list for this resource. Defaults to \"`kind`List\".",
              "type": "string"
            },
            "plural": {
              "description": "plural is the plural name of the resource to serve.\nThe custom resources are served under `/apis/<group>/<version>/.../<plural>`.\nMust match the name of the CustomResourceDefinition (in the form `<names.plural>.<group>`).\nMust be all lowercase.",
              "type": "string"
            },
            "shortNames": {
              "description": "shortNames are short names for the resource, exposed in API discovery documents,\nand used by clients to support invocations like `kubectl get <shortname>`.\nIt must be all lowercase.",
              "items": {
                "type": "string"
              },
              "type": "array",
              "x-kubernetes-list-type": "atomic"
            },
            "singular": {
              "description": "singular is the singular name of the resource. It must be all lowercase. Defaults to lowercased `kind`.",
              "type": "string"
            }
          },
          "required": [
            "kind",
            "plural"
          ],
          "type": "object",
          "x-kubernetes-validations": [
            {
              "message": "Value is immutable",
              "rule": "self == oldSelf"
            },
            {
              "message": "Plural name must be lowercase",
              "rule": "self.plural == self.plural.lowerAscii()"
            },
            {
              "message": "Singular name must be lowercase",
              "rule": "!has(self.singular) || self.singular == self.singular.lowerAscii()"
            }
          ],
          "additionalProperties": false
        },
        "scope": {
          "default": "Namespaced",
          "description": "Scope of the defined composite resource. Namespaced composite resources\nare scoped to a single namespace. Cluster scoped composite resource exist\noutside the scope of any namespace.",
          "enum": [
            "Namespaced",
            "Cluster"
          ],
          "type": "string",
          "x-kubernetes-validations": [
            {
              "message": "Value is immutable",
              "rule": "self == oldSelf"
            }
          ]
        },
        "versions": {
          "description": "Versions is the list of all API versions of the defined composite\nresource. Version names are used to compute the order in which served\nversions are listed in API discovery. If the version string is\n\"kube-like\", it will sort above non \"kube-like\" version strings, which\nare ordered lexicographically. \"Kube-like\" versions start with a \"v\",\nthen are followed by a number (the major version), then optionally the\nstring \"alpha\" or \"beta\" and another number (the minor version). These\nare sorted first by GA > beta > alpha (where GA is a version with no\nsuffix such as beta or alpha), and then by comparing major version, then\nminor version. An example sorted list of versions: v10, v2, v1, v11beta2,\nv10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.",
          "items": {
            "description": "CompositeResourceDefinitionVersion describes a version of an XR.",
            "properties": {
              "additionalPrinterColumns": {
                "description": "AdditionalPrinterColumns specifies additional columns returned in Table\noutput. If no columns are specified, a single column displaying the age\nof the custom resource is used. See the following link for details:\nhttps://kubernetes.io/docs/reference/using-api/api-concepts/#receiving-resources-as-tables",
                "items": {
                  "description": "CustomResourceColumnDefinition specifies a column for server side printing.",
                  "properties": {
                    "description": {
                      "description": "description is a human readable description of this column.",
                      "type": "string"
                    },
                    "format": {
                      "description": "format is an optional OpenAPI type definition for this column. The 'name' format is applied\nto the primary identifier column to assist in clients identifying column is the resource name.\nSee https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details.",
                      "type": "string"
                    },
                    "jsonPath": {
                      "description": "jsonPath is a simple JSON path (i.e. with array notation) which is evaluated against\neach custom resource to produce the value for this column.",
                      "type": "string"
                    },
                    "name": {
                      "description": "name is a human readable name for the column.",
                      "type": "string"
                    },
                    "priority": {
                      "description": "priority is an integer defining the relative importance of this column compared to others. Lower\nnumbers are considered higher priority. Columns that may be omitted in limited space scenarios\nshould be given a priority greater than 0.",
                      "format": "int32",
                      "type": "integer"
                    },
                    "type": {
                      "description": "type is an OpenAPI type definition for this column.\nSee https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for details.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "jsonPath",
                    "name",
                    "type"
                  ],
                  "type": "object",
                  "additionalProperties": false
                },
                "type": "array"
              },
              "deprecated": {
                "description": "The deprecated field specifies that this version is deprecated and should\nnot be used.",
                "type": "boolean"
              },
              "deprecationWarning": {
                "description": "DeprecationWarning specifies the message that should be shown to the user\nwhen using this version.",
                "maxLength": 256,
                "type": "string"
              },
              "name": {
                "description": "Name of this version, e.g. \u201cv1\u201d, \u201cv2beta1\u201d, etc. Composite resources are\nserved under this version at `/apis/<group>/<version>/...` if `served` is\ntrue.",
                "type": "string"
              },
              "referenceable": {
                "description": "Referenceable specifies that this version may be referenced by a\nComposition in order to configure which resources an XR may be composed\nof. Exactly one version must be marked as referenceable; all Compositions\nmust target only the referenceable version. The referenceable version\nmust be served. It's mapped to the CRD's `spec.versions[*].storage` field.",
                "type": "boolean"
              },
              "schema": {
                "description": "Schema describes the schema used for validation, pruning, and defaulting\nof this version of the defined composite resource. Fields required by all\ncomposite resources will be injected into this schema automatically, and\nwill override equivalently named fields in this schema. Omitting this\nschema results in a schema that contains only the fields required by all\ncomposite resources.",
                "properties": {
                  "openAPIV3Schema": {
                    "description": "OpenAPIV3Schema is the OpenAPI v3 schema to use for validation and\npruning.",
                    "type": "object",
                    "x-kubernetes-preserve-unknown-fields": true
                  }
                },
                "type": "object",
                "additionalProperties": false
              },
              "served": {
                "description": "Served specifies that this version should be served via REST APIs.",
                "type": "boolean"
              }
            },
            "required": [
              "name",
              "referenceable",
              "served"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array"
        }
      },
      "required": [
        "group",
        "names",
        "versions"
      ],
      "type": "object",
      "x-kubernetes-validations": [
        {
          "message": "Claims aren't supported in apiextensions.crossplane.io/v2",
          "rule": "!has(self.claimNames)"
        },
        {
          "message": "XR connection secrets aren't supported in apiextensions.crossplane.io/v2",
          "rule": "!has(self.connectionSecretKeys)"
        }
      ],
      "additionalProperties": false
    },
    "status": {
      "description": "CompositeResourceDefinitionStatus shows the observed state of the definition.",
      "properties": {
        "conditions": {
          "description": "Conditions of the resource.",
          "items": {
            "description": "A Condition that may apply to a resource.",
            "properties": {
              "lastTransitionTime": {
                "description": "LastTransitionTime is the last time this condition transitioned from one\nstatus to another.",
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "description": "A Message containing details about this condition's last transition from\none status to another, if any.",
                "type": "string"
              },
              "observedGeneration": {
                "description": "ObservedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
                "format": "int64",
                "type": "integer"
              },
              "reason": {
                "description": "A Reason for this condition's last transition from one status to another.",
                "type": "string"
              },
              "status": {
                "description": "Status of this condition; is it currently True, False, or Unknown?",
                "type": "string"
              },
              "type": {
                "description": "Type of this condition. At most one of each condition type may apply to\na resource at any point in time.",
                "type": "string"
              }
            },
            "required": [
              "lastTransitionTime",
              "reason",
              "status",
              "type"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        },
        "controllers": {
          "description": "Controllers represents the status of the controllers that power this\ncomposite resource definition.",
          "properties": {
            "compositeResourceClaimType": {
              "description": "The CompositeResourceClaimTypeRef is the type of composite resource claim\nthat Crossplane is currently reconciling for this definition. Its version\nwill eventually become consistent with the definition's referenceable\nversion. Note that clients may interact with any served type; this is\nsimply the type that Crossplane interacts with.",
              "properties": {
                "apiVersion": {
                  "description": "APIVersion of the type.",
                  "type": "string"
                },
                "kind": {
                  "description": "Kind of the type.",
                  "type": "string"
                }
              },
              "required": [
                "apiVersion",
                "kind"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "compositeResourceType": {
              "description": "The CompositeResourceTypeRef is the type of composite resource that\nCrossplane is currently reconciling for this definition. Its version will\neventually become consistent with the definition's referenceable version.\nNote that clients may interact with any served type; this is simply the\ntype that Crossplane interacts with.",
              "properties": {
                "apiVersion": {
                  "description": "APIVersion of the type.",
                  "type": "string"
                },
                "kind": {
                  "description": "Kind of the type.",
                  "type": "string"
                }
              },
              "required": [
                "apiVersion",
                "kind"
              ],
              "type": "object",
              "additionalProperties": false
            }
          },
          "type": "object",
          "additionalProperties": false
        }
      },
      "type": "object",
      "additionalProperties": false
    }
  },
  "type": "object"
}
