magodo / terraform-provider-restful

Terraform provider to manage RESTful resources
https://registry.terraform.io/providers/magodo/restful
Mozilla Public License 2.0
15 stars 5 forks source link

How to use poll_create.status_locator if resourceId is not part of the url and result is a list of resources? #121

Closed gr00vaLisTic closed 1 week ago

gr00vaLisTic commented 2 weeks ago

Hi,

I'm currently trying to use the poll_create mechanism of restful_resource in order to verify that resource creation was actually finished (body has a state property which is CREATING at first, and CREATED when actually done. Unfortunately, there is no endpoint allowing to get just one resource by id, only a generic "GetAll" endpoint.

Example:

POST /my/resource returns

{
  "id": "123",
  "name": "some name",
  "state": "CREATING"
}

GET /my/resource then might return something like

{
  "items": [
    {
      "id": "123",
      "name": "some name",
      "state": "CREATING"
    },
    {
      "id": "234",
      "name": "some other name",
      "state": "CREATED"
    },
    ...
  ]
}

As far as I understood, in this case I would need to setup the poll as follows:

poll_create = {
    status = {
      success = "CREATED"
      pending = ["CREATING"]
    }
    url_locator = "exact./my/resource"
    status_locator = "body.items.#(id==\"$(body.id)\").state"
  }

This unfortunately doesn't work and my guess by looking at the code is, that status_locator doesn't seem to resolve the $(body.id) value.

Am I using this wrong or is this just not possible at the moment?

Thank you, regards!

magodo commented 2 weeks ago

@gr00vaLisTic Thank you for reaching out! Currently, the capability to use the $() interpolation is only available to [read|update|delete]_path.

gr00vaLisTic commented 2 weeks ago

Thanks @magodo for your quick response. Is there any workaround to achieve something like this right now or any plans to add the $() interpolation to locators?

gr00vaLisTic commented 2 weeks ago

One more addition: I think the same issue is there when it comes to using [read|create]_path in conjunction with [read|create]_selector, which also doesn’t support $() interpolation. So, in case you are willing to add this in the future, it would be very nice to have it for both.

magodo commented 2 weeks ago

Yes, I'm looking into a solution.

About:

One more addition: I think the same issue is there when it comes to using [read|create]_path in conjunction with [read|create]_selector, which also doesn’t support $() interpolation. So, in case you are willing to add this in the future, it would be very nice to have it for both.

Could you elaborate about how do you use the $() for [read|update|delete]_path, and how it doesn't work for you?

magodo commented 2 weeks ago

@gr00vaLisTic As a workaround, if the name in your case is canonical, then you can use that as a filter.

gr00vaLisTic commented 2 weeks ago

Yes, I'm looking into a solution.

About:

One more addition: I think the same issue is there when it comes to using [read|create]_path in conjunction with [read|create]_selector, which also doesn’t support $() interpolation. So, in case you are willing to add this in the future, it would be very nice to have it for both.

Could you elaborate about how do you use the $() for [read|update|delete]_path, and how it doesn't work for you?

No, in the path it is working fine. But in cases like the one i mentioned, where the path is not where I can filter the collection result to my specific resource I'm interested in, then i would set e.g. the read_path to a static resource path like /my/resource and then would need to filter the result collection by using a selector, which would then again need to filter the entries to the one I need, e.g. by using something like body.items.#(id==\"$(body.id)\").

All those cases only apply when you have to deal with a collection result because there is no GET-Endpoint for a specific single resource and you can't use the path to select your needed resource by having an id param or at least some filtering by query params etc.

gr00vaLisTic commented 2 weeks ago

@gr00vaLisTic As a workaround, if the name in your case is canonical, then you can use that as a filter.

unfortunately, the name is not unique in our case. :(

gr00vaLisTic commented 2 weeks ago

One more occurance of this would be the status_locator when using the prechecks.api schema btw.

magodo commented 1 week ago

@gr00vaLisTic Could you try out the main branch? I'll cut a release if it works for you.