crossplane / terrajet

Generate Crossplane Providers from any Terraform Provider
https://crossplane.io
Apache License 2.0
289 stars 38 forks source link

Could not generate a unique name for SubnetworkParameters #135

Closed turkenh closed 2 years ago

turkenh commented 2 years ago

What happened?

While trying to generate google_compute_subnetwork together with google_compute_router_nat resource, Terrajet fails to find a unique name for SubnetworkParameters:

panic: cannot generate crd for resource google_compute_subnetwork: cannot build types for Subnetwork: cannot build the types: cannot generate parameters type name of Subnetwork: could not generate a unique name for SubnetworkParameters

goroutine 1 [running]:
github.com/crossplane-contrib/terrajet/pkg/pipeline.Run(0xc000636300)
    /Users/hasanturken/Workspace/crossplane-contrib/provider-tf-gcp/.work/pkg/pkg/mod/github.com/crossplane-contrib/terrajet@v0.1.1-0.20211104212137-874bb6ad5cff/pkg/pipeline/run.go:82 +0x2053
main.main()
    /Users/hasanturken/Workspace/crossplane-contrib/provider-tf-gcp/cmd/generator/main.go:10 +0x2a
exit status 2
make[1]: *** [terrajet.run] Error 1
make: *** [generate] Error 2

This is because google_compute_router_nat resource already have a type named SubnetworkParameters generated and google_compute_subnetwork resource coming after it alphabetically (since we are sorting for stability) fails to generate a type for top level parameter struct.

I believe we will need a way to configure type names to handle such cases.

How can we reproduce it?

Try generating both resources together in provider-tf-gcp.

turkenh commented 2 years ago

@muvaf, as we discussed offline on possible solutions here, I gave it a try simply appending indexes as long as we could find a unique type name. It worked well at first but then I realized that we are appending Parameter to the top-level resource spec no matter what we generate as type.

Not being happy to modify the logic there to print the generated type, I gave it a try to another approach, which is always generating the longest possible name instead of starting with shorted and extending as long as it already in use.

@@ -285,9 +290,6 @@ func (g *Builder) buildSchema(sch *schema.Schema, cfg *config.Resource, tfPath [
 func (g *Builder) generateTypeName(suffix string, names ...string) (string, error) {
        n := names[len(names)-1] + suffix
        for i := len(names) - 2; i >= 0; i-- {
-               if g.Package.Scope().Lookup(n) == nil {
-                       return n, nil
-               }
                n = names[i] + n
        }
        if g.Package.Scope().Lookup(n) == nil {

This sounded like a solution at least for the resource here, however, I found out that this wouldn't work for another resource in provider-tf-gcp, which fails due to a contention between google_bigquery_dataset and google_bigquery_dataset_access:

panic: cannot generate crd for resource google_bigquery_dataset_access: cannot build types for DatasetAccess: cannot build the types: cannot generate parameters type name of DatasetAccess: could not generate a unique name for DatasetAccessParameters

Hence, falling back to the initial plan and will modify the logic in the CRD template accordingly.