Repository: rancher/fleet
Pull request #1904 (2023-10-26 15:39:51)

Replace wrangler for kubebuilder for generating CRDs
This PR replaces wrangler CRD generation with `controller-gen` (kubebuilder). It also removes the dynamic creation of CRDs from the `fleet-controller`. 
`code-gen` from wrangler is still used to generate code for wrangler controllers (e.g. `BundleController`). This can't be removed until wrangler controllers are not used anymore.

refers to https://github.com/rancher/fleet/issues/1815





Patch:
diff --git a/charts/fleet-crd/templates/crds.yaml b/charts/fleet-crd/templates/crds.yaml
index 75b250c6..c528630e 100644
--- a/charts/fleet-crd/templates/crds.yaml
+++ b/charts/fleet-crd/templates/crds.yaml
@@ -2,14 +2,16 @@
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: bundledeployments.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: BundleDeployment
+    listKind: BundleDeploymentList
     plural: bundledeployments
     singular: bundledeployment
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -88,13 +90,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -104,25 +104,24 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                     type: object
                   nullable: true
                   type: array
@@ -178,7 +177,6 @@ spec:
                                 description: JSONPointers ignore diffs at a certain
                                   JSON path.
                                 items:
-                                  nullable: true
                                   type: string
                                 nullable: true
                                 type: array
@@ -223,6 +221,7 @@ spec:
                       type: object
                     forceSyncGeneration:
                       description: ForceSyncGeneration is used to force a redeployment
+                      format: int64
                       type: integer
                     helm:
                       description: Helm options for the deployment, like the chart
@@ -289,7 +288,6 @@ spec:
                           description: ValuesFiles is a list of files to load values
                             from.
                           items:
-                            nullable: true
                             type: string
                           nullable: true
                           type: array
@@ -356,9 +354,7 @@ spec:
                             when monitoring the Bundle.
                           items:
                             additionalProperties:
-                              nullable: true
                               type: string
-                            nullable: true
                             type: object
                           nullable: true
                           type: array
@@ -387,7 +383,6 @@ spec:
                       type: string
                     namespaceAnnotations:
                       additionalProperties:
-                        nullable: true
                         type: string
                       description: NamespaceAnnotations are annotations that will
                         be appended to the namespace created by Fleet.
@@ -395,7 +390,6 @@ spec:
                       type: object
                     namespaceLabels:
                       additionalProperties:
-                        nullable: true
                         type: string
                       description: NamespaceLabels are labels that will be appended
                         to the namespace created by Fleet.
@@ -419,7 +413,6 @@ spec:
                             will replace the base file. A file named ./overlays/myoverlay/subdir/resource_patch.yaml
                             will patch the base file.
                           items:
-                            nullable: true
                             type: string
                           nullable: true
                           type: array
@@ -482,7 +475,6 @@ spec:
                                 description: JSONPointers ignore diffs at a certain
                                   JSON path.
                                 items:
-                                  nullable: true
                                   type: string
                                 nullable: true
                                 type: array
@@ -527,6 +519,7 @@ spec:
                       type: object
                     forceSyncGeneration:
                       description: ForceSyncGeneration is used to force a redeployment
+                      format: int64
                       type: integer
                     helm:
                       description: Helm options for the deployment, like the chart
@@ -562,7 +555,9 @@ spec:
                           description: ReleaseName sets a custom release name to deploy
                             the chart as. If not specified a release name will be
                             generated by combining the invoking GitRepo.name + GitRepo.path.
+                          maxLength: 53
                           nullable: true
+                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                           type: string
                         repo:
                           description: Repo is the name of the HTTPS helm repo to
@@ -591,7 +586,6 @@ spec:
                           description: ValuesFiles is a list of files to load values
                             from.
                           items:
-                            nullable: true
                             type: string
                           nullable: true
                           type: array
@@ -658,9 +652,7 @@ spec:
                             when monitoring the Bundle.
                           items:
                             additionalProperties:
-                              nullable: true
                               type: string
-                            nullable: true
                             type: object
                           nullable: true
                           type: array
@@ -689,7 +681,6 @@ spec:
                       type: string
                     namespaceAnnotations:
                       additionalProperties:
-                        nullable: true
                         type: string
                       description: NamespaceAnnotations are annotations that will
                         be appended to the namespace created by Fleet.
@@ -697,7 +688,6 @@ spec:
                       type: object
                     namespaceLabels:
                       additionalProperties:
-                        nullable: true
                         type: string
                       description: NamespaceLabels are labels that will be appended
                         to the namespace created by Fleet.
@@ -721,7 +711,6 @@ spec:
                             will replace the base file. A file named ./overlays/myoverlay/subdir/resource_patch.yaml
                             will patch the base file.
                           items:
-                            nullable: true
                             type: string
                           nullable: true
                           type: array
@@ -739,34 +728,32 @@ spec:
                       lastTransitionTime:
                         description: Last time the condition transitioned from one
                           status to another.
-                        nullable: true
                         type: string
                       lastUpdateTime:
                         description: The last time this condition was updated.
-                        nullable: true
                         type: string
                       message:
                         description: Human-readable message indicating details about
                           last transition
-                        nullable: true
                         type: string
                       reason:
                         description: The reason for the condition's last transition.
-                        nullable: true
                         type: string
                       status:
                         description: Status of the condition, one of True, False,
                           Unknown.
-                        nullable: true
                         type: string
                       type:
                         description: Type of cluster condition.
-                        nullable: true
                         type: string
+                    required:
+                      - status
+                      - type
                     type: object
                   nullable: true
                   type: array
                 display:
+                  nullable: true
                   properties:
                     deployed:
                       nullable: true
@@ -831,12 +818,9 @@ spec:
                             type: boolean
                           message:
                             items:
-                              nullable: true
                               type: string
-                            nullable: true
                             type: array
                           state:
-                            nullable: true
                             type: string
                           transitioning:
                             type: boolean
@@ -867,6 +851,7 @@ spec:
                         nullable: true
                         type: string
                       createdAt:
+                        format: date-time
                         nullable: true
                         type: string
                       kind:
@@ -882,6 +867,7 @@ spec:
                   nullable: true
                   type: array
                 syncGeneration:
+                  format: int64
                   nullable: true
                   type: integer
               type: object
@@ -894,14 +880,16 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: bundlenamespacemappings.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: BundleNamespaceMapping
+    listKind: BundleNamespaceMappingList
     plural: bundlenamespacemappings
     singular: bundlenamespacemapping
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - name: v1alpha1
@@ -931,13 +919,11 @@ spec:
                       key:
                         description: key is the label key that the selector applies
                           to.
-                        nullable: true
                         type: string
                       operator:
                         description: operator represents a key's relationship to a
                           set of values. Valid operators are In, NotIn, Exists and
                           DoesNotExist.
-                        nullable: true
                         type: string
                       values:
                         description: values is an array of string values. If the operator
@@ -946,25 +932,24 @@ spec:
                           be empty. This array is replaced during a strategic merge
                           patch.
                         items:
-                          nullable: true
                           type: string
-                        nullable: true
                         type: array
+                    required:
+                      - key
+                      - operator
                     type: object
-                  nullable: true
                   type: array
                 matchLabels:
                   additionalProperties:
-                    nullable: true
                     type: string
                   description: matchLabels is a map of {key,value} pairs. A single
                     {key,value} in the matchLabels map is equivalent to an element
                     of matchExpressions, whose key field is "key", the operator is
                     "In", and the values array contains only "value". The requirements
                     are ANDed.
-                  nullable: true
                   type: object
               type: object
+              x-kubernetes-map-type: atomic
             kind:
               description: 'Kind is a string value representing the REST resource
                 this object represents. Servers may infer this from the endpoint the
@@ -990,13 +975,11 @@ spec:
                       key:
                         description: key is the label key that the selector applies
                           to.
-                        nullable: true
                         type: string
                       operator:
                         description: operator represents a key's relationship to a
                           set of values. Valid operators are In, NotIn, Exists and
                           DoesNotExist.
-                        nullable: true
                         type: string
                       values:
                         description: values is an array of string values. If the operator
@@ -1005,25 +988,24 @@ spec:
                           be empty. This array is replaced during a strategic merge
                           patch.
                         items:
-                          nullable: true
                           type: string
-                        nullable: true
                         type: array
+                    required:
+                      - key
+                      - operator
                     type: object
-                  nullable: true
                   type: array
                 matchLabels:
                   additionalProperties:
-                    nullable: true
                     type: string
                   description: matchLabels is a map of {key,value} pairs. A single
                     {key,value} in the matchLabels map is equivalent to an element
                     of matchExpressions, whose key field is "key", the operator is
                     "In", and the values array contains only "value". The requirements
                     are ANDed.
-                  nullable: true
                   type: object
               type: object
+              x-kubernetes-map-type: atomic
           type: object
       served: true
       storage: true
@@ -1033,14 +1015,16 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: bundles.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: Bundle
+    listKind: BundleList
     plural: bundles
     singular: bundle
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -1125,13 +1109,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -1141,25 +1123,24 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                     type: object
                   nullable: true
                   type: array
@@ -1184,7 +1165,6 @@ spec:
                             description: JSONPointers ignore diffs at a certain JSON
                               path.
                             items:
-                              nullable: true
                               type: string
                             nullable: true
                             type: array
@@ -1227,6 +1207,7 @@ spec:
                   type: object
                 forceSyncGeneration:
                   description: ForceSyncGeneration is used to force a redeployment
+                  format: int64
                   type: integer
                 helm:
                   description: Helm options for the deployment, like the chart name,
@@ -1291,7 +1272,6 @@ spec:
                     valuesFiles:
                       description: ValuesFiles is a list of files to load values from.
                       items:
-                        nullable: true
                         type: string
                       nullable: true
                       type: array
@@ -1357,9 +1337,7 @@ spec:
                         when monitoring the Bundle.
                       items:
                         additionalProperties:
-                          nullable: true
                           type: string
-                        nullable: true
                         type: object
                       nullable: true
                       type: array
@@ -1387,7 +1365,6 @@ spec:
                   type: string
                 namespaceAnnotations:
                   additionalProperties:
-                    nullable: true
                     type: string
                   description: NamespaceAnnotations are annotations that will be appended
                     to the namespace created by Fleet.
@@ -1395,7 +1372,6 @@ spec:
                   type: object
                 namespaceLabels:
                   additionalProperties:
-                    nullable: true
                     type: string
                   description: NamespaceLabels are labels that will be appended to
                     the namespace created by Fleet.
@@ -1415,19 +1391,15 @@ spec:
                     properties:
                       content:
                         description: The content of the resource, can be compressed.
-                        nullable: true
                         type: string
                       encoding:
                         description: Encoding is either empty or "base64+gz".
-                        nullable: true
                         type: string
                       name:
                         description: Name of the resource, can include the bundle's
                           internal path.
-                        nullable: true
                         type: string
                     type: object
-                  nullable: true
                   type: array
                 rolloutStrategy:
                   description: RolloutStrategy controls the rollout of bundles, by
@@ -1435,12 +1407,18 @@ spec:
                   nullable: true
                   properties:
                     autoPartitionSize:
+                      anyOf:
+                        - type: integer
+                        - type: string
                       description: 'A number or percentage of how to automatically
                         partition clusters if no specific partitioning strategy is
                         configured. default: 25%'
                       nullable: true
                       x-kubernetes-int-or-string: true
                     maxUnavailable:
+                      anyOf:
+                        - type: integer
+                        - type: string
                       description: 'A number or percentage of clusters that can be
                         unavailable during an update of a bundle. This follows the
                         same basic approach as a deployment rollout strategy. Once
@@ -1450,6 +1428,9 @@ spec:
                       nullable: true
                       x-kubernetes-int-or-string: true
                     maxUnavailablePartitions:
+                      anyOf:
+                        - type: integer
+                        - type: string
                       description: 'A number or percentage of cluster partitions that
                         can be unavailable during an update of a bundle. default:
                         0'
@@ -1465,12 +1446,10 @@ spec:
                         properties:
                           clusterGroup:
                             description: A cluster group name to include in this partition
-                            nullable: true
                             type: string
                           clusterGroupSelector:
                             description: Selector matching cluster group labels to
                               include in this partition
-                            nullable: true
                             properties:
                               matchExpressions:
                                 description: matchExpressions is a list of label selector
@@ -1483,13 +1462,11 @@ spec:
                                     key:
                                       description: key is the label key that the selector
                                         applies to.
-                                      nullable: true
                                       type: string
                                     operator:
                                       description: operator represents a key's relationship
                                         to a set of values. Valid operators are In,
                                         NotIn, Exists and DoesNotExist.
-                                      nullable: true
                                       type: string
                                     values:
                                       description: values is an array of string values.
@@ -1499,34 +1476,31 @@ spec:
                                         be empty. This array is replaced during a
                                         strategic merge patch.
                                       items:
-                                        nullable: true
                                         type: string
-                                      nullable: true
                                       type: array
+                                  required:
+                                    - key
+                                    - operator
                                   type: object
-                                nullable: true
                                 type: array
                               matchLabels:
                                 additionalProperties:
-                                  nullable: true
                                   type: string
                                 description: matchLabels is a map of {key,value} pairs.
                                   A single {key,value} in the matchLabels map is equivalent
                                   to an element of matchExpressions, whose key field
                                   is "key", the operator is "In", and the values array
                                   contains only "value". The requirements are ANDed.
-                                nullable: true
                                 type: object
                             type: object
+                            x-kubernetes-map-type: atomic
                           clusterName:
                             description: ClusterName is the name of a cluster to include
                               in this partition
-                            nullable: true
                             type: string
                           clusterSelector:
                             description: Selector matching cluster labels to include
                               in this partition
-                            nullable: true
                             properties:
                               matchExpressions:
                                 description: matchExpressions is a list of label selector
@@ -1539,13 +1513,11 @@ spec:
                                     key:
                                       description: key is the label key that the selector
                                         applies to.
-                                      nullable: true
                                       type: string
                                     operator:
                                       description: operator represents a key's relationship
                                         to a set of values. Valid operators are In,
                                         NotIn, Exists and DoesNotExist.
-                                      nullable: true
                                       type: string
                                     values:
                                       description: values is an array of string values.
@@ -1555,35 +1527,35 @@ spec:
                                         be empty. This array is replaced during a
                                         strategic merge patch.
                                       items:
-                                        nullable: true
                                         type: string
-                                      nullable: true
                                       type: array
+                                  required:
+                                    - key
+                                    - operator
                                   type: object
-                                nullable: true
                                 type: array
                               matchLabels:
                                 additionalProperties:
-                                  nullable: true
                                   type: string
                                 description: matchLabels is a map of {key,value} pairs.
                                   A single {key,value} in the matchLabels map is equivalent
                                   to an element of matchExpressions, whose key field
                                   is "key", the operator is "In", and the values array
                                   contains only "value". The requirements are ANDed.
-                                nullable: true
                                 type: object
                             type: object
+                            x-kubernetes-map-type: atomic
                           maxUnavailable:
+                            anyOf:
+                              - type: integer
+                              - type: string
                             description: 'A number or percentage of clusters that
                               can be unavailable in this partition before this partition
                               is treated as done. default: 10%'
-                            nullable: true
                             x-kubernetes-int-or-string: true
                           name:
                             description: A user-friendly name given to the partition
                               used for Display (optional).
-                            nullable: true
                             type: string
                         type: object
                       nullable: true
@@ -1623,13 +1595,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -1639,25 +1609,24 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                       clusterName:
                         nullable: true
                         type: string
@@ -1679,13 +1648,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -1695,30 +1662,28 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                       name:
                         nullable: true
                         type: string
                     type: object
-                  nullable: true
                   type: array
                 targets:
                   description: Targets refer to the clusters which will be deployed
@@ -1750,13 +1715,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -1766,25 +1729,24 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                       clusterName:
                         description: ClusterName to match a specific cluster by name
                           that will be selected
@@ -1809,13 +1771,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -1825,25 +1785,24 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                       correctDrift:
                         description: CorrectDrift specifies how drift correction should
                           work.
@@ -1889,7 +1848,6 @@ spec:
                                   description: JSONPointers ignore diffs at a certain
                                     JSON path.
                                   items:
-                                    nullable: true
                                     type: string
                                   nullable: true
                                   type: array
@@ -1940,6 +1898,7 @@ spec:
                         type: boolean
                       forceSyncGeneration:
                         description: ForceSyncGeneration is used to force a redeployment
+                        format: int64
                         type: integer
                       helm:
                         description: Helm options for the deployment, like the chart
@@ -1976,7 +1935,9 @@ spec:
                               deploy the chart as. If not specified a release name
                               will be generated by combining the invoking GitRepo.name
                               + GitRepo.path.
+                            maxLength: 53
                             nullable: true
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                             type: string
                           repo:
                             description: Repo is the name of the HTTPS helm repo to
@@ -2005,7 +1966,6 @@ spec:
                             description: ValuesFiles is a list of files to load values
                               from.
                             items:
-                              nullable: true
                               type: string
                             nullable: true
                             type: array
@@ -2073,9 +2033,7 @@ spec:
                               ignored when monitoring the Bundle.
                             items:
                               additionalProperties:
-                                nullable: true
                                 type: string
-                              nullable: true
                               type: object
                             nullable: true
                             type: array
