-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathin.go
159 lines (144 loc) · 3.95 KB
/
in.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package concourse_tfe_resource
import (
"context"
"encoding/json"
tfe "github.com/hashicorp/go-tfe"
"log"
"os"
"path"
"time"
)
func in(input inputJSON) ([]byte, error) {
run, err := waitForRun(input)
if err != nil {
return nil, err
}
output := inOutputJSON{Version: version{Ref: input.Version.Ref}}
output.Metadata = runMetadata(input, run)
metadataMap := make(map[string]string)
for _, v := range output.Metadata {
metadataMap[v.Name] = v.Value
}
if err := writeOutputDirectory(input, metadataMap); err != nil {
return nil, err
}
return json.Marshal(output)
}
func waitForRun(input inputJSON) (*tfe.Run, error) {
var run *tfe.Run
for {
var err error
run, err = client.Runs.Read(context.Background(), input.Version.Ref)
if err != nil {
return run, formatError(err, "retrieving run")
}
if needsConfirmation(run) && input.Params.Confirm {
err = client.Runs.Apply(context.Background(), input.Version.Ref, tfe.RunApplyOptions{Comment: &input.Params.ApplyMessage})
if err != nil {
return run, formatError(err, "applying run")
}
}
if finished(run) {
break
} else {
log.Printf("Run still in progress (status = %s)", run.Status)
time.Sleep(time.Duration(input.Params.PollingPeriod) * time.Second)
}
}
return run, nil
}
func writeOutputDirectory(input inputJSON, metadataMap map[string]string) error {
if err := writeJSONFile(metadataMap, "metadata.json"); err != nil {
return err
}
if err := writeWorkspaceVariables(); err != nil {
return err
}
if err := writeStateOutputs(input.Params.Sensitive); err != nil {
return err
}
return nil
}
func writeStateOutputs(sensitive bool) error {
outputDir := path.Join(workingDirectory, "outputs")
if err := os.MkdirAll(outputDir, os.FileMode(0777)); err != nil {
return formatError(err, "creating run output directory")
}
outputs, err := getWorkspaceOutputs()
if err != nil {
return err
}
jsonOutput := make(map[string]json.RawMessage)
for _, output := range outputs {
key := output.Name
fileName := path.Join(outputDir, key)
var outputValue json.RawMessage
if !output.Sensitive || sensitive {
ov, err := json.Marshal(output.Value)
if err != nil {
return formatError(err, "marshalling state output")
}
outputValue = json.RawMessage(ov)
}
jsonOutput[key] = outputValue
if err := writeAndClose(fileName, outputValue); err != nil {
return err
}
}
return writeJSONFile(jsonOutput, "outputs.json")
}
func writeWorkspaceVariables() error {
var (
vars tfe.VariableList
err error
varsDir = path.Join(workingDirectory, "vars")
envVarsDir = path.Join(workingDirectory, "env_vars")
hclVarsDir = path.Join(varsDir, "hcl")
)
if vars, err = getVariableList(); err != nil {
return err
}
if err := os.MkdirAll(hclVarsDir, os.FileMode(0777)); err != nil {
return formatError(err, "creating output directories")
}
if err := os.MkdirAll(envVarsDir, os.FileMode(0777)); err != nil {
return formatError(err, "creating output directories")
}
for _, v := range vars.Items {
var fileName string
if v.Category == tfe.CategoryEnv {
fileName = path.Join(envVarsDir, v.Key)
} else if v.HCL {
fileName = path.Join(hclVarsDir, v.Key)
} else {
fileName = path.Join(varsDir, v.Key)
}
if err := writeAndClose(fileName, []byte(v.Value)); err != nil {
return err
}
}
return nil
}
func writeJSONFile(contents interface{}, fileName string) error {
byteContents, err := json.Marshal(contents)
if err != nil {
return formatError(err, "marshaling "+fileName)
}
if err = writeAndClose(path.Join(workingDirectory, fileName), byteContents); err != nil {
return err
}
return nil
}
func writeAndClose(fileName string, value []byte) error {
f, err := os.Create(fileName)
if err != nil {
return formatError(err, "creating "+fileName)
}
if _, err := f.Write(value); err != nil {
return formatError(err, "writing "+fileName)
}
if err := f.Close(); err != nil {
return formatError(err, "closing "+fileName)
}
return nil
}