-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
provisioner: new Puppet provisioner (#18851)
* Basic Puppet provisioner * (fixup) fix snake_case use in Bolt * (fixup) Remove unused ValidateFunc * (fixup) Check bolt result status * (lint) go fmt * Requested changes * Remove PE autodetection * Apply suggestions from @svanharmelen Co-Authored-By: rodjek <[email protected]> * Tag all JSON fields in bolt output * Defer comm.Disconnect() as suggested * Make bolt timeout configurable * Update builtin/provisioners/puppet/resource_provisioner.go Co-Authored-By: rodjek <[email protected]> * Make extension_requests and custom_attributes configurable
- Loading branch information
1 parent
0abb0a0
commit 615110e
Showing
9 changed files
with
1,457 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/hashicorp/terraform/builtin/provisioners/puppet" | ||
"github.com/hashicorp/terraform/plugin" | ||
) | ||
|
||
func main() { | ||
plugin.Serve(&plugin.ServeOpts{ | ||
ProvisionerFunc: puppet.Provisioner, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package puppet | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
|
||
"github.com/hashicorp/terraform/communicator/remote" | ||
) | ||
|
||
func (p *provisioner) linuxUploadFile(f io.Reader, dir string, filename string) error { | ||
_, err := p.runCommand("mkdir -p " + dir) | ||
if err != nil { | ||
return fmt.Errorf("Failed to make directory %s: %s", dir, err) | ||
} | ||
|
||
err = p.comm.Upload("/tmp/"+filename, f) | ||
if err != nil { | ||
return fmt.Errorf("Failed to upload %s to /tmp: %s", filename, err) | ||
} | ||
|
||
_, err = p.runCommand(fmt.Sprintf("mv /tmp/%s %s/%s", filename, dir, filename)) | ||
return err | ||
} | ||
|
||
func (p *provisioner) linuxDefaultCertname() (string, error) { | ||
certname, err := p.runCommand("hostname -f") | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return certname, nil | ||
} | ||
|
||
func (p *provisioner) linuxInstallPuppetAgent() error { | ||
_, err := p.runCommand(fmt.Sprintf("curl -kO https://%s:8140/packages/current/install.bash", p.Server)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = p.runCommand("bash -- ./install.bash --puppet-service-ensure stopped") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = p.runCommand("rm -f install.bash") | ||
return err | ||
} | ||
|
||
func (p *provisioner) linuxRunPuppetAgent() error { | ||
_, err := p.runCommand(fmt.Sprintf( | ||
"/opt/puppetlabs/puppet/bin/puppet agent --test --server %s --environment %s", | ||
p.Server, | ||
p.Environment, | ||
)) | ||
|
||
// Puppet exits 2 if changes have been successfully made. | ||
if err != nil { | ||
errStruct, _ := err.(*remote.ExitError) | ||
if errStruct.ExitStatus == 2 { | ||
return nil | ||
} | ||
} | ||
|
||
return err | ||
} |
Oops, something went wrong.