@@ -2100,7 +2058,6 @@ spec:
                         description: Name of target. This value is largely for display
                           and logging. If not specified a default name of the format
                           "target000" will be used
-                        nullable: true
                         type: string
                       namespace:
                         description: TargetNamespace if present will assign all resource
@@ -2110,7 +2067,6 @@ spec:
                         type: string
                       namespaceAnnotations:
                         additionalProperties:
-                          nullable: true
                           type: string
                         description: NamespaceAnnotations are annotations that will
                           be appended to the namespace created by Fleet.
@@ -2118,7 +2074,6 @@ spec:
                         type: object
                       namespaceLabels:
                         additionalProperties:
-                          nullable: true
                           type: string
                         description: NamespaceLabels are labels that will be appended
                           to the namespace created by Fleet.
@@ -2142,13 +2097,11 @@ spec:
                               will replace the base file. A file named ./overlays/myoverlay/subdir/resource_patch.yaml
                               will patch the base file.
                             items:
-                              nullable: true
                               type: string
                             nullable: true
                             type: array
                         type: object
                     type: object
-                  nullable: true
                   type: array
                 yaml:
                   description: YAML options, if using raw YAML these are names that
@@ -2163,7 +2116,6 @@ spec:
                         replace the base file. A file named ./overlays/myoverlay/subdir/resource_patch.yaml
                         will patch the base file.
                       items:
-                        nullable: true
                         type: string
                       nullable: true
                       type: array
@@ -2179,32 +2131,28 @@ spec:
                       lastTransitionTime:
                         description: Last time the condition transitioned from one
                           status to another.
-                        nullable: true
                         type: string
                       lastUpdateTime:
                         description: The last time this condition was updated.
-                        nullable: true
                         type: string
                       message:
                         description: Human-readable message indicating details about
                           last transition
-                        nullable: true
                         type: string
                       reason:
                         description: The reason for the condition's last transition.
-                        nullable: true
                         type: string
                       status:
                         description: Status of the condition, one of True, False,
                           Unknown.
-                        nullable: true
                         type: string
                       type:
                         description: Type of cluster condition.
-                        nullable: true
                         type: string
+                    required:
+                      - status
+                      - type
                     type: object
-                  nullable: true
                   type: array
                 display:
                   description: Display contains the number of ready, desiredready
@@ -2242,6 +2190,7 @@ spec:
                 observedGeneration:
                   description: ObservedGeneration is the current generation of the
                     bundle.
+                  format: int64
                   type: integer
                 partitions:
                   description: PartitionStatus lists the status of each partition.
@@ -2328,7 +2277,6 @@ spec:
                                         nullable: true
                                         type: string
                                     type: object
-                                  nullable: true
                                   type: array
                                 name:
                                   description: Name is the name of the resource.
@@ -2360,12 +2308,9 @@ spec:
                                             type: boolean
                                           message:
                                             items:
-                                              nullable: true
                                               type: string
-                                            nullable: true
                                             type: array
                                           state:
-                                            nullable: true
                                             type: string
                                           transitioning:
                                             type: boolean
@@ -2380,10 +2325,8 @@ spec:
                                         nullable: true
                                         type: string
                                     type: object
-                                  nullable: true
                                   type: array
                               type: object
-                            nullable: true
                             type: array
                           notReady:
                             description: NotReady is the number of bundle deployments
@@ -2414,7 +2357,6 @@ spec:
                           in the partition.
                         type: integer
                     type: object
-                  nullable: true
                   type: array
                 resourceKey:
                   description: ResourceKey lists resources, which will likely be deployed.
@@ -2441,7 +2383,6 @@ spec:
                         nullable: true
                         type: string
                     type: object
-                  nullable: true
                   type: array
                 summary:
                   description: Summary contains the number of bundle deployments in
@@ -2509,7 +2450,6 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                           name:
                             description: Name is the name of the resource.
@@ -2540,12 +2480,9 @@ spec:
                                       type: boolean
                                     message:
                                       items:
-                                        nullable: true
                                         type: string
-                                      nullable: true
                                       type: array
                                     state:
-                                      nullable: true
                                       type: string
                                     transitioning:
                                       type: boolean
@@ -2559,10 +2496,8 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                         type: object
-                      nullable: true
                       type: array
                     notReady:
                       description: NotReady is the number of bundle deployments that
@@ -2606,6 +2541,8 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: clustergroups.fleet.cattle.io
 spec:
   group: fleet.cattle.io
@@ -2613,9 +2550,9 @@ spec:
     categories:
       - fleet
     kind: ClusterGroup
+    listKind: ClusterGroupList
     plural: clustergroups
     singular: clustergroup
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -2664,13 +2601,11 @@ spec:
                           key:
                             description: key is the label key that the selector applies
                               to.
-                            nullable: true
                             type: string
                           operator:
                             description: operator represents a key's relationship
                               to a set of values. Valid operators are In, NotIn, Exists
                               and DoesNotExist.
-                            nullable: true
                             type: string
                           values:
                             description: values is an array of string values. If the
@@ -2679,25 +2614,24 @@ spec:
                               array must be empty. This array is replaced during a
                               strategic merge patch.
                             items:
-                              nullable: true
                               type: string
-                            nullable: true
                             type: array
+                        required:
+                          - key
+                          - operator
                         type: object
-                      nullable: true
                       type: array
                     matchLabels:
                       additionalProperties:
-                        nullable: true
                         type: string
                       description: matchLabels is a map of {key,value} pairs. A single
                         {key,value} in the matchLabels map is equivalent to an element
                         of matchExpressions, whose key field is "key", the operator
                         is "In", and the values array contains only "value". The requirements
                         are ANDed.
-                      nullable: true
                       type: object
                   type: object
+                  x-kubernetes-map-type: atomic
               type: object
             status:
               properties:
@@ -2713,32 +2647,28 @@ spec:
                       lastTransitionTime:
                         description: Last time the condition transitioned from one
                           status to another.
-                        nullable: true
                         type: string
                       lastUpdateTime:
                         description: The last time this condition was updated.
-                        nullable: true
                         type: string
                       message:
                         description: Human-readable message indicating details about
                           last transition
-                        nullable: true
                         type: string
                       reason:
                         description: The reason for the condition's last transition.
-                        nullable: true
                         type: string
                       status:
                         description: Status of the condition, one of True, False,
                           Unknown.
-                        nullable: true
                         type: string
                       type:
                         description: Type of cluster condition.
-                        nullable: true
                         type: string
+                    required:
+                      - status
+                      - type
                     type: object
-                  nullable: true
                   type: array
                 display:
                   description: Display contains the number of ready, desiredready
@@ -2770,7 +2700,6 @@ spec:
                   description: NonReadyClusters is a list of cluster names that are
                     not ready.
                   items:
-                    nullable: true
                     type: string
                   nullable: true
                   type: array
@@ -2874,7 +2803,6 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                           name:
                             description: Name is the name of the resource.
@@ -2905,12 +2833,9 @@ spec:
                                       type: boolean
                                     message:
                                       items:
-                                        nullable: true
                                         type: string
-                                      nullable: true
                                       type: array
                                     state:
-                                      nullable: true
                                       type: string
                                     transitioning:
                                       type: boolean
@@ -2924,10 +2849,8 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                         type: object
-                      nullable: true
                       type: array
                     notReady:
                       description: NotReady is the number of bundle deployments that
@@ -2962,14 +2885,16 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: clusterregistrations.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: ClusterRegistration
+    listKind: ClusterRegistrationList
     plural: clusterregistrations
     singular: clusterregistration
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -3013,7 +2938,6 @@ spec:
                   type: string
                 clusterLabels:
                   additionalProperties:
-                    nullable: true
                     type: string
                   description: ClusterLabels are copied to the cluster resource during
                     the registration.
@@ -3042,14 +2966,16 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: clusterregistrationtokens.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: ClusterRegistrationToken
+    listKind: ClusterRegistrationTokenList
     plural: clusterregistrationtokens
     singular: clusterregistrationtoken
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -3074,11 +3000,6 @@ spec:
                 info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
               type: string
             metadata:
-              properties:
-                name:
-                  maxLength: 63
-                  pattern: ^[-a-z0-9]+$
-                  type: string
               type: object
             spec:
               properties:
@@ -3093,7 +3014,7 @@ spec:
               properties:
                 expires:
                   description: Expires is the time when the token expires.
-                  nullable: true
+                  format: date-time
                   type: string
                 secretName:
                   description: SecretName is the name of the secret containing the
@@ -3110,14 +3031,16 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: clusters.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: Cluster
+    listKind: ClusterList
     plural: clusters
     singular: cluster
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -3157,11 +3080,6 @@ spec:
                 info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
               type: string
             metadata:
-              properties:
-                name:
-                  maxLength: 63
-                  pattern: ^[-a-z0-9]+$
-                  type: string
               type: object
             spec:
               properties:
@@ -3174,7 +3092,6 @@ spec:
                     nodeAffinity:
                       description: Describes node affinity scheduling rules for the
                         pod.
-                      nullable: true
                       properties:
                         preferredDuringSchedulingIgnoredDuringExecution:
                           description: The scheduler will prefer to schedule pods
@@ -3209,21 +3126,12 @@ spec:
                                         key:
                                           description: The label key that the selector
                                             applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: Represents a key's relationship
                                             to a set of values. Valid operators are
                                             In, NotIn, Exists, DoesNotExist. Gt, and
                                             Lt.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                            - Gt
-                                            - Lt
-                                          nullable: true
                                           type: string
                                         values:
                                           description: An array of string values.
@@ -3236,12 +3144,12 @@ spec:
                                             as an integer. This array is replaced
                                             during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                   matchFields:
                                     description: A list of node selector requirements
@@ -3254,21 +3162,12 @@ spec:
                                         key:
                                           description: The label key that the selector
                                             applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: Represents a key's relationship
                                             to a set of values. Valid operators are
                                             In, NotIn, Exists, DoesNotExist. Gt, and
                                             Lt.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                            - Gt
-                                            - Lt
-                                          nullable: true
                                           type: string
                                         values:
                                           description: An array of string values.
@@ -3281,20 +3180,24 @@ spec:
                                             as an integer. This array is replaced
                                             during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                 type: object
+                                x-kubernetes-map-type: atomic
                               weight:
                                 description: Weight associated with matching the corresponding
                                   nodeSelectorTerm, in the range 1-100.
+                                format: int32
                                 type: integer
+                            required:
+                              - preference
+                              - weight
                             type: object
-                          nullable: true
                           type: array
                         requiredDuringSchedulingIgnoredDuringExecution:
                           description: If the affinity requirements specified by this
@@ -3304,7 +3207,6 @@ spec:
                             during pod execution (e.g. due to an update), the system
                             may or may not try to eventually evict the pod from its
                             node.
-                          nullable: true
                           properties:
                             nodeSelectorTerms:
                               description: Required. A list of node selector terms.
@@ -3326,21 +3228,12 @@ spec:
                                         key:
                                           description: The label key that the selector
                                             applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: Represents a key's relationship
                                             to a set of values. Valid operators are
                                             In, NotIn, Exists, DoesNotExist. Gt, and
                                             Lt.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                            - Gt
-                                            - Lt
-                                          nullable: true
                                           type: string
                                         values:
                                           description: An array of string values.
@@ -3353,12 +3246,12 @@ spec:
                                             as an integer. This array is replaced
                                             during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                   matchFields:
                                     description: A list of node selector requirements
@@ -3371,21 +3264,12 @@ spec:
                                         key:
                                           description: The label key that the selector
                                             applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: Represents a key's relationship
                                             to a set of values. Valid operators are
                                             In, NotIn, Exists, DoesNotExist. Gt, and
                                             Lt.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                            - Gt
-                                            - Lt
-                                          nullable: true
                                           type: string
                                         values:
                                           description: An array of string values.
@@ -3398,22 +3282,24 @@ spec:
                                             as an integer. This array is replaced
                                             during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                 type: object
-                              nullable: true
+                                x-kubernetes-map-type: atomic
                               type: array
+                          required:
+                            - nodeSelectorTerms
                           type: object
+                          x-kubernetes-map-type: atomic
                       type: object
                     podAffinity:
                       description: Describes pod affinity scheduling rules (e.g. co-locate
                         this pod in the same node, zone, etc. as some other pod(s)).
-                      nullable: true
                       properties:
                         preferredDuringSchedulingIgnoredDuringExecution:
                           description: The scheduler will prefer to schedule pods
@@ -3439,7 +3325,6 @@ spec:
                                   labelSelector:
                                     description: A label query over a set of resources,
                                       in this case pods.
-                                    nullable: true
                                     properties:
                                       matchExpressions:
                                         description: matchExpressions is a list of
@@ -3454,19 +3339,12 @@ spec:
                                             key:
                                               description: key is the label key that
                                                 the selector applies to.
-                                              nullable: true
                                               type: string
                                             operator:
                                               description: operator represents a key's
                                                 relationship to a set of values. Valid
                                                 operators are In, NotIn, Exists and
                                                 DoesNotExist.
-                                              enum:
-                                                - In
-                                                - NotIn
-                                                - Exists
-                                                - DoesNotExist
-                                              nullable: true
                                               type: string
                                             values:
                                               description: values is an array of string
@@ -3477,16 +3355,15 @@ spec:
                                                 array is replaced during a strategic
                                                 merge patch.
                                               items:
-                                                nullable: true
                                                 type: string
-                                              nullable: true
                                               type: array
+                                          required:
+                                            - key
+                                            - operator
                                           type: object
-                                        nullable: true
                                         type: array
                                       matchLabels:
                                         additionalProperties:
-                                          nullable: true
                                           type: string
                                         description: matchLabels is a map of {key,value}
                                           pairs. A single {key,value} in the matchLabels
@@ -3494,9 +3371,9 @@ spec:
                                           whose key field is "key", the operator is
                                           "In", and the values array contains only
                                           "value". The requirements are ANDed.
-                                        nullable: true
                                         type: object
                                     type: object
+                                    x-kubernetes-map-type: atomic
                                   namespaceSelector:
                                     description: A label query over the set of namespaces
                                       that the term applies to. The term is applied
@@ -3505,7 +3382,6 @@ spec:
                                       field. null selector and null or empty namespaces
                                       list means "this pod's namespace". An empty
                                       selector ({}) matches all namespaces.
-                                    nullable: true
                                     properties:
                                       matchExpressions:
                                         description: matchExpressions is a list of
@@ -3520,19 +3396,12 @@ spec:
                                             key:
                                               description: key is the label key that
                                                 the selector applies to.
-                                              nullable: true
                                               type: string
                                             operator:
                                               description: operator represents a key's
                                                 relationship to a set of values. Valid
                                                 operators are In, NotIn, Exists and
                                                 DoesNotExist.
-                                              enum:
-                                                - In
-                                                - NotIn
-                                                - Exists
-                                                - DoesNotExist
-                                              nullable: true
                                               type: string
                                             values:
                                               description: values is an array of string
@@ -3543,16 +3412,15 @@ spec:
                                                 array is replaced during a strategic
                                                 merge patch.
                                               items:
-                                                nullable: true
                                                 type: string
-                                              nullable: true
                                               type: array
+                                          required:
+                                            - key
+                                            - operator
                                           type: object
-                                        nullable: true
                                         type: array
                                       matchLabels:
                                         additionalProperties:
-                                          nullable: true
                                           type: string
                                         description: matchLabels is a map of {key,value}
                                           pairs. A single {key,value} in the matchLabels
@@ -3560,9 +3428,9 @@ spec:
                                           whose key field is "key", the operator is
                                           "In", and the values array contains only
                                           "value". The requirements are ANDed.
-                                        nullable: true
                                         type: object
                                     type: object
+                                    x-kubernetes-map-type: atomic
                                   namespaces:
                                     description: namespaces specifies a static list
                                       of namespace names that the term applies to.
@@ -3572,9 +3440,7 @@ spec:
                                       list and null namespaceSelector means "this
                                       pod's namespace".
                                     items:
-                                      nullable: true
                                       type: string
-                                    nullable: true
                                     type: array
                                   topologyKey:
                                     description: This pod should be co-located (affinity)
@@ -3585,15 +3451,19 @@ spec:
                                       topologyKey matches that of any node on which
                                       any of the selected pods is running. Empty topologyKey
                                       is not allowed.
-                                    nullable: true
                                     type: string
+                                required:
+                                  - topologyKey
                                 type: object
                               weight:
                                 description: weight associated with matching the corresponding
                                   podAffinityTerm, in the range 1-100.
+                                format: int32
                                 type: integer
+                            required:
+                              - podAffinityTerm
+                              - weight
                             type: object
-                          nullable: true
                           type: array
                         requiredDuringSchedulingIgnoredDuringExecution:
                           description: If the affinity requirements specified by this
@@ -3617,7 +3487,6 @@ spec:
                               labelSelector:
                                 description: A label query over a set of resources,
                                   in this case pods.
-                                nullable: true
                                 properties:
                                   matchExpressions:
                                     description: matchExpressions is a list of label
@@ -3631,18 +3500,11 @@ spec:
                                         key:
                                           description: key is the label key that the
                                             selector applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: operator represents a key's
                                             relationship to a set of values. Valid
                                             operators are In, NotIn, Exists and DoesNotExist.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                          nullable: true
                                           type: string
                                         values:
                                           description: values is an array of string
