github.com/mkuzmin/terraform@v0.3.7-0.20161118171027-ec4c00ff92a9/command/graph.go (about) 1 package command 2 3 import ( 4 "flag" 5 "fmt" 6 "os" 7 "strings" 8 9 "github.com/hashicorp/terraform/dag" 10 "github.com/hashicorp/terraform/terraform" 11 ) 12 13 // GraphCommand is a Command implementation that takes a Terraform 14 // configuration and outputs the dependency tree in graphical form. 15 type GraphCommand struct { 16 Meta 17 } 18 19 func (c *GraphCommand) Run(args []string) int { 20 var moduleDepth int 21 var verbose bool 22 var drawCycles bool 23 24 args = c.Meta.process(args, false) 25 26 cmdFlags := flag.NewFlagSet("graph", flag.ContinueOnError) 27 c.addModuleDepthFlag(cmdFlags, &moduleDepth) 28 cmdFlags.BoolVar(&verbose, "verbose", false, "verbose") 29 cmdFlags.BoolVar(&drawCycles, "draw-cycles", false, "draw-cycles") 30 cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } 31 if err := cmdFlags.Parse(args); err != nil { 32 return 1 33 } 34 35 var path string 36 args = cmdFlags.Args() 37 if len(args) > 1 { 38 c.Ui.Error("The graph command expects one argument.\n") 39 cmdFlags.Usage() 40 return 1 41 } else if len(args) == 1 { 42 path = args[0] 43 } else { 44 var err error 45 path, err = os.Getwd() 46 if err != nil { 47 c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err)) 48 } 49 } 50 51 ctx, _, err := c.Context(contextOpts{ 52 Path: path, 53 StatePath: "", 54 }) 55 if err != nil { 56 c.Ui.Error(fmt.Sprintf("Error loading Terraform: %s", err)) 57 return 1 58 } 59 60 // Skip validation during graph generation - we want to see the graph even if 61 // it is invalid for some reason. 62 g, err := ctx.Graph(&terraform.ContextGraphOpts{ 63 Verbose: verbose, 64 Validate: false, 65 }) 66 if err != nil { 67 c.Ui.Error(fmt.Sprintf("Error creating graph: %s", err)) 68 return 1 69 } 70 71 graphStr, err := terraform.GraphDot(g, &dag.DotOpts{ 72 DrawCycles: drawCycles, 73 MaxDepth: moduleDepth, 74 Verbose: verbose, 75 }) 76 if err != nil { 77 c.Ui.Error(fmt.Sprintf("Error converting graph: %s", err)) 78 return 1 79 } 80 81 c.Ui.Output(graphStr) 82 83 return 0 84 } 85 86 func (c *GraphCommand) Help() string { 87 helpText := ` 88 Usage: terraform graph [options] [DIR] 89 90 Outputs the visual dependency graph of Terraform resources according to 91 configuration files in DIR (or the current directory if omitted). 92 93 The graph is outputted in DOT format. The typical program that can 94 read this format is GraphViz, but many web services are also available 95 to read this format. 96 97 Options: 98 99 -draw-cycles Highlight any cycles in the graph with colored edges. 100 This helps when diagnosing cycle errors. 101 102 -module-depth=n The maximum depth to expand modules. By default this is 103 -1, which will expand resources within all modules. 104 105 -verbose Generate a verbose, "worst-case" graph, with all nodes 106 for potential operations in place. 107 108 -no-color If specified, output won't contain any color. 109 110 ` 111 return strings.TrimSpace(helpText) 112 } 113 114 func (c *GraphCommand) Synopsis() string { 115 return "Create a visual graph of Terraform resources" 116 }