Summary
ApplyAPIConverters (added in #538) correctly flattens single-element arrays for TypeList/TypeSet with MaxItems=1 fields in generated example manifests. However, it does not handle SchemaTypeObject fields (Terraform plugin framework's NestingModeSingle blocks), which also need flattening.
Background
The HCL-to-JSON scraper always wraps Terraform blocks in arrays per HCL spec. For NestingModeSingle blocks, upjet maps these to SchemaTypeObject (ValueType 9) and generates CRD types as embedded objects (pointer-to-struct), not slices. But the generated example manifests retain the array syntax from the scraper, producing invalid YAML that fails with "unknown field" errors when applied.
Why this doesn't affect AWS/GCP/Azure providers
Those providers use the older SDK v2 TypeList + MaxItems=1 pattern. The SingletonListEmbedder + ApplyAPIConverters pipeline handles that correctly because:
SingletonListEmbedder registers conversion paths with [*] wildcards for TypeList/TypeSet fields
conversion.Convert uses fieldpath.Pave to traverse these paths and flatten arrays
For SchemaTypeObject fields, SingletonListEmbedder correctly skips them (they're already objects in the CRD). But the traverser does NOT add [*] wildcards to SchemaTypeObject paths, so conversion.Convert fails with "not an object" when trying to traverse the arrays that remain in the scraped examples.
Who is affected
Any upjet-based provider whose Terraform provider uses the plugin framework NestingModeSingle pattern instead of the older TypeList + MaxItems=1 pattern. The grafana/crossplane-provider-grafana provider is the first to hit this (grafana/crossplane-provider-grafana#549).
Workaround
We added a post-processing step in our generator that uses upjet's schema traverser to collect CRD paths for SchemaTypeObject fields, then walks generated example YAML files and flattens single-element arrays at those paths (grafana/crossplane-provider-grafana#557).
Expected behavior
ApplyAPIConverters (or a related utility) should also handle SchemaTypeObject fields by flattening single-element arrays in generated examples to plain objects, matching the CRD's pointer-to-struct type.
Related
Summary
ApplyAPIConverters(added in #538) correctly flattens single-element arrays forTypeList/TypeSetwithMaxItems=1fields in generated example manifests. However, it does not handleSchemaTypeObjectfields (Terraform plugin framework'sNestingModeSingleblocks), which also need flattening.Background
The HCL-to-JSON scraper always wraps Terraform blocks in arrays per HCL spec. For
NestingModeSingleblocks, upjet maps these toSchemaTypeObject(ValueType 9) and generates CRD types as embedded objects (pointer-to-struct), not slices. But the generated example manifests retain the array syntax from the scraper, producing invalid YAML that fails with "unknown field" errors when applied.Why this doesn't affect AWS/GCP/Azure providers
Those providers use the older SDK v2
TypeList + MaxItems=1pattern. TheSingletonListEmbedder+ApplyAPIConverterspipeline handles that correctly because:SingletonListEmbedderregisters conversion paths with[*]wildcards forTypeList/TypeSetfieldsconversion.Convertusesfieldpath.Paveto traverse these paths and flatten arraysFor
SchemaTypeObjectfields,SingletonListEmbeddercorrectly skips them (they're already objects in the CRD). But the traverser does NOT add[*]wildcards toSchemaTypeObjectpaths, soconversion.Convertfails with "not an object" when trying to traverse the arrays that remain in the scraped examples.Who is affected
Any upjet-based provider whose Terraform provider uses the plugin framework
NestingModeSinglepattern instead of the olderTypeList + MaxItems=1pattern. Thegrafana/crossplane-provider-grafanaprovider is the first to hit this (grafana/crossplane-provider-grafana#549).Workaround
We added a post-processing step in our generator that uses upjet's schema traverser to collect CRD paths for
SchemaTypeObjectfields, then walks generated example YAML files and flattens single-element arrays at those paths (grafana/crossplane-provider-grafana#557).Expected behavior
ApplyAPIConverters(or a related utility) should also handleSchemaTypeObjectfields by flattening single-element arrays in generated examples to plain objects, matching the CRD's pointer-to-struct type.Related
ApplyAPIConvertersforTypeList/TypeSetwithMaxItems=1NestingModeSingleComputed flag