@@ -3652,16 +3514,15 @@ spec:
                                             the values array must be empty. This array
                                             is replaced during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                   matchLabels:
                                     additionalProperties:
-                                      nullable: true
                                       type: string
                                     description: matchLabels is a map of {key,value}
                                       pairs. A single {key,value} in the matchLabels
@@ -3669,9 +3530,9 @@ spec:
                                       whose key field is "key", the operator is "In",
                                       and the values array contains only "value".
                                       The requirements are ANDed.
-                                    nullable: true
                                     type: object
                                 type: object
+                                x-kubernetes-map-type: atomic
                               namespaceSelector:
                                 description: A label query over the set of namespaces
                                   that the term applies to. The term is applied to
@@ -3680,7 +3541,6 @@ spec:
                                   selector and null or empty namespaces list means
                                   "this pod's namespace". An empty selector ({}) matches
                                   all namespaces.
-                                nullable: true
                                 properties:
                                   matchExpressions:
                                     description: matchExpressions is a list of label
@@ -3694,18 +3554,11 @@ spec:
                                         key:
                                           description: key is the label key that the
                                             selector applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: operator represents a key's
                                             relationship to a set of values. Valid
                                             operators are In, NotIn, Exists and DoesNotExist.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                          nullable: true
                                           type: string
                                         values:
                                           description: values is an array of string
@@ -3715,16 +3568,15 @@ spec:
                                             the values array must be empty. This array
                                             is replaced during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                   matchLabels:
                                     additionalProperties:
-                                      nullable: true
                                       type: string
                                     description: matchLabels is a map of {key,value}
                                       pairs. A single {key,value} in the matchLabels
@@ -3732,9 +3584,9 @@ spec:
                                       whose key field is "key", the operator is "In",
                                       and the values array contains only "value".
                                       The requirements are ANDed.
-                                    nullable: true
                                     type: object
                                 type: object
+                                x-kubernetes-map-type: atomic
                               namespaces:
                                 description: namespaces specifies a static list of
                                   namespace names that the term applies to. The term
@@ -3743,9 +3595,7 @@ spec:
                                   null or empty namespaces list and null namespaceSelector
                                   means "this pod's namespace".
                                 items:
-                                  nullable: true
                                   type: string
-                                nullable: true
                                 type: array
                               topologyKey:
                                 description: This pod should be co-located (affinity)
@@ -3755,17 +3605,16 @@ spec:
                                   whose value of the label with key topologyKey matches
                                   that of any node on which any of the selected pods
                                   is running. Empty topologyKey is not allowed.
-                                nullable: true
                                 type: string
+                            required:
+                              - topologyKey
                             type: object
-                          nullable: true
                           type: array
                       type: object
                     podAntiAffinity:
                       description: Describes pod anti-affinity scheduling rules (e.g.
                         avoid putting this pod in the same node, zone, etc. as some
                         other pod(s)).
-                      nullable: true
                       properties:
                         preferredDuringSchedulingIgnoredDuringExecution:
                           description: The scheduler will prefer to schedule pods
@@ -3792,7 +3641,6 @@ spec:
                                   labelSelector:
                                     description: A label query over a set of resources,
                                       in this case pods.
-                                    nullable: true
                                     properties:
                                       matchExpressions:
                                         description: matchExpressions is a list of
@@ -3807,19 +3655,12 @@ spec:
                                             key:
                                               description: key is the label key that
                                                 the selector applies to.
-                                              nullable: true
                                               type: string
                                             operator:
                                               description: operator represents a key's
                                                 relationship to a set of values. Valid
                                                 operators are In, NotIn, Exists and
                                                 DoesNotExist.
-                                              enum:
-                                                - In
-                                                - NotIn
-                                                - Exists
-                                                - DoesNotExist
-                                              nullable: true
                                               type: string
                                             values:
                                               description: values is an array of string
@@ -3830,16 +3671,15 @@ spec:
                                                 array is replaced during a strategic
                                                 merge patch.
                                               items:
-                                                nullable: true
                                                 type: string
-                                              nullable: true
                                               type: array
+                                          required:
+                                            - key
+                                            - operator
                                           type: object
-                                        nullable: true
                                         type: array
                                       matchLabels:
                                         additionalProperties:
-                                          nullable: true
                                           type: string
                                         description: matchLabels is a map of {key,value}
                                           pairs. A single {key,value} in the matchLabels
@@ -3847,9 +3687,9 @@ spec:
                                           whose key field is "key", the operator is
                                           "In", and the values array contains only
                                           "value". The requirements are ANDed.
-                                        nullable: true
                                         type: object
                                     type: object
+                                    x-kubernetes-map-type: atomic
                                   namespaceSelector:
                                     description: A label query over the set of namespaces
                                       that the term applies to. The term is applied
@@ -3858,7 +3698,6 @@ spec:
                                       field. null selector and null or empty namespaces
                                       list means "this pod's namespace". An empty
                                       selector ({}) matches all namespaces.
-                                    nullable: true
                                     properties:
                                       matchExpressions:
                                         description: matchExpressions is a list of
@@ -3873,19 +3712,12 @@ spec:
                                             key:
                                               description: key is the label key that
                                                 the selector applies to.
-                                              nullable: true
                                               type: string
                                             operator:
                                               description: operator represents a key's
                                                 relationship to a set of values. Valid
                                                 operators are In, NotIn, Exists and
                                                 DoesNotExist.
-                                              enum:
-                                                - In
-                                                - NotIn
-                                                - Exists
-                                                - DoesNotExist
-                                              nullable: true
                                               type: string
                                             values:
                                               description: values is an array of string
@@ -3896,16 +3728,15 @@ spec:
                                                 array is replaced during a strategic
                                                 merge patch.
                                               items:
-                                                nullable: true
                                                 type: string
-                                              nullable: true
                                               type: array
+                                          required:
+                                            - key
+                                            - operator
                                           type: object
-                                        nullable: true
                                         type: array
                                       matchLabels:
                                         additionalProperties:
-                                          nullable: true
                                           type: string
                                         description: matchLabels is a map of {key,value}
                                           pairs. A single {key,value} in the matchLabels
@@ -3913,9 +3744,9 @@ spec:
                                           whose key field is "key", the operator is
                                           "In", and the values array contains only
                                           "value". The requirements are ANDed.
-                                        nullable: true
                                         type: object
                                     type: object
+                                    x-kubernetes-map-type: atomic
                                   namespaces:
                                     description: namespaces specifies a static list
                                       of namespace names that the term applies to.
@@ -3925,9 +3756,7 @@ spec:
                                       list and null namespaceSelector means "this
                                       pod's namespace".
                                     items:
-                                      nullable: true
                                       type: string
-                                    nullable: true
                                     type: array
                                   topologyKey:
                                     description: This pod should be co-located (affinity)
@@ -3938,15 +3767,19 @@ spec:
                                       topologyKey matches that of any node on which
                                       any of the selected pods is running. Empty topologyKey
                                       is not allowed.
-                                    nullable: true
                                     type: string
+                                required:
+                                  - topologyKey
                                 type: object
                               weight:
                                 description: weight associated with matching the corresponding
                                   podAffinityTerm, in the range 1-100.
+                                format: int32
                                 type: integer
+                            required:
+                              - podAffinityTerm
+                              - weight
                             type: object
-                          nullable: true
                           type: array
                         requiredDuringSchedulingIgnoredDuringExecution:
                           description: If the anti-affinity requirements specified
@@ -3970,7 +3803,6 @@ spec:
                               labelSelector:
                                 description: A label query over a set of resources,
                                   in this case pods.
-                                nullable: true
                                 properties:
                                   matchExpressions:
                                     description: matchExpressions is a list of label
@@ -3984,18 +3816,11 @@ spec:
                                         key:
                                           description: key is the label key that the
                                             selector applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: operator represents a key's
                                             relationship to a set of values. Valid
                                             operators are In, NotIn, Exists and DoesNotExist.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                          nullable: true
                                           type: string
                                         values:
                                           description: values is an array of string
@@ -4005,16 +3830,15 @@ spec:
                                             the values array must be empty. This array
                                             is replaced during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                   matchLabels:
                                     additionalProperties:
-                                      nullable: true
                                       type: string
                                     description: matchLabels is a map of {key,value}
                                       pairs. A single {key,value} in the matchLabels
@@ -4022,9 +3846,9 @@ spec:
                                       whose key field is "key", the operator is "In",
                                       and the values array contains only "value".
                                       The requirements are ANDed.
-                                    nullable: true
                                     type: object
                                 type: object
+                                x-kubernetes-map-type: atomic
                               namespaceSelector:
                                 description: A label query over the set of namespaces
                                   that the term applies to. The term is applied to
@@ -4033,7 +3857,6 @@ spec:
                                   selector and null or empty namespaces list means
                                   "this pod's namespace". An empty selector ({}) matches
                                   all namespaces.
-                                nullable: true
                                 properties:
                                   matchExpressions:
                                     description: matchExpressions is a list of label
@@ -4047,18 +3870,11 @@ spec:
                                         key:
                                           description: key is the label key that the
                                             selector applies to.
-                                          nullable: true
                                           type: string
                                         operator:
                                           description: operator represents a key's
                                             relationship to a set of values. Valid
                                             operators are In, NotIn, Exists and DoesNotExist.
-                                          enum:
-                                            - In
-                                            - NotIn
-                                            - Exists
-                                            - DoesNotExist
-                                          nullable: true
                                           type: string
                                         values:
                                           description: values is an array of string
@@ -4068,16 +3884,15 @@ spec:
                                             the values array must be empty. This array
                                             is replaced during a strategic merge patch.
                                           items:
-                                            nullable: true
                                             type: string
-                                          nullable: true
                                           type: array
+                                      required:
+                                        - key
+                                        - operator
                                       type: object
-                                    nullable: true
                                     type: array
                                   matchLabels:
                                     additionalProperties:
-                                      nullable: true
                                       type: string
                                     description: matchLabels is a map of {key,value}
                                       pairs. A single {key,value} in the matchLabels
@@ -4085,9 +3900,9 @@ spec:
                                       whose key field is "key", the operator is "In",
                                       and the values array contains only "value".
                                       The requirements are ANDed.
-                                    nullable: true
                                     type: object
                                 type: object
+                                x-kubernetes-map-type: atomic
                               namespaces:
                                 description: namespaces specifies a static list of
                                   namespace names that the term applies to. The term
@@ -4096,9 +3911,7 @@ spec:
                                   null or empty namespaces list and null namespaceSelector
                                   means "this pod's namespace".
                                 items:
-                                  nullable: true
                                   type: string
-                                nullable: true
                                 type: array
                               topologyKey:
                                 description: This pod should be co-located (affinity)
@@ -4108,10 +3921,10 @@ spec:
                                   whose value of the label with key topologyKey matches
                                   that of any node on which any of the selected pods
                                   is running. Empty topologyKey is not allowed.
-                                nullable: true
                                 type: string
+                            required:
+                              - topologyKey
                             type: object
-                          nullable: true
                           type: array
                       type: object
                   type: object
@@ -4124,7 +3937,6 @@ spec:
                     properties:
                       name:
                         description: Name of the environment variable. Must be a C_IDENTIFIER.
-                        nullable: true
                         type: string
                       value:
                         description: 'Variable references $(VAR_NAME) are expanded
@@ -4136,97 +3948,97 @@ spec:
                           will produce the string literal "$(VAR_NAME)". Escaped references
                           will never be expanded, regardless of whether the variable
                           exists or not. Defaults to "".'
-                        nullable: true
                         type: string
                       valueFrom:
                         description: Source for the environment variable's value.
                           Cannot be used if value is not empty.
-                        nullable: true
                         properties:
                           configMapKeyRef:
                             description: Selects a key of a ConfigMap.
-                            nullable: true
                             properties:
                               key:
                                 description: The key to select.
-                                nullable: true
                                 type: string
                               name:
                                 description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
                                   TODO: Add other useful fields. apiVersion, kind,
                                   uid?'
-                                nullable: true
                                 type: string
                               optional:
                                 description: Specify whether the ConfigMap or its
                                   key must be defined
-                                nullable: true
                                 type: boolean
+                            required:
+                              - key
                             type: object
+                            x-kubernetes-map-type: atomic
                           fieldRef:
                             description: 'Selects a field of the pod: supports metadata.name,
                               metadata.namespace, `metadata.labels[''<KEY>'']`, `metadata.annotations[''<KEY>'']`,
                               spec.nodeName, spec.serviceAccountName, status.hostIP,
                               status.podIP, status.podIPs.'
-                            nullable: true
                             properties:
                               apiVersion:
                                 description: Version of the schema the FieldPath is
                                   written in terms of, defaults to "v1".
-                                nullable: true
                                 type: string
                               fieldPath:
                                 description: Path of the field to select in the specified
                                   API version.
-                                nullable: true
                                 type: string
+                            required:
+                              - fieldPath
                             type: object
+                            x-kubernetes-map-type: atomic
                           resourceFieldRef:
                             description: 'Selects a resource of the container: only
                               resources limits and requests (limits.cpu, limits.memory,
                               limits.ephemeral-storage, requests.cpu, requests.memory
                               and requests.ephemeral-storage) are currently supported.'
-                            nullable: true
                             properties:
                               containerName:
                                 description: 'Container name: required for volumes,
                                   optional for env vars'
-                                nullable: true
                                 type: string
                               divisor:
+                                anyOf:
+                                  - type: integer
+                                  - type: string
                                 description: Specifies the output format of the exposed
                                   resources, defaults to "1"
-                                nullable: true
-                                type: string
+                                pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                                x-kubernetes-int-or-string: true
                               resource:
                                 description: 'Required: resource to select'
-                                nullable: true
                                 type: string
+                            required:
+                              - resource
                             type: object
+                            x-kubernetes-map-type: atomic
                           secretKeyRef:
                             description: Selects a key of a secret in the pod's namespace
-                            nullable: true
                             properties:
                               key:
                                 description: The key of the secret to select from.  Must
                                   be a valid secret key.
-                                nullable: true
                                 type: string
                               name:
                                 description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
                                   TODO: Add other useful fields. apiVersion, kind,
                                   uid?'
-                                nullable: true
                                 type: string
                               optional:
                                 description: Specify whether the Secret or its key
                                   must be defined
-                                nullable: true
                                 type: boolean
+                            required:
+                              - key
                             type: object
+                            x-kubernetes-map-type: atomic
                         type: object
+                    required:
+                      - name
                     type: object
-                  nullable: true
                   type: array
                 agentNamespace:
                   description: AgentNamespace defaults to the system namespace, e.g.
@@ -4251,29 +4063,36 @@ spec:
                             description: Name must match the name of one entry in
                               pod.spec.resourceClaims of the Pod where this field
                               is used. It makes that resource available inside a container.
-                            nullable: true
                             type: string
+                        required:
+                          - name
                         type: object
-                      nullable: true
                       type: array
+                      x-kubernetes-list-map-keys:
+                        - name
+                      x-kubernetes-list-type: map
                     limits:
                       additionalProperties:
-                        nullable: true
-                        type: string
+                        anyOf:
+                          - type: integer
+                          - type: string
+                        pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                        x-kubernetes-int-or-string: true
                       description: 'Limits describes the maximum amount of compute
                         resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
-                      nullable: true
                       type: object
                     requests:
                       additionalProperties:
-                        nullable: true
-                        type: string
+                        anyOf:
+                          - type: integer
+                          - type: string
+                        pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                        x-kubernetes-int-or-string: true
                       description: 'Requests describes the minimum amount of compute
                         resources required. If Requests is omitted for a container,
                         it defaults to Limits if that is explicitly specified, otherwise
                         to an implementation-defined value. Requests cannot exceed
                         Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
-                      nullable: true
                       type: object
                   type: object
                 agentTolerations:
@@ -4288,21 +4107,18 @@ spec:
                         description: Effect indicates the taint effect to match. Empty
                           means match all taint effects. When specified, allowed values
                           are NoSchedule, PreferNoSchedule and NoExecute.
-                        nullable: true
                         type: string
                       key:
                         description: Key is the taint key that the toleration applies
                           to. Empty means match all taint keys. If the key is empty,
                           operator must be Exists; this combination means to match
                           all values and all keys.
-                        nullable: true
                         type: string
                       operator:
                         description: Operator represents a key's relationship to the
                           value. Valid operators are Exists and Equal. Defaults to
                           Equal. Exists is equivalent to wildcard for value, so that
                           a pod can tolerate all taints of a particular category.
-                        nullable: true
                         type: string
                       tolerationSeconds:
                         description: TolerationSeconds represents the period of time
@@ -4311,17 +4127,14 @@ spec:
                           it is not set, which means tolerate the taint forever (do
                           not evict). Zero and negative values will be treated as
                           0 (evict immediately) by the system.
-                        maximum: 86400
-                        nullable: true
+                        format: int64
                         type: integer
                       value:
                         description: Value is the taint value the toleration matches
                           to. If the operator is Exists, the value should be empty,
                           otherwise just a regular string.
-                        nullable: true
                         type: string
                     type: object
-                  nullable: true
                   type: array
                 clientID:
                   description: ClientID is a unique string that will identify the
