feat: upgrade crossplane init command to use v2#230
Merged
Conversation
1. Panic fix: xrd.Spec.ClaimNames.Kind → nil-safe with fallback to xrd.Spec.Names.Kind. In Crossplane v2, claimNames is replaced by scope: Namespaced on the XRD spec, so ClaimNames is always nil. 2. Dependency fidelity: Replaced runtime.DefaultUnstructuredConverter.ToUnstructured(xrd) with a new readFileAsUnstructured() that reads the raw YAML. This preserves v2-specific fields like scope: Namespaced that aren't in the v1 Go struct, and drops spurious fields that the typed conversion was injecting (metadata.creationTimestamp: null, status.controllers.*). 3. Nil guard in generateCRDFromXRD: Added a check for version.Schema == nil before accessing version.Schema.OpenAPIV3Schema.
The mandatoryAdditionalClaimFields map injected Crossplane-internal plumbing fields (compositionRef, compositeDeletePolicy, etc.) into every generated Kratix API CRD spec, which are not user-facing API fields and should not appear in the Promise API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously the generated CRD always set spec.default to {}, which is
invalid when the spec has required fields that lack their own defaults.
buildSpecDefault now inspects required fields: if all have defaults, it
returns a default object containing those values; if any required field
has no default, it returns nil so no spec-level default is set.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With Crossplane upgrading and releasing a stable v2, it is important that this CLI generates successfully on v2 resources.
The biggest change here is to actively not pass through the autogenerated XRD fields to the Kratix API. That is what created large test data changes.
This has been tested with the following files which were generated from following the official composition docs:
xrd
``` apiVersion: apiextensions.crossplane.io/v2 kind: CompositeResourceDefinition metadata: name: apps.example.crossplane.io spec: scope: Namespaced group: example.crossplane.io names: kind: App plural: apps versions: - name: v1 served: true referenceable: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: image: description: The app's OCI container image. type: string default: nginx required: - image status: type: object properties: replicas: description: The number of available app replicas. type: integer address: description: The app's IP address. type: string ```composition
``` apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: app-yaml spec: compositeTypeRef: apiVersion: example.crossplane.io/v1 kind: App mode: Pipeline pipeline: - step: create-deployment-and-service functionRef: name: crossplane-contrib-function-patch-and-transform input: apiVersion: pt.fn.crossplane.io/v1beta1 kind: Resources resources: - name: deployment base: apiVersion: apps/v1 kind: Deployment spec: replicas: 2 template: spec: containers: - name: app ports: - containerPort: 80 patches: - type: FromCompositeFieldPath fromFieldPath: metadata.name toFieldPath: metadata.labels[example.crossplane.io/app] - type: FromCompositeFieldPath fromFieldPath: metadata.name toFieldPath: spec.selector.matchLabels[example.crossplane.io/app] - type: FromCompositeFieldPath fromFieldPath: metadata.name toFieldPath: spec.template.metadata.labels[example.crossplane.io/app] - type: FromCompositeFieldPath fromFieldPath: spec.image toFieldPath: spec.template.spec.containers[0].image - type: ToCompositeFieldPath fromFieldPath: status.availableReplicas toFieldPath: status.replicas readinessChecks: - type: MatchCondition matchCondition: type: Available status: "True" - name: service base: apiVersion: v1 kind: Service spec: ports: - protocol: TCP port: 8080 targetPort: 80 patches: - type: FromCompositeFieldPath fromFieldPath: metadata.name toFieldPath: metadata.labels[example.crossplane.io/app] - type: FromCompositeFieldPath fromFieldPath: metadata.name toFieldPath: spec.selector[example.crossplane.io/app] - type: ToCompositeFieldPath fromFieldPath: spec.clusterIP toFieldPath: status.address readinessChecks: - type: NonEmpty fieldPath: spec.clusterIP ```function
``` apiVersion: pkg.crossplane.io/v1 kind: Function metadata: name: crossplane-contrib-function-patch-and-transform spec: package: xpkg.crossplane.io/crossplane-contrib/function-patch-and-transform:v0.8.2 ```example request
``` apiVersion: example.crossplane.io/v1 kind: App metadata: namespace: default name: my-app spec: image: nginx ```