// Module included in the following assemblies:
//
// * extensions/ce/crd-upgrade-safety.adoc

:_mod-docs-content-type: REFERENCE

[id="examples-unsafe_{context}"]
= Examples of unsafe CRD changes

The following examples demonstrate specific changes to sections of an example custom resource definition (CRD) that would be caught by the CRD upgrade safety preflight check.

For the following examples, consider a CRD object in the following starting state:

.Example CRD object
[%collapsible]
====
[source,yaml]
----
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.13.0
  name: example.test.example.com
spec:
  group: test.example.com
  names:
    kind: Sample
    listKind: SampleList
    plural: samples
    singular: sample
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        properties:
          apiVersion:
            type: string
          kind:
            type: string
          metadata:
            type: object
          spec:
            type: object
          status:
            type: object
          pollInterval:
            type: string
        type: object
    served: true
    storage: true
    subresources:
      status: {}
----
====

[id="scope-change_{context}"]
== Scope change

In the following custom resource definition (CRD) example, the `scope` field is changed from `Namespaced` to `Cluster`:

.Example scope change in a CRD
[%collapsible]
====
[source,yaml]
----
    spec:
      group: test.example.com
      names:
        kind: Sample
        listKind: SampleList
        plural: samples
        singular: sample
      scope: Cluster
      versions:
      - name: v1alpha1
----
====

.Example error output
[%collapsible]
====
[source,text]
----
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "NoScopeChange" validation failed: scope changed from "Namespaced" to "Cluster"
----
====

[id="stored-version-removal_{context}"]
== Removal of a stored version

In the following custom resource definition (CRD) example, the existing stored version, `v1alpha1`, is removed:

.Example removal of a stored version in a CRD
[%collapsible]
====
[source,yaml]
----
      versions:
      - name: v1alpha2
        schema:
          openAPIV3Schema:
            properties:
              apiVersion:
                type: string
              kind:
                type: string
              metadata:
                type: object
              spec:
                type: object
              status:
                type: object
              pollInterval:
                type: string
            type: object
----
====

.Example error output
[%collapsible]
====
[source,text]
----
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "NoStoredVersionRemoved" validation failed: stored version "v1alpha1" removed
----
====

[id="removal-existing-field_{context}"]
== Removal of an existing field

In the following custom resource definition (CRD) example, the `pollInterval` property field is removed from the `v1alpha1` schema:

.Example removal of an existing field in a CRD
[%collapsible]
====
[source,yaml]
----
      versions:
      - name: v1alpha1
        schema:
          openAPIV3Schema:
            properties:
              apiVersion:
                type: string
              kind:
                type: string
              metadata:
                type: object
              spec:
                type: object
              status:
                type: object
            type: object
----
====

.Example error output
[%collapsible]
====
[source,text]
----
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "NoExistingFieldRemoved" validation failed: crd/test.example.com version/v1alpha1 field/^.spec.pollInterval may not be removed
----
====

[id="addition-required-field_{context}"]
== Addition of a required field

In the following custom resource definition (CRD) example, the `pollInterval` property has been changed to a required field:

.Example addition of a required field in a CRD
[%collapsible]
====
[source,yaml]
----
      versions:
      - name: v1alpha2
        schema:
          openAPIV3Schema:
            properties:
              apiVersion:
                type: string
              kind:
                type: string
              metadata:
                type: object
              spec:
                type: object
              status:
                type: object
              pollInterval:
                type: string
            type: object
            required:
            - pollInterval
----
====

.Example error output
[%collapsible]
====
[source,text]
----
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "ChangeValidator" validation failed: version "v1alpha1", field "^": new required fields added: [pollInterval]
----
====