@@ -4355,13 +4168,12 @@ spec:
                 redeployAgentGeneration:
                   description: RedeployAgentGeneration can be used to force redeploying
                     the agent.
+                  format: int64
                   type: integer
                 templateValues:
                   description: TemplateValues defines a cluster specific mapping of
                     values to be sent to fleet.yaml values templating.
-                  nullable: true
                   type: object
-                  x-kubernetes-preserve-unknown-fields: true
               type: object
             status:
               properties:
@@ -4371,6 +4183,7 @@ spec:
                     lastSeen:
                       description: LastSeen is the last time the agent checked in
                         to update the status of the cluster resource.
+                      format: date-time
                       nullable: true
                       type: string
                     namespace:
@@ -4382,9 +4195,7 @@ spec:
                       description: NonReadyNode contains the names of non-ready nodes.
                         The list is limited to at most 3 names.
                       items:
-                        nullable: true
                         type: string
-                      nullable: true
                       type: array
                     nonReadyNodes:
                       description: NonReadyNodes is the number of nodes that are not
@@ -4394,9 +4205,7 @@ spec:
                       description: ReadyNodes contains the names of ready nodes. The
                         list is limited to at most 3 names.
                       items:
-                        nullable: true
                         type: string
-                      nullable: true
                       type: array
                     readyNodes:
                       description: ReadyNodes is the number of nodes that are ready.
@@ -4405,7 +4214,6 @@ spec:
                 agentAffinityHash:
                   description: AgentAffinityHash is a hash of the agent's affinity
                     configuration, used to detect changes.
-                  nullable: true
                   type: string
                 agentConfigChanged:
                   description: AgentConfigChanged is set to true if any of the agent
@@ -4415,6 +4223,7 @@ spec:
                 agentDeployedGeneration:
                   description: AgentDeployedGeneration is the generation of the agent
                     that is currently deployed.
+                  format: int64
                   nullable: true
                   type: integer
                 agentEnvVarsHash:
@@ -4468,32 +4277,28 @@ spec:
                       lastTransitionTime:
                         description: Last time the condition transitioned from one
                           status to another.
-                        nullable: true
                         type: string
                       lastUpdateTime:
                         description: The last time this condition was updated.
-                        nullable: true
                         type: string
                       message:
                         description: Human-readable message indicating details about
                           last transition
-                        nullable: true
                         type: string
                       reason:
                         description: The reason for the condition's last transition.
-                        nullable: true
                         type: string
                       status:
                         description: Status of the condition, one of True, False,
                           Unknown.
-                        nullable: true
                         type: string
                       type:
                         description: Type of cluster condition.
-                        nullable: true
                         type: string
+                    required:
+                      - status
+                      - type
                     type: object
-                  nullable: true
                   type: array
                 desiredReadyGitRepos:
                   description: DesiredReadyGitRepos is the number of gitrepos for
@@ -4507,31 +4312,26 @@ spec:
                       description: ReadyBundles is a string in the form "%d/%d", that
                         describes the number of bundles that are ready vs. the number
                         of bundles desired to be ready.
-                      nullable: true
                       type: string
                     readyNodes:
                       description: ReadyNodes is a string in the form "%d/%d", that
                         describes the number of nodes that are ready vs. the number
                         of expected nodes.
-                      nullable: true
                       type: string
                     sampleNode:
                       description: SampleNode is the name of one of the nodes that
                         are ready. If no node is ready, it's the name of a node that
                         is not ready.
-                      nullable: true
                       type: string
                     state:
                       description: State of the cluster, either one of the bundle
                         states, or "WaitCheckIn".
-                      nullable: true
                       type: string
                   type: object
                 namespace:
                   description: 'Namespace is the cluster namespace, it contains the
                     clusters service account as well as any bundledeployments. Example:
                     "cluster-fleet-local-cluster-294db1acfa77-d9ccf852678f"'
-                  nullable: true
                   type: string
                 readyGitRepos:
                   description: ReadyGitRepos is the number of gitrepos for this cluster
@@ -4636,7 +4436,6 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                           name:
                             description: Name is the name of the resource.
@@ -4667,12 +4466,9 @@ spec:
                                       type: boolean
                                     message:
                                       items:
-                                        nullable: true
                                         type: string
-                                      nullable: true
                                       type: array
                                     state:
-                                      nullable: true
                                       type: string
                                     transitioning:
                                       type: boolean
@@ -4686,10 +4482,8 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                         type: object
-                      nullable: true
                       type: array
                     notReady:
                       description: NotReady is the number of bundle deployments that
@@ -4724,14 +4518,16 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: contents.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: Content
+    listKind: ContentList
     plural: contents
     singular: content
-  preserveUnknownFields: false
   scope: Cluster
   versions:
     - name: v1alpha1
@@ -4750,6 +4546,7 @@ spec:
               description: Content is a byte array, which contains the manifests of
                 a bundle. The bundle resources are copied into the bundledeployment's
                 content resource, so the downstream agent can deploy them.
+              format: byte
               nullable: true
               type: string
             kind:
@@ -4763,18 +4560,22 @@ spec:
           type: object
       served: true
       storage: true
+      subresources:
+        status: {}
 ---
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: gitreporestrictions.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
     kind: GitRepoRestriction
+    listKind: GitRepoRestrictionList
     plural: gitreporestrictions
     singular: gitreporestriction
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -4794,7 +4595,6 @@ spec:
               description: AllowedClientSecretNames is a list of client secret names
                 that GitRepos are allowed to use.
               items:
-                nullable: true
                 type: string
               nullable: true
               type: array
@@ -4802,7 +4602,6 @@ spec:
               description: AllowedRepoPatterns is a list of regex patterns that restrict
                 the valid values of the Repo field of a GitRepo.
               items:
-                nullable: true
                 type: string
               nullable: true
               type: array
@@ -4810,7 +4609,6 @@ spec:
               description: AllowedServiceAccounts is a list of service accounts that
                 GitRepos are allowed to use.
               items:
-                nullable: true
                 type: string
               nullable: true
               type: array
@@ -4819,7 +4617,6 @@ spec:
                 given namespaces. If AllowedTargetNamespaces is set, TargetNamespace
                 must be set.
               items:
-                nullable: true
                 type: string
               nullable: true
               type: array
@@ -4855,6 +4652,8 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: gitrepos.fleet.cattle.io
 spec:
   group: fleet.cattle.io
@@ -4862,9 +4661,9 @@ spec:
     categories:
       - fleet
     kind: GitRepo
+    listKind: GitRepoList
     plural: gitrepos
     singular: gitrepo
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -4909,6 +4708,7 @@ spec:
                 caBundle:
                   description: CABundle is a PEM encoded CA bundle which will be used
                     to validate the repo's certificate.
+                  format: byte
                   nullable: true
                   type: string
                 clientSecretName:
@@ -4937,6 +4737,7 @@ spec:
                 forceSyncGeneration:
                   description: Increment this number to force a redeployment of contents
                     from Git.
+                  format: int64
                   type: integer
                 helmRepoURLRegex:
                   description: HelmRepoURLRegex Helm credentials will be used if the
@@ -4978,7 +4779,6 @@ spec:
                 imageScanInterval:
                   description: ImageScanInterval is the interval of syncing scanned
                     images and writing back to git repo.
-                  nullable: true
                   type: string
                 insecureSkipTLSVerify:
                   description: InsecureSkipTLSverify will use insecure HTTPS to clone
@@ -4994,7 +4794,6 @@ spec:
                     for example ["charts/*"] will match all folders as a subdirectory
                     of charts/ If empty, "/" is the default.
                   items:
-                    nullable: true
                     type: string
                   nullable: true
                   type: array
@@ -5053,13 +4852,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -5069,25 +4866,24 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                       clusterName:
                         description: ClusterName is the name of a cluster.
                         nullable: true
@@ -5108,13 +4904,11 @@ spec:
                                 key:
                                   description: key is the label key that the selector
                                     applies to.
-                                  nullable: true
                                   type: string
                                 operator:
                                   description: operator represents a key's relationship
                                     to a set of values. Valid operators are In, NotIn,
                                     Exists and DoesNotExist.
-                                  nullable: true
                                   type: string
                                 values:
                                   description: values is an array of string values.
@@ -5124,31 +4918,29 @@ spec:
                                     This array is replaced during a strategic merge
                                     patch.
                                   items:
-                                    nullable: true
                                     type: string
-                                  nullable: true
                                   type: array
+                              required:
+                                - key
+                                - operator
                               type: object
-                            nullable: true
                             type: array
                           matchLabels:
                             additionalProperties:
-                              nullable: true
                               type: string
                             description: matchLabels is a map of {key,value} pairs.
                               A single {key,value} in the matchLabels map is equivalent
                               to an element of matchExpressions, whose key field is
                               "key", the operator is "In", and the values array contains
                               only "value". The requirements are ANDed.
-                            nullable: true
                             type: object
                         type: object
+                        x-kubernetes-map-type: atomic
                       name:
                         description: Name is the name of this target.
                         nullable: true
                         type: string
                     type: object
-                  nullable: true
                   type: array
               type: object
             status:
@@ -5166,32 +4958,28 @@ spec:
                       lastTransitionTime:
                         description: Last time the condition transitioned from one
                           status to another.
-                        nullable: true
                         type: string
                       lastUpdateTime:
                         description: The last time this condition was updated.
-                        nullable: true
                         type: string
                       message:
                         description: Human-readable message indicating details about
                           last transition
-                        nullable: true
                         type: string
                       reason:
                         description: The reason for the condition's last transition.
-                        nullable: true
                         type: string
                       status:
                         description: Status of the condition, one of True, False,
                           Unknown.
-                        nullable: true
                         type: string
                       type:
                         description: Type of cluster condition.
-                        nullable: true
                         type: string
+                    required:
+                      - status
+                      - type
                     type: object
-                  nullable: true
                   type: array
                 desiredReadyClusters:
                   description: "DesiredReadyClusters\tis the number of clusters that\
@@ -5206,35 +4994,32 @@ spec:
                     message:
                       description: Message contains the relevant message from the
                         deployment conditions.
-                      nullable: true
                       type: string
                     readyBundleDeployments:
                       description: ReadyBundleDeployments is a string in the form
                         "%d/%d", that describes the number of ready bundledeployments
                         over the total number of bundledeployments.
-                      nullable: true
                       type: string
                     state:
                       description: State is the state of the GitRepo, e.g. "GitUpdating"
                         or the maximal BundleState according to StateRank.
-                      nullable: true
                       type: string
                   type: object
                 gitJobStatus:
                   description: GitJobStatus is the status of the last GitJob run,
                     e.g. "Current" if there was no error.
-                  nullable: true
                   type: string
                 lastSyncedImageScanTime:
                   description: LastSyncedImageScanTime is the time of the last image
                     scan.
-                  nullable: true
+                  format: date-time
                   type: string
                 observedGeneration:
                   description: ObservedGeneration is the current generation of the
                     resource in the cluster. It is copied from k8s metadata.Generation.
                     The value is incremented for all changes, except for changes to
                     .metadata or .status.
+                  format: int64
                   type: integer
                 readyClusters:
                   description: ReadyClusters is the lowest number of clusters that
@@ -5278,9 +5063,7 @@ spec:
                   description: ResourceErrors is a sorted list of errors from the
                     resources.
                   items:
-                    nullable: true
                     type: string
-                  nullable: true
                   type: array
                 resources:
                   description: Resources contains metadata about the resources of
@@ -5291,7 +5074,6 @@ spec:
                     properties:
                       apiVersion:
                         description: APIVersion is the API version of the resource.
-                        nullable: true
                         type: string
                       error:
                         description: Error is true if any Error in the PerClusterState
@@ -5300,7 +5082,6 @@ spec:
                       id:
                         description: ID is the name of the resource, e.g. "namespace1/my-config"
                           or "backingimagemanagers.storage.io".
-                        nullable: true
                         type: string
                       incompleteState:
                         description: IncompleteState is true if a bundle summary has
@@ -5309,19 +5090,15 @@ spec:
                         type: boolean
                       kind:
                         description: Kind is the k8s kind of the resource.
-                        nullable: true
                         type: string
                       message:
                         description: Message is the first message from the PerClusterStates.
-                        nullable: true
                         type: string
                       name:
                         description: Name of the resource.
-                        nullable: true
                         type: string
                       namespace:
                         description: Namespace of the resource.
-                        nullable: true
                         type: string
                       perClusterState:
                         description: PerClusterState is a list of states for each
@@ -5332,7 +5109,6 @@ spec:
                           properties:
                             clusterId:
                               description: ClusterID is the id of the cluster.
-                              nullable: true
                               type: string
                             error:
                               description: Error is true if the resource is in an
@@ -5343,16 +5119,12 @@ spec:
                               description: Message combines the messages from the
                                 bundle's summary. Messages are joined with the delimiter
                                 ';'.
-                              nullable: true
                               type: string
                             patch:
                               description: Patch for modified resources.
-                              nullable: true
                               type: object
-                              x-kubernetes-preserve-unknown-fields: true
                             state:
                               description: State is the state of the resource.
-                              nullable: true
                               type: string
                             transitioning:
                               description: Transitioning is true if the resource is
@@ -5360,12 +5132,10 @@ spec:
                                 summary for non-ready resources.
                               type: boolean
                           type: object
-                        nullable: true
                         type: array
                       state:
                         description: State is the state of the resource, e.g. "Unknown",
                           "WaitApplied", "ErrApplied" or "Ready".
-                        nullable: true
                         type: string
                       transitioning:
                         description: Transitioning is true if any Transitioning in
@@ -5374,10 +5144,8 @@ spec:
                       type:
                         description: Type is the type of the resource, e.g. "apiextensions.k8s.io.customresourcedefinition"
                           or "configmap".
-                        nullable: true
                         type: string
                     type: object
-                  nullable: true
                   type: array
                 summary:
                   description: Summary contains the number of bundle deployments in
@@ -5445,7 +5213,6 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                           name:
                             description: Name is the name of the resource.
@@ -5476,12 +5243,9 @@ spec:
                                       type: boolean
                                     message:
                                       items:
-                                        nullable: true
                                         type: string
-                                      nullable: true
                                       type: array
                                     state:
-                                      nullable: true
                                       type: string
                                     transitioning:
                                       type: boolean
@@ -5495,10 +5259,8 @@ spec:
                                   nullable: true
                                   type: string
                               type: object
-                            nullable: true
                             type: array
                         type: object
-                      nullable: true
                       type: array
                     notReady:
                       description: NotReady is the number of bundle deployments that
@@ -5533,16 +5295,16 @@ spec:
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.12.0
   name: imagescans.fleet.cattle.io
 spec:
   group: fleet.cattle.io
   names:
-    categories:
-      - fleet
     kind: ImageScan
+    listKind: ImageScanList
     plural: imagescans
     singular: imagescan
-  preserveUnknownFields: false
   scope: Namespaced
   versions:
     - additionalPrinterColumns:
@@ -5623,9 +5385,9 @@ spec:
                     name:
                       description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
                         TODO: Add other useful fields. apiVersion, kind, uid?'
-                      nullable: true
                       type: string
                   type: object
+                  x-kubernetes-map-type: atomic
                 suspend:
                   description: This flag tells the controller to suspend subsequent
                     image scans. It does not apply to already started scans. Defaults
@@ -5643,7 +5405,6 @@ spec:
                   description: CanonicalName is the name of the image repository with
                     all the implied bits made explicit; e.g., `docker.io/library/alpine`
                     rather than `alpine`.
-                  nullable: true
                   type: string
                 conditions:
                   items:
@@ -5651,52 +5412,46 @@ spec:
                       lastTransitionTime:
                         description: Last time the condition transitioned from one
                           status to another.
-                        nullable: true
                         type: string
                       lastUpdateTime:
                         description: The last time this condition was updated.
-                        nullable: true
                         type: string
                       message:
                         description: Human-readable message indicating details about
                           last transition
-                        nullable: true
                         type: string
                       reason:
                         description: The reason for the condition's last transition.
-                        nullable: true
                         type: string
                       status:
                         description: Status of the condition, one of True, False,
                           Unknown.
-                        nullable: true
                         type: string
                       type:
                         description: Type of cluster condition.
-                        nullable: true
                         type: string
+                    required:
+                      - status
+                      - type
                     type: object
-                  nullable: true
                   type: array
                 lastScanTime:
                   description: LastScanTime is the last time image was scanned
-                  nullable: true
+                  format: date-time
                   type: string
                 latestDigest:
                   description: LatestDigest is the digest of latest tag
-                  nullable: true
                   type: string
                 latestImage:
                   description: LatestImage gives the first in the list of images scanned
                     by the image repository, when filtered and ordered according to
                     the policy.
-                  nullable: true
                   type: string
                 latestTag:
                   description: Latest tag is the latest tag filtered by the policy
-                  nullable: true
                   type: string
                 observedGeneration:
+                  format: int64
                   type: integer
               type: object
           type: object
diff --git a/cmd/codegen/hack/patch_crd_descriptions.sh b/cmd/codegen/hack/generate_and_sort_crds.sh
similarity index 59%
rename from cmd/codegen/hack/patch_crd_descriptions.sh
rename to cmd/codegen/hack/generate_and_sort_crds.sh
index 7b96d052..c4d2ce6a 100644
--- a/cmd/codegen/hack/patch_crd_descriptions.sh
+++ b/cmd/codegen/hack/generate_and_sort_crds.sh
@@ -24,12 +24,7 @@ FROM bitnami/python:3.10
 RUN install_packages jq
 RUN python -m pip install yq
 EOF
