2018-10-16 12:40:07 -04:00
|
|
|
// +build !windows
|
|
|
|
|
2015-03-10 00:11:57 -04:00
|
|
|
package ansible
|
|
|
|
|
|
|
|
import (
|
2016-07-06 20:02:10 -04:00
|
|
|
"bytes"
|
2019-03-19 13:11:19 -04:00
|
|
|
"context"
|
2015-03-10 00:11:57 -04:00
|
|
|
"crypto/rand"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2016-03-01 13:35:48 -05:00
|
|
|
"path"
|
2017-03-21 23:26:41 -04:00
|
|
|
"strings"
|
2015-03-10 00:11:57 -04:00
|
|
|
"testing"
|
|
|
|
|
2020-02-04 13:42:55 -05:00
|
|
|
confighelper "github.com/hashicorp/packer/helper/config"
|
2017-04-04 16:39:01 -04:00
|
|
|
"github.com/hashicorp/packer/packer"
|
2020-04-01 19:07:14 -04:00
|
|
|
"github.com/stretchr/testify/assert"
|
2015-03-10 00:11:57 -04:00
|
|
|
)
|
|
|
|
|
2016-03-01 13:35:48 -05:00
|
|
|
// Be sure to remove the Ansible stub file in each test with:
|
|
|
|
// defer os.Remove(config["command"].(string))
|
2018-09-10 19:48:42 -04:00
|
|
|
func testConfig(t *testing.T) map[string]interface{} {
|
|
|
|
m := make(map[string]interface{})
|
2016-03-01 13:35:48 -05:00
|
|
|
wd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
ansible_stub := path.Join(wd, "packer-ansible-stub.sh")
|
|
|
|
|
|
|
|
err = ioutil.WriteFile(ansible_stub, []byte("#!/usr/bin/env bash\necho ansible 1.6.0"), 0777)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
m["command"] = ansible_stub
|
|
|
|
|
2015-03-10 00:11:57 -04:00
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProvisioner_Impl(t *testing.T) {
|
|
|
|
var raw interface{}
|
|
|
|
raw = &Provisioner{}
|
|
|
|
if _, ok := raw.(packer.Provisioner); !ok {
|
|
|
|
t.Fatalf("must be a Provisioner")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProvisionerPrepare_Defaults(t *testing.T) {
|
|
|
|
var p Provisioner
|
2016-03-01 13:35:48 -05:00
|
|
|
config := testConfig(t)
|
|
|
|
defer os.Remove(config["command"].(string))
|
2015-03-10 00:11:57 -04:00
|
|
|
|
|
|
|
err := p.Prepare(config)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("should have error")
|
|
|
|
}
|
|
|
|
|
|
|
|
hostkey_file, err := ioutil.TempFile("", "hostkey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(hostkey_file.Name())
|
|
|
|
|
|
|
|
publickey_file, err := ioutil.TempFile("", "publickey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(publickey_file.Name())
|
|
|
|
|
|
|
|
playbook_file, err := ioutil.TempFile("", "playbook")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(playbook_file.Name())
|
|
|
|
|
2015-03-10 01:25:45 -04:00
|
|
|
config["ssh_host_key_file"] = hostkey_file.Name()
|
2015-03-10 00:11:57 -04:00
|
|
|
config["ssh_authorized_key_file"] = publickey_file.Name()
|
|
|
|
config["playbook_file"] = playbook_file.Name()
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2018-01-03 02:33:32 -05:00
|
|
|
defer os.Remove(playbook_file.Name())
|
|
|
|
|
|
|
|
err = os.Unsetenv("USER")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2015-03-10 00:11:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestProvisionerPrepare_PlaybookFile(t *testing.T) {
|
|
|
|
var p Provisioner
|
2016-03-01 13:35:48 -05:00
|
|
|
config := testConfig(t)
|
|
|
|
defer os.Remove(config["command"].(string))
|
2015-03-10 00:11:57 -04:00
|
|
|
|
|
|
|
hostkey_file, err := ioutil.TempFile("", "hostkey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(hostkey_file.Name())
|
|
|
|
|
|
|
|
publickey_file, err := ioutil.TempFile("", "publickey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(publickey_file.Name())
|
|
|
|
|
2015-03-10 01:25:45 -04:00
|
|
|
config["ssh_host_key_file"] = hostkey_file.Name()
|
2015-03-10 00:11:57 -04:00
|
|
|
config["ssh_authorized_key_file"] = publickey_file.Name()
|
|
|
|
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("should have error")
|
|
|
|
}
|
|
|
|
|
|
|
|
playbook_file, err := ioutil.TempFile("", "playbook")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(playbook_file.Name())
|
|
|
|
|
|
|
|
config["playbook_file"] = playbook_file.Name()
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProvisionerPrepare_HostKeyFile(t *testing.T) {
|
|
|
|
var p Provisioner
|
2016-03-01 13:35:48 -05:00
|
|
|
config := testConfig(t)
|
|
|
|
defer os.Remove(config["command"].(string))
|
2015-03-10 00:11:57 -04:00
|
|
|
|
|
|
|
publickey_file, err := ioutil.TempFile("", "publickey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(publickey_file.Name())
|
|
|
|
|
|
|
|
playbook_file, err := ioutil.TempFile("", "playbook")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(playbook_file.Name())
|
|
|
|
|
|
|
|
filename := make([]byte, 10)
|
|
|
|
n, err := io.ReadFull(rand.Reader, filename)
|
|
|
|
if n != len(filename) || err != nil {
|
|
|
|
t.Fatal("could not create random file name")
|
|
|
|
}
|
|
|
|
|
2015-03-10 01:25:45 -04:00
|
|
|
config["ssh_host_key_file"] = fmt.Sprintf("%x", filename)
|
2015-03-10 00:11:57 -04:00
|
|
|
config["ssh_authorized_key_file"] = publickey_file.Name()
|
|
|
|
config["playbook_file"] = playbook_file.Name()
|
|
|
|
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err == nil {
|
2015-03-10 01:25:45 -04:00
|
|
|
t.Fatal("should error if ssh_host_key_file does not exist")
|
2015-03-10 00:11:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
hostkey_file, err := ioutil.TempFile("", "hostkey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(hostkey_file.Name())
|
|
|
|
|
2015-03-10 01:25:45 -04:00
|
|
|
config["ssh_host_key_file"] = hostkey_file.Name()
|
2015-03-10 00:11:57 -04:00
|
|
|
err = p.Prepare(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProvisionerPrepare_AuthorizedKeyFile(t *testing.T) {
|
|
|
|
var p Provisioner
|
2016-03-01 13:35:48 -05:00
|
|
|
config := testConfig(t)
|
|
|
|
defer os.Remove(config["command"].(string))
|
2015-03-10 00:11:57 -04:00
|
|
|
|
|
|
|
hostkey_file, err := ioutil.TempFile("", "hostkey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(hostkey_file.Name())
|
|
|
|
|
|
|
|
playbook_file, err := ioutil.TempFile("", "playbook")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(playbook_file.Name())
|
|
|
|
|
2016-02-06 21:22:38 -05:00
|
|
|
filename := make([]byte, 10)
|
|
|
|
n, err := io.ReadFull(rand.Reader, filename)
|
|
|
|
if n != len(filename) || err != nil {
|
|
|
|
t.Fatal("could not create random file name")
|
|
|
|
}
|
|
|
|
|
2015-03-10 01:25:45 -04:00
|
|
|
config["ssh_host_key_file"] = hostkey_file.Name()
|
2015-03-10 00:11:57 -04:00
|
|
|
config["playbook_file"] = playbook_file.Name()
|
2016-02-06 21:22:38 -05:00
|
|
|
config["ssh_authorized_key_file"] = fmt.Sprintf("%x", filename)
|
2015-03-10 00:11:57 -04:00
|
|
|
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err == nil {
|
2016-02-06 21:22:38 -05:00
|
|
|
t.Errorf("should error if ssh_authorized_key_file does not exist")
|
2015-03-10 00:11:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
publickey_file, err := ioutil.TempFile("", "publickey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(publickey_file.Name())
|
|
|
|
|
|
|
|
config["ssh_authorized_key_file"] = publickey_file.Name()
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err != nil {
|
2016-02-06 21:22:38 -05:00
|
|
|
t.Errorf("err: %s", err)
|
2015-03-10 00:11:57 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProvisionerPrepare_LocalPort(t *testing.T) {
|
|
|
|
var p Provisioner
|
2016-03-01 13:35:48 -05:00
|
|
|
config := testConfig(t)
|
|
|
|
defer os.Remove(config["command"].(string))
|
2015-03-10 00:11:57 -04:00
|
|
|
|
|
|
|
hostkey_file, err := ioutil.TempFile("", "hostkey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(hostkey_file.Name())
|
|
|
|
|
|
|
|
publickey_file, err := ioutil.TempFile("", "publickey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(publickey_file.Name())
|
|
|
|
|
|
|
|
playbook_file, err := ioutil.TempFile("", "playbook")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(playbook_file.Name())
|
|
|
|
|
2015-03-10 01:25:45 -04:00
|
|
|
config["ssh_host_key_file"] = hostkey_file.Name()
|
2015-03-10 00:11:57 -04:00
|
|
|
config["ssh_authorized_key_file"] = publickey_file.Name()
|
|
|
|
config["playbook_file"] = playbook_file.Name()
|
|
|
|
|
2019-03-19 09:47:21 -04:00
|
|
|
config["local_port"] = 65537
|
2015-03-10 00:11:57 -04:00
|
|
|
err = p.Prepare(config)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("should have error")
|
|
|
|
}
|
|
|
|
|
2019-03-19 09:47:21 -04:00
|
|
|
config["local_port"] = 22222
|
2015-03-10 00:11:57 -04:00
|
|
|
err = p.Prepare(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
2016-07-06 20:02:10 -04:00
|
|
|
|
2017-04-04 23:49:24 -04:00
|
|
|
func TestProvisionerPrepare_InventoryDirectory(t *testing.T) {
|
|
|
|
var p Provisioner
|
|
|
|
config := testConfig(t)
|
|
|
|
defer os.Remove(config["command"].(string))
|
|
|
|
|
|
|
|
hostkey_file, err := ioutil.TempFile("", "hostkey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(hostkey_file.Name())
|
|
|
|
|
|
|
|
publickey_file, err := ioutil.TempFile("", "publickey")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(publickey_file.Name())
|
|
|
|
|
|
|
|
playbook_file, err := ioutil.TempFile("", "playbook")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(playbook_file.Name())
|
|
|
|
|
|
|
|
config["ssh_host_key_file"] = hostkey_file.Name()
|
|
|
|
config["ssh_authorized_key_file"] = publickey_file.Name()
|
|
|
|
config["playbook_file"] = playbook_file.Name()
|
|
|
|
|
|
|
|
config["inventory_directory"] = "doesnotexist"
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("should error if inventory_directory does not exist")
|
|
|
|
}
|
|
|
|
|
|
|
|
inventoryDirectory, err := ioutil.TempDir("", "some_inventory_dir")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(inventoryDirectory)
|
|
|
|
|
|
|
|
config["inventory_directory"] = inventoryDirectory
|
|
|
|
err = p.Prepare(config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-06 20:02:10 -04:00
|
|
|
func TestAnsibleGetVersion(t *testing.T) {
|
|
|
|
if os.Getenv("PACKER_ACC") == "" {
|
|
|
|
t.Skip("This test is only run with PACKER_ACC=1 and it requires Ansible to be installed")
|
|
|
|
}
|
|
|
|
|
|
|
|
var p Provisioner
|
|
|
|
p.config.Command = "ansible-playbook"
|
2016-07-07 15:01:23 -04:00
|
|
|
err := p.getVersion()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2016-07-06 20:02:10 -04:00
|
|
|
}
|
|
|
|
|
2017-03-21 23:26:41 -04:00
|
|
|
func TestAnsibleGetVersionError(t *testing.T) {
|
|
|
|
var p Provisioner
|
|
|
|
p.config.Command = "./test-fixtures/exit1"
|
|
|
|
err := p.getVersion()
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Should return error")
|
|
|
|
}
|
|
|
|
if !strings.Contains(err.Error(), "./test-fixtures/exit1 --version") {
|
|
|
|
t.Fatal("Error message should include command name")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-06 20:02:10 -04:00
|
|
|
func TestAnsibleLongMessages(t *testing.T) {
|
|
|
|
if os.Getenv("PACKER_ACC") == "" {
|
|
|
|
t.Skip("This test is only run with PACKER_ACC=1 and it requires Ansible to be installed")
|
|
|
|
}
|
|
|
|
|
|
|
|
var p Provisioner
|
|
|
|
p.config.Command = "ansible-playbook"
|
|
|
|
p.config.PlaybookFile = "./test-fixtures/long-debug-message.yml"
|
2016-07-07 15:01:23 -04:00
|
|
|
err := p.Prepare()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2016-07-06 20:02:10 -04:00
|
|
|
|
|
|
|
comm := &packer.MockCommunicator{}
|
|
|
|
ui := &packer.BasicUi{
|
|
|
|
Reader: new(bytes.Buffer),
|
|
|
|
Writer: new(bytes.Buffer),
|
|
|
|
}
|
|
|
|
|
2019-12-12 13:59:44 -05:00
|
|
|
err = p.Provision(context.Background(), ui, comm, make(map[string]interface{}))
|
2016-07-07 15:01:23 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2016-07-06 20:02:10 -04:00
|
|
|
}
|
2020-02-04 13:42:55 -05:00
|
|
|
|
2020-03-28 16:00:07 -04:00
|
|
|
func TestCreateInventoryFile(t *testing.T) {
|
|
|
|
type inventoryFileTestCases struct {
|
|
|
|
AnsibleVersion uint
|
|
|
|
User string
|
|
|
|
Groups []string
|
|
|
|
EmptyGroups []string
|
|
|
|
UseProxy confighelper.Trilean
|
|
|
|
GeneratedData map[string]interface{}
|
|
|
|
Expected string
|
|
|
|
}
|
|
|
|
|
|
|
|
TestCases := []inventoryFileTestCases{
|
|
|
|
{
|
|
|
|
AnsibleVersion: 1,
|
|
|
|
User: "testuser",
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
GeneratedData: basicGenData(nil),
|
|
|
|
Expected: "default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234\n",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AnsibleVersion: 2,
|
|
|
|
User: "testuser",
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
GeneratedData: basicGenData(nil),
|
|
|
|
Expected: "default ansible_host=123.45.67.89 ansible_user=testuser ansible_port=1234\n",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AnsibleVersion: 1,
|
|
|
|
User: "testuser",
|
|
|
|
Groups: []string{"Group1", "Group2"},
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
GeneratedData: basicGenData(nil),
|
|
|
|
Expected: `default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
2020-02-04 13:42:55 -05:00
|
|
|
[Group1]
|
|
|
|
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
|
|
|
[Group2]
|
|
|
|
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
2020-03-28 16:00:07 -04:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AnsibleVersion: 1,
|
|
|
|
User: "testuser",
|
|
|
|
EmptyGroups: []string{"Group1", "Group2"},
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
GeneratedData: basicGenData(nil),
|
|
|
|
Expected: `default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
2020-02-04 13:42:55 -05:00
|
|
|
[Group1]
|
|
|
|
[Group2]
|
2020-03-28 16:00:07 -04:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AnsibleVersion: 1,
|
|
|
|
User: "testuser",
|
|
|
|
Groups: []string{"Group1", "Group2"},
|
|
|
|
EmptyGroups: []string{"Group3"},
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
GeneratedData: basicGenData(nil),
|
|
|
|
Expected: `default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
2020-02-04 13:42:55 -05:00
|
|
|
[Group1]
|
|
|
|
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
|
|
|
[Group2]
|
|
|
|
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
|
|
|
[Group3]
|
2020-03-28 16:00:07 -04:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AnsibleVersion: 2,
|
|
|
|
User: "testuser",
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
GeneratedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "winrm",
|
|
|
|
"Password": "12345",
|
|
|
|
}),
|
2020-03-31 20:03:39 -04:00
|
|
|
Expected: "default ansible_host=123.45.67.89 ansible_connection=winrm ansible_winrm_transport=basic ansible_shell_type=powershell ansible_user=testuser ansible_port=1234\n",
|
2020-03-28 16:00:07 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range TestCases {
|
|
|
|
var p Provisioner
|
|
|
|
p.Prepare(testConfig(t))
|
|
|
|
defer os.Remove(p.config.Command)
|
|
|
|
p.ansibleMajVersion = tc.AnsibleVersion
|
|
|
|
p.config.User = tc.User
|
|
|
|
p.config.Groups = tc.Groups
|
|
|
|
p.config.EmptyGroups = tc.EmptyGroups
|
|
|
|
p.config.UseProxy = tc.UseProxy
|
|
|
|
p.generatedData = tc.GeneratedData
|
|
|
|
|
|
|
|
err := p.createInventoryFile()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating config using localhost and local port proxy")
|
|
|
|
}
|
|
|
|
if p.config.InventoryFile == "" {
|
|
|
|
t.Fatalf("No inventory file was created")
|
|
|
|
}
|
|
|
|
defer os.Remove(p.config.InventoryFile)
|
|
|
|
f, err := ioutil.ReadFile(p.config.InventoryFile)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("couldn't read created inventoryfile: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := tc.Expected
|
|
|
|
if fmt.Sprintf("%s", f) != expected {
|
|
|
|
t.Fatalf("File didn't match expected:\n\n expected: \n%s\n; recieved: \n%s\n", expected, f)
|
|
|
|
}
|
2020-02-04 13:42:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-28 15:16:01 -04:00
|
|
|
func basicGenData(input map[string]interface{}) map[string]interface{} {
|
|
|
|
gd := map[string]interface{}{
|
2020-03-28 16:00:07 -04:00
|
|
|
"Host": "123.45.67.89",
|
2020-03-28 15:16:01 -04:00
|
|
|
"Port": int64(1234),
|
|
|
|
"ConnType": "ssh",
|
|
|
|
"SSHPrivateKeyFile": "",
|
|
|
|
"SSHPrivateKey": "asdf",
|
|
|
|
"User": "PartyPacker",
|
|
|
|
}
|
|
|
|
if input == nil {
|
|
|
|
return gd
|
|
|
|
}
|
|
|
|
for k, v := range input {
|
|
|
|
gd[k] = v
|
|
|
|
}
|
|
|
|
return gd
|
|
|
|
}
|
|
|
|
|
2020-04-01 19:07:14 -04:00
|
|
|
func TestCreateCmdArgs(t *testing.T) {
|
|
|
|
type testcase struct {
|
|
|
|
PackerBuildName string
|
|
|
|
PackerBuilderType string
|
|
|
|
UseProxy confighelper.Trilean
|
|
|
|
generatedData map[string]interface{}
|
|
|
|
ExtraArguments []string
|
|
|
|
AnsibleEnvVars []string
|
|
|
|
callArgs []string // httpAddr inventory playbook privKeyFile
|
|
|
|
ExpectedArgs []string
|
|
|
|
ExpectedEnvVars []string
|
|
|
|
}
|
|
|
|
TestCases := []testcase{
|
|
|
|
{
|
|
|
|
// SSH with private key and an extra argument.
|
|
|
|
PackerBuildName: "packerparty",
|
|
|
|
generatedData: basicGenData(nil),
|
|
|
|
ExtraArguments: []string{"-e", "hello-world"},
|
|
|
|
AnsibleEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
callArgs: []string{"", "/var/inventory", "test-playbook.yml", "/path/to/privkey.pem"},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_build_name=packerparty", "-e", "packer_builder_type=fakebuilder", "-e", "ansible_ssh_private_key_file=/path/to/privkey.pem", "--ssh-extra-args", "-o IdentitiesOnly=yes", "-i", "/var/inventory", "test-playbook.yml", "-e", "hello-world"},
|
|
|
|
ExpectedEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
PackerBuildName: "packerparty",
|
|
|
|
UseProxy: confighelper.TriTrue,
|
|
|
|
generatedData: basicGenData(nil),
|
|
|
|
ExtraArguments: []string{"-e", "hello-world"},
|
|
|
|
callArgs: []string{"", "/var/inventory", "test-playbook.yml", "/path/to/privkey.pem"},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_build_name=packerparty", "-e", "packer_builder_type=fakebuilder", "-e", "ansible_ssh_private_key_file=/path/to/privkey.pem", "--ssh-extra-args", "-o IdentitiesOnly=yes", "-i", "/var/inventory", "test-playbook.yml", "-e", "hello-world"},
|
|
|
|
ExpectedEnvVars: []string{},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Winrm, but no_proxy is unset so we don't do anything with ansible_password.
|
|
|
|
PackerBuildName: "packerparty",
|
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "winrm",
|
|
|
|
}),
|
|
|
|
ExtraArguments: []string{"-e", "hello-world"},
|
|
|
|
AnsibleEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
callArgs: []string{"", "/var/inventory", "test-playbook.yml", ""},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_build_name=packerparty", "-e", "packer_builder_type=fakebuilder", "-i", "/var/inventory", "test-playbook.yml", "-e", "hello-world"},
|
|
|
|
ExpectedEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// HTTPAddr should be set. No env vars.
|
|
|
|
PackerBuildName: "packerparty",
|
|
|
|
ExtraArguments: []string{"-e", "hello-world"},
|
|
|
|
generatedData: basicGenData(nil),
|
|
|
|
callArgs: []string{"123.45.67.89", "/var/inventory", "test-playbook.yml", ""},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_build_name=packerparty", "-e", "packer_builder_type=fakebuilder", "-e", "packer_http_addr=123.45.67.89", "--ssh-extra-args", "-o IdentitiesOnly=yes", "-i", "/var/inventory", "test-playbook.yml", "-e", "hello-world"},
|
|
|
|
ExpectedEnvVars: []string{},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Add ansible_password for proxyless winrm connection.
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "winrm",
|
|
|
|
"Password": "ilovebananapancakes",
|
|
|
|
}),
|
|
|
|
AnsibleEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
callArgs: []string{"123.45.67.89", "/var/inventory", "test-playbook.yml", ""},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_builder_type=fakebuilder", "-e", "packer_http_addr=123.45.67.89", "-e", "ansible_password=ilovebananapancakes", "-i", "/var/inventory", "test-playbook.yml"},
|
|
|
|
ExpectedEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Neither special ssh stuff, nor special windows stuff. This is docker!
|
|
|
|
PackerBuildName: "packerparty",
|
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "docker",
|
|
|
|
}),
|
|
|
|
ExtraArguments: []string{"-e", "hello-world"},
|
|
|
|
AnsibleEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
callArgs: []string{"", "/var/inventory", "test-playbook.yml", ""},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_build_name=packerparty", "-e", "packer_builder_type=fakebuilder", "-i", "/var/inventory", "test-playbook.yml", "-e", "hello-world"},
|
|
|
|
ExpectedEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Windows, no proxy, with extra vars.
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "winrm",
|
|
|
|
"Password": "ilovebananapancakes",
|
|
|
|
}),
|
|
|
|
ExtraArguments: []string{"-e", "hello-world"},
|
|
|
|
AnsibleEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
callArgs: []string{"123.45.67.89", "/var/inventory", "test-playbook.yml", ""},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_builder_type=fakebuilder", "-e", "packer_http_addr=123.45.67.89", "-e", "ansible_password=ilovebananapancakes", "-i", "/var/inventory", "test-playbook.yml", "-e", "hello-world"},
|
|
|
|
ExpectedEnvVars: []string{"ENV_1=pancakes", "ENV_2=bananas"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// No builder name. This shouldn't cause an error, it just shouldn't be set. HCL, yo.
|
|
|
|
generatedData: basicGenData(nil),
|
|
|
|
callArgs: []string{"", "/var/inventory", "test-playbook.yml", ""},
|
|
|
|
ExpectedArgs: []string{"-e", "packer_builder_type=fakebuilder", "--ssh-extra-args", "-o IdentitiesOnly=yes", "-i", "/var/inventory", "test-playbook.yml"},
|
|
|
|
ExpectedEnvVars: []string{},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range TestCases {
|
|
|
|
var p Provisioner
|
|
|
|
p.Prepare(testConfig(t))
|
|
|
|
defer os.Remove(p.config.Command)
|
|
|
|
p.config.UseProxy = tc.UseProxy
|
|
|
|
p.config.PackerBuilderType = "fakebuilder"
|
|
|
|
p.config.PackerBuildName = tc.PackerBuildName
|
|
|
|
p.generatedData = tc.generatedData
|
|
|
|
p.config.ExtraArguments = tc.ExtraArguments
|
|
|
|
p.config.AnsibleEnvVars = tc.AnsibleEnvVars
|
|
|
|
|
|
|
|
args, envVars := p.createCmdArgs(tc.callArgs[0], tc.callArgs[1], tc.callArgs[2], tc.callArgs[3])
|
|
|
|
|
|
|
|
assert.ElementsMatch(t, args, tc.ExpectedArgs,
|
|
|
|
"Args didn't match expected:\n\n expected: \n%s\n; recieved: \n%s\n", tc.ExpectedArgs, args)
|
|
|
|
assert.ElementsMatch(t, envVars, tc.ExpectedEnvVars, "EnvVars didn't match expected:\n\n expected: \n%s\n; recieved: \n%s\n", tc.ExpectedEnvVars, envVars)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-04 13:42:55 -05:00
|
|
|
func TestUseProxy(t *testing.T) {
|
|
|
|
type testcase struct {
|
|
|
|
UseProxy confighelper.Trilean
|
|
|
|
generatedData map[string]interface{}
|
|
|
|
expectedSetupAdapterCalled bool
|
|
|
|
explanation string
|
|
|
|
}
|
|
|
|
|
|
|
|
tcs := []testcase{
|
|
|
|
{
|
2020-03-28 15:16:01 -04:00
|
|
|
explanation: "use_proxy is true; we should set up adapter",
|
|
|
|
UseProxy: confighelper.TriTrue,
|
|
|
|
generatedData: basicGenData(nil),
|
2020-02-04 13:42:55 -05:00
|
|
|
expectedSetupAdapterCalled: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
explanation: "use_proxy is false but no IP addr is available; we should set up adapter anyway.",
|
|
|
|
UseProxy: confighelper.TriFalse,
|
2020-03-28 15:16:01 -04:00
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"Host": "",
|
|
|
|
"Port": nil,
|
|
|
|
}),
|
2020-02-04 13:42:55 -05:00
|
|
|
expectedSetupAdapterCalled: true,
|
|
|
|
},
|
|
|
|
{
|
2020-03-28 15:16:01 -04:00
|
|
|
explanation: "use_proxy is false; we shouldn't set up adapter.",
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
generatedData: basicGenData(nil),
|
2020-02-04 13:42:55 -05:00
|
|
|
expectedSetupAdapterCalled: false,
|
|
|
|
},
|
2020-03-27 19:44:41 -04:00
|
|
|
{
|
|
|
|
explanation: "use_proxy is false but connType isn't ssh or winrm.",
|
|
|
|
UseProxy: confighelper.TriFalse,
|
2020-03-28 15:16:01 -04:00
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "docker",
|
|
|
|
}),
|
2020-03-27 19:44:41 -04:00
|
|
|
expectedSetupAdapterCalled: true,
|
|
|
|
},
|
2020-02-04 13:42:55 -05:00
|
|
|
{
|
2020-03-28 15:16:01 -04:00
|
|
|
explanation: "use_proxy is unset; we should default to setting up the adapter (for now).",
|
|
|
|
UseProxy: confighelper.TriUnset,
|
|
|
|
generatedData: basicGenData(nil),
|
2020-02-04 13:42:55 -05:00
|
|
|
expectedSetupAdapterCalled: true,
|
|
|
|
},
|
2020-03-28 16:00:07 -04:00
|
|
|
{
|
|
|
|
explanation: "use_proxy is false and connType is winRM. we should not set up the adapter.",
|
|
|
|
UseProxy: confighelper.TriFalse,
|
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "winrm",
|
|
|
|
}),
|
|
|
|
expectedSetupAdapterCalled: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
explanation: "use_proxy is unset and connType is winRM. we should set up the adapter.",
|
|
|
|
UseProxy: confighelper.TriUnset,
|
|
|
|
generatedData: basicGenData(map[string]interface{}{
|
|
|
|
"ConnType": "winrm",
|
|
|
|
}),
|
|
|
|
expectedSetupAdapterCalled: true,
|
|
|
|
},
|
2020-02-04 13:42:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range tcs {
|
|
|
|
var p Provisioner
|
|
|
|
p.Prepare(testConfig(t))
|
|
|
|
p.config.UseProxy = tc.UseProxy
|
|
|
|
defer os.Remove(p.config.Command)
|
|
|
|
p.ansibleMajVersion = 1
|
|
|
|
|
|
|
|
var l provisionLogicTracker
|
|
|
|
l.setupAdapterCalled = false
|
|
|
|
p.setupAdapterFunc = l.setupAdapter
|
|
|
|
p.executeAnsibleFunc = l.executeAnsible
|
|
|
|
ctx := context.TODO()
|
|
|
|
comm := new(packer.MockCommunicator)
|
|
|
|
ui := &packer.BasicUi{
|
|
|
|
Reader: new(bytes.Buffer),
|
|
|
|
Writer: new(bytes.Buffer),
|
|
|
|
}
|
|
|
|
p.Provision(ctx, ui, comm, tc.generatedData)
|
|
|
|
|
|
|
|
if l.setupAdapterCalled != tc.expectedSetupAdapterCalled {
|
2020-03-28 16:00:07 -04:00
|
|
|
t.Fatalf("%s", tc.explanation)
|
2020-02-04 13:42:55 -05:00
|
|
|
}
|
|
|
|
os.Remove(p.config.Command)
|
|
|
|
}
|
|
|
|
}
|