Skip to content

crossplane xrd generate models the autoscaling Scale type instead of the resource when a scale subresource is declared #117

@negz

Description

@negz

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?

  1. Add a scale subresource to any XRD version (the YAML above).
  2. Run crossplane xrd generate (or crossplane dependency update-cache / crossplane project build, which generate schemas) with schemas.languages: [python].
  3. 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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions