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