github.com/opentofu/opentofu@v1.7.1/internal/command/views/json/output.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package json 7 8 import ( 9 "encoding/json" 10 "fmt" 11 12 ctyjson "github.com/zclconf/go-cty/cty/json" 13 14 "github.com/opentofu/opentofu/internal/plans" 15 "github.com/opentofu/opentofu/internal/states" 16 "github.com/opentofu/opentofu/internal/tfdiags" 17 ) 18 19 type Output struct { 20 Sensitive bool `json:"sensitive"` 21 Type json.RawMessage `json:"type,omitempty"` 22 Value json.RawMessage `json:"value,omitempty"` 23 Action ChangeAction `json:"action,omitempty"` 24 } 25 26 type Outputs map[string]Output 27 28 func OutputsFromMap(outputValues map[string]*states.OutputValue) (Outputs, tfdiags.Diagnostics) { 29 var diags tfdiags.Diagnostics 30 31 outputs := make(map[string]Output, len(outputValues)) 32 33 for name, ov := range outputValues { 34 unmarked, _ := ov.Value.UnmarkDeep() 35 value, err := ctyjson.Marshal(unmarked, unmarked.Type()) 36 if err != nil { 37 diags = diags.Append(tfdiags.Sourceless( 38 tfdiags.Error, 39 fmt.Sprintf("Error serializing output %q", name), 40 fmt.Sprintf("Error: %s", err), 41 )) 42 return nil, diags 43 } 44 valueType, err := ctyjson.MarshalType(unmarked.Type()) 45 if err != nil { 46 diags = diags.Append(err) 47 return nil, diags 48 } 49 50 var redactedValue json.RawMessage 51 if !ov.Sensitive { 52 redactedValue = json.RawMessage(value) 53 } 54 55 outputs[name] = Output{ 56 Sensitive: ov.Sensitive, 57 Type: json.RawMessage(valueType), 58 Value: redactedValue, 59 } 60 } 61 62 return outputs, nil 63 } 64 65 func OutputsFromChanges(changes []*plans.OutputChangeSrc) Outputs { 66 outputs := make(map[string]Output, len(changes)) 67 68 for _, change := range changes { 69 outputs[change.Addr.OutputValue.Name] = Output{ 70 Sensitive: change.Sensitive, 71 Action: changeAction(change.Action), 72 } 73 } 74 75 return outputs 76 } 77 78 func (o Outputs) String() string { 79 return fmt.Sprintf("Outputs: %d", len(o)) 80 }