github.com/scottwinkler/terraform@v0.11.6-0.20180329211809-05143987aea8/repl/session.go (about) 1 package repl 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 "github.com/hashicorp/terraform/config" 9 "github.com/hashicorp/terraform/terraform" 10 ) 11 12 // ErrSessionExit is a special error result that should be checked for 13 // from Handle to signal a graceful exit. 14 var ErrSessionExit = errors.New("session exit") 15 16 // Session represents the state for a single REPL session. 17 type Session struct { 18 // Interpolater is used for calculating interpolations 19 Interpolater *terraform.Interpolater 20 } 21 22 // Handle handles a single line of input from the REPL. 23 // 24 // This is a stateful operation if a command is given (such as setting 25 // a variable). This function should not be called in parallel. 26 // 27 // The return value is the output and the error to show. 28 func (s *Session) Handle(line string) (string, error) { 29 switch { 30 case strings.TrimSpace(line) == "exit": 31 return "", ErrSessionExit 32 case strings.TrimSpace(line) == "help": 33 return s.handleHelp() 34 default: 35 return s.handleEval(line) 36 } 37 } 38 39 func (s *Session) handleEval(line string) (string, error) { 40 // Wrap the line to make it an interpolation. 41 line = fmt.Sprintf("${%s}", line) 42 43 // Parse the line 44 raw, err := config.NewRawConfig(map[string]interface{}{ 45 "value": line, 46 }) 47 if err != nil { 48 return "", err 49 } 50 51 // Set the value 52 raw.Key = "value" 53 54 // Get the values 55 vars, err := s.Interpolater.Values(&terraform.InterpolationScope{ 56 Path: []string{"root"}, 57 }, raw.Variables) 58 if err != nil { 59 return "", err 60 } 61 62 // Interpolate 63 if err := raw.Interpolate(vars); err != nil { 64 return "", err 65 } 66 67 // If we have any unknown keys, let the user know. 68 if ks := raw.UnknownKeys(); len(ks) > 0 { 69 return "", fmt.Errorf("unknown values referenced, can't compute value") 70 } 71 72 // Read the value 73 result, err := FormatResult(raw.Value()) 74 if err != nil { 75 return "", err 76 } 77 78 return result, nil 79 } 80 81 func (s *Session) handleHelp() (string, error) { 82 text := ` 83 The Terraform console allows you to experiment with Terraform interpolations. 84 You may access resources in the state (if you have one) just as you would 85 from a configuration. For example: "aws_instance.foo.id" would evaluate 86 to the ID of "aws_instance.foo" if it exists in your state. 87 88 Type in the interpolation to test and hit <enter> to see the result. 89 90 To exit the console, type "exit" and hit <enter>, or use Control-C or 91 Control-D. 92 ` 93 94 return strings.TrimSpace(text), nil 95 }