github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/views/json/output.go (about)

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