terraform/builtin/provisioners/puppet/bolt/bolt.go

75 lines
1.7 KiB
Go

package bolt
import (
"context"
"encoding/json"
"fmt"
"os/exec"
"runtime"
"strings"
"time"
)
type Result struct {
Items []struct {
Node string `json:"node"`
Status string `json:"status"`
Result map[string]string `json:"result"`
} `json:"items"`
NodeCount int `json:"node_count"`
ElapsedTime int `json:"elapsed_time"`
}
func runCommand(command string, timeout time.Duration) ([]byte, error) {
var cmdargs []string
if runtime.GOOS == "windows" {
cmdargs = []string{"cmd", "/C"}
} else {
cmdargs = []string{"/bin/sh", "-c"}
}
cmdargs = append(cmdargs, command)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, cmdargs[0], cmdargs[1:]...)
return cmd.Output()
}
func Task(connInfo map[string]string, timeout time.Duration, sudo bool, task string, args map[string]string) (*Result, error) {
cmdargs := []string{
"bolt", "task", "run", "--nodes", connInfo["type"] + "://" + connInfo["host"], "-u", connInfo["user"],
}
if connInfo["type"] == "winrm" {
cmdargs = append(cmdargs, "-p", "\""+connInfo["password"]+"\"", "--no-ssl")
} else {
if sudo {
cmdargs = append(cmdargs, "--run-as", "root")
}
cmdargs = append(cmdargs, "--no-host-key-check")
}
cmdargs = append(cmdargs, "--format", "json", "--connect-timeout", "120", task)
if args != nil {
for key, value := range args {
cmdargs = append(cmdargs, strings.Join([]string{key, value}, "="))
}
}
out, err := runCommand(strings.Join(cmdargs, " "), timeout)
if err != nil {
return nil, fmt.Errorf("Bolt: \"%s\": %s: %s", strings.Join(cmdargs, " "), out, err)
}
result := new(Result)
if err = json.Unmarshal(out, result); err != nil {
return nil, err
}
return result, nil
}