-    container_id=$(docker create --rm -i -v ${PWD}:${PWD}:ro -w ${PWD} -v ${tmpdir}:${tmpdir} ${image} yq $@ )
-    if [ -n "${COPY_FILE}" ] ; then
-      # When running on CI, docker-in-docker may be used, so the generated input file, which is outside the working directory, is not mounted and not available
-      docker cp "${COPY_FILE}" "${container_id}:${COPY_FILE}"
-    fi
-    docker start -ai "${container_id}"
+    docker run --rm -i -v ${PWD}:${PWD} -w ${PWD} ${image} yq $@
   else
     yq $@
   fi
@@ -45,13 +40,6 @@ if ! $CONTROLLERGEN --version | grep -q "${CONTROLLERGEN_VERSION}" ; then
 fi
 
 # Run controller-gen
-CONTROLLERGEN_CRDS_YAML="${tmpdir}/crds-controllergen.yaml"
-${CONTROLLERGEN} crd webhook paths="./pkg/apis/..." output:stdout > "${CONTROLLERGEN_CRDS_YAML}"
-
-# Patch existing CRDs with the descriptions from controller-gen
-PATCHED_CRDS_YAML="${tmpdir}/crds-patched.yaml"
-COPY_FILE="${CONTROLLERGEN_CRDS_YAML}" run_yq -f cmd/codegen/hack/patch_crd_descriptions.jq "${CRDS_YAML}" "${CONTROLLERGEN_CRDS_YAML}" \
-  --slurp --sort-keys --explicit-start --yaml-output > "${PATCHED_CRDS_YAML}"
-
-# Override previous CRDs file
-cp "${PATCHED_CRDS_YAML}" "${CRDS_YAML}"
+${CONTROLLERGEN} crd webhook paths="./pkg/apis/..." output:stdout > $CRDS_YAML
+# Sort
+run_yq --slurp --sort-keys --explicit-start --yaml-output -i 'sort_by(.metadata.name)[]' $CRDS_YAML
\ No newline at end of file
diff --git a/cmd/codegen/hack/patch_crd_descriptions.jq b/cmd/codegen/hack/patch_crd_descriptions.jq
deleted file mode 100644
index f799c35c..00000000
--- a/cmd/codegen/hack/patch_crd_descriptions.jq
+++ /dev/null
@@ -1,21 +0,0 @@
-# This jq script is expected to be called with "-s" and using 2 yaml file as command line args
-
-# 1. jq merges both files into one single array with the contents, we assume they are both the same length
-(. | length / 2) as $num_crds |
-
-# 2. Convert the array into 2 maps, indexed by CRD names. This will 
-(.[:$num_crds] | map({key: .metadata.name, value: .}) | from_entries) as $orig |
-(.[$num_crds:] | map({key: .metadata.name, value: .}) | from_entries) as $aux |
-
-# 4. Copy every leaf description field onto the original structure, then finally go back to an array of CRDs
-$aux | [paths] |
-    map(select(
-        # description fields
-        .[-1] == "description" or
-        # Special cases for top-level common values
-        .[-3:] == ["openAPIV3Schema", "properties", "apiVersion"] or
-        .[-3:] == ["openAPIV3Schema", "properties", "kind"] or
-        .[-4:] == ["openAPIV3Schema", "properties", "metadata", "type"])) |
-    map(. as $p | {path: $p , value: $aux | getpath($p)}) as $desc_spec |
-reduce $desc_spec[] as $s ($orig; setpath($s.path; $s.value)) |
-    to_entries | sort_by(.key) | .[].value
diff --git a/cmd/codegen/main.go b/cmd/codegen/main.go
index abaef041..88f349c2 100644
--- a/cmd/codegen/main.go
+++ b/cmd/codegen/main.go
@@ -1,10 +1,8 @@
 package main
 
 import (
-	"fmt"
 	"os"
 
-	"github.com/rancher/fleet/pkg/crd"
 	controllergen "github.com/rancher/wrangler/v2/pkg/controller-gen"
 	"github.com/rancher/wrangler/v2/pkg/controller-gen/args"
 
@@ -16,14 +14,6 @@ import (
 )
 
 func main() {
-	if len(os.Args) > 2 && os.Args[1] == "crds" {
-		fmt.Println("Writing CRDs to", os.Args[2])
-		if err := crd.WriteFile(os.Args[2]); err != nil {
-			panic(err)
-		}
-		return
-	}
-
 	os.Unsetenv("GOPATH")
 	controllergen.Run(args.Options{
 		OutputPackage: "github.com/rancher/fleet/pkg/generated",
diff --git a/generate.go b/generate.go
index c33b7b54..eb4b1bcc 100644
--- a/generate.go
+++ b/generate.go
@@ -1,6 +1,5 @@
 //go:generate go run ./cmd/codegen/cleanup/main.go
 //go:generate go run ./cmd/codegen/main.go
-//go:generate go run ./cmd/codegen crds ./charts/fleet-crd/templates/crds.yaml
-//go:generate bash ./cmd/codegen/hack/patch_crd_descriptions.sh ./charts/fleet-crd/templates/crds.yaml
+//go:generate bash ./cmd/codegen/hack/generate_and_sort_crds.sh ./charts/fleet-crd/templates/crds.yaml
 
 package main
diff --git a/go.mod b/go.mod
index a7f3f2a8..f92a11af 100644
--- a/go.mod
+++ b/go.mod
@@ -226,7 +226,7 @@ require (
 	google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
-	google.golang.org/grpc v1.55.0 // indirect
+	google.golang.org/grpc v1.56.3 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
diff --git a/go.sum b/go.sum
index fdf6cb8c..52268f9f 100644
--- a/go.sum
+++ b/go.sum
@@ -1515,8 +1515,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
 google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
-google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
-google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
+google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
+google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
diff --git a/internal/cmd/controller/start.go b/internal/cmd/controller/start.go
index 9f62bad7..8ed7e01f 100644
--- a/internal/cmd/controller/start.go
+++ b/internal/cmd/controller/start.go
@@ -4,8 +4,6 @@ import (
 	"context"
 
 	"github.com/rancher/fleet/internal/cmd/controller/controllers"
-	"github.com/rancher/fleet/pkg/crd"
-
 	"github.com/rancher/wrangler/v2/pkg/kubeconfig"
 	"github.com/rancher/wrangler/v2/pkg/ratelimit"
 )
@@ -19,9 +17,5 @@ func start(ctx context.Context, systemNamespace string, kubeconfigFile string, d
 
 	clientConfig.RateLimiter = ratelimit.None
 
-	if err := crd.Create(ctx, clientConfig); err != nil {
-		return err
-	}
-
 	return controllers.Register(ctx, systemNamespace, cfg, disableGitops, disableBootstrap)
 }
diff --git a/package/Dockerfile b/package/Dockerfile
index 58b5b5b6..45cbc066 100644
--- a/package/Dockerfile
+++ b/package/Dockerfile
@@ -1,6 +1,6 @@
 ARG BUILD_ENV=dapper
 
-FROM registry.suse.com/bci/bci-base:15.5.36.5.42 AS base
+FROM registry.suse.com/bci/bci-base:15.5.36.5.47 AS base
 USER 1000
 
 FROM base AS copy_dapper
diff --git a/package/Dockerfile.agent b/package/Dockerfile.agent
index a483c466..f024e110 100644
--- a/package/Dockerfile.agent
+++ b/package/Dockerfile.agent
@@ -1,6 +1,6 @@
 ARG BUILD_ENV=dapper
 
-FROM registry.suse.com/bci/bci-base:15.5.36.5.42 AS base
+FROM registry.suse.com/bci/bci-base:15.5.36.5.47 AS base
 RUN zypper in --no-recommends -y git bash openssh && groupadd -g 1000 fleet-apply && useradd -u 1000 -g 1000 -m fleet-apply; rm -fr /var/cache/* /var/log/*log
 COPY package/log.sh /usr/bin/
 
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/bundle_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/bundle_types.go
index 38c1af17..66abe199 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/bundle_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/bundle_types.go
@@ -48,6 +48,8 @@ type BundleState string
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="BundleDeployments-Ready",type=string,JSONPath=`.status.display.readyClusters`
+// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].message`
 
 // Bundle contains the resources of an application and its deployment options.
 // It will be deployed as a Helm chart to target clusters.
@@ -62,7 +64,9 @@ type Bundle struct {
 	metav1.TypeMeta   `json:",inline"`
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
-	Spec   BundleSpec   `json:"spec"`
+	// +optional
+	Spec BundleSpec `json:"spec"`
+	// +optional
 	Status BundleStatus `json:"status"`
 }
 
@@ -74,6 +78,7 @@ type BundleSpec struct {
 
 	// RolloutStrategy controls the rollout of bundles, by defining
 	// partitions, canaries and percentages for cluster availability.
+	// +nullable
 	RolloutStrategy *RolloutStrategy `json:"rolloutStrategy,omitempty"`
 
 	// Resources contains the resources that were read from the bundle's
@@ -88,13 +93,16 @@ type BundleSpec struct {
 	TargetRestrictions []BundleTargetRestriction `json:"targetRestrictions,omitempty"`
 
 	// DependsOn refers to the bundles which must be ready before this bundle can be deployed.
+	// +nullable
 	DependsOn []BundleRef `json:"dependsOn,omitempty"`
 }
 
 type BundleRef struct {
 	// Name of the bundle.
+	// +nullable
 	Name string `json:"name,omitempty"`
 	// Selector matching bundle's labels.
+	// +nullable
 	Selector *metav1.LabelSelector `json:"selector,omitempty"`
 }
 
@@ -115,18 +123,22 @@ type RolloutStrategy struct {
 	// strategy. Once the number of clusters meets unavailable state update will be
 	// paused. Default value is 100% which doesn't take effect on update.
 	// default: 100%
+	// +nullable
 	MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
 	// A number or percentage of cluster partitions that can be unavailable during
 	// an update of a bundle.
 	// default: 0
+	// +nullable
 	MaxUnavailablePartitions *intstr.IntOrString `json:"maxUnavailablePartitions,omitempty"`
 	// A number or percentage of how to automatically partition clusters if no
 	// specific partitioning strategy is configured.
 	// default: 25%
+	// +nullable
 	AutoPartitionSize *intstr.IntOrString `json:"autoPartitionSize,omitempty"`
 	// A list of definitions of partitions.  If any target clusters do not match
 	// the configuration they are added to partitions at the end following the
 	// autoPartitionSize.
+	// +nullable
 	Partitions []Partition `json:"partitions,omitempty"`
 }
 
@@ -152,10 +164,15 @@ type Partition struct {
 // It acts as an allow list, to prevent the creation of BundleDeployments from
 // Targets created by TargetCustomizations in fleet.yaml.
 type BundleTargetRestriction struct {
-	Name                 string                `json:"name,omitempty"`
-	ClusterName          string                `json:"clusterName,omitempty"`
-	ClusterSelector      *metav1.LabelSelector `json:"clusterSelector,omitempty"`
-	ClusterGroup         string                `json:"clusterGroup,omitempty"`
+	// +nullable
+	Name string `json:"name,omitempty"`
+	// +nullable
+	ClusterName string `json:"clusterName,omitempty"`
+	// +nullable
+	ClusterSelector *metav1.LabelSelector `json:"clusterSelector,omitempty"`
+	// +nullable
+	ClusterGroup string `json:"clusterGroup,omitempty"`
+	// +nullable
 	ClusterGroupSelector *metav1.LabelSelector `json:"clusterGroupSelector,omitempty"`
 }
 
@@ -168,16 +185,20 @@ type BundleTarget struct {
 	Name string `json:"name,omitempty"`
 	// ClusterName to match a specific cluster by name that will be
 	// selected
+	// +nullable
 	ClusterName string `json:"clusterName,omitempty"`
 	// ClusterSelector is a selector to match clusters. The structure is
 	// the standard metav1.LabelSelector format. If clusterGroupSelector or
 	// clusterGroup is specified, clusterSelector will be used only to
 	// further refine the selection after clusterGroupSelector and
 	// clusterGroup is evaluated.
+	// +nullable
 	ClusterSelector *metav1.LabelSelector `json:"clusterSelector,omitempty"`
 	// ClusterGroup to match a specific cluster group by name.
+	// +nullable
 	ClusterGroup string `json:"clusterGroup,omitempty"`
 	// ClusterGroupSelector is a selector to match cluster groups.
+	// +nullable
 	ClusterGroupSelector *metav1.LabelSelector `json:"clusterGroupSelector,omitempty"`
 	// DoNotDeploy if set to true, will not deploy to this target.
 	DoNotDeploy bool `json:"doNotDeploy,omitempty"`
@@ -207,12 +228,14 @@ type BundleSummary struct {
 	Modified int `json:"modified,omitempty"`
 	// Ready is the number of bundle deployments that have been deployed
 	// where all resources are ready.
+	// +optional
 	Ready int `json:"ready"`
 	// Pending is the number of bundle deployments that are being processed
 	// by Fleet controller.
 	Pending int `json:"pending,omitempty"`
 	// DesiredReady is the number of bundle deployments that should be
 	// ready.
+	// +optional
 	DesiredReady int `json:"desiredReady"`
 	// NonReadyClusters is a list of states, which is filled for a bundle
 	// that is not ready.
@@ -224,10 +247,13 @@ type BundleSummary struct {
 // resources and their states.
 type NonReadyResource struct {
 	// Name is the name of the resource.
+	// +nullable
 	Name string `json:"name,omitempty"`
 	// State is the state of the resource, like e.g. "NotReady" or "ErrApplied".
+	// +nullable
 	State BundleState `json:"bundleState,omitempty"`
 	// Message contains information why the bundle is not ready.
+	// +nullable
 	Message string `json:"message,omitempty"`
 	// ModifiedStatus lists the state for each modified resource.
 	ModifiedStatus []ModifiedStatus `json:"modifiedStatus,omitempty"`
@@ -255,6 +281,7 @@ var (
 type BundleStatus struct {
 	// Conditions is a list of Wrangler conditions that describe the state
 	// of the bundle.
+	// +optional
 	Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"`
 
 	// Summary contains the number of bundle deployments in each state and
@@ -266,15 +293,19 @@ type BundleStatus struct {
 	// Unavailable is the number of bundle deployments that are not ready or
 	// where the AppliedDeploymentID in the status does not match the
 	// DeploymentID from the spec.
+	// +optional
 	Unavailable int `json:"unavailable"`
 	// UnavailablePartitions is the number of unavailable partitions.
+	// +optional
 	UnavailablePartitions int `json:"unavailablePartitions"`
 	// MaxUnavailable is the maximum number of unavailable deployments. See
 	// rollout configuration.
+	// +optional
 	MaxUnavailable int `json:"maxUnavailable"`
 	// MaxUnavailablePartitions is the maximum number of unavailable
 	// partitions. The rollout configuration defines a maximum number or
 	// percentage of unavailable partitions.
+	// +optional
 	MaxUnavailablePartitions int `json:"maxUnavailablePartitions"`
 	// MaxNew is always 50. A bundle change can only stage 50
 	// bundledeployments at a time.
@@ -289,18 +320,23 @@ type BundleStatus struct {
 	// helm chart, value templating, etc..
 	ResourceKey []ResourceKey `json:"resourceKey,omitempty"`
 	// ObservedGeneration is the current generation of the bundle.
+	// +optional
 	ObservedGeneration int64 `json:"observedGeneration"`
 }
 
 // ResourceKey lists resources, which will likely be deployed.
 type ResourceKey struct {
 	// Kind is the k8s api kind of the resource.
+	// +nullable
 	Kind string `json:"kind,omitempty"`
 	// APIVersion is the k8s api version of the resource.
+	// +nullable
 	APIVersion string `json:"apiVersion,omitempty"`
 	// Namespace is the namespace of the resource.
+	// +nullable
 	Namespace string `json:"namespace,omitempty"`
 	// Name is the name of the resource.
+	// +nullable
 	Name string `json:"name,omitempty"`
 }
 
@@ -310,14 +346,17 @@ type BundleDisplay struct {
 	// ReadyClusters is a string in the form "%d/%d", that describes the
 	// number of clusters that are ready vs. the number of clusters desired
 	// to be ready.
+	// +nullable
 	ReadyClusters string `json:"readyClusters,omitempty"`
 	// State is a summary state for the bundle, calculated over the non-ready resources.
+	// +nullable
 	State string `json:"state,omitempty"`
 }
 
 // PartitionStatus is the status of a single rollout partition.
 type PartitionStatus struct {
 	// Name is the name of the partition.
+	// +nullable
 	Name string `json:"name,omitempty"`
 	// Count is the number of clusters in the partition.
 	Count int `json:"count,omitempty"`
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/bundledeployment_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/bundledeployment_types.go
index 924efff1..921f15c5 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/bundledeployment_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/bundledeployment_types.go
@@ -18,6 +18,9 @@ const MaxHelmReleaseNameLen = 53
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="Deployed",type=string,JSONPath=`.status.display.deployed`
+// +kubebuilder:printcolumn:name="Monitored",type=string,JSONPath=`.status.display.monitored`
+// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].message`
 
 // BundleDeployment is used internally by Fleet and should not be used directly.
 // When a Bundle is deployed to a cluster an instance of a Bundle is called a
@@ -37,21 +40,26 @@ type BundleDeploymentOptions struct {
 	// DefaultNamespace is the namespace to use for resources that do not
 	// specify a namespace. This field is not used to enforce or lock down
 	// the deployment to a specific namespace.
+	// +nullable
 	DefaultNamespace string `json:"defaultNamespace,omitempty"`
 
 	// TargetNamespace if present will assign all resource to this
 	// namespace and if any cluster scoped resource exists the deployment
 	// will fail.
+	// +nullable
 	TargetNamespace string `json:"namespace,omitempty"`
 
 	// Kustomize options for the deployment, like the dir containing the
 	// kustomization.yaml file.
+	// +nullable
 	Kustomize *KustomizeOptions `json:"kustomize,omitempty"`
 
 	// Helm options for the deployment, like the chart name, repo and values.
+	// +nullable
 	Helm *HelmOptions `json:"helm,omitempty"`
 
 	// ServiceAccount which will be used to perform this deployment.
+	// +nullable
 	ServiceAccount string `json:"serviceAccount,omitempty"`
 
 	// ForceSyncGeneration is used to force a redeployment
@@ -59,9 +67,11 @@ type BundleDeploymentOptions struct {
 
 	// YAML options, if using raw YAML these are names that map to
 	// overlays/{name} files that will be used to replace or patch a resource.
+	// +nullable
 	YAML *YAMLOptions `json:"yaml,omitempty"`
 
 	// Diff can be used to ignore the modified state of objects which are amended at runtime.
+	// +nullable
 	Diff *DiffOptions `json:"diff,omitempty"`
 
 	// KeepResources can be used to keep the deployed resources when removing the bundle
@@ -74,40 +84,52 @@ type BundleDeploymentOptions struct {
 	CorrectDrift CorrectDrift `json:"correctDrift,omitempty"`
 
 	// NamespaceLabels are labels that will be appended to the namespace created by Fleet.
+	// +nullable
 	NamespaceLabels *map[string]string `json:"namespaceLabels,omitempty"`
 
 	// NamespaceAnnotations are annotations that will be appended to the namespace created by Fleet.
+	// +nullable
 	NamespaceAnnotations *map[string]string `json:"namespaceAnnotations,omitempty"`
 }
 
 type DiffOptions struct {
 	// ComparePatches match a resource and remove fields from the check for modifications.
+	// +nullable
 	ComparePatches []ComparePatch `json:"comparePatches,omitempty"`
 }
 
 // ComparePatch matches a resource and removes fields from the check for modifications.
 type ComparePatch struct {
 	// Kind is the kind of the resource to match.
+	// +nullable
 	Kind string `json:"kind,omitempty"`
 	// APIVersion is the apiVersion of the resource to match.
+	// +nullable
 	APIVersion string `json:"apiVersion,omitempty"`
 	// Namespace is the namespace of the resource to match.
+	// +nullable
 	Namespace string `json:"namespace,omitempty"`
 	// Name is the name of the resource to match.
+	// +nullable
 	Name string `json:"name,omitempty"`
 	// Operations remove a JSON path from the resource.
+	// +nullable
 	Operations []Operation `json:"operations,omitempty"`
 	// JSONPointers ignore diffs at a certain JSON path.
+	// +nullable
 	JsonPointers []string `json:"jsonPointers,omitempty"`
 }
 
 // Operation of a ComparePatch, usually "remove".
 type Operation struct {
 	// Op is usually "remove"
+	// +nullable
 	Op string `json:"op,omitempty"`
 	// Path is the JSON path to remove.
+	// +nullable
 	Path string `json:"path,omitempty"`
 	// Value is usually empty.
+	// +nullable
 	Value string `json:"value,omitempty"`
 }
 
@@ -119,6 +141,7 @@ type YAMLOptions struct {
 	// ./overlays/myoverlay/subdir/resource.yaml will replace the base
 	// file.
 	// A file named ./overlays/myoverlay/subdir/resource_patch.yaml will patch the base file.
+	// +nullable
 	Overlays []string `json:"overlays,omitempty"`
 }
 
@@ -126,6 +149,7 @@ type YAMLOptions struct {
 type KustomizeOptions struct {
 	// Dir points to a custom folder for kustomize resources. This folder must contain
 	// a kustomization.yaml file.
+	// +nullable
 	Dir string `json:"dir,omitempty"`
 }
 
@@ -135,16 +159,22 @@ type KustomizeOptions struct {
 type HelmOptions struct {
 	// Chart can refer to any go-getter URL or OCI registry based helm
 	// chart URL. The chart will be downloaded.
+	// +nullable
 	Chart string `json:"chart,omitempty"`
 
+	// +nullable
 	// Repo is the name of the HTTPS helm repo to download the chart from.
 	Repo string `json:"repo,omitempty"`
 
 	// ReleaseName sets a custom release name to deploy the chart as. If
 	// not specified a release name will be generated by combining the
 	// invoking GitRepo.name + GitRepo.path.
+	// +nullable
+	// +kubebuilder:validation:MaxLength=53
+	// +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
 	ReleaseName string `json:"releaseName,omitempty"`
 
+	// +nullable
 	// Version of the chart to download
 	Version string `json:"version,omitempty"`
 
@@ -153,8 +183,11 @@ type HelmOptions struct {
 
 	// Values passed to Helm. It is possible to specify the keys and values
 	// as go template strings.
+	// +nullable
+	// +kubebuilder:validation:XPreserveUnknownFields
 	Values *GenericMap `json:"values,omitempty"`
 
+	// +nullable
 	// ValuesFrom loads the values from configmaps and secrets.
 	ValuesFrom []ValuesFrom `json:"valuesFrom,omitempty"`
 
@@ -168,6 +201,7 @@ type HelmOptions struct {
 	MaxHistory int `json:"maxHistory,omitempty"`
 
 	// ValuesFiles is a list of files to load values from.
+	// +nullable
 	ValuesFiles []string `json:"valuesFiles,omitempty"`
 
 	// WaitForJobs if set and timeoutSeconds provided, will wait until all
@@ -191,6 +225,7 @@ type HelmOptions struct {
 // IgnoreOptions defines conditions to be ignored when monitoring the Bundle.
 type IgnoreOptions struct {
 	// Conditions is a list of conditions to be ignored when monitoring the Bundle.
+	// +nullable
 	Conditions []map[string]string `json:"conditions,omitempty"`
 }
 
@@ -198,30 +233,38 @@ type IgnoreOptions struct {
 type ValuesFrom struct {
 	// The reference to a config map with release values.
 	// +optional
+	// +nullable
 	ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
 	// The reference to a secret with release values.
 	// +optional
+	// +nullable
 	SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"`
 }
 
 type ConfigMapKeySelector struct {
 	LocalObjectReference `json:",inline"`
 	// +optional
+	// +nullable
 	Namespace string `json:"namespace,omitempty"`
 	// +optional
+	// +nullable
 	Key string `json:"key,omitempty"`
 }
 
 type SecretKeySelector struct {
 	LocalObjectReference `json:",inline"`
 	// +optional
+	// +nullable
 	Namespace string `json:"namespace,omitempty"`
 	// +optional
+	// +nullable
 	Key string `json:"key,omitempty"`
 }
 
 type LocalObjectReference struct {
 	// Name of a resource in the same namespace as the referent.
+	// +nullable
+	// +optional
 	Name string `json:"name"`
 }
 
@@ -234,12 +277,15 @@ type BundleDeploymentSpec struct {
 	// the next deployment.
 	StagedOptions BundleDeploymentOptions `json:"stagedOptions,omitempty"`
 	// StagedDeploymentID is the ID of the staged deployment.
+	// +nullable
 	StagedDeploymentID string `json:"stagedDeploymentID,omitempty"`
 	// Options are the deployment options, that are currently applied.
 	Options BundleDeploymentOptions `json:"options,omitempty"`
 	// DeploymentID is the ID of the currently applied deployment.
+	// +nullable
 	DeploymentID string `json:"deploymentID,omitempty"`
 	// DependsOn refers to the bundles which must be ready before this bundle can be deployed.
+	// +nullable
 	DependsOn []BundleRef `json:"dependsOn,omitempty"`
 	// CorrectDrift specifies how drift correction should work.
 	CorrectDrift CorrectDrift `json:"correctDrift,omitempty"`
@@ -247,42 +293,63 @@ type BundleDeploymentSpec struct {
 
 // BundleDeploymentResource contains the metadata of a deployed resource.
 type BundleDeploymentResource struct {
-	Kind       string      `json:"kind,omitempty"`
-	APIVersion string      `json:"apiVersion,omitempty"`
-	Namespace  string      `json:"namespace,omitempty"`
-	Name       string      `json:"name,omitempty"`
-	CreatedAt  metav1.Time `json:"createdAt,omitempty"`
+	// +nullable
+	Kind string `json:"kind,omitempty"`
+	// +nullable
+	APIVersion string `json:"apiVersion,omitempty"`
+	// +nullable
+	Namespace string `json:"namespace,omitempty"`
+	// +nullable
+	Name string `json:"name,omitempty"`
+	// +nullable
+	CreatedAt metav1.Time `json:"createdAt,omitempty"`
 }
 
 type BundleDeploymentStatus struct {
-	Conditions          []genericcondition.GenericCondition `json:"conditions,omitempty"`
-	AppliedDeploymentID string                              `json:"appliedDeploymentID,omitempty"`
-	Release             string                              `json:"release,omitempty"`
-	Ready               bool                                `json:"ready,omitempty"`
-	NonModified         bool                                `json:"nonModified,omitempty"`
-	NonReadyStatus      []NonReadyStatus                    `json:"nonReadyStatus,omitempty"`
-	ModifiedStatus      []ModifiedStatus                    `json:"modifiedStatus,omitempty"`
-	Display             BundleDeploymentDisplay             `json:"display,omitempty"`
-	SyncGeneration      *int64                              `json:"syncGeneration,omitempty"`
+	// +nullable
+	Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"`
+	// +nullable
+	AppliedDeploymentID string `json:"appliedDeploymentID,omitempty"`
+	// +nullable
+	Release     string `json:"release,omitempty"`
+	Ready       bool   `json:"ready,omitempty"`
+	NonModified bool   `json:"nonModified,omitempty"`
+	// +nullable
+	NonReadyStatus []NonReadyStatus `json:"nonReadyStatus,omitempty"`
+	// +nullable
+	ModifiedStatus []ModifiedStatus `json:"modifiedStatus,omitempty"`
+	// +nullable
+	Display BundleDeploymentDisplay `json:"display,omitempty"`
+	// +nullable
+	SyncGeneration *int64 `json:"syncGeneration,omitempty"`
 	// Resources lists the metadata of resources that were deployed
 	// according to the helm release history.
+	// +nullable
 	Resources []BundleDeploymentResource `json:"resources,omitempty"`
 }
 
 type BundleDeploymentDisplay struct {
-	Deployed  string `json:"deployed,omitempty"`
+	// +nullable
+	Deployed string `json:"deployed,omitempty"`
+	// +nullable
 	Monitored string `json:"monitored,omitempty"`
-	State     string `json:"state,omitempty"`
+	// +nullable
+	State string `json:"state,omitempty"`
 }
 
 // NonReadyStatus is used to report the status of a resource that is not ready. It includes a summary.
 type NonReadyStatus struct {
-	UID        types.UID       `json:"uid,omitempty"`
-	Kind       string          `json:"kind,omitempty"`
-	APIVersion string          `json:"apiVersion,omitempty"`
-	Namespace  string          `json:"namespace,omitempty"`
-	Name       string          `json:"name,omitempty"`
-	Summary    summary.Summary `json:"summary,omitempty"`
+	// +nullable
+	UID types.UID `json:"uid,omitempty"`
+	// +nullable
+	Kind string `json:"kind,omitempty"`
+	// +nullable
+	APIVersion string `json:"apiVersion,omitempty"`
+	// +nullable
+	Namespace string `json:"namespace,omitempty"`
+	// +nullable
+	Name    string          `json:"name,omitempty"`
+	Summary summary.Summary `json:"summary,omitempty"`
 }
 
 func (in NonReadyStatus) String() string {
@@ -305,13 +372,18 @@ func name(apiVersion, kind, namespace, name string) string {
 // ModifiedStatus is used to report the status of a resource that is modified.
 // It indicates if the modification was a create, a delete or a patch.
 type ModifiedStatus struct {
-	Kind       string `json:"kind,omitempty"`
+	// +nullable
+	Kind string `json:"kind,omitempty"`
+	// +nullable
 	APIVersion string `json:"apiVersion,omitempty"`
-	Namespace  string `json:"namespace,omitempty"`
-	Name       string `json:"name,omitempty"`
-	Create     bool   `json:"missing,omitempty"`
-	Delete     bool   `json:"delete,omitempty"`
-	Patch      string `json:"patch,omitempty"`
+	// +nullable
+	Namespace string `json:"namespace,omitempty"`
+	// +nullable
+	Name   string `json:"name,omitempty"`
+	Create bool   `json:"missing,omitempty"`
+	Delete bool   `json:"delete,omitempty"`
+	// +nullable
+	Patch string `json:"patch,omitempty"`
 }
 
 func (in ModifiedStatus) String() string {
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/bundlenamespacemapping_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/bundlenamespacemapping_types.go
index 54b3aec8..0b84c865 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/bundlenamespacemapping_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/bundlenamespacemapping_types.go
@@ -14,6 +14,8 @@ type BundleNamespaceMapping struct {
 	metav1.TypeMeta   `json:",inline"`
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
-	BundleSelector    *metav1.LabelSelector `json:"bundleSelector,omitempty"`
+	// +nullable
+	BundleSelector *metav1.LabelSelector `json:"bundleSelector,omitempty"`
+	// +nullable
 	NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
 }
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/cluster_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/cluster_types.go
index c96772fe..84bd2980 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/cluster_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/cluster_types.go
@@ -39,6 +39,11 @@ var (
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="Bundles-Ready",type=string,JSONPath=`.status.display.readyBundles`
+// +kubebuilder:printcolumn:name="Nodes-Ready",type=string,JSONPath=`.status.display.readyNodes`
+// +kubebuilder:printcolumn:name="Sample-Node",type=string,JSONPath=`.status.display.sampleNode`
+// +kubebuilder:printcolumn:name="Last-Seen",type=string,JSONPath=`.status.agent.lastSeen`
+// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].message`
 
 // Cluster corresponds to a Kubernetes cluster. Fleet deploys bundles to targeted clusters.
 // Clusters to which Fleet deploys manifests are referred to as downstream
@@ -58,15 +63,18 @@ type ClusterSpec struct {
 
 	// ClientID is a unique string that will identify the cluster. It can
 	// either be predefined, or generated when importing the cluster.
+	// +nullable
 	ClientID string `json:"clientID,omitempty"`
 
 	// KubeConfigSecret is the name of the secret containing the kubeconfig for the downstream cluster.
 	// It can optionally contain a APIServerURL and CA to override the
 	// values in the fleet-controller's configmap.
+	// +nullable
 	KubeConfigSecret string `json:"kubeConfigSecret,omitempty"`
 
 	// KubeConfigSecretNamespace is the namespace of the secret containing the kubeconfig for the downstream cluster.
 	// If unset, it will be assumed the secret can be found in the namespace that the Cluster object resides within.
+	// +nullable
 	KubeConfigSecretNamespace string `json:"kubeConfigSecretNamespace,omitempty"`
 
 	// RedeployAgentGeneration can be used to force redeploying the agent.
@@ -76,9 +84,11 @@ type ClusterSpec struct {
 	AgentEnvVars []corev1.EnvVar `json:"agentEnvVars,omitempty"`
 
 	// AgentNamespace defaults to the system namespace, e.g. cattle-fleet-system.
+	// +nullable
 	AgentNamespace string `json:"agentNamespace,omitempty"`
 
 	// PrivateRepoURL prefixes the image name and overrides a global repo URL from the agents config.
+	// +nullable
 	PrivateRepoURL string `json:"privateRepoURL,omitempty"`
 
 	// TemplateValues defines a cluster specific mapping of values to be sent to fleet.yaml values templating.
@@ -89,8 +99,10 @@ type ClusterSpec struct {
 
 	// AgentAffinity overrides the default affinity for the cluster's agent
 	// deployment. If this value is nil the default affinity is used.
+	// +nullable
 	AgentAffinity *corev1.Affinity `json:"agentAffinity,omitempty"`
 
+	// +nullable
 	// AgentResources sets the resources for the cluster's agent deployment.
 	AgentResources *corev1.ResourceRequirements `json:"agentResources,omitempty"`
 }
@@ -109,16 +121,21 @@ type ClusterStatus struct {
 	// ResourceCounts is an aggregate over the GitRepoResourceCounts.
 	ResourceCounts GitRepoResourceCounts `json:"resourceCounts,omitempty"`
 	// ReadyGitRepos is the number of gitrepos for this cluster that are ready.
+	// +optional
 	ReadyGitRepos int `json:"readyGitRepos"`
 	// DesiredReadyGitRepos is the number of gitrepos for this cluster that
 	// are desired to be ready.
+	// +optional
 	DesiredReadyGitRepos int `json:"desiredReadyGitRepos"`
 
 	// AgentEnvVarsHash is a hash of the agent's env vars, used to detect changes.
+	// +nullable
 	AgentEnvVarsHash string `json:"agentEnvVarsHash,omitempty"`
 	// AgentPrivateRepoURL is the private repo URL for the agent that is currently used.
+	// +nullable
 	AgentPrivateRepoURL string `json:"agentPrivateRepoURL,omitempty"`
 	// AgentDeployedGeneration is the generation of the agent that is currently deployed.
+	// +nullable
 	AgentDeployedGeneration *int64 `json:"agentDeployedGeneration,omitempty"`
 	// AgentMigrated is always set to true after importing a cluster. If
 	// false, it will trigger a migration. Old agents don't have
@@ -138,9 +155,11 @@ type ClusterStatus struct {
 	AgentAffinityHash string `json:"agentAffinityHash,omitempty"`
 	// AgentResourcesHash is a hash of the agent's resources configuration,
 	// used to detect changes.
+	// +nullable
 	AgentResourcesHash string `json:"agentResourcesHash,omitempty"`
 	// AgentTolerationsHash is a hash of the agent's tolerations
 	// configuration, used to detect changes.
+	// +nullable
 	AgentTolerationsHash string `json:"agentTolerationsHash,omitempty"`
 	// AgentConfigChanged is set to true if any of the agent configuration
 	// changed, like the API server URL or CA. Setting it to true will
@@ -149,8 +168,10 @@ type ClusterStatus struct {
 
 	// APIServerURL is the currently used URL of the API server that the
 	// cluster uses to connect to upstream.
+	// +nullable
 	APIServerURL string `json:"apiServerURL,omitempty"`
 	// APIServerCAHash is a hash of the upstream API server CA, used to detect changes.
+	// +nullable
 	APIServerCAHash string `json:"apiServerCAHash,omitempty"`
 
 	// Display contains the number of ready bundles, nodes and a summary state.
@@ -177,17 +198,25 @@ type ClusterDisplay struct {
 type AgentStatus struct {
 	// LastSeen is the last time the agent checked in to update the status
 	// of the cluster resource.
+	// +nullable
+	// +optional
 	LastSeen metav1.Time `json:"lastSeen"`
 	// Namespace is the namespace of the agent deployment, e.g. "cattle-fleet-system".
+	// +nullable
+	// +optional
 	Namespace string `json:"namespace"`
 	// NonReadyNodes is the number of nodes that are not ready.
+	// +optional
 	NonReadyNodes int `json:"nonReadyNodes"`
 	// ReadyNodes is the number of nodes that are ready.
+	// +optional
 	ReadyNodes int `json:"readyNodes"`
 	// NonReadyNode contains the names of non-ready nodes. The list is
 	// limited to at most 3 names.
+	// +optional
 	NonReadyNodeNames []string `json:"nonReadyNodeNames"`
 	// ReadyNodes contains the names of ready nodes. The list is limited to
 	// at most 3 names.
+	// +optional
 	ReadyNodeNames []string `json:"readyNodeNames"`
 }
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/clustergroup_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/clustergroup_types.go
index d59f55b9..0287205e 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/clustergroup_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/clustergroup_types.go
@@ -9,27 +9,37 @@ import (
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:resource:categories=fleet
+// +kubebuilder:printcolumn:name="Clusters-Ready",type=string,JSONPath=`.status.display.readyClusters`
+// +kubebuilder:printcolumn:name="Bundles-Ready",type=string,JSONPath=`.status.display.readyBundles`
+// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].message`
 
 // ClusterGroup is a re-usable selector to target a group of clusters.
 type ClusterGroup struct {
 	metav1.TypeMeta   `json:",inline"`
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
-	Spec   ClusterGroupSpec   `json:"spec"`
+	// +optional
+	Spec ClusterGroupSpec `json:"spec"`
+	// +optional
 	Status ClusterGroupStatus `json:"status"`
 }
 
 type ClusterGroupSpec struct {
 	// Selector is a label selector, used to select clusters for this group.
+	// +nullable
 	Selector *metav1.LabelSelector `json:"selector,omitempty"`
 }
 
 type ClusterGroupStatus struct {
 	// ClusterCount is the number of clusters in the cluster group.
+	// +optional
 	ClusterCount int `json:"clusterCount"`
 	// NonReadyClusterCount is the number of clusters that are not ready.
+	// +optional
 	NonReadyClusterCount int `json:"nonReadyClusterCount"`
 	// NonReadyClusters is a list of cluster names that are not ready.
+	// +nullable
 	NonReadyClusters []string `json:"nonReadyClusters,omitempty"`
 	// Conditions is a list of conditions and their statuses for the cluster group.
 	Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"`
@@ -48,12 +58,15 @@ type ClusterGroupDisplay struct {
 	// ReadyClusters is a string in the form "%d/%d", that describes the
 	// number of clusters that are ready vs. the number of clusters desired
 	// to be ready.
+	// +nullable
 	ReadyClusters string `json:"readyClusters,omitempty"`
 	// ReadyBundles is a string in the form "%d/%d", that describes the
 	// number of bundles that are ready vs. the number of bundles desired
 	// to be ready.
+	// +nullable
 	ReadyBundles string `json:"readyBundles,omitempty"`
 	// State is a summary state for the cluster group, showing "NotReady" if
 	// there are non-ready resources.
+	// +nullable
 	State string `json:"state,omitempty"`
 }
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistration_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistration_types.go
index 433baa08..44f68b59 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistration_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistration_types.go
@@ -8,6 +8,8 @@ import (
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="Cluster-Name",type=string,JSONPath=`.status.clusterName`
+// +kubebuilder:printcolumn:name="Labels",type=string,JSONPath=`.spec.clusterLabels`
 
 // ClusterRegistration is used internally by Fleet and should not be used directly.
 type ClusterRegistration struct {
@@ -21,18 +23,22 @@ type ClusterRegistration struct {
 type ClusterRegistrationSpec struct {
 	// ClientID is a unique string that will identify the cluster. The
 	// agent either uses the configured ID or the kubeSystem.UID.
+	// +nullable
 	ClientID string `json:"clientID,omitempty"`
 	// ClientRandom is a random string that the agent generates. When
 	// fleet-controller grants a registration, it creates a registration
 	// secret with this string in the name.
+	// +nullable
 	ClientRandom string `json:"clientRandom,omitempty"`
 	// ClusterLabels are copied to the cluster resource during the registration.
+	// +nullable
 	ClusterLabels map[string]string `json:"clusterLabels,omitempty"`
 }
 
 type ClusterRegistrationStatus struct {
 	// ClusterName is only set after the registration is being processed by
 	// fleet-controller.
+	// +nullable
 	ClusterName string `json:"clusterName,omitempty"`
 	// Granted is set to true, if the request service account is present
 	// and its token secret exists. This happens directly before creating
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistrationtoken_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistrationtoken_types.go
index 7496078d..ea64317a 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistrationtoken_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/clusterregistrationtoken_types.go
@@ -8,6 +8,7 @@ import (
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="Secret-Name",type=string,JSONPath=`.status.secretName`
 
 // ClusterRegistrationToken is used by agents to register a new cluster.
 type ClusterRegistrationToken struct {
@@ -21,6 +22,7 @@ type ClusterRegistrationToken struct {
 type ClusterRegistrationTokenSpec struct {
 	// TTL is the time to live for the token. It is used to calculate the
 	// expiration time. If the token expires, it will be deleted.
+	// +nullable
 	TTL *metav1.Duration `json:"ttl,omitempty"`
 }
 
@@ -28,5 +30,6 @@ type ClusterRegistrationTokenStatus struct {
 	// Expires is the time when the token expires.
 	Expires *metav1.Time `json:"expires,omitempty"`
 	// SecretName is the name of the secret containing the token.
+	// +nullable
 	SecretName string `json:"secretName,omitempty"`
 }
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/content_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/content_types.go
index 23957e84..4e6f547a 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/content_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/content_types.go
@@ -9,6 +9,7 @@ import (
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster
 
 // Content is used internally by Fleet and should not be used directly. It
 // contains the resources from a bundle for a specific target cluster.
@@ -19,5 +20,6 @@ type Content struct {
 	// Content is a byte array, which contains the manifests of a bundle.
 	// The bundle resources are copied into the bundledeployment's content
 	// resource, so the downstream agent can deploy them.
+	// +nullable
 	Content []byte `json:"content,omitempty"`
 }
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/gitrepo_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/gitrepo_types.go
index ee9b64c8..cbe61656 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/gitrepo_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/gitrepo_types.go
@@ -16,6 +16,10 @@ var (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=fleet,path=gitrepos
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="Repo",type=string,JSONPath=`.spec.repo`
+// +kubebuilder:printcolumn:name="Commit",type=string,JSONPath=`.status.commit`
+// +kubebuilder:printcolumn:name="BundleDeployments-Ready",type=string,JSONPath=`.status.display.readyBundleDeployments`
+// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].message`
 
 // GitRepo describes a git repository that is watched by Fleet.
 // The resource contains the necessary information to deploy the repo, or parts
@@ -30,34 +34,43 @@ type GitRepo struct {
 
 type GitRepoSpec struct {
 	// Repo is a URL to a git repo to clone and index.
+	// +nullable
 	Repo string `json:"repo,omitempty"`
 
 	// Branch The git branch to follow.
+	// +nullable
 	Branch string `json:"branch,omitempty"`
 
 	// Revision A specific commit or tag to operate on.
+	// +nullable
 	Revision string `json:"revision,omitempty"`
 
 	// Ensure that all resources are created in this namespace
 	// Any cluster scoped resource will be rejected if this is set
 	// Additionally this namespace will be created on demand.
+	// +nullable
 	TargetNamespace string `json:"targetNamespace,omitempty"`
 
 	// ClientSecretName is the name of the client secret to be used to connect to the repo
 	// It is expected the secret be of type "kubernetes.io/basic-auth" or "kubernetes.io/ssh-auth".
+	// +nullable
 	ClientSecretName string `json:"clientSecretName,omitempty"`
 
 	// HelmSecretName contains the auth secret for a private Helm repository.
+	// +nullable
 	HelmSecretName string `json:"helmSecretName,omitempty"`
 
 	// HelmSecretNameForPaths contains the auth secret for private Helm repository for each path.
+	// +nullable
 	HelmSecretNameForPaths string `json:"helmSecretNameForPaths,omitempty"`
 
 	// HelmRepoURLRegex Helm credentials will be used if the helm repo matches this regex
 	// Credentials will always be used if this is empty or not provided.
+	// +nullable
 	HelmRepoURLRegex string `json:"helmRepoURLRegex,omitempty"`
 
 	// CABundle is a PEM encoded CA bundle which will be used to validate the repo's certificate.
+	// +nullable
 	CABundle []byte `json:"caBundle,omitempty"`
 
 	// InsecureSkipTLSverify will use insecure HTTPS to clone the repo.
@@ -66,6 +79,7 @@ type GitRepoSpec struct {
 	// Paths is the directories relative to the git repo root that contain resources to be applied.
 	// Path globbing is supported, for example ["charts/*"] will match all folders as a subdirectory of charts/
 	// If empty, "/" is the default.
+	// +nullable
 	Paths []string `json:"paths,omitempty"`
 
 	// Paused, when true, causes changes in Git not to be propagated down to the clusters but instead to mark
@@ -73,12 +87,14 @@ type GitRepoSpec struct {
 	Paused bool `json:"paused,omitempty"`
 
 	// ServiceAccount used in the downstream cluster for deployment.
+	// +nullable
 	ServiceAccount string `json:"serviceAccount,omitempty"`
 
 	// Targets is a list of targets this repo will deploy to.
 	Targets []GitTarget `json:"targets,omitempty"`
 
 	// PollingInterval is how often to check git for new updates.
+	// +nullable
 	PollingInterval *metav1.Duration `json:"pollingInterval,omitempty"`
 
 	// Increment this number to force a redeployment of contents from Git.
@@ -101,27 +117,36 @@ type GitRepoSpec struct {
 // GitTarget is a cluster or cluster group to deploy to.
 type GitTarget struct {
 	// Name is the name of this target.
+	// +nullable
 	Name string `json:"name,omitempty"`
 	// ClusterName is the name of a cluster.
+	// +nullable
 	ClusterName string `json:"clusterName,omitempty"`
 	// ClusterSelector is a label selector to select clusters.
+	// +nullable
 	ClusterSelector *metav1.LabelSelector `json:"clusterSelector,omitempty"`
 	// ClusterGroup is the name of a cluster group in the same namespace as the clusters.
+	// +nullable
 	ClusterGroup string `json:"clusterGroup,omitempty"`
 	// ClusterGroupSelector is a label selector to select cluster groups.
+	// +nullable
 	ClusterGroupSelector *metav1.LabelSelector `json:"clusterGroupSelector,omitempty"`
 }
 
 type GitRepoStatus struct {
 	// ObservedGeneration is the current generation of the resource in the cluster. It is copied from k8s
 	// metadata.Generation. The value is incremented for all changes, except for changes to .metadata or .status.
+	// +optional
 	ObservedGeneration int64 `json:"observedGeneration"`
 	// Commit is the Git commit hash from the last gitjob run.
+	// +nullable
 	Commit string `json:"commit,omitempty"`
 	// ReadyClusters is the lowest number of clusters that are ready over
 	// all the bundles of this GitRepo.
+	// +optional
 	ReadyClusters int `json:"readyClusters"`
 	// DesiredReadyClusters	is the number of clusters that should be ready for bundles of this GitRepo.
+	// +optional
 	DesiredReadyClusters int `json:"desiredReadyClusters"`
 	// GitJobStatus is the status of the last GitJob run, e.g. "Current" if there was no error.
 	GitJobStatus string `json:"gitJobStatus,omitempty"`
@@ -145,21 +170,29 @@ type GitRepoStatus struct {
 // GitRepoResourceCounts contains the number of resources in each state.
 type GitRepoResourceCounts struct {
 	// Ready is the number of ready resources.
+	// +optional
 	Ready int `json:"ready"`
 	// DesiredReady is the number of resources that should be ready.
+	// +optional
 	DesiredReady int `json:"desiredReady"`
 	// WaitApplied is the number of resources that are waiting to be applied.
+	// +optional
 	WaitApplied int `json:"waitApplied"`
 	// Modified is the number of resources that have been modified.
+	// +optional
 	Modified int `json:"modified"`
 	// Orphaned is the number of orphaned resources.
+	// +optional
 	Orphaned int `json:"orphaned"`
 	// Missing is the number of missing resources.
+	// +optional
 	Missing int `json:"missing"`
 	// Unknown is the number of resources in an unknown state.
+	// +optional
 	Unknown int `json:"unknown"`
 	// NotReady is the number of not ready resources. Resources are not
 	// ready if they do not match any other state.
+	// +optional
 	NotReady int `json:"notReady"`
 }
 
@@ -226,14 +259,17 @@ type ResourcePerClusterState struct {
 // CommitSpec specifies how to commit changes to the git repository
 type CommitSpec struct {
 	// AuthorName gives the name to provide when making a commit
-	// +required
+	// +optional
+	// +nullable
 	AuthorName string `json:"authorName"`
 	// AuthorEmail gives the email to provide when making a commit
-	// +required
+	// +optional
+	// +nullable
 	AuthorEmail string `json:"authorEmail"`
 	// MessageTemplate provides a template for the commit message,
 	// into which will be interpolated the details of the change made.
 	// +optional
+	// +nullable
 	MessageTemplate string `json:"messageTemplate,omitempty"`
 }
 
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/gitreporestriction_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/gitreporestriction_types.go
index 150fe209..614566b4 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/gitreporestriction_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/gitreporestriction_types.go
@@ -8,6 +8,8 @@ import (
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="Default-ServiceAccount",type=string,JSONPath=`.defaultServiceAccount`
+// +kubebuilder:printcolumn:name="Allowed-ServiceAccounts",type=string,JSONPath=`.allowedServiceAccounts`
 
 // GitRepoRestriction is a resource that can optionally be used to restrict
 // the options of GitRepos in the same namespace.
@@ -16,20 +18,26 @@ type GitRepoRestriction struct {
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// DefaultServiceAccount overrides the GitRepo's default service account.
+	// +nullable
 	DefaultServiceAccount string `json:"defaultServiceAccount,omitempty"`
 	// AllowedServiceAccounts is a list of service accounts that GitRepos are allowed to use.
+	// +nullable
 	AllowedServiceAccounts []string `json:"allowedServiceAccounts,omitempty"`
 	// AllowedRepoPatterns is a list of regex patterns that restrict the
 	// valid values of the Repo field of a GitRepo.
+	// +nullable
 	AllowedRepoPatterns []string `json:"allowedRepoPatterns,omitempty"`
 
 	// DefaultClientSecretName overrides the GitRepo's default client secret.
+	// +nullable
 	DefaultClientSecretName string `json:"defaultClientSecretName,omitempty"`
 	// AllowedClientSecretNames is a list of client secret names that GitRepos are allowed to use.
+	// +nullable
 	AllowedClientSecretNames []string `json:"allowedClientSecretNames,omitempty"`
 
 	// AllowedTargetNamespaces restricts TargetNamespace to the given
 	// namespaces. If AllowedTargetNamespaces is set, TargetNamespace must
 	// be set.
+	// +nullable
 	AllowedTargetNamespaces []string `json:"allowedTargetNamespaces,omitempty"`
 }
diff --git a/pkg/apis/fleet.cattle.io/v1alpha1/imagescan_types.go b/pkg/apis/fleet.cattle.io/v1alpha1/imagescan_types.go
index 96eb83ab..aad61047 100644
--- a/pkg/apis/fleet.cattle.io/v1alpha1/imagescan_types.go
+++ b/pkg/apis/fleet.cattle.io/v1alpha1/imagescan_types.go
@@ -10,6 +10,8 @@ import (
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name="Repository",type=string,JSONPath=`.spec.image`
+// +kubebuilder:printcolumn:name="Latest",type=string,JSONPath=`.status.latestTag`
 
 type ImageScan struct {
 	metav1.TypeMeta   `json:",inline"`
@@ -22,17 +24,21 @@ type ImageScan struct {
 // API is taken from https://github.com/fluxcd/image-reflector-controller
 type ImageScanSpec struct {
 	// TagName is the tag ref that needs to be put in manifest to replace fields
+	// +nullable
 	TagName string `json:"tagName,omitempty"`
 
 	// GitRepo reference name
+	// +nullable
 	GitRepoName string `json:"gitrepoName,omitempty"`
 
 	// Image is the name of the image repository
 	// +required
+	// +nullable
 	Image string `json:"image,omitempty"`
 
 	// Interval is the length of time to wait between
 	// scans of the image repository.
+	// +nullable
 	// +required
 	Interval metav1.Duration `json:"interval,omitempty"`
 
@@ -40,6 +46,7 @@ type ImageScanSpec struct {
 	// credentials to use for the image registry. The secret should be
 	// created with `kubectl create secret docker-registry`, or the
 	// equivalent.
+	// +nullable
 	SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
 
 	// This flag tells the controller to suspend subsequent image scans.
@@ -49,7 +56,7 @@ type ImageScanSpec struct {
 
 	// Policy gives the particulars of the policy to be followed in
 	// selecting the most recent image
-	// +required
+	// +optional
 	Policy ImagePolicyChoice `json:"policy"`
 }
 
@@ -59,9 +66,11 @@ type ImagePolicyChoice struct {
 	// SemVer gives a semantic version range to check against the tags
 	// available.
 	// +optional
+	// +nullable
 	SemVer *SemVerPolicy `json:"semver,omitempty"`
 	// Alphabetical set of rules to use for alphabetical ordering of the tags.
 	// +optional
+	// +nullable
 	Alphabetical *AlphabeticalPolicy `json:"alphabetical,omitempty"`
 }
 
@@ -69,7 +78,8 @@ type ImagePolicyChoice struct {
 type SemVerPolicy struct {
 	// Range gives a semver range for the image tag; the highest
 	// version within the range that's a tag yields the latest image.
-	// +required
+	// +optional
+	// +nullable
 	Range string `json:"range"`
 }
 
@@ -78,9 +88,8 @@ type AlphabeticalPolicy struct {
 	// Order specifies the sorting order of the tags. Given the letters of the
 	// alphabet as tags, ascending order would select Z, and descending order
 	// would select A.
-	// +kubebuilder:default:="asc"
-	// +kubebuilder:validation:Enum=asc;desc
 	// +optional
+	// +nullable
 	Order string `json:"order,omitempty"`
 }
 
diff --git a/pkg/crd/crds.go b/pkg/crd/crds.go
deleted file mode 100644
index 481dcc47..00000000
--- a/pkg/crd/crds.go
+++ /dev/null
@@ -1,271 +0,0 @@
-package crd
-
-import (
-	"context"
-	"io"
-	"os"
-	"path/filepath"
-
-	fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
-	"github.com/rancher/wrangler/v2/pkg/crd"
-	"github.com/rancher/wrangler/v2/pkg/schemas/openapi"
-	"github.com/rancher/wrangler/v2/pkg/yaml"
-	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/client-go/rest"
-)
-
-func Create(ctx context.Context, cfg *rest.Config) error {
-	factory, err := crd.NewFactoryFromClient(cfg)
-	if err != nil {
-		return err
-	}
-
-	return factory.BatchCreateCRDs(ctx, list()...).BatchWait()
-}
-
-func WriteFile(filename string) error {
-	if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
-		return err
-	}
-	f, err := os.Create(filename)
-	if err != nil {
-		return err
-	}
-	defer f.Close()
-
-	return print(f)
-}
-
-func print(out io.Writer) error {
-	obj, err := objects()
-	if err != nil {
-		return err
-	}
-	data, err := yaml.Export(obj...)
-	if err != nil {
-		return err
-	}
-
-	_, err = out.Write(data)
-	return err
-}
-
-func objects() (result []runtime.Object, err error) {
-	for _, crdDef := range list() {
-		crd, err := crdDef.ToCustomResourceDefinition()
-		if err != nil {
-			return nil, err
-		}
-		result = append(result, crd)
-	}
-	return
-}
-
-func list() []crd.CRD {
-	return []crd.CRD{
-		newCRD(&fleet.Bundle{}, func(c crd.CRD) crd.CRD {
-			schema := mustSchema(fleet.Bundle{})
-			schema.Properties["spec"].Properties["helm"].Properties["releaseName"] = releaseNameValidation()
-
-			c.GVK.Kind = "Bundle"
-			return c.
-				WithSchemaFromStruct(nil).
-				WithSchema(schema).
-				WithColumn("BundleDeployments-Ready", ".status.display.readyClusters").
-				WithColumn("Status", ".status.conditions[?(@.type==\"Ready\")].message")
-		}),
-		newCRD(&fleet.BundleDeployment{}, func(c crd.CRD) crd.CRD {
-			schema := mustSchema(fleet.BundleDeployment{})
-			schema.Properties["spec"].Properties["options"].Properties["helm"].Properties["releaseName"] = releaseNameValidation()
-
-			c.GVK.Kind = "BundleDeployment"
-			return c.
-				WithSchemaFromStruct(nil).
-				WithSchema(schema).
-				WithColumn("Deployed", ".status.display.deployed").
-				WithColumn("Monitored", ".status.display.monitored").
-				WithColumn("Status", ".status.conditions[?(@.type==\"Ready\")].message")
-		}),
-		newCRD(&fleet.BundleNamespaceMapping{}, func(c crd.CRD) crd.CRD {
-			return c
-		}),
-		newCRD(&fleet.ClusterGroup{}, func(c crd.CRD) crd.CRD {
-			return c.
-				WithCategories("fleet").
-				WithColumn("Clusters-Ready", ".status.display.readyClusters").
-				WithColumn("Bundles-Ready", ".status.display.readyBundles").
-				WithColumn("Status", ".status.conditions[?(@.type==\"Ready\")].message")
-		}),
-		newCRD(&fleet.Cluster{}, func(c crd.CRD) crd.CRD {
-			schema := mustSchema(fleet.Cluster{})
-			schema.Properties["metadata"] = metadataNameValidation()
-			schema.Properties["spec"].Properties["agentTolerations"].Items.Schema.Properties["tolerationSeconds"] = tolerationSecondsValidation()
-
-			nodeAffinity := nodeAffinity(schema)
-			nodeAffinity.Properties["requiredDuringSchedulingIgnoredDuringExecution"].Properties["nodeSelectorTerms"].Items.Schema.Properties["matchExpressions"].Items.Schema.Properties["operator"] = nodeSelectorOperatorValidation()
-			nodeAffinity.Properties["requiredDuringSchedulingIgnoredDuringExecution"].Properties["nodeSelectorTerms"].Items.Schema.Properties["matchFields"].Items.Schema.Properties["operator"] = nodeSelectorOperatorValidation()
-			nodeAffinity.Properties["preferredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["preference"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = nodeSelectorOperatorValidation()
-			nodeAffinity.Properties["preferredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["preference"].Properties["matchFields"].Items.Schema.Properties["operator"] = nodeSelectorOperatorValidation()
-
-			podAffinity := podAffinity(schema)
-			podAffinity.Properties["requiredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["labelSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-			podAffinity.Properties["requiredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["namespaceSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-			podAffinity.Properties["preferredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["podAffinityTerm"].Properties["labelSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-			podAffinity.Properties["preferredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["podAffinityTerm"].Properties["namespaceSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-
-			podAntiAffinity := podAntiAffinity(schema)
-			podAntiAffinity.Properties["requiredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["labelSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-			podAntiAffinity.Properties["requiredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["namespaceSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-			podAntiAffinity.Properties["preferredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["podAffinityTerm"].Properties["labelSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-			podAntiAffinity.Properties["preferredDuringSchedulingIgnoredDuringExecution"].Items.Schema.Properties["podAffinityTerm"].Properties["namespaceSelector"].Properties["matchExpressions"].Items.Schema.Properties["operator"] = labelSelectorOperatorValidation()
-
-			c.GVK.Kind = "Cluster"
-			return c.
-				WithSchemaFromStruct(nil).
-				WithSchema(schema).
-				WithColumn("Bundles-Ready", ".status.display.readyBundles").
-				WithColumn("Nodes-Ready", ".status.display.readyNodes").
-				WithColumn("Sample-Node", ".status.display.sampleNode").
-				WithColumn("Last-Seen", ".status.agent.lastSeen").
-				WithColumn("Status", ".status.conditions[?(@.type==\"Ready\")].message")
-		}),
-		newCRD(&fleet.ClusterRegistrationToken{}, func(c crd.CRD) crd.CRD {
-			schema := mustSchema(fleet.ClusterRegistrationToken{})
-			schema.Properties["metadata"] = metadataNameValidation()
-
-			c.GVK.Kind = "ClusterRegistrationToken"
-			return c.
-				WithSchemaFromStruct(nil).
-				WithSchema(schema).
-				WithColumn("Secret-Name", ".status.secretName")
-		}),
-		newCRD(&fleet.GitRepo{}, func(c crd.CRD) crd.CRD {
-			return c.
-				WithCategories("fleet").
-				WithColumn("Repo", ".spec.repo").
-				WithColumn("Commit", ".status.commit").
-				WithColumn("BundleDeployments-Ready", ".status.display.readyBundleDeployments").
-				WithColumn("Status", ".status.conditions[?(@.type==\"Ready\")].message")
-		}),
-		newCRD(&fleet.ClusterRegistration{}, func(c crd.CRD) crd.CRD {
-			return c.
-				WithColumn("Cluster-Name", ".status.clusterName").
-				WithColumn("Labels", ".spec.clusterLabels")
-		}),
-		newCRD(&fleet.GitRepoRestriction{}, func(c crd.CRD) crd.CRD {
-			return c.
-				WithColumn("Default-ServiceAccount", ".defaultServiceAccount").
-				WithColumn("Allowed-ServiceAccounts", ".allowedServiceAccounts")
-		}),
-		newCRD(&fleet.Content{}, func(c crd.CRD) crd.CRD {
-			c.NonNamespace = true
-			c.Status = false
-			return c
-		}),
-		newCRD(&fleet.ImageScan{}, func(c crd.CRD) crd.CRD {
-			return c.WithCategories("fleet").
-				WithColumn("Repository", ".spec.image").
-				WithColumn("Latest", ".status.latestTag")
-		}),
-	}
-}
-
-func newCRD(obj interface{}, customize func(crd.CRD) crd.CRD) crd.CRD {
-	crd := crd.CRD{
-		GVK: schema.GroupVersionKind{
-			Group:   "fleet.cattle.io",
-			Version: "v1alpha1",
-		},
-		Status:       true,
-		SchemaObject: obj,
-	}
-	if customize != nil {
-		crd = customize(crd)
-	}
-	return crd
-}
-
-// metadataNameValidation returns a schema that validates the metadata.name field
-// metadata:
-//
-//	properties:
-//	  name:
-//	    type: string
-//	    pattern: "^[-a-z0-9]*$"
-//	    maxLength: 63
-//	type: object
-func metadataNameValidation() apiextv1.JSONSchemaProps {
-	prop := apiextv1.JSONSchemaProps{
-		Type:      "string",
-		Pattern:   "^[-a-z0-9]+$",
-		MaxLength: &[]int64{63}[0],
-	}
-	return apiextv1.JSONSchemaProps{
-		Type:       "object",
-		Properties: map[string]apiextv1.JSONSchemaProps{"name": prop},
-	}
-
-}
-
-// releaseNameValidation for helm release names according to helm itself
-func releaseNameValidation() apiextv1.JSONSchemaProps {
-	return apiextv1.JSONSchemaProps{
-		Type:      "string",
-		Pattern:   `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`,
-		MaxLength: &[]int64{fleet.MaxHelmReleaseNameLen}[0],
-		Nullable:  true,
-	}
-}
-
-// tolerationSecondsValidation limits the maximum of TolerationSeconds to one day
-func tolerationSecondsValidation() apiextv1.JSONSchemaProps {
-	return apiextv1.JSONSchemaProps{
-		Type:     "integer",
-		Maximum:  &[]float64{86400}[0],
-		Nullable: true,
-	}
-}
-
-// nodeSelectorOperatorValidation validates the Operator is one of: In, NotIn, Exists, DoesNotExist, Gt, Lt
-func nodeSelectorOperatorValidation() apiextv1.JSONSchemaProps {
-	return apiextv1.JSONSchemaProps{
-		Type:     "string",
-		Enum:     []apiextv1.JSON{{Raw: []byte(`"In"`)}, {Raw: []byte(`"NotIn"`)}, {Raw: []byte(`"Exists"`)}, {Raw: []byte(`"DoesNotExist"`)}, {Raw: []byte(`"Gt"`)}, {Raw: []byte(`"Lt"`)}},
-		Nullable: true,
-	}
-}
-
-// labelSelectorOperatorValidation validates the Operator is one of: In, NotIn, Exists, DoesNotExist
-func labelSelectorOperatorValidation() apiextv1.JSONSchemaProps {
-	return apiextv1.JSONSchemaProps{
-		Type:     "string",
-		Enum:     []apiextv1.JSON{{Raw: []byte(`"In"`)}, {Raw: []byte(`"NotIn"`)}, {Raw: []byte(`"Exists"`)}, {Raw: []byte(`"DoesNotExist"`)}},
-		Nullable: true,
-	}
-}
-
-func mustSchema(obj interface{}) *apiextv1.JSONSchemaProps {
-	result, err := openapi.ToOpenAPIFromStruct(obj)
-	if err != nil {
-		panic(err)
-	}
-	return result
-}
-
-func agentAffinity(schema *apiextv1.JSONSchemaProps) apiextv1.JSONSchemaProps {
-	return schema.Properties["spec"].Properties["agentAffinity"]
-}
-
-func nodeAffinity(schema *apiextv1.JSONSchemaProps) apiextv1.JSONSchemaProps {
-	return agentAffinity(schema).Properties["nodeAffinity"]
-}
-
-func podAffinity(schema *apiextv1.JSONSchemaProps) apiextv1.JSONSchemaProps {
-	return agentAffinity(schema).Properties["podAffinity"]
-}
-
-func podAntiAffinity(schema *apiextv1.JSONSchemaProps) apiextv1.JSONSchemaProps {
-	return agentAffinity(schema).Properties["podAntiAffinity"]
-}


Test patch:
diff --git a/e2e/testenv/infra/go.mod b/e2e/testenv/infra/go.mod
index b5aaa879..79d04254 100644
--- a/e2e/testenv/infra/go.mod
+++ b/e2e/testenv/infra/go.mod
@@ -63,7 +63,7 @@ require (
 	golang.org/x/sys v0.13.0 // indirect
 	golang.org/x/tools v0.13.0 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
-	google.golang.org/grpc v1.55.0 // indirect
+	google.golang.org/grpc v1.56.3 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	k8s.io/client-go v12.0.0+incompatible // indirect
diff --git a/e2e/testenv/infra/go.sum b/e2e/testenv/infra/go.sum
index 3bd98ab1..29b75afa 100644
--- a/e2e/testenv/infra/go.sum
+++ b/e2e/testenv/infra/go.sum
@@ -257,8 +257,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
-google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
-google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
+google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
+google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
diff --git a/internal/cmd/agent/register/register_test.go b/internal/cmd/agent/register/register_test.go
index 540371ba..93cf214b 100644
--- a/internal/cmd/agent/register/register_test.go
+++ b/internal/cmd/agent/register/register_test.go
@@ -61,6 +61,7 @@ func TestRunRegistrationLabelSmokeTest(t *testing.T) {
 	agentSecret, err := runRegistration(context.Background(), mockCoreController, namespace, "my-clusterID")
 
 	assert.Nil(t, agentSecret)
-	// expecting a timeout at cluster registration creation time because the API server URL is a dummy.
-	assert.Regexp(t, regexp.MustCompile("cannot create clusterregistration.*timeout"), err.Error())
+	// expecting an error at cluster registration creation time because the API server URL is a dummy.
+	// this may be a timeout or a simple 'connection refused' error.
+	assert.Regexp(t, regexp.MustCompile("cannot create clusterregistration.*"), err.Error())
 }