github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/provisioners/chef/resource_provisioner_test.go (about)

     1  package chef
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/communicator"
     9  	"github.com/hashicorp/terraform/config"
    10  	"github.com/hashicorp/terraform/terraform"
    11  )
    12  
    13  func TestResourceProvisioner_impl(t *testing.T) {
    14  	var _ terraform.ResourceProvisioner = new(ResourceProvisioner)
    15  }
    16  
    17  func TestResourceProvider_Validate_good(t *testing.T) {
    18  	c := testConfig(t, map[string]interface{}{
    19  		"environment": "_default",
    20  		"node_name":   "nodename1",
    21  		"run_list":    []interface{}{"cookbook::recipe"},
    22  		"server_url":  "https://chef.local",
    23  		"user_name":   "bob",
    24  		"user_key":    "USER-KEY",
    25  	})
    26  	r := new(ResourceProvisioner)
    27  	warn, errs := r.Validate(c)
    28  	if len(warn) > 0 {
    29  		t.Fatalf("Warnings: %v", warn)
    30  	}
    31  	if len(errs) > 0 {
    32  		t.Fatalf("Errors: %v", errs)
    33  	}
    34  }
    35  
    36  func TestResourceProvider_Validate_bad(t *testing.T) {
    37  	c := testConfig(t, map[string]interface{}{
    38  		"invalid": "nope",
    39  	})
    40  	p := new(ResourceProvisioner)
    41  	warn, errs := p.Validate(c)
    42  	if len(warn) > 0 {
    43  		t.Fatalf("Warnings: %v", warn)
    44  	}
    45  	if len(errs) == 0 {
    46  		t.Fatalf("Should have errors")
    47  	}
    48  }
    49  
    50  func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig {
    51  	r, err := config.NewRawConfig(c)
    52  	if err != nil {
    53  		t.Fatalf("bad: %s", err)
    54  	}
    55  
    56  	return terraform.NewResourceConfig(r)
    57  }
    58  
    59  func TestResourceProvider_runChefClient(t *testing.T) {
    60  	cases := map[string]struct {
    61  		Config   *terraform.ResourceConfig
    62  		ChefCmd  string
    63  		ConfDir  string
    64  		Commands map[string]bool
    65  	}{
    66  		"Sudo": {
    67  			Config: testConfig(t, map[string]interface{}{
    68  				"node_name":  "nodename1",
    69  				"run_list":   []interface{}{"cookbook::recipe"},
    70  				"server_url": "https://chef.local",
    71  				"user_name":  "bob",
    72  				"user_key":   "USER-KEY",
    73  			}),
    74  
    75  			ChefCmd: linuxChefCmd,
    76  
    77  			ConfDir: linuxConfDir,
    78  
    79  			Commands: map[string]bool{
    80  				fmt.Sprintf(`sudo %s -j %q -E "_default"`,
    81  					linuxChefCmd,
    82  					path.Join(linuxConfDir, "first-boot.json")): true,
    83  			},
    84  		},
    85  
    86  		"NoSudo": {
    87  			Config: testConfig(t, map[string]interface{}{
    88  				"node_name":    "nodename1",
    89  				"prevent_sudo": true,
    90  				"run_list":     []interface{}{"cookbook::recipe"},
    91  				"server_url":   "https://chef.local",
    92  				"user_name":    "bob",
    93  				"user_key":     "USER-KEY",
    94  			}),
    95  
    96  			ChefCmd: linuxChefCmd,
    97  
    98  			ConfDir: linuxConfDir,
    99  
   100  			Commands: map[string]bool{
   101  				fmt.Sprintf(`%s -j %q -E "_default"`,
   102  					linuxChefCmd,
   103  					path.Join(linuxConfDir, "first-boot.json")): true,
   104  			},
   105  		},
   106  
   107  		"Environment": {
   108  			Config: testConfig(t, map[string]interface{}{
   109  				"environment":  "production",
   110  				"node_name":    "nodename1",
   111  				"prevent_sudo": true,
   112  				"run_list":     []interface{}{"cookbook::recipe"},
   113  				"server_url":   "https://chef.local",
   114  				"user_name":    "bob",
   115  				"user_key":     "USER-KEY",
   116  			}),
   117  
   118  			ChefCmd: windowsChefCmd,
   119  
   120  			ConfDir: windowsConfDir,
   121  
   122  			Commands: map[string]bool{
   123  				fmt.Sprintf(`%s -j %q -E "production"`,
   124  					windowsChefCmd,
   125  					path.Join(windowsConfDir, "first-boot.json")): true,
   126  			},
   127  		},
   128  	}
   129  
   130  	r := new(ResourceProvisioner)
   131  	o := new(terraform.MockUIOutput)
   132  	c := new(communicator.MockCommunicator)
   133  
   134  	for k, tc := range cases {
   135  		c.Commands = tc.Commands
   136  
   137  		p, err := r.decodeConfig(tc.Config)
   138  		if err != nil {
   139  			t.Fatalf("Error: %v", err)
   140  		}
   141  
   142  		p.runChefClient = p.runChefClientFunc(tc.ChefCmd, tc.ConfDir)
   143  		p.useSudo = !p.PreventSudo
   144  
   145  		err = p.runChefClient(o, c)
   146  		if err != nil {
   147  			t.Fatalf("Test %q failed: %v", k, err)
   148  		}
   149  	}
   150  }
   151  
   152  func TestResourceProvider_fetchChefCertificates(t *testing.T) {
   153  	cases := map[string]struct {
   154  		Config   *terraform.ResourceConfig
   155  		KnifeCmd string
   156  		ConfDir  string
   157  		Commands map[string]bool
   158  	}{
   159  		"Sudo": {
   160  			Config: testConfig(t, map[string]interface{}{
   161  				"fetch_chef_certificates": true,
   162  				"node_name":               "nodename1",
   163  				"run_list":                []interface{}{"cookbook::recipe"},
   164  				"server_url":              "https://chef.local",
   165  				"user_name":               "bob",
   166  				"user_key":                "USER-KEY",
   167  			}),
   168  
   169  			KnifeCmd: linuxKnifeCmd,
   170  
   171  			ConfDir: linuxConfDir,
   172  
   173  			Commands: map[string]bool{
   174  				fmt.Sprintf(`sudo %s ssl fetch -c %s`,
   175  					linuxKnifeCmd,
   176  					path.Join(linuxConfDir, "client.rb")): true,
   177  			},
   178  		},
   179  
   180  		"NoSudo": {
   181  			Config: testConfig(t, map[string]interface{}{
   182  				"fetch_chef_certificates": true,
   183  				"node_name":               "nodename1",
   184  				"prevent_sudo":            true,
   185  				"run_list":                []interface{}{"cookbook::recipe"},
   186  				"server_url":              "https://chef.local",
   187  				"user_name":               "bob",
   188  				"user_key":                "USER-KEY",
   189  			}),
   190  
   191  			KnifeCmd: windowsKnifeCmd,
   192  
   193  			ConfDir: windowsConfDir,
   194  
   195  			Commands: map[string]bool{
   196  				fmt.Sprintf(`%s ssl fetch -c %s`,
   197  					windowsKnifeCmd,
   198  					path.Join(windowsConfDir, "client.rb")): true,
   199  			},
   200  		},
   201  	}
   202  
   203  	r := new(ResourceProvisioner)
   204  	o := new(terraform.MockUIOutput)
   205  	c := new(communicator.MockCommunicator)
   206  
   207  	for k, tc := range cases {
   208  		c.Commands = tc.Commands
   209  
   210  		p, err := r.decodeConfig(tc.Config)
   211  		if err != nil {
   212  			t.Fatalf("Error: %v", err)
   213  		}
   214  
   215  		p.fetchChefCertificates = p.fetchChefCertificatesFunc(tc.KnifeCmd, tc.ConfDir)
   216  		p.useSudo = !p.PreventSudo
   217  
   218  		err = p.fetchChefCertificates(o, c)
   219  		if err != nil {
   220  			t.Fatalf("Test %q failed: %v", k, err)
   221  		}
   222  	}
   223  }
   224  
   225  func TestResourceProvider_configureVaults(t *testing.T) {
   226  	cases := map[string]struct {
   227  		Config   *terraform.ResourceConfig
   228  		GemCmd   string
   229  		KnifeCmd string
   230  		ConfDir  string
   231  		Commands map[string]bool
   232  	}{
   233  		"Linux Vault string": {
   234  			Config: testConfig(t, map[string]interface{}{
   235  				"node_name":    "nodename1",
   236  				"prevent_sudo": true,
   237  				"run_list":     []interface{}{"cookbook::recipe"},
   238  				"server_url":   "https://chef.local",
   239  				"user_name":    "bob",
   240  				"user_key":     "USER-KEY",
   241  				"vault_json":   `{"vault1": "item1"}`,
   242  			}),
   243  
   244  			GemCmd:   linuxGemCmd,
   245  			KnifeCmd: linuxKnifeCmd,
   246  			ConfDir:  linuxConfDir,
   247  
   248  			Commands: map[string]bool{
   249  				fmt.Sprintf("%s install chef-vault", linuxGemCmd): true,
   250  				fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
   251  					"-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true,
   252  			},
   253  		},
   254  
   255  		"Linux Vault []string": {
   256  			Config: testConfig(t, map[string]interface{}{
   257  				"fetch_chef_certificates": true,
   258  				"node_name":               "nodename1",
   259  				"prevent_sudo":            true,
   260  				"run_list":                []interface{}{"cookbook::recipe"},
   261  				"server_url":              "https://chef.local",
   262  				"user_name":               "bob",
   263  				"user_key":                "USER-KEY",
   264  				"vault_json":              `{"vault1": ["item1", "item2"]}`,
   265  			}),
   266  
   267  			GemCmd:   linuxGemCmd,
   268  			KnifeCmd: linuxKnifeCmd,
   269  			ConfDir:  linuxConfDir,
   270  
   271  			Commands: map[string]bool{
   272  				fmt.Sprintf("%s install chef-vault", linuxGemCmd): true,
   273  				fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
   274  					"-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true,
   275  				fmt.Sprintf("%s vault update vault1 item2 -A nodename1 -M client -c %s/client.rb "+
   276  					"-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true,
   277  			},
   278  		},
   279  
   280  		"Windows Vault string": {
   281  			Config: testConfig(t, map[string]interface{}{
   282  				"node_name":    "nodename1",
   283  				"prevent_sudo": true,
   284  				"run_list":     []interface{}{"cookbook::recipe"},
   285  				"server_url":   "https://chef.local",
   286  				"user_name":    "bob",
   287  				"user_key":     "USER-KEY",
   288  				"vault_json":   `{"vault1": "item1"}`,
   289  			}),
   290  
   291  			GemCmd:   windowsGemCmd,
   292  			KnifeCmd: windowsKnifeCmd,
   293  			ConfDir:  windowsConfDir,
   294  
   295  			Commands: map[string]bool{
   296  				fmt.Sprintf("%s install chef-vault", windowsGemCmd): true,
   297  				fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
   298  					"-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true,
   299  			},
   300  		},
   301  
   302  		"Windows Vault []string": {
   303  			Config: testConfig(t, map[string]interface{}{
   304  				"fetch_chef_certificates": true,
   305  				"node_name":               "nodename1",
   306  				"prevent_sudo":            true,
   307  				"run_list":                []interface{}{"cookbook::recipe"},
   308  				"server_url":              "https://chef.local",
   309  				"user_name":               "bob",
   310  				"user_key":                "USER-KEY",
   311  				"vault_json":              `{"vault1": ["item1", "item2"]}`,
   312  			}),
   313  
   314  			GemCmd:   windowsGemCmd,
   315  			KnifeCmd: windowsKnifeCmd,
   316  			ConfDir:  windowsConfDir,
   317  
   318  			Commands: map[string]bool{
   319  				fmt.Sprintf("%s install chef-vault", windowsGemCmd): true,
   320  				fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
   321  					"-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true,
   322  				fmt.Sprintf("%s vault update vault1 item2 -A nodename1 -M client -c %s/client.rb "+
   323  					"-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true,
   324  			},
   325  		},
   326  	}
   327  
   328  	r := new(ResourceProvisioner)
   329  	o := new(terraform.MockUIOutput)
   330  	c := new(communicator.MockCommunicator)
   331  
   332  	for k, tc := range cases {
   333  		c.Commands = tc.Commands
   334  
   335  		p, err := r.decodeConfig(tc.Config)
   336  		if err != nil {
   337  			t.Fatalf("Error: %v", err)
   338  		}
   339  
   340  		p.configureVaults = p.configureVaultsFunc(tc.GemCmd, tc.KnifeCmd, tc.ConfDir)
   341  		p.useSudo = !p.PreventSudo
   342  
   343  		err = p.configureVaults(o, c)
   344  		if err != nil {
   345  			t.Fatalf("Test %q failed: %v", k, err)
   346  		}
   347  	}
   348  }