diff --git a/brokerpaktestframework/terraform_mock.go b/brokerpaktestframework/terraform_mock.go index 67b386cc1..b939de85c 100644 --- a/brokerpaktestframework/terraform_mock.go +++ b/brokerpaktestframework/terraform_mock.go @@ -134,15 +134,16 @@ type TFStateValue struct { // SetTFState set the Terraform State in a JSON file. func (p TerraformMock) SetTFState(values []TFStateValue) error { var outputs = make(map[string]struct { - Type string `json:"type"` - Value any `json:"value"` + Type json.RawMessage `json:"type"` + Value any `json:"value"` }) + for _, value := range values { outputs[value.Name] = struct { - Type string `json:"type"` - Value any `json:"value"` + Type json.RawMessage `json:"type"` + Value any `json:"value"` }{ - Type: value.Type, + Type: normalizeOutputType(value.Type), Value: value.Value, } } @@ -150,7 +151,24 @@ func (p TerraformMock) SetTFState(values []TFStateValue) error { return p.setTFStateFile(workspace.Tfstate{ Version: 4, TerraformVersion: p.Version, - Outputs: outputs}) + Outputs: outputs, + }) +} + +func normalizeOutputType(t string) json.RawMessage { + s := strings.TrimSpace(t) + if s == "" { + return json.RawMessage(`"string"`) + } + + if (strings.HasPrefix(s, "[") && strings.HasSuffix(s, "]")) || + (strings.HasPrefix(s, "{") && strings.HasSuffix(s, "}")) || + (strings.HasPrefix(s, "\"") && strings.HasSuffix(s, "\"")) { + return json.RawMessage(s) + } + + b, _ := json.Marshal(s) + return json.RawMessage(b) } // ReturnTFState set the Terraform State in a JSON file. diff --git a/pkg/providers/tf/workspace/tfstate.go b/pkg/providers/tf/workspace/tfstate.go index 1e2afe307..0fd8b89c1 100644 --- a/pkg/providers/tf/workspace/tfstate.go +++ b/pkg/providers/tf/workspace/tfstate.go @@ -42,8 +42,8 @@ type Tfstate struct { Version int `json:"version"` TerraformVersion string `json:"terraform_version"` Outputs map[string]struct { - Type string `json:"type"` - Value any `json:"value"` + Type json.RawMessage `json:"type"` + Value any `json:"value"` } `json:"outputs"` } diff --git a/pkg/providers/tf/workspace/tfstate_test.go b/pkg/providers/tf/workspace/tfstate_test.go index 2ca2f5ae4..4bc12ec88 100644 --- a/pkg/providers/tf/workspace/tfstate_test.go +++ b/pkg/providers/tf/workspace/tfstate_test.go @@ -14,7 +14,10 @@ package workspace -import "fmt" +import ( + "fmt" + "testing" +) func ExampleNewTfstate_good() { state := `{ @@ -110,3 +113,26 @@ func ExampleTfstate_GetOutputs() { // Output: map[hostname:somehost] } + +func TestNewTfstate_AllowsArrayOutputType(t *testing.T) { + state := []byte(`{ + "version": 4, + "terraform_version": "1.8.2", + "outputs": { + "list_output": { + "value": ["a", "b", "c"], + "type": ["list", "string"] + } + } + }`) + + tfstate, err := NewTfstate(state) + if err != nil { + t.Fatalf("unexpected error when output.type is an array: %v", err) + } + + outputs := tfstate.GetOutputs() + if outputs["list_output"] == nil { + t.Fatal("expected list_output to be present in outputs") + } +}