github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/builtin/provisioners/puppet/bolt/bolt.go (about)

     1  package bolt
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"os/exec"
     8  	"runtime"
     9  	"strings"
    10  	"time"
    11  )
    12  
    13  type Result struct {
    14  	Items []struct {
    15  		Node   string            `json:"node"`
    16  		Status string            `json:"status"`
    17  		Result map[string]string `json:"result"`
    18  	} `json:"items"`
    19  	NodeCount   int `json:"node_count"`
    20  	ElapsedTime int `json:"elapsed_time"`
    21  }
    22  
    23  func runCommand(command string, timeout time.Duration) ([]byte, error) {
    24  	var cmdargs []string
    25  
    26  	if runtime.GOOS == "windows" {
    27  		cmdargs = []string{"cmd", "/C"}
    28  	} else {
    29  		cmdargs = []string{"/bin/sh", "-c"}
    30  	}
    31  	cmdargs = append(cmdargs, command)
    32  
    33  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
    34  	defer cancel()
    35  
    36  	cmd := exec.CommandContext(ctx, cmdargs[0], cmdargs[1:]...)
    37  	return cmd.Output()
    38  }
    39  
    40  func Task(connInfo map[string]string, timeout time.Duration, sudo bool, task string, args map[string]string) (*Result, error) {
    41  	cmdargs := []string{
    42  		"bolt", "task", "run", "--nodes", connInfo["type"] + "://" + connInfo["host"], "-u", connInfo["user"],
    43  	}
    44  
    45  	if connInfo["type"] == "winrm" {
    46  		cmdargs = append(cmdargs, "-p", "\""+connInfo["password"]+"\"", "--no-ssl")
    47  	} else {
    48  		if sudo {
    49  			cmdargs = append(cmdargs, "--run-as", "root")
    50  		}
    51  
    52  		cmdargs = append(cmdargs, "--no-host-key-check")
    53  	}
    54  
    55  	cmdargs = append(cmdargs, "--format", "json", "--connect-timeout", "120", task)
    56  
    57  	if args != nil {
    58  		for key, value := range args {
    59  			cmdargs = append(cmdargs, strings.Join([]string{key, value}, "="))
    60  		}
    61  	}
    62  
    63  	out, err := runCommand(strings.Join(cmdargs, " "), timeout)
    64  	if err != nil {
    65  		return nil, fmt.Errorf("Bolt: \"%s\": %s: %s", strings.Join(cmdargs, " "), out, err)
    66  	}
    67  
    68  	result := new(Result)
    69  	if err = json.Unmarshal(out, result); err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	return result, nil
    74  }