terraform/builtin/provisioners/puppet/linux_provisioner_test.go

380 lines
9.6 KiB
Go

package puppet
import (
"io"
"strings"
"testing"
"github.com/hashicorp/terraform/communicator"
"github.com/hashicorp/terraform/communicator/remote"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
func TestResourceProvisioner_linuxUploadFile(t *testing.T) {
cases := map[string]struct {
Config map[string]interface{}
Commands map[string]bool
CommandFunc func(*remote.Cmd) error
ExpectedError bool
Uploads map[string]string
File io.Reader
Dir string
Filename string
}{
"Successful upload": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"mkdir -p /etc/puppetlabs/puppet": true,
"mv /tmp/csr_attributes.yaml /etc/puppetlabs/puppet/csr_attributes.yaml": true,
},
Uploads: map[string]string{
"/tmp/csr_attributes.yaml": "",
},
Dir: "/etc/puppetlabs/puppet",
Filename: "csr_attributes.yaml",
File: strings.NewReader(""),
},
"Failure when creating the directory": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"mkdir -p /etc/puppetlabs/puppet": true,
},
Dir: "/etc/puppetlabs/puppet",
Filename: "csr_attributes.yaml",
File: strings.NewReader(""),
CommandFunc: func(r *remote.Cmd) error {
r.SetExitStatus(1, &remote.ExitError{
Command: "mkdir -p /etc/puppetlabs/puppet",
ExitStatus: 1,
Err: nil,
})
return nil
},
ExpectedError: true,
},
}
for k, tc := range cases {
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
c := new(communicator.MockCommunicator)
c.Commands = tc.Commands
c.Uploads = tc.Uploads
if tc.CommandFunc != nil {
c.CommandFunc = tc.CommandFunc
}
p.comm = c
p.output = new(terraform.MockUIOutput)
err = p.linuxUploadFile(tc.File, tc.Dir, tc.Filename)
if tc.ExpectedError {
if err == nil {
t.Fatalf("Expected error, but no error returned")
}
} else {
if err != nil {
t.Fatalf("Test %q failed: %v", k, err)
}
}
}
}
func TestResourceProvisioner_linuxDefaultCertname(t *testing.T) {
cases := map[string]struct {
Config map[string]interface{}
Commands map[string]bool
CommandFunc func(*remote.Cmd) error
ExpectedError bool
}{
"No sudo": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"hostname -f": true,
},
},
"With sudo": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": true,
},
Commands: map[string]bool{
"sudo hostname -f": true,
},
},
"Failed execution": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"hostname -f": true,
},
CommandFunc: func(r *remote.Cmd) error {
if r.Command == "hostname -f" {
r.SetExitStatus(1, &remote.ExitError{
Command: "hostname -f",
ExitStatus: 1,
Err: nil,
})
} else {
r.SetExitStatus(0, nil)
}
return nil
},
ExpectedError: true,
},
}
for k, tc := range cases {
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
c := new(communicator.MockCommunicator)
c.Commands = tc.Commands
if tc.CommandFunc != nil {
c.CommandFunc = tc.CommandFunc
}
p.comm = c
p.output = new(terraform.MockUIOutput)
_, err = p.linuxDefaultCertname()
if tc.ExpectedError {
if err == nil {
t.Fatalf("Expected error, but no error returned")
}
} else {
if err != nil {
t.Fatalf("Test %q failed: %v", k, err)
}
}
}
}
func TestResourceProvisioner_linuxInstallPuppetAgent(t *testing.T) {
cases := map[string]struct {
Config map[string]interface{}
Commands map[string]bool
CommandFunc func(*remote.Cmd) error
ExpectedError bool
}{
"Everything runs succcessfully": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"curl -kO https://puppet.test.com:8140/packages/current/install.bash": true,
"bash -- ./install.bash --puppet-service-ensure stopped": true,
"rm -f install.bash": true,
},
},
"Respects the use_sudo config flag": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": true,
},
Commands: map[string]bool{
"sudo curl -kO https://puppet.test.com:8140/packages/current/install.bash": true,
"sudo bash -- ./install.bash --puppet-service-ensure stopped": true,
"sudo rm -f install.bash": true,
},
},
"When the curl command fails": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"curl -kO https://puppet.test.com:8140/packages/current/install.bash": true,
"bash -- ./install.bash --puppet-service-ensure stopped": false,
"rm -f install.bash": false,
},
CommandFunc: func(r *remote.Cmd) error {
if r.Command == "curl -kO https://puppet.test.com:8140/packages/current/install.bash" {
r.SetExitStatus(1, &remote.ExitError{
Command: "curl -kO https://puppet.test.com:8140/packages/current/install.bash",
ExitStatus: 1,
Err: nil,
})
} else {
r.SetExitStatus(0, nil)
}
return nil
},
ExpectedError: true,
},
"When the install script fails": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"curl -kO https://puppet.test.com:8140/packages/current/install.bash": true,
"bash -- ./install.bash --puppet-service-ensure stopped": true,
"rm -f install.bash": false,
},
CommandFunc: func(r *remote.Cmd) error {
if r.Command == "bash -- ./install.bash --puppet-service-ensure stopped" {
r.SetExitStatus(1, &remote.ExitError{
Command: "bash -- ./install.bash --puppet-service-ensure stopped",
ExitStatus: 1,
Err: nil,
})
} else {
r.SetExitStatus(0, nil)
}
return nil
},
ExpectedError: true,
},
"When the cleanup rm fails": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"curl -kO https://puppet.test.com:8140/packages/current/install.bash": true,
"bash -- ./install.bash --puppet-service-ensure stopped": true,
"rm -f install.bash": true,
},
CommandFunc: func(r *remote.Cmd) error {
if r.Command == "rm -f install.bash" {
r.SetExitStatus(1, &remote.ExitError{
Command: "rm -f install.bash",
ExitStatus: 1,
Err: nil,
})
} else {
r.SetExitStatus(0, nil)
}
return nil
},
ExpectedError: true,
},
}
for k, tc := range cases {
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
c := new(communicator.MockCommunicator)
c.Commands = tc.Commands
if tc.CommandFunc != nil {
c.CommandFunc = tc.CommandFunc
}
p.comm = c
p.output = new(terraform.MockUIOutput)
err = p.linuxInstallPuppetAgent()
if tc.ExpectedError {
if err == nil {
t.Fatalf("Expected error, but no error returned")
}
} else {
if err != nil {
t.Fatalf("Test %q failed: %v", k, err)
}
}
}
}
func TestResourceProvisioner_linuxRunPuppetAgent(t *testing.T) {
cases := map[string]struct {
Config map[string]interface{}
Commands map[string]bool
CommandFunc func(*remote.Cmd) error
ExpectedError bool
}{
"When puppet returns 0": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
Commands: map[string]bool{
"/opt/puppetlabs/puppet/bin/puppet agent --test --server puppet.test.com --environment production": true,
},
},
"When puppet returns 2 (changes applied without error)": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
CommandFunc: func(r *remote.Cmd) error {
r.SetExitStatus(2, &remote.ExitError{
Command: "/opt/puppetlabs/puppet/bin/puppet agent --test --server puppet.test.com",
ExitStatus: 2,
Err: nil,
})
return nil
},
ExpectedError: false,
},
"When puppet returns something not 0 or 2": {
Config: map[string]interface{}{
"server": "puppet.test.com",
"use_sudo": false,
},
CommandFunc: func(r *remote.Cmd) error {
r.SetExitStatus(1, &remote.ExitError{
Command: "/opt/puppetlabs/puppet/bin/puppet agent --test --server puppet.test.com",
ExitStatus: 1,
Err: nil,
})
return nil
},
ExpectedError: true,
},
}
for k, tc := range cases {
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
c := new(communicator.MockCommunicator)
c.Commands = tc.Commands
if tc.CommandFunc != nil {
c.CommandFunc = tc.CommandFunc
}
p.comm = c
p.output = new(terraform.MockUIOutput)
err = p.linuxRunPuppetAgent()
if tc.ExpectedError {
if err == nil {
t.Fatalf("Expected error, but no error returned")
}
} else {
if err != nil {
t.Fatalf("Test %q failed: %v", k, err)
}
}
}
}