salrashid123 / terraform-provider-http-full

Terraform HTTP provider with mTLS and JSON POST support
Apache License 2.0
13 stars 4 forks source link

400 Errors #2

Closed dutsmiller closed 3 years ago

dutsmiller commented 3 years ago

Is there a way to get the result of the http request? I'm currently trying to use the Azure REST API and I have working curl commands that always result in a 400 error when using http-full. I've tried to get something other than 400, but even purposefully use a bad url resulting in a 401 error from curl, I'm still getting a 400 error from http-full. I've tried setting TF_LOG=TRACE but I'm still not seeing any helpful messages. Any advice would be appreciated.

dutsmiller commented 3 years ago

As an example:

curl -i -X POST -d 'foo=bar' "https://login.microsoftonline.com/1/oauth2/token"

will result in a 400 error and output

{"error":"invalid_request","error_description":"AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: 9d91294a-1ca1-474e-b718-cf3ecb36ca01\r\nCorrelation ID: 09aaec69-cd78-4000-8783-8c8a5c175ec9\r\nTimestamp: 2021-09-15 19:50:04Z","error_codes":[900144],"timestamp":"2021-09-15 19:50:04Z","trace_id":"9d91294a-1ca1-474e-b718-cf3ecb36ca01","correlation_id":"09aaec69-cd78-4000-8783-8c8a5c175ec9","error_uri":"https://login.microsoftonline.com/error?code=900144"}%

However, this:

data "http" "token" { provider = http-full url = "https://login.microsoftonline.com/1/oauth2/token" request_body = { foo = "bar" } }

spits out a 400

Error: HTTP request error. Response code: 400 with data.http.token, on main.tf line 10, in data "http" "token": 10: data "http" "token"

With no further details.

salrashid123 commented 3 years ago

the curl command is using Content-Type: application/x-www-form-urlencoded which is supported in 1.1.0 https://registry.terraform.io/providers/salrashid123/http-full/latest/docs/data-sources/http#post-form

terraform {
  required_providers {
    http-full = {
      source = "salrashid123/http-full"
      version = "1.1.0"
    }
  }
}

provider "http-full" {
}

data "http" "example" {
  provider = http-full
  url = "https://login.microsoftonline.com/1/oauth2/token"
  request_headers = {
    content-type = "application/x-www-form-urlencoded"
  }
  request_body = {
    body = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&client_id=bar&client_secret=asdfasdf&assertion=adfsfa&scope=email&requested_token_use=on_behalf_of"
  }
}

output "data" {
  value = jsondecode(data.http.example.body)
}

the data.http.example.body is notpopulated if the response is an error

see: https://github.com/salrashid123/terraform-provider-http-full/blob/main/internal/provider/data_source.go#L177

i suppose i could return status and body always but the calling terraform module would have to handle non 200 responses..i'm not sure if thats what terraform datasources are supposed to do though (i.,e not fail fast). if it is ok terraform-wise, the logic cited above could accomodate a return values received as-is

dutsmiller commented 3 years ago

Ok, that was a big help. I was able to clone the repo, compile the provider then use a dev_override to use my local http-full binary. By commenting out that != 200 conditional it now return the error in full. It was indeed an encoding issue.

salrashid123 commented 3 years ago

https://github.com/salrashid123/terraform-provider-http-full/commit/b316f9230e4bd7ee2e117bf4d6291300ec22e24e

adds the response body back if there's an error.

its included in 1.1.1 provider

terraform {
  required_providers {
    http-full = {
      source = "salrashid123/http-full"
      version = "1.1.1"
    }
  }
}