What happened?
When an XRD (or CRD) declares a scale subresource, crossplane xrd generate produces language schemas for the autoscaling/v1 Scale type instead of for the resource itself. The resource's own model is replaced entirely.
Crossplane v2.3 added the ability to configure the scale subresource on an XRD (crossplane/crossplane#7004). Adding it to an XRD like this:
versions:
- name: v1alpha1
subresources:
scale:
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas.total
causes the generated Python module for the resource (e.g. models/ai/modelplane/modeldeployment/v1alpha1.py) to contain only Scale, ScaleSpec, and ScaleStatus classes. The resource's own kind, spec, and status classes are gone, and the module's relative imports change shape, so anything importing the generated model fails:
ModuleNotFoundError: No module named 'models.ai.apimachinery'
Root cause
internal/crd/convert.go's ToOpenAPI builds the intermediate OpenAPI document with builder.BuildOpenAPIV3 (from k8s.io/apiextensions-apiserver). That builder emits the full Kubernetes REST surface for the resource: paths for list/get/create/scale, and a components.schemas map.
When the resource has a scale subresource, the builder adds io.k8s.api.autoscaling.v1.Scale, ScaleSpec, and ScaleStatus to components.schemas alongside the resource's own schema. The downstream language generator (datamodel-code-generator for Python) then models those Scale schemas into the resource's module, displacing the resource.
You can see it directly: feeding a CRD with a scale subresource through crd.FilesToOpenAPI yields a components.schemas map containing both ai.<group>.<version>.<Kind> and io.k8s.api.autoscaling.v1.Scale (plus ScaleSpec/ScaleStatus). Clearing the scale subresource before the conversion removes the autoscaling schemas and leaves the resource's schema intact.
How can we reproduce it?
- Add a scale subresource to any XRD version (the YAML above).
- Run
crossplane xrd generate (or crossplane dependency update-cache / crossplane project build, which generate schemas) with schemas.languages: [python].
- Inspect the generated module for that resource: it contains
Scale/ScaleSpec/ScaleStatus instead of the resource's own classes.
What environment did it happen in?
- Crossplane CLI version:
main (commit 3df82fc)
- Platform: linux/amd64
- Crossplane version (if applicable): v2.3.2
What happened?
When an XRD (or CRD) declares a
scalesubresource,crossplane xrd generateproduces language schemas for theautoscaling/v1Scaletype instead of for the resource itself. The resource's own model is replaced entirely.Crossplane v2.3 added the ability to configure the scale subresource on an XRD (crossplane/crossplane#7004). Adding it to an XRD like this:
causes the generated Python module for the resource (e.g.
models/ai/modelplane/modeldeployment/v1alpha1.py) to contain onlyScale,ScaleSpec, andScaleStatusclasses. The resource's own kind, spec, and status classes are gone, and the module's relative imports change shape, so anything importing the generated model fails:Root cause
internal/crd/convert.go'sToOpenAPIbuilds the intermediate OpenAPI document withbuilder.BuildOpenAPIV3(fromk8s.io/apiextensions-apiserver). That builder emits the full Kubernetes REST surface for the resource:pathsfor list/get/create/scale, and acomponents.schemasmap.When the resource has a scale subresource, the builder adds
io.k8s.api.autoscaling.v1.Scale,ScaleSpec, andScaleStatustocomponents.schemasalongside the resource's own schema. The downstream language generator (datamodel-code-generator for Python) then models thoseScaleschemas into the resource's module, displacing the resource.You can see it directly: feeding a CRD with a scale subresource through
crd.FilesToOpenAPIyields acomponents.schemasmap containing bothai.<group>.<version>.<Kind>andio.k8s.api.autoscaling.v1.Scale(plusScaleSpec/ScaleStatus). Clearing the scale subresource before the conversion removes the autoscaling schemas and leaves the resource's schema intact.How can we reproduce it?
crossplane xrd generate(orcrossplane dependency update-cache/crossplane project build, which generate schemas) withschemas.languages: [python].Scale/ScaleSpec/ScaleStatusinstead of the resource's own classes.What environment did it happen in?
main(commit3df82fc)