github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/jsonformat/renderer.go (about)

     1  package jsonformat
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/mitchellh/colorstring"
     7  
     8  	"github.com/hashicorp/terraform/internal/command/format"
     9  	"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
    10  	"github.com/hashicorp/terraform/internal/command/jsonformat/differ"
    11  	"github.com/hashicorp/terraform/internal/command/jsonplan"
    12  	"github.com/hashicorp/terraform/internal/command/jsonprovider"
    13  	"github.com/hashicorp/terraform/internal/command/jsonstate"
    14  	viewsjson "github.com/hashicorp/terraform/internal/command/views/json"
    15  	"github.com/hashicorp/terraform/internal/plans"
    16  	"github.com/hashicorp/terraform/internal/terminal"
    17  	ctyjson "github.com/zclconf/go-cty/cty/json"
    18  )
    19  
    20  type JSONLogType string
    21  
    22  type JSONLog struct {
    23  	Message    string                 `json:"@message"`
    24  	Type       JSONLogType            `json:"type"`
    25  	Diagnostic *viewsjson.Diagnostic  `json:"diagnostic"`
    26  	Outputs    viewsjson.Outputs      `json:"outputs"`
    27  	Hook       map[string]interface{} `json:"hook"`
    28  }
    29  
    30  const (
    31  	LogVersion           JSONLogType = "version"
    32  	LogDiagnostic        JSONLogType = "diagnostic"
    33  	LogPlannedChange     JSONLogType = "planned_change"
    34  	LogRefreshStart      JSONLogType = "refresh_start"
    35  	LogRefreshComplete   JSONLogType = "refresh_complete"
    36  	LogApplyStart        JSONLogType = "apply_start"
    37  	LogApplyErrored      JSONLogType = "apply_errored"
    38  	LogApplyComplete     JSONLogType = "apply_complete"
    39  	LogChangeSummary     JSONLogType = "change_summary"
    40  	LogProvisionStart    JSONLogType = "provision_start"
    41  	LogProvisionProgress JSONLogType = "provision_progress"
    42  	LogProvisionComplete JSONLogType = "provision_complete"
    43  	LogProvisionErrored  JSONLogType = "provision_errored"
    44  	LogOutputs           JSONLogType = "outputs"
    45  )
    46  
    47  type Renderer struct {
    48  	Streams  *terminal.Streams
    49  	Colorize *colorstring.Colorize
    50  
    51  	RunningInAutomation bool
    52  }
    53  
    54  func (renderer Renderer) RenderHumanPlan(plan Plan, mode plans.Mode, opts ...PlanRendererOpt) {
    55  	// TODO(liamcervante): Tidy up this detection of version differences, we
    56  	// should only report warnings when the plan is generated using a newer
    57  	// version then we are executing. We could also look into major vs minor
    58  	// version differences. This should work for alpha testing in the meantime.
    59  	if plan.PlanFormatVersion != jsonplan.FormatVersion || plan.ProviderFormatVersion != jsonprovider.FormatVersion {
    60  		renderer.Streams.Println(format.WordWrap(
    61  			renderer.Colorize.Color("\n[bold][red]Warning:[reset][bold] This plan was generated using a different version of Terraform, the diff presented here maybe missing representations of recent features."),
    62  			renderer.Streams.Stdout.Columns()))
    63  	}
    64  
    65  	plan.renderHuman(renderer, mode, opts...)
    66  }
    67  
    68  func (renderer Renderer) RenderHumanState(state State) {
    69  	// TODO(liamcervante): Tidy up this detection of version differences, we
    70  	// should only report warnings when the plan is generated using a newer
    71  	// version then we are executing. We could also look into major vs minor
    72  	// version differences. This should work for alpha testing in the meantime.
    73  	if state.StateFormatVersion != jsonstate.FormatVersion || state.ProviderFormatVersion != jsonprovider.FormatVersion {
    74  		renderer.Streams.Println(format.WordWrap(
    75  			renderer.Colorize.Color("\n[bold][red]Warning:[reset][bold] This state was retrieved using a different version of Terraform, the state presented here maybe missing representations of recent features."),
    76  			renderer.Streams.Stdout.Columns()))
    77  	}
    78  
    79  	if state.Empty() {
    80  		renderer.Streams.Println("The state file is empty. No resources are represented.")
    81  		return
    82  	}
    83  
    84  	opts := computed.NewRenderHumanOpts(renderer.Colorize)
    85  	opts.ShowUnchangedChildren = true
    86  	opts.HideDiffActionSymbols = true
    87  
    88  	state.renderHumanStateModule(renderer, state.RootModule, opts, true)
    89  	state.renderHumanStateOutputs(renderer, opts)
    90  }
    91  
    92  func (r Renderer) RenderLog(log *JSONLog) error {
    93  	switch log.Type {
    94  	case LogRefreshComplete,
    95  		LogVersion,
    96  		LogPlannedChange,
    97  		LogProvisionComplete,
    98  		LogProvisionErrored,
    99  		LogApplyErrored:
   100  		// We won't display these types of logs
   101  		return nil
   102  
   103  	case LogApplyStart, LogApplyComplete, LogRefreshStart, LogProvisionStart:
   104  		msg := fmt.Sprintf(r.Colorize.Color("[bold]%s[reset]"), log.Message)
   105  		r.Streams.Println(msg)
   106  
   107  	case LogDiagnostic:
   108  		diag := format.DiagnosticFromJSON(log.Diagnostic, r.Colorize, 78)
   109  		r.Streams.Print(diag)
   110  
   111  	case LogOutputs:
   112  		if len(log.Outputs) > 0 {
   113  			r.Streams.Println(r.Colorize.Color("[bold][green]Outputs:[reset]"))
   114  			for name, output := range log.Outputs {
   115  				change := differ.FromJsonViewsOutput(output)
   116  				ctype, err := ctyjson.UnmarshalType(output.Type)
   117  				if err != nil {
   118  					return err
   119  				}
   120  
   121  				opts := computed.NewRenderHumanOpts(r.Colorize)
   122  				opts.ShowUnchangedChildren = true
   123  
   124  				outputDiff := change.ComputeDiffForType(ctype)
   125  				outputStr := outputDiff.RenderHuman(0, opts)
   126  
   127  				msg := fmt.Sprintf("%s = %s", name, outputStr)
   128  				r.Streams.Println(msg)
   129  			}
   130  		}
   131  
   132  	case LogProvisionProgress:
   133  		provisioner := log.Hook["provisioner"].(string)
   134  		output := log.Hook["output"].(string)
   135  		resource := log.Hook["resource"].(map[string]interface{})
   136  		resourceAddr := resource["addr"].(string)
   137  
   138  		msg := fmt.Sprintf(r.Colorize.Color("[bold]%s: (%s):[reset] %s"),
   139  			resourceAddr, provisioner, output)
   140  		r.Streams.Println(msg)
   141  
   142  	case LogChangeSummary:
   143  		// Normally, we will only render the apply change summary since the renderer
   144  		// generates a plan change summary for us
   145  		msg := fmt.Sprintf(r.Colorize.Color("[bold][green]%s[reset]"), log.Message)
   146  		r.Streams.Println("\n" + msg + "\n")
   147  
   148  	default:
   149  		// If the log type is not a known log type, we will just print the log message
   150  		r.Streams.Println(log.Message)
   151  	}
   152  
   153  	return nil
   154  }