jdamata / terraform-provider-sonarqube

Terraform provider for managing Sonarqube configuration
GNU General Public License v3.0
62 stars 50 forks source link

API returned an error: Either 'value', 'values' or 'fieldValues' must be provided #245

Closed srtab closed 4 months ago

srtab commented 4 months ago

Terraform Version

Terraform v1.7.4 jdamata/sonarqube v0.16.10

Affected Resource(s)

Please list the resources as a list, for example:

Terraform Configuration Files

resource "sonarqube_setting" "this" {
  key   = "sonar.lf.logoUrl"
  value = ""
}

Expected Behavior

What I was expecting was to define sonar.lf.logoUrl as an empty value.

Actual Behavior

This is the plan output (where value is not being outputted):

  + resource "sonarqube_setting" "this" {
      + id  = (known after apply)
      + key = "sonar.lf.logoUrl"
    }

Which causes:

│ Error: API returned an error: Either 'value', 'values' or 'fieldValues' must be provided
│ 
│   with sonarqube_setting.this,
│   on main.tf line 49, in resource "sonarqube_setting" "this":
│   49: resource "sonarqube_setting" "this" {
│ 

If I define a null or "" on value, it seems that value is not being considered and then not sent when making the request to the API.

Steps to Reproduce

  1. terraform apply
freeranger commented 4 months ago

Hi Just wondering what is the use-case for creating an empty setting vs simply not creating a setting at all? I’m not sure if we can differentiate between an empty value explicitly supplied and not supplying a value at all.

Have you checked if this can be done via the SonarQube API directly? If the API doesn’t support it then there may be nothing we can do.

If the API does support it then looking at the code here: https://github.com/jdamata/terraform-provider-sonarqube/blob/694763e0d4410e460e9e01cc4eea616df27d1e20/sonarqube/resource_sonarqube_setting.go#L196 It seems like we just end up with one of value/values/fieldValues added depending on them having a value or not (in that order) - or none of them are added if none of them have a value. It might be a case of refactoring that logic to for example add values first if it exists, then if not try fieldValues and then maybe add value regardless of if it is empty or not if neither of the other two had values - though what if the setting should take values and you want to set that to an empty array?

srtab commented 4 months ago

HI @freeranger, A simple use case is the following: at some point, I define a custom logo and, for some reason, I don't want any logo defined, how can I do it if I can't pass an empty value? I have no experience in GO or in developing providers for terraform, so I can't help much. But by my experience using other Terraform providers, I think such distinction can be done.

freeranger commented 4 months ago

Have you tried simply adding the logo setting resource in your terraform and then deleting that resource afterwards to see what happens? Also you don’t need any GO experience to check if the SonarQube API supports this directly - just curl or a tool like Postman..

srtab commented 4 months ago

I confess that I didn't try and make sense yes! I will try to see what happen. About GO experience, I was talking about "differentiate between an empty value explicitly supplied and not supplying a value at all" and not the API. I end up with this problem because I was tying to use for_each to iterate over a mapping with settings defined. But maybe I'm doing it in a wrong way and I will define each setting on its own resource.

srtab commented 4 months ago

I've changed to declare each setting on its own resource, and it solves my use case. Thanks for the help @freeranger.

freeranger commented 4 months ago

Hi @srtab It's great that you are working again but you should not need to declare the resources individually, though you do need to be aware of issues with for_each - see https://jeffbrown.tech/terraform-for-each-index/ Whether you declare a resource individually or declare it using some construct you loop around, the way to remove it should be to stop creating it (remove the resource declaration or remove it from your construct) rather than creating it with a null/empty value.

It may be that the logic in the provider should change anyway and essentially default to providing the value parameter but it is an exercise for another day to a) check if the SonarQube API will accept a null/empty value at all and b) update the provider if appropriate.

For now, since your problem is solved, I will close the issue - but feel free to open it again if required

srtab commented 4 months ago

@freeranger Makes sense yes! Using loop with count would be a solution to achieve the behavior I was trying to implement.

I called the API with an empty value and returned the following: {"errors":[{"msg":"A non empty value must be provided"}]}%. So, it's not possible to define an empty value.