github.com/ddnomad/packer@v1.3.2/provisioner/ansible/provisioner_test.go (about)

     1  // +build !windows
     2  
     3  package ansible
     4  
     5  import (
     6  	"bytes"
     7  	"crypto/rand"
     8  	"fmt"
     9  	"io"
    10  	"io/ioutil"
    11  	"os"
    12  	"path"
    13  	"strings"
    14  	"testing"
    15  
    16  	"github.com/hashicorp/packer/packer"
    17  )
    18  
    19  // Be sure to remove the Ansible stub file in each test with:
    20  //   defer os.Remove(config["command"].(string))
    21  func testConfig(t *testing.T) map[string]interface{} {
    22  	m := make(map[string]interface{})
    23  	wd, err := os.Getwd()
    24  	if err != nil {
    25  		t.Fatalf("err: %s", err)
    26  	}
    27  	ansible_stub := path.Join(wd, "packer-ansible-stub.sh")
    28  
    29  	err = ioutil.WriteFile(ansible_stub, []byte("#!/usr/bin/env bash\necho ansible 1.6.0"), 0777)
    30  	if err != nil {
    31  		t.Fatalf("err: %s", err)
    32  	}
    33  	m["command"] = ansible_stub
    34  
    35  	return m
    36  }
    37  
    38  func TestProvisioner_Impl(t *testing.T) {
    39  	var raw interface{}
    40  	raw = &Provisioner{}
    41  	if _, ok := raw.(packer.Provisioner); !ok {
    42  		t.Fatalf("must be a Provisioner")
    43  	}
    44  }
    45  
    46  func TestProvisionerPrepare_Defaults(t *testing.T) {
    47  	var p Provisioner
    48  	config := testConfig(t)
    49  	defer os.Remove(config["command"].(string))
    50  
    51  	err := p.Prepare(config)
    52  	if err == nil {
    53  		t.Fatalf("should have error")
    54  	}
    55  
    56  	hostkey_file, err := ioutil.TempFile("", "hostkey")
    57  	if err != nil {
    58  		t.Fatalf("err: %s", err)
    59  	}
    60  	defer os.Remove(hostkey_file.Name())
    61  
    62  	publickey_file, err := ioutil.TempFile("", "publickey")
    63  	if err != nil {
    64  		t.Fatalf("err: %s", err)
    65  	}
    66  	defer os.Remove(publickey_file.Name())
    67  
    68  	playbook_file, err := ioutil.TempFile("", "playbook")
    69  	if err != nil {
    70  		t.Fatalf("err: %s", err)
    71  	}
    72  	defer os.Remove(playbook_file.Name())
    73  
    74  	config["ssh_host_key_file"] = hostkey_file.Name()
    75  	config["ssh_authorized_key_file"] = publickey_file.Name()
    76  	config["playbook_file"] = playbook_file.Name()
    77  	err = p.Prepare(config)
    78  	if err != nil {
    79  		t.Fatalf("err: %s", err)
    80  	}
    81  	defer os.Remove(playbook_file.Name())
    82  
    83  	err = os.Unsetenv("USER")
    84  	if err != nil {
    85  		t.Fatalf("err: %s", err)
    86  	}
    87  	err = p.Prepare(config)
    88  	if err != nil {
    89  		t.Fatalf("err: %s", err)
    90  	}
    91  }
    92  
    93  func TestProvisionerPrepare_PlaybookFile(t *testing.T) {
    94  	var p Provisioner
    95  	config := testConfig(t)
    96  	defer os.Remove(config["command"].(string))
    97  
    98  	hostkey_file, err := ioutil.TempFile("", "hostkey")
    99  	if err != nil {
   100  		t.Fatalf("err: %s", err)
   101  	}
   102  	defer os.Remove(hostkey_file.Name())
   103  
   104  	publickey_file, err := ioutil.TempFile("", "publickey")
   105  	if err != nil {
   106  		t.Fatalf("err: %s", err)
   107  	}
   108  	defer os.Remove(publickey_file.Name())
   109  
   110  	config["ssh_host_key_file"] = hostkey_file.Name()
   111  	config["ssh_authorized_key_file"] = publickey_file.Name()
   112  
   113  	err = p.Prepare(config)
   114  	if err == nil {
   115  		t.Fatal("should have error")
   116  	}
   117  
   118  	playbook_file, err := ioutil.TempFile("", "playbook")
   119  	if err != nil {
   120  		t.Fatalf("err: %s", err)
   121  	}
   122  	defer os.Remove(playbook_file.Name())
   123  
   124  	config["playbook_file"] = playbook_file.Name()
   125  	err = p.Prepare(config)
   126  	if err != nil {
   127  		t.Fatalf("err: %s", err)
   128  	}
   129  }
   130  
   131  func TestProvisionerPrepare_HostKeyFile(t *testing.T) {
   132  	var p Provisioner
   133  	config := testConfig(t)
   134  	defer os.Remove(config["command"].(string))
   135  
   136  	publickey_file, err := ioutil.TempFile("", "publickey")
   137  	if err != nil {
   138  		t.Fatalf("err: %s", err)
   139  	}
   140  	defer os.Remove(publickey_file.Name())
   141  
   142  	playbook_file, err := ioutil.TempFile("", "playbook")
   143  	if err != nil {
   144  		t.Fatalf("err: %s", err)
   145  	}
   146  	defer os.Remove(playbook_file.Name())
   147  
   148  	filename := make([]byte, 10)
   149  	n, err := io.ReadFull(rand.Reader, filename)
   150  	if n != len(filename) || err != nil {
   151  		t.Fatal("could not create random file name")
   152  	}
   153  
   154  	config["ssh_host_key_file"] = fmt.Sprintf("%x", filename)
   155  	config["ssh_authorized_key_file"] = publickey_file.Name()
   156  	config["playbook_file"] = playbook_file.Name()
   157  
   158  	err = p.Prepare(config)
   159  	if err == nil {
   160  		t.Fatal("should error if ssh_host_key_file does not exist")
   161  	}
   162  
   163  	hostkey_file, err := ioutil.TempFile("", "hostkey")
   164  	if err != nil {
   165  		t.Fatalf("err: %s", err)
   166  	}
   167  	defer os.Remove(hostkey_file.Name())
   168  
   169  	config["ssh_host_key_file"] = hostkey_file.Name()
   170  	err = p.Prepare(config)
   171  	if err != nil {
   172  		t.Fatalf("err: %s", err)
   173  	}
   174  }
   175  
   176  func TestProvisionerPrepare_AuthorizedKeyFile(t *testing.T) {
   177  	var p Provisioner
   178  	config := testConfig(t)
   179  	defer os.Remove(config["command"].(string))
   180  
   181  	hostkey_file, err := ioutil.TempFile("", "hostkey")
   182  	if err != nil {
   183  		t.Fatalf("err: %s", err)
   184  	}
   185  	defer os.Remove(hostkey_file.Name())
   186  
   187  	playbook_file, err := ioutil.TempFile("", "playbook")
   188  	if err != nil {
   189  		t.Fatalf("err: %s", err)
   190  	}
   191  	defer os.Remove(playbook_file.Name())
   192  
   193  	filename := make([]byte, 10)
   194  	n, err := io.ReadFull(rand.Reader, filename)
   195  	if n != len(filename) || err != nil {
   196  		t.Fatal("could not create random file name")
   197  	}
   198  
   199  	config["ssh_host_key_file"] = hostkey_file.Name()
   200  	config["playbook_file"] = playbook_file.Name()
   201  	config["ssh_authorized_key_file"] = fmt.Sprintf("%x", filename)
   202  
   203  	err = p.Prepare(config)
   204  	if err == nil {
   205  		t.Errorf("should error if ssh_authorized_key_file does not exist")
   206  	}
   207  
   208  	publickey_file, err := ioutil.TempFile("", "publickey")
   209  	if err != nil {
   210  		t.Fatalf("err: %s", err)
   211  	}
   212  	defer os.Remove(publickey_file.Name())
   213  
   214  	config["ssh_authorized_key_file"] = publickey_file.Name()
   215  	err = p.Prepare(config)
   216  	if err != nil {
   217  		t.Errorf("err: %s", err)
   218  	}
   219  }
   220  
   221  func TestProvisionerPrepare_LocalPort(t *testing.T) {
   222  	var p Provisioner
   223  	config := testConfig(t)
   224  	defer os.Remove(config["command"].(string))
   225  
   226  	hostkey_file, err := ioutil.TempFile("", "hostkey")
   227  	if err != nil {
   228  		t.Fatalf("err: %s", err)
   229  	}
   230  	defer os.Remove(hostkey_file.Name())
   231  
   232  	publickey_file, err := ioutil.TempFile("", "publickey")
   233  	if err != nil {
   234  		t.Fatalf("err: %s", err)
   235  	}
   236  	defer os.Remove(publickey_file.Name())
   237  
   238  	playbook_file, err := ioutil.TempFile("", "playbook")
   239  	if err != nil {
   240  		t.Fatalf("err: %s", err)
   241  	}
   242  	defer os.Remove(playbook_file.Name())
   243  
   244  	config["ssh_host_key_file"] = hostkey_file.Name()
   245  	config["ssh_authorized_key_file"] = publickey_file.Name()
   246  	config["playbook_file"] = playbook_file.Name()
   247  
   248  	config["local_port"] = "65537"
   249  	err = p.Prepare(config)
   250  	if err == nil {
   251  		t.Fatal("should have error")
   252  	}
   253  
   254  	config["local_port"] = "22222"
   255  	err = p.Prepare(config)
   256  	if err != nil {
   257  		t.Fatalf("err: %s", err)
   258  	}
   259  }
   260  
   261  func TestProvisionerPrepare_InventoryDirectory(t *testing.T) {
   262  	var p Provisioner
   263  	config := testConfig(t)
   264  	defer os.Remove(config["command"].(string))
   265  
   266  	hostkey_file, err := ioutil.TempFile("", "hostkey")
   267  	if err != nil {
   268  		t.Fatalf("err: %s", err)
   269  	}
   270  	defer os.Remove(hostkey_file.Name())
   271  
   272  	publickey_file, err := ioutil.TempFile("", "publickey")
   273  	if err != nil {
   274  		t.Fatalf("err: %s", err)
   275  	}
   276  	defer os.Remove(publickey_file.Name())
   277  
   278  	playbook_file, err := ioutil.TempFile("", "playbook")
   279  	if err != nil {
   280  		t.Fatalf("err: %s", err)
   281  	}
   282  	defer os.Remove(playbook_file.Name())
   283  
   284  	config["ssh_host_key_file"] = hostkey_file.Name()
   285  	config["ssh_authorized_key_file"] = publickey_file.Name()
   286  	config["playbook_file"] = playbook_file.Name()
   287  
   288  	config["inventory_directory"] = "doesnotexist"
   289  	err = p.Prepare(config)
   290  	if err == nil {
   291  		t.Errorf("should error if inventory_directory does not exist")
   292  	}
   293  
   294  	inventoryDirectory, err := ioutil.TempDir("", "some_inventory_dir")
   295  	if err != nil {
   296  		t.Fatalf("err: %s", err)
   297  	}
   298  	defer os.Remove(inventoryDirectory)
   299  
   300  	config["inventory_directory"] = inventoryDirectory
   301  	err = p.Prepare(config)
   302  	if err != nil {
   303  		t.Fatalf("err: %s", err)
   304  	}
   305  }
   306  
   307  func TestAnsibleGetVersion(t *testing.T) {
   308  	if os.Getenv("PACKER_ACC") == "" {
   309  		t.Skip("This test is only run with PACKER_ACC=1 and it requires Ansible to be installed")
   310  	}
   311  
   312  	var p Provisioner
   313  	p.config.Command = "ansible-playbook"
   314  	err := p.getVersion()
   315  	if err != nil {
   316  		t.Fatalf("err: %s", err)
   317  	}
   318  }
   319  
   320  func TestAnsibleGetVersionError(t *testing.T) {
   321  	var p Provisioner
   322  	p.config.Command = "./test-fixtures/exit1"
   323  	err := p.getVersion()
   324  	if err == nil {
   325  		t.Fatal("Should return error")
   326  	}
   327  	if !strings.Contains(err.Error(), "./test-fixtures/exit1 --version") {
   328  		t.Fatal("Error message should include command name")
   329  	}
   330  }
   331  
   332  func TestAnsibleLongMessages(t *testing.T) {
   333  	if os.Getenv("PACKER_ACC") == "" {
   334  		t.Skip("This test is only run with PACKER_ACC=1 and it requires Ansible to be installed")
   335  	}
   336  
   337  	var p Provisioner
   338  	p.config.Command = "ansible-playbook"
   339  	p.config.PlaybookFile = "./test-fixtures/long-debug-message.yml"
   340  	err := p.Prepare()
   341  	if err != nil {
   342  		t.Fatalf("err: %s", err)
   343  	}
   344  
   345  	comm := &packer.MockCommunicator{}
   346  	ui := &packer.BasicUi{
   347  		Reader: new(bytes.Buffer),
   348  		Writer: new(bytes.Buffer),
   349  	}
   350  
   351  	err = p.Provision(ui, comm)
   352  	if err != nil {
   353  		t.Fatalf("err: %s", err)
   354  	}
   355  }