Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating a resource with id in the payload #230

Open
seblatre opened this issue Aug 11, 2023 · 8 comments
Open

Updating a resource with id in the payload #230

seblatre opened this issue Aug 11, 2023 · 8 comments

Comments

@seblatre
Copy link

Hello !
I'm trying to make use of the Dremio Role API with this great restapi provider.

I managed perfectly the Create and Delete lifecycle but I cannot make the Update part work.
The specificity of this API is that id is required both in the URL and in the JSON payload.
I tried several ways and read many things but couldn't make it.

Do you have any idea/hint to tackle this?
Thanks in advance !

Provider configuration:

provider "restapi" {
  uri                  = "https://dremio.xxx.com/api/v3"
  debug                = true
  write_returns_object = true
  create_method        = "POST"
  update_method        = "PUT"

  headers = {
    "Content-Type"  = "application/json"
    "Authorization" = "Bearer ..."
  }
}

Created like this:

resource "restapi_object" "poc" {
  path         = "/role"
  id_attribute = "id"
  data         = <<-EOT
  {
    "name": "test"
  }
  EOT
}

Would like to update it by changing the name to "test_2" but gives error from API as update body is missing the "id":

│ Error: unexpected response code '400': {"errorMessage":"Id in the url path is not the same as the id in the request.","context":[],"moreInfo":""}
│
│   with module.dremio.restapi_object.poc,
│   on modules\dremio\main.tf line 333, in resource "restapi_object" "poc":
│  333: resource "restapi_object" "poc" {

@amvapor
Copy link

amvapor commented Sep 27, 2023

I'm running into a similar situation, with the API I am interacting with, I can POST /people to create a user object, and I can refresh the data with GET /people/{id} But the interface does updates with a POST /people the same as create, but when an ID is included in the data payload, it's considered an update.
I'd love to be able to do something like the following with {id} being rewritten to the actual ID value on the update call.

resource "restapi_object" "users" {
  path = "/people"
  
  data = jsonencode({
    firstName          = "John"
    lastName           = "Doe"
  })
  update_data = jsonencode({
    id                        = "{id}"
    firstName          = "John"
    lastName           = "Doe"
  })
}

@ivank
Copy link

ivank commented Feb 10, 2024

Actually just discovered that copy_keys provides functionality for exactly this purpose!

so the fix would be:

provider "restapi" {
  uri                  = "https://dremio.xxx.com/api/v3"
  debug                = true
  write_returns_object = true
  create_method        = "POST"
  update_method        = "PUT"
  copy_keys            = ["id"]

  headers = {
    "Content-Type"  = "application/json"
    "Authorization" = "Bearer ..."
  }
}

@iam-take
Copy link

@ivank I am having the same request but I am really struggling with this option do you perhaps have piece of example code to see how this would work?

@seblatre
Copy link
Author

seblatre commented May 2, 2024

Thanks @ivank, your post saved my life with this use case. Works perfectly for another use case as well with AzureDevops release/definitions's REST API.
I personnaly used the following configuration in the restapi provider

copy_keys = ["id", "revision"]

@mdepedrof
Copy link

mdepedrof commented Oct 15, 2024

I have in the same situation. Could you explain how we can reference the {id} on data for read or destroy not in path?

resource "restapi_object" "ipsec_phase1" {
  for_each     = module.yaml_json_decoder.files
  
  path = "/api/v2/vpn/ipsec/phase1"
  id_attribute = "data/id"

  data = jsonencode({
    descr                 = "vpn-${each.value}"
    disabled              = true
    iketype               = "ikev2"
    mode                  = "main"
    protocol              = "inet"
  })

  read_method = "GET"
  read_data  = jsonencode({
    id = "{id}"
  })

  destroy_method = "DELETE"
  destroy_data  = jsonencode({
    id = "{id}"
    apply = true
  })

}

this is the payload of the api when I call to create method without using postman:

{
    "code": 200,
    "status": "ok",
    "response_id": "SUCCESS",
    "message": "",
    "data": {
        "id": 0,
        "ikeid": 1,
        "descr": "test-*****",
        "disabled": true,
        "iketype": "****",
        "mode": null,
        "protocol": "****",
        "interface": "****",
        "remote_gateway": "*****",
        "authentication_method": "****",
        "myid_type": "****",
        "myid_data": "****",
        "peerid_type": "***",
        "peerid_data": ****,
        "certref": **,
        "caref": **,
        "rekey_time": *,
        "reauth_time": *,
        "rand_time": ****,
        "lifetime": ***,
        "startaction": "**",
        "closeaction": "****",
        "nat_traversal": "****",
        "gw_duplicates": ***,
        "mobike": ***,
        "splitconn": ****,
        "prfselect_enable": ****,
        "ikeport": "****",
        "nattport": "****",
        "dpd_delay": **,
        "dpd_maxfail": **,
        "encryption": [
            {
                "parent_id": 0,
                "id": 0,
                "encryption_algorithm_name": "****",
                "encryption_algorithm_keylen": ****,
                "hash_algorithm": "****",
                "dhgroup": ****,
                "prf_algorithm": "****"
            }
        ]
    }
}

to read one object or destroy I need to pass the id inside of payload:

{
  "id": 0, #<----- this is the id that you can find in the create API response on data/id
  "apply": true
}

@mdepedrof
Copy link

Reading the doc maybe the problem is we use PATCH and DESTROY as methods and the doc said only works with PUT?

image

@mdepedrof
Copy link

Any idea about this? Thanks!

@mdepedrof
Copy link

@ivank could you please explain with some example how to use copy_keys to use the id in the payload?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants