Mastercard / terraform-provider-restapi

A terraform provider to manage objects in a RESTful API
Other
808 stars 217 forks source link

Help with Object ID is not set, but *may* have been created #132

Closed jpmonge86 closed 3 years ago

jpmonge86 commented 3 years ago

Hi, I am getting started with this provider, I am trying to create (POST) a cloud resource using the below provider/resource syntax. I had success with a different resource, but this was an update operation as opposed to create, I suspect the ID is might be causing/related the problem, but I am not sure, and if it is I am not sure how to fix it.

Provider (I am using same for both)>

provider "restapi" {
  uri = "https:"
  write_returns_object = true
  debug = true
  headers = {
    Authorization = data.cloud_iam_auth_token.tokendata.iam_access_token
    Content-Type = "application/json"
  }
  create_method  = "PUT"
}

Create Secret Group

resource "restapi_object" "Secret_Group" {
  path = "//${data.cloud_resource_instance.secrets-manager-instance.guid}.${var.Region}.secrets-manager.appdomain.cloud/api/v1/secret_groups"
  data = "{\"metadata\": {\"collection_type\": \"application/vnd.cloud.secrets-manager.secret.group+json\",\"collection_total\": 1},\"resources\": [{\"name\": \"${var.Secret_Group_Name}\",\"description\": \"Extended description for this group.\"}]}"

}

The error I am getting is the following:

Error: Unexpected response code '400': {"metadata":{"collection_type":"application/vnd.cloud.secrets-manager.error+json","collection_total":1},"resources":[{"error_message":"Request validation error: Invalid parameter 'id' in path"}]}

  on main.tf line 22, in resource "restapi_object" "Secret_Group":
  22: resource "restapi_object" "Secret_Group" {

The original API syntax for creating this resource is this:

curl -X POST "{base_url}/api/v1/secret_groups" -H "Authorization: Bearer {IAM_token}" -H "Accept: application/json" -H "Content-Type: application/json" -d '{ 
    "metadata": { 
      "collection_type": "application/vnd.cloud.secrets-manager.secret.group+json", 
      "collection_total": 1 
    }, 
    "resources": [ 
      { 
        "name": "example-secret-group", 
        "description": "Extended description for my secret group."
      } 
    ] 
  }'

Any help or pointers would be very helpful.

DRuggeri commented 3 years ago

Hi there, @jpmonge86 - everything looks right in your base configuration, I think. To see the 400 means the provider is reaching out to the API successfully, so that's a good thing. I would suggest enabling debig logs as noted in README so you can compare what goes "across the wire" to your curl command. I assume there's something in the payload that the API doesn't like.

jpmonge86 commented 3 years ago

@DRuggeri I realize I was using the wrong method, I had PUT as opposed to POST, I changed this and the object gets created, but I get this error: Internal validation failed. Object ID is not set, but *may* have been created. This should never happen!

This is the full Debug file

Whenever I use CURL or postman, I do see id being returned in response

curl --location --request POST 'https://fda8cfe2-d730-4989-ace3-dc5b78b0ae9e.us-south.secrets-manager.appdomain.cloud/api/v1/secret_groups' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer eLB9LEI4W-N2t22b4s66u7Xj4-KifgM_3YK-ZByVz6XYvtGPsvF8Yn3Rq_48OTPcdJd7W_WPW7WL_gEa1uoAdGRGmidM-4PZbqZiI9O0nh9fskiOq79HcCMKf07-HCV3a7X_s11NqVM9CgHR4myQvQKJ46myu8boCSmCyOQ1ra3hKFPYlmVCKvSelGNtX3mtRjUyEOISbHA' \
--header 'Content-Type: application/json' \
--header 'Cookie: __cfduid=d9052268271ddd8bc537dade4193c154f1618503497' \
--data-raw '{
  "metadata": {
    "collection_type": "application/vnd.ibm.secrets-manager.secret.group+json",
    "collection_total": 1
  },
  "resources": [
    {
      "name": "my-secret-group",
      "description": "Extended description for this group."
    }
  ]
}'

Response

{
    "metadata": {
        "collection_type": "application/vnd.ibm.secrets-manager.secret.group+json",
        "collection_total": 1
    },
    "resources": [
        {
            "creation_date": "2021-04-25T18:59:34Z",
            "description": "Extended description for this group.",
            "id": "8609704d-c5fd-e0fe-56ec-31570a11adfb",
            "last_update_date": "2021-04-25T18:59:34Z",
            "name": "my-secret-group",
            "type": "application/vnd.ibm.secrets-manager.secret.group+json"
        }
    ]
}

It looks like I have specify somehow that id is not on top level but in the resources array, if so, how would I do that? I tried setting id_attribute like this, but no luck.

id_attribute = "resources/id"
id_attribute = "resources[0]/id"
id_attribute = "resources[]/id"

This is the updated provider syntax:

provider "restapi" {
  uri = "https:"
  write_returns_object = true
  debug = true
  headers = {
    Authorization = data.ibm_iam_auth_token.tokendata.iam_access_token
    Content-Type = "application/json"
  }

}
stefanvangastel commented 3 years ago

Having the same issue

DRuggeri commented 3 years ago

Thanks for the explanation, @jpmonge86 - that helps a lot! Yes, I think you've honed in on the root of the problem. The ID key is living inside of an array so requires the right syntax to dig into the array. Your syntax is super close - you just need to set resources/0/id as the id_attribute. I know that's not the most intuitive given how jq syntax is so popular, but it ended up being the easiest code implementation.

Let me know if that helps!

jpmonge86 commented 3 years ago

thanks @DRuggeri !