terraform-coop / terraform-provider-foreman

Terraform provider for Foreman
https://registry.terraform.io/providers/terraform-coop/foreman
Mozilla Public License 2.0
33 stars 31 forks source link

Host parameters of type JSON lead to errors on import #136

Open rsommer opened 8 months ago

rsommer commented 8 months ago

Having an existing host in foreman with a host parameter of type JSON, a terraform import of said host results in

Error: json: cannot unmarshal object into Go struct field ForemanKVParameter.parameters.value of type string

This may relate to #129

bitkeks commented 8 months ago

Hi @rsommer,

could you provide an example of your Terraform code? Issue #129 is related to host groups, and your issue seems to be related to importing existing hosts as foreman_hosts. Since the error message is the same, I'd guess it's the same source of error as #129, but we should make sure the path to the error is the same.

What provider version are you using? Are earlier versions working with the same code? (you can downgrade to all published versions in the TF registry).

rsommer commented 8 months ago

Hi @bitkeks,

I am using terraform-coop/foreman v0.6.2, I have a nearly empty host definition like

resource "foreman_host" "testnode01" {
   set_build_flag = false 
}

and using terraform import testnode01 <FOREMAN_ID> leads to the said error as soon as a host parameter of type JSON is defined - just retried with another node with a dummy JSON parameter containing {"dummy":false} as JSON parameter value. Result:

Error: json: cannot unmarshal object into Go struct field ForemanKVParameter.parameters.value of type string

Simply removing the parameter resolves the problem which is fine in the test case, but not when the parameter is actually used.

I tried the provider versions 0.5.1, 0.5.8, 0.6.0 and 0.6.2 - all with the same result.

bitkeks commented 6 months ago

The issue is in the host JSON unmarshal function. It does not handle the JSON/map structure behind the value key at the moment:

"parameters": [
  {
    "name": "json_testparam",
    "parameter_type": "json",
    "associated_type": "host",
    "hidden_value?": false,
    "value": {
      "testkey": 123
    }
  },
  {
    "name": "testhoststring",
    "parameter_type": "string",
    "associated_type": "host",
    "hidden_value?": false,
    "value": "yes"
  }
]

The first entry is the JSON type, and value is in fact another JSON object. The second is the string parameter_type, therefore the code below works.

type ForemanKVParameter struct {
    Name  string `json:"name"`
    Value string `json:"value"`
}

We'd need to have to refactor/create the foremanHostDecode UnmarshalJSON function to handle parameters of different types.