Skip to content

Commit 3086980

Browse files
committed
ReportHistory
1 parent 082a9b1 commit 3086980

3 files changed

Lines changed: 80 additions & 0 deletions

File tree

cmd/exec.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ var execCmd = &cobra.Command{
135135
exitCodeFinal = execChildCommand.ProcessState.ExitCode()
136136
}
137137

138+
s.ReportHistory(cmdToExec, cmdArgs, args[0], exitCodeFinal)
139+
138140
if (exitCodeFinal == 0 && (args[0] == "apply" || args[0] == "destroy")) || forceCleanTempDir {
139141
os.RemoveAll(s.CmdWorkTempDir)
140142
log.Println("removed temp dir: " + s.CmdWorkTempDir)

utils/agent_executor.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ func ExecuteAgentCommand(conn *websocket.Conn, cmd AgentCommand, state *State) {
150150
}
151151
}
152152

153+
state.ReportHistory(cmdToExec, args, cmd.Action, exitCode)
154+
153155
// 10. Cleanup
154156
if exitCode == 0 && (cmd.Action == "apply" || cmd.Action == "destroy") {
155157
os.RemoveAll(state.CmdWorkTempDir)

utils/externals.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package utils
22

33
import (
4+
"context"
45
"crypto/md5"
56
"encoding/hex"
67
"encoding/json"
@@ -9,6 +10,7 @@ import (
910
"log"
1011
"net/http"
1112
"os"
13+
"os/exec"
1214
"strings"
1315

1416
"github.com/spf13/viper"
@@ -122,3 +124,77 @@ func (s *State) GetDimData(dimensionKey string, dimensionValue string, skipOnNot
122124

123125
return dimensionJsonMap, nil
124126
}
127+
128+
func (s *State) ReportHistory(cmdToExec string, cmdArgs []string, cmdMainArg string, exitCode int) {
129+
if s.IacconsoleApiUrl == "" {
130+
// Only report to API if URL is configured
131+
return
132+
}
133+
134+
var outputs map[string]interface{}
135+
136+
if exitCode == 0 && (cmdMainArg == "apply" || cmdMainArg == "destroy") {
137+
// Run tofu output -json to gather outputs
138+
outputCmd := exec.Command(cmdToExec, "output", "-json")
139+
outputCmd.Dir = s.CmdWorkTempDir
140+
141+
outputBytes, err := outputCmd.Output()
142+
if err == nil && len(outputBytes) > 0 {
143+
// Terraform outputs structure: {"name": {"sensitive": false, "type": "string", "value": "val"}}
144+
var tfOutputs map[string]interface{}
145+
if err := json.Unmarshal(outputBytes, &tfOutputs); err == nil {
146+
// We can either pass the entire tfOutputs or extract just the values
147+
// The API's HistoryRequestPost map[string]interface{} can handle the whole structure,
148+
// so let's pass it as is, or we can unpack values. Passing as is gives type and sensitive flags.
149+
outputs = tfOutputs
150+
} else {
151+
log.Printf("Failed to parse tf outputs: %v\n", err)
152+
}
153+
} else if err != nil {
154+
log.Printf("Failed to get tf outputs: %v\n", err)
155+
}
156+
}
157+
158+
workspace := s.Workspace
159+
if workspace == "" {
160+
workspace = "master"
161+
}
162+
163+
payload := map[string]interface{}{
164+
"cmdtoexec": cmdToExec,
165+
"cmdargs": cmdArgs,
166+
"cmdmainarg": cmdMainArg,
167+
"exitcode": exitCode,
168+
"dimensions": s.ParsedDimensions,
169+
"outputs": outputs,
170+
}
171+
172+
payloadBytes, err := json.Marshal(payload)
173+
if err != nil {
174+
log.Printf("Failed to marshal history payload: %v", err)
175+
return
176+
}
177+
178+
url := fmt.Sprintf("%s/v1/history/%s/%s/%s", s.IacconsoleApiUrl, s.OrgName, workspace, s.UnitName)
179+
req, err := http.NewRequestWithContext(context.TODO(), "POST", url, strings.NewReader(string(payloadBytes)))
180+
if err != nil {
181+
log.Printf("Failed to create request for history: %v", err)
182+
return
183+
}
184+
req.Header.Set("Content-Type", "application/json")
185+
186+
client := &http.Client{}
187+
resp, err := client.Do(req)
188+
if err != nil {
189+
log.Printf("Failed to report history to %s: %v", url, err)
190+
return
191+
}
192+
defer resp.Body.Close()
193+
194+
if resp.StatusCode != http.StatusOK {
195+
body, _ := io.ReadAll(resp.Body)
196+
log.Printf("Failed to report history, status code %d: %s", resp.StatusCode, string(body))
197+
} else {
198+
log.Println("Successfully reported execution history to IaC Console API")
199+
}
200+
}

0 commit comments

Comments
 (0)