Skip to content

Commit

Permalink
fix: handle singular resource payloads with a transform
Browse files Browse the repository at this point in the history
If the API responds with a singular result (`result = {}`) but it is a list endpoint, we need to wrap it as an array to continue with the generation steps.

Signed-off-by: Jacob Bednarz <[email protected]>
  • Loading branch information
jacobbednarz committed Jan 28, 2025
1 parent c0877b2 commit ca58303
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
20 changes: 15 additions & 5 deletions internal/app/cf-terraforming/cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ func runImport() func(cmd *cobra.Command, args []string) {

continue
}
err = json.Unmarshal([]byte(value.String()), &jsonStructData)

modifiedJSON := modifyResponsePayload(resourceType, value)
err = json.Unmarshal([]byte(modifiedJSON), &jsonStructData)
if err != nil {
log.Fatalf("failed to unmarshal result: %s", err)
}
Expand Down Expand Up @@ -753,10 +755,18 @@ func buildRawImportAddress(resourceType, resourceID, endpoint string) string {
r, _ := regexp.Compile("({[a-z0-9_]*})")
matches := r.FindAllString(endpoint, -1)

if len(matches) == 1 {
matches[0] = resourceID
} else {
matches[1] = resourceID
if len(matches) > 0 {
// Naive assumptions below but if we only have a single placeholder (`{}`)
// we can replace that with the `resourceID` however, if we have more than
// a single one, we assume it is the second match since that is our URL
// conventions.
//
// Note: this will likely break on un-RESTful routes.
if len(matches) == 1 {
matches[0] = resourceID
} else {
matches[1] = resourceID
}
}

output := strings.Join(matches, "/")
Expand Down
16 changes: 15 additions & 1 deletion internal/app/cf-terraforming/cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,23 @@ func boolToEnabledOrDisabled(value bool) string {
return "disabled"
}

// transformToCollection takes a JSON payload that is a singlular resource but
// operates as a `list` endpoint and transforms it into a JSON to correctly
// handle the output.
func transformToCollection(value string) string {
return fmt.Sprintf("[%s]", value)
}

// modifyResponsePayload takes the current resource and the `gjson.Result`
// to run arbitary modifications to the JSON before passing it to be overlayed
// the provider schema.
func modifyResponsePayload(resourceName string, value gjson.Result) string {
return value.String()
output := value.String()

switch resourceName {
case "cloudflare_zero_trust_organization":
output = transformToCollection(output)
}

return output
}

0 comments on commit ca58303

Please sign in to comment.