github.com/nicgrayson/terraform@v0.4.3-0.20150415203910-c4de50829380/command/format_state.go (about)

     1  package command
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/terraform/terraform"
    10  	"github.com/mitchellh/colorstring"
    11  )
    12  
    13  // FormatStateOpts are the options for formatting a state.
    14  type FormatStateOpts struct {
    15  	// State is the state to format. This is required.
    16  	State *terraform.State
    17  
    18  	// Color is the colorizer. This is optional.
    19  	Color *colorstring.Colorize
    20  
    21  	// ModuleDepth is the depth of the modules to expand. By default this
    22  	// is zero which will not expand modules at all.
    23  	ModuleDepth int
    24  }
    25  
    26  // FormatState takes a state and returns a string
    27  func FormatState(opts *FormatStateOpts) string {
    28  	if opts.Color == nil {
    29  		panic("colorize not given")
    30  	}
    31  
    32  	s := opts.State
    33  	if len(s.Modules) == 0 {
    34  		return "The state file is empty. No resources are represented."
    35  	}
    36  
    37  	var buf bytes.Buffer
    38  	buf.WriteString("[reset]")
    39  
    40  	// Format all the modules
    41  	for _, m := range s.Modules {
    42  		if len(m.Path)-1 <= opts.ModuleDepth || opts.ModuleDepth == -1 {
    43  			formatStateModuleExpand(&buf, m, opts)
    44  		} else {
    45  			formatStateModuleSingle(&buf, m, opts)
    46  		}
    47  	}
    48  
    49  	// Write the outputs for the root module
    50  	m := s.RootModule()
    51  	if len(m.Outputs) > 0 {
    52  		buf.WriteString("\nOutputs:\n\n")
    53  
    54  		// Sort the outputs
    55  		ks := make([]string, 0, len(m.Outputs))
    56  		for k, _ := range m.Outputs {
    57  			ks = append(ks, k)
    58  		}
    59  		sort.Strings(ks)
    60  
    61  		// Output each output k/v pair
    62  		for _, k := range ks {
    63  			v := m.Outputs[k]
    64  			buf.WriteString(fmt.Sprintf("%s = %s\n", k, v))
    65  		}
    66  	}
    67  
    68  	return opts.Color.Color(strings.TrimSpace(buf.String()))
    69  }
    70  
    71  func formatStateModuleExpand(
    72  	buf *bytes.Buffer, m *terraform.ModuleState, opts *FormatStateOpts) {
    73  	var moduleName string
    74  	if !m.IsRoot() {
    75  		moduleName = fmt.Sprintf("module.%s", strings.Join(m.Path[1:], "."))
    76  	}
    77  
    78  	// First get the names of all the resources so we can show them
    79  	// in alphabetical order.
    80  	names := make([]string, 0, len(m.Resources))
    81  	for name, _ := range m.Resources {
    82  		names = append(names, name)
    83  	}
    84  	sort.Strings(names)
    85  
    86  	// Go through each resource and begin building up the output.
    87  	for _, k := range names {
    88  		name := k
    89  		if moduleName != "" {
    90  			name = moduleName + "." + name
    91  		}
    92  
    93  		rs := m.Resources[k]
    94  		is := rs.Primary
    95  		var id string
    96  		if is != nil {
    97  			id = is.ID
    98  		}
    99  		if id == "" {
   100  			id = "<not created>"
   101  		}
   102  
   103  		taintStr := ""
   104  		if len(rs.Tainted) > 0 {
   105  			taintStr = " (tainted)"
   106  		}
   107  
   108  		buf.WriteString(fmt.Sprintf("%s:%s\n", name, taintStr))
   109  		buf.WriteString(fmt.Sprintf("  id = %s\n", id))
   110  
   111  		if is != nil {
   112  			// Sort the attributes
   113  			attrKeys := make([]string, 0, len(is.Attributes))
   114  			for ak, _ := range is.Attributes {
   115  				// Skip the id attribute since we just show the id directly
   116  				if ak == "id" {
   117  					continue
   118  				}
   119  
   120  				attrKeys = append(attrKeys, ak)
   121  			}
   122  			sort.Strings(attrKeys)
   123  
   124  			// Output each attribute
   125  			for _, ak := range attrKeys {
   126  				av := is.Attributes[ak]
   127  				buf.WriteString(fmt.Sprintf("  %s = %s\n", ak, av))
   128  			}
   129  		}
   130  	}
   131  
   132  	buf.WriteString("[reset]\n")
   133  }
   134  
   135  func formatStateModuleSingle(
   136  	buf *bytes.Buffer, m *terraform.ModuleState, opts *FormatStateOpts) {
   137  	// Header with the module name
   138  	buf.WriteString(fmt.Sprintf("module.%s\n", strings.Join(m.Path[1:], ".")))
   139  
   140  	// Now just write how many resources are in here.
   141  	buf.WriteString(fmt.Sprintf("  %d resource(s)\n", len(m.Resources)))
   142  }