github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 // Test that the JSON attributes with an unknown value don't 51 // validate. 52 func TestResourceProvider_Validate_computedValues(t *testing.T) { 53 c := testConfig(t, map[string]interface{}{ 54 "environment": "_default", 55 "node_name": "nodename1", 56 "run_list": []interface{}{"cookbook::recipe"}, 57 "server_url": "https://chef.local", 58 "user_name": "bob", 59 "user_key": "USER-KEY", 60 "attributes_json": config.UnknownVariableValue, 61 }) 62 r := new(ResourceProvisioner) 63 warn, errs := r.Validate(c) 64 if len(warn) > 0 { 65 t.Fatalf("Warnings: %v", warn) 66 } 67 if len(errs) > 0 { 68 t.Fatalf("Errors: %v", errs) 69 } 70 } 71 72 func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig { 73 r, err := config.NewRawConfig(c) 74 if err != nil { 75 t.Fatalf("bad: %s", err) 76 } 77 78 return terraform.NewResourceConfig(r) 79 } 80 81 func TestResourceProvider_runChefClient(t *testing.T) { 82 cases := map[string]struct { 83 Config *terraform.ResourceConfig 84 ChefCmd string 85 ConfDir string 86 Commands map[string]bool 87 }{ 88 "Sudo": { 89 Config: testConfig(t, map[string]interface{}{ 90 "node_name": "nodename1", 91 "run_list": []interface{}{"cookbook::recipe"}, 92 "server_url": "https://chef.local", 93 "user_name": "bob", 94 "user_key": "USER-KEY", 95 }), 96 97 ChefCmd: linuxChefCmd, 98 99 ConfDir: linuxConfDir, 100 101 Commands: map[string]bool{ 102 fmt.Sprintf(`sudo %s -j %q -E "_default"`, 103 linuxChefCmd, 104 path.Join(linuxConfDir, "first-boot.json")): true, 105 }, 106 }, 107 108 "NoSudo": { 109 Config: testConfig(t, map[string]interface{}{ 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: linuxChefCmd, 119 120 ConfDir: linuxConfDir, 121 122 Commands: map[string]bool{ 123 fmt.Sprintf(`%s -j %q -E "_default"`, 124 linuxChefCmd, 125 path.Join(linuxConfDir, "first-boot.json")): true, 126 }, 127 }, 128 129 "Environment": { 130 Config: testConfig(t, map[string]interface{}{ 131 "environment": "production", 132 "node_name": "nodename1", 133 "prevent_sudo": true, 134 "run_list": []interface{}{"cookbook::recipe"}, 135 "server_url": "https://chef.local", 136 "user_name": "bob", 137 "user_key": "USER-KEY", 138 }), 139 140 ChefCmd: windowsChefCmd, 141 142 ConfDir: windowsConfDir, 143 144 Commands: map[string]bool{ 145 fmt.Sprintf(`%s -j %q -E "production"`, 146 windowsChefCmd, 147 path.Join(windowsConfDir, "first-boot.json")): true, 148 }, 149 }, 150 } 151 152 r := new(ResourceProvisioner) 153 o := new(terraform.MockUIOutput) 154 c := new(communicator.MockCommunicator) 155 156 for k, tc := range cases { 157 c.Commands = tc.Commands 158 159 p, err := r.decodeConfig(tc.Config) 160 if err != nil { 161 t.Fatalf("Error: %v", err) 162 } 163 164 p.runChefClient = p.runChefClientFunc(tc.ChefCmd, tc.ConfDir) 165 p.useSudo = !p.PreventSudo 166 167 err = p.runChefClient(o, c) 168 if err != nil { 169 t.Fatalf("Test %q failed: %v", k, err) 170 } 171 } 172 } 173 174 func TestResourceProvider_fetchChefCertificates(t *testing.T) { 175 cases := map[string]struct { 176 Config *terraform.ResourceConfig 177 KnifeCmd string 178 ConfDir string 179 Commands map[string]bool 180 }{ 181 "Sudo": { 182 Config: testConfig(t, map[string]interface{}{ 183 "fetch_chef_certificates": true, 184 "node_name": "nodename1", 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: linuxKnifeCmd, 192 193 ConfDir: linuxConfDir, 194 195 Commands: map[string]bool{ 196 fmt.Sprintf(`sudo %s ssl fetch -c %s`, 197 linuxKnifeCmd, 198 path.Join(linuxConfDir, "client.rb")): true, 199 }, 200 }, 201 202 "NoSudo": { 203 Config: testConfig(t, map[string]interface{}{ 204 "fetch_chef_certificates": true, 205 "node_name": "nodename1", 206 "prevent_sudo": true, 207 "run_list": []interface{}{"cookbook::recipe"}, 208 "server_url": "https://chef.local", 209 "user_name": "bob", 210 "user_key": "USER-KEY", 211 }), 212 213 KnifeCmd: windowsKnifeCmd, 214 215 ConfDir: windowsConfDir, 216 217 Commands: map[string]bool{ 218 fmt.Sprintf(`%s ssl fetch -c %s`, 219 windowsKnifeCmd, 220 path.Join(windowsConfDir, "client.rb")): true, 221 }, 222 }, 223 } 224 225 r := new(ResourceProvisioner) 226 o := new(terraform.MockUIOutput) 227 c := new(communicator.MockCommunicator) 228 229 for k, tc := range cases { 230 c.Commands = tc.Commands 231 232 p, err := r.decodeConfig(tc.Config) 233 if err != nil { 234 t.Fatalf("Error: %v", err) 235 } 236 237 p.fetchChefCertificates = p.fetchChefCertificatesFunc(tc.KnifeCmd, tc.ConfDir) 238 p.useSudo = !p.PreventSudo 239 240 err = p.fetchChefCertificates(o, c) 241 if err != nil { 242 t.Fatalf("Test %q failed: %v", k, err) 243 } 244 } 245 } 246 247 func TestResourceProvider_configureVaults(t *testing.T) { 248 cases := map[string]struct { 249 Config *terraform.ResourceConfig 250 GemCmd string 251 KnifeCmd string 252 ConfDir string 253 Commands map[string]bool 254 }{ 255 "Linux Vault string": { 256 Config: testConfig(t, map[string]interface{}{ 257 "node_name": "nodename1", 258 "prevent_sudo": true, 259 "run_list": []interface{}{"cookbook::recipe"}, 260 "server_url": "https://chef.local", 261 "user_name": "bob", 262 "user_key": "USER-KEY", 263 "vault_json": `{"vault1": "item1"}`, 264 }), 265 266 GemCmd: linuxGemCmd, 267 KnifeCmd: linuxKnifeCmd, 268 ConfDir: linuxConfDir, 269 270 Commands: map[string]bool{ 271 fmt.Sprintf("%s install chef-vault", linuxGemCmd): true, 272 fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+ 273 "-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true, 274 }, 275 }, 276 277 "Linux Vault []string": { 278 Config: testConfig(t, map[string]interface{}{ 279 "fetch_chef_certificates": true, 280 "node_name": "nodename1", 281 "prevent_sudo": true, 282 "run_list": []interface{}{"cookbook::recipe"}, 283 "server_url": "https://chef.local", 284 "user_name": "bob", 285 "user_key": "USER-KEY", 286 "vault_json": `{"vault1": ["item1", "item2"]}`, 287 }), 288 289 GemCmd: linuxGemCmd, 290 KnifeCmd: linuxKnifeCmd, 291 ConfDir: linuxConfDir, 292 293 Commands: map[string]bool{ 294 fmt.Sprintf("%s install chef-vault", linuxGemCmd): true, 295 fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+ 296 "-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true, 297 fmt.Sprintf("%s vault update vault1 item2 -A nodename1 -M client -c %s/client.rb "+ 298 "-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true, 299 }, 300 }, 301 302 "Windows Vault string": { 303 Config: testConfig(t, map[string]interface{}{ 304 "node_name": "nodename1", 305 "prevent_sudo": true, 306 "run_list": []interface{}{"cookbook::recipe"}, 307 "server_url": "https://chef.local", 308 "user_name": "bob", 309 "user_key": "USER-KEY", 310 "vault_json": `{"vault1": "item1"}`, 311 }), 312 313 GemCmd: windowsGemCmd, 314 KnifeCmd: windowsKnifeCmd, 315 ConfDir: windowsConfDir, 316 317 Commands: map[string]bool{ 318 fmt.Sprintf("%s install chef-vault", windowsGemCmd): true, 319 fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+ 320 "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, 321 }, 322 }, 323 324 "Windows Vault []string": { 325 Config: testConfig(t, map[string]interface{}{ 326 "fetch_chef_certificates": true, 327 "node_name": "nodename1", 328 "prevent_sudo": true, 329 "run_list": []interface{}{"cookbook::recipe"}, 330 "server_url": "https://chef.local", 331 "user_name": "bob", 332 "user_key": "USER-KEY", 333 "vault_json": `{"vault1": ["item1", "item2"]}`, 334 }), 335 336 GemCmd: windowsGemCmd, 337 KnifeCmd: windowsKnifeCmd, 338 ConfDir: windowsConfDir, 339 340 Commands: map[string]bool{ 341 fmt.Sprintf("%s install chef-vault", windowsGemCmd): true, 342 fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+ 343 "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, 344 fmt.Sprintf("%s vault update vault1 item2 -A nodename1 -M client -c %s/client.rb "+ 345 "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, 346 }, 347 }, 348 } 349 350 r := new(ResourceProvisioner) 351 o := new(terraform.MockUIOutput) 352 c := new(communicator.MockCommunicator) 353 354 for k, tc := range cases { 355 c.Commands = tc.Commands 356 357 p, err := r.decodeConfig(tc.Config) 358 if err != nil { 359 t.Fatalf("Error: %v", err) 360 } 361 362 p.configureVaults = p.configureVaultsFunc(tc.GemCmd, tc.KnifeCmd, tc.ConfDir) 363 p.useSudo = !p.PreventSudo 364 365 err = p.configureVaults(o, c) 366 if err != nil { 367 t.Fatalf("Test %q failed: %v", k, err) 368 } 369 } 370 }