hashicorp / terraform-plugin-codegen-openapi

OpenAPI to Terraform Provider Code Generation Specification
Mozilla Public License 2.0
53 stars 12 forks source link

Circular reference in OpenAPI spec causes a stack overflow #132

Open umeshkumhar opened 8 months ago

umeshkumhar commented 8 months ago

tfplugingen-openapi CLI version

tfplugingen-openapi module: v0.3.0

OpenAPI Spec File

https://gist.github.com/umeshkumhar/97c7888fbcf6f294bb54210e0faec918

Generator Config

provider:
  name: backupdr

resources:
  slp:
    create:
      path:  /slp
      method: POST
    read:
      path:  /slp
      method: GET

Expected Behavior

It should have generated provider spec json.

Actual Behavior

This just executed and later on get killed due to OOM (i guess). in some iteration it shows stack overflow error. The activity monitor states that it consumes 70+GB memory, please find the attached screenshot below. Seems like its failing during Marshalling the openapi file.

Screenshot 2024-01-29 at 10 16 38 Screenshot 2024-01-29 at 10 19 40

Additional Information

Please suggest some workaround this.. if we can still generate some provider spec json for at least /slt, /sla, /slp. to kickstart.

Code of Conduct

austinvalle commented 8 months ago

Hey there @umeshkumhar 👋🏻, thanks for the detailed bug report and sorry you're running into trouble here.

I took a quick look at your OpenAPI spec and I believe the root issue is coming from some circular references in the spec. Currently our tooling doesn't throw an error if a circular reference exists, however, the current logic for building a schema assumes there are no circular references (which should be adjusted).

There are a couple things we'll need to consider for the tfplugingen-openapi tool here:

Locally I adjusted the logic to print out all the circular references found in the OpenAPI spec you provided:

time=2024-01-29T15:21:14.346-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SourceRest -> SlpRest -> DiskPoolRest -> DiskPoolCopiesRest -> CloudCredentialRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SourceRest -> SlpRest -> DiskPoolRest -> DiskPoolCopiesRest -> CloudCredentialRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SourceRest -> SlpRest -> DiskPoolRest -> DiskPoolCopiesRest -> CloudCredentialRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SourceRest -> HostRest -> SourceRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SourceRest -> HostRest -> HostRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SltRest -> AdvancedOptionRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SltRest -> AdvancedOptionRest -> SltRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SltRest -> AdvancedOptionRest -> SlaRest -> AdvancedOptionRest -> LogicalGroupRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SltRest -> AdvancedOptionRest -> SlaRest -> AdvancedOptionRest -> LogicalGroupRest -> ExportVolumeInfoRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SltRest -> AdvancedOptionRest -> SlaRest -> AdvancedOptionRest -> LogicalGroupRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="BackupNowRest -> PolicyRest -> SltRest -> AdvancedOptionRest -> SlaRest -> AdvancedOptionRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="MountRest -> SystemStateOptionRest -> SystemStateOptionRest"
time=2024-01-29T15:21:14.347-05:00 level=WARN msg="circular reference found in OpenAPI spec" circular_ref="SessionRest -> UserRest -> RightRest -> RightRest"

I will spend some time investigating what we can do here 👍🏻

austinvalle commented 8 months ago

Also worth noting here that Terraform resource/data source schemas don't support a notion of a recursive schema, so the final solution may end up behind some form of skip/controlled depth configuration.

At the very least, an explicit error should be returned in a case where we can't create a schema due to a circular reference.

hegerdes commented 6 months ago

Was also facing this issue when i tested out this tool using the keycloak openapi. Most likely also caused by a recursive schema.

It chews up memory binging the whole system down if not killed. A informative error message would be very helpful as long as recursive schemas are not supported. It might also be sensible to add some safety nets for unsupported/unexpected configs. Like setting a max execution time or detect if things go wrong and just crash.