Skip to content

Commit c19d92f

Browse files
author
Sander van Harmelen
committed
Refactored quite a few things after review...
Also renamed the provisioner to just `chef` as it’s out intention to end up with one provisioner for all types of `chef` clients.
1 parent d4150d5 commit c19d92f

11 files changed

Lines changed: 90 additions & 63 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package main
22

33
import (
4-
"github.com/hashicorp/terraform/builtin/provisioners/chef-client"
4+
"github.com/hashicorp/terraform/builtin/provisioners/chef"
55
"github.com/hashicorp/terraform/plugin"
66
"github.com/hashicorp/terraform/terraform"
77
)
88

99
func main() {
1010
plugin.Serve(&plugin.ServeOpts{
1111
ProvisionerFunc: func() terraform.ResourceProvisioner {
12-
return new(chefclient.ResourceProvisioner)
12+
return new(chef.ResourceProvisioner)
1313
},
1414
})
1515
}
File renamed without changes.

builtin/provisioners/chef-client/resource_provisioner.go renamed to builtin/provisioners/chef/resource_provisioner.go

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package chefclient
1+
package chef
22

33
import (
44
"bytes"
@@ -22,9 +22,12 @@ import (
2222
)
2323

2424
const (
25+
clienrb = "client.rb"
26+
defaultChefEnv = "_default"
2527
firstBoot = "first-boot.json"
2628
logfileDir = "logfiles"
2729
linuxConfDir = "/etc/chef"
30+
validationKey = "validation.pem"
2831
windowsConfDir = "C:/chef"
2932
)
3033

@@ -52,7 +55,7 @@ ENV['HTTPS_PROXY'] = "{{ .HTTPSProxy }}"
5255

5356
// Provisioner represents a specificly configured chef provisioner
5457
type Provisioner struct {
55-
Attributes interface{} `mapstructure:"-"`
58+
Attributes interface{} `mapstructure:"attributes"`
5659
Environment string `mapstructure:"environment"`
5760
LogToFile bool `mapstructure:"log_to_file"`
5861
HTTPProxy string `mapstructure:"http_proxy"`
@@ -169,6 +172,7 @@ func (r *ResourceProvisioner) decodeConfig(c *terraform.ResourceConfig) (*Provis
169172
p := new(Provisioner)
170173

171174
decConf := &mapstructure.DecoderConfig{
175+
ErrorUnused: true,
172176
WeaklyTypedInput: true,
173177
Result: p,
174178
}
@@ -182,7 +186,7 @@ func (r *ResourceProvisioner) decodeConfig(c *terraform.ResourceConfig) (*Provis
182186
}
183187

184188
if p.Environment == "" {
185-
p.Environment = "_default"
189+
p.Environment = defaultChefEnv
186190
}
187191

188192
if attrs, ok := c.Raw["attributes"]; ok {
@@ -241,7 +245,7 @@ func (p *Provisioner) runChefClientFunc(
241245
cmd := fmt.Sprintf("chef-client -j %q -E %q", fb, p.Environment)
242246

243247
if p.LogToFile {
244-
if err := os.MkdirAll(logfileDir, 0777); err != nil {
248+
if err := os.MkdirAll(logfileDir, 0755); err != nil {
245249
return fmt.Errorf("Error creating logfile directory %s: %v", logfileDir, err)
246250
}
247251

@@ -290,35 +294,35 @@ func (p *Provisioner) deployConfigFiles(
290294
o terraform.UIOutput,
291295
comm communicator.Communicator,
292296
confDir string) error {
293-
// Open the validation .pem file
297+
// Open the validation key file
294298
f, err := os.Open(p.ValidationKeyPath)
295299
if err != nil {
296300
return err
297301
}
298302
defer f.Close()
299303

300-
// Copy the validation .pem to the new instance
301-
if err := comm.Upload(path.Join(confDir, "validation.pem"), f); err != nil {
302-
return fmt.Errorf("Uploading validation.pem failed: %v", err)
304+
// Copy the validation key to the new instance
305+
if err := comm.Upload(path.Join(confDir, validationKey), f); err != nil {
306+
return fmt.Errorf("Uploading %s failed: %v", validationKey, err)
303307
}
304308

305309
// Make strings.Join available for use within the template
306310
funcMap := template.FuncMap{
307311
"join": strings.Join,
308312
}
309313

310-
// Create a new template and parse the client.rb into it
311-
t := template.Must(template.New("client.rb").Funcs(funcMap).Parse(clientConf))
314+
// Create a new template and parse the client config into it
315+
t := template.Must(template.New(clienrb).Funcs(funcMap).Parse(clientConf))
312316

313317
var buf bytes.Buffer
314318
err = t.Execute(&buf, p)
315319
if err != nil {
316-
return fmt.Errorf("Error executing client.rb template: %s", err)
320+
return fmt.Errorf("Error executing %s template: %s", clienrb, err)
317321
}
318322

319-
// Copy the client.rb to the new instance
320-
if err := comm.Upload(path.Join(confDir, "client.rb"), &buf); err != nil {
321-
return fmt.Errorf("Uploading client.rb failed: %v", err)
323+
// Copy the client config to the new instance
324+
if err := comm.Upload(path.Join(confDir, clienrb), &buf); err != nil {
325+
return fmt.Errorf("Uploading %s failed: %v", clienrb, err)
322326
}
323327

324328
// Create a map with first boot settings
@@ -327,6 +331,13 @@ func (p *Provisioner) deployConfigFiles(
327331
fb = p.Attributes.(map[string]interface{})
328332
}
329333

334+
// Check if the run_list was also in the attributes and if so log a warning
335+
// that it will be overwritten with the value of the run_list argument.
336+
if _, found := fb["run_list"]; found {
337+
log.Printf("[WARNING] Found a 'run_list' specified in the configured attributes! " +
338+
"This value will be overwritten by the value of the `run_list` argument!")
339+
}
340+
330341
// Add the initial runlist to the first boot settings
331342
fb["run_list"] = p.RunList
332343

@@ -338,7 +349,7 @@ func (p *Provisioner) deployConfigFiles(
338349

339350
// Copy the first-boot.json to the new instance
340351
if err := comm.Upload(path.Join(confDir, firstBoot), bytes.NewReader(d)); err != nil {
341-
return fmt.Errorf("Uploading first-boot.json failed: %v", err)
352+
return fmt.Errorf("Uploading %s failed: %v", firstBoot, err)
342353
}
343354

344355
return nil
@@ -369,6 +380,7 @@ func (p *Provisioner) runCommand(
369380
Stderr: errW,
370381
}
371382

383+
log.Printf("[DEBUG] Executing remote command: %q", cmd.Command)
372384
if err := comm.Start(cmd); err != nil {
373385
return fmt.Errorf("Error executing command %q: %v", cmd.Command, err)
374386
}

builtin/provisioners/chef-client/resource_provisioner_test.go renamed to builtin/provisioners/chef/resource_provisioner_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package chefclient
1+
package chef
22

33
import (
44
"testing"

builtin/provisioners/chef-client/ssh_provisioner.go renamed to builtin/provisioners/chef/ssh_provisioner.go

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,44 @@
1-
package chefclient
1+
package chef
22

33
import (
4-
"bytes"
4+
"fmt"
55
"strings"
66

77
"github.com/hashicorp/terraform/communicator"
88
"github.com/hashicorp/terraform/terraform"
99
)
1010

11+
const (
12+
installURL = "https://www.chef.io/chef/install.sh"
13+
)
14+
1115
func (p *Provisioner) sshInstallChefClient(
1216
o terraform.UIOutput,
1317
comm communicator.Communicator) error {
14-
var installCmd bytes.Buffer
1518

16-
// Build up a single command based on the given config options
17-
installCmd.WriteString("curl")
19+
// Build up the command prefix
20+
prefix := ""
1821
if p.HTTPProxy != "" {
19-
installCmd.WriteString(" --proxy " + p.HTTPProxy)
22+
prefix += fmt.Sprintf("proxy_http='%s' ", p.HTTPProxy)
2023
}
2124
if p.NOProxy != nil {
22-
installCmd.WriteString(" --noproxy " + strings.Join(p.NOProxy, ","))
25+
prefix += fmt.Sprintf("no_proxy='%s' ", strings.Join(p.NOProxy, ","))
2326
}
24-
installCmd.WriteString(" -LO https://www.chef.io/chef/install.sh 2>/dev/null &&")
25-
if !p.PreventSudo {
26-
installCmd.WriteString(" sudo")
27-
}
28-
installCmd.WriteString(" bash ./install.sh")
29-
if p.Version != "" {
30-
installCmd.WriteString(" -v " + p.Version)
27+
28+
// First download the install.sh script from Chef
29+
err := p.runCommand(o, comm, fmt.Sprintf("%scurl -LO %s", prefix, installURL))
30+
if err != nil {
31+
return err
3132
}
32-
installCmd.WriteString(" &&")
33-
if !p.PreventSudo {
34-
installCmd.WriteString(" sudo")
33+
34+
// Then execute the install.sh scrip to download and install Chef Client
35+
err = p.runCommand(o, comm, fmt.Sprintf("%sbash ./install.sh -v %s", prefix, p.Version))
36+
if err != nil {
37+
return err
3538
}
36-
installCmd.WriteString(" rm -f install.sh")
3739

38-
// Execute the command to install Chef Client
39-
return p.runCommand(o, comm, installCmd.String())
40+
// And finally cleanup the install.sh script again
41+
return p.runCommand(o, comm, fmt.Sprintf("%srm -f install.sh", prefix))
4042
}
4143

4244
func (p *Provisioner) sshCreateConfigFiles(

builtin/provisioners/chef-client/ssh_provisioner_test.go renamed to builtin/provisioners/chef/ssh_provisioner_test.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package chefclient
1+
package chef
22

33
import (
44
"testing"
@@ -22,8 +22,9 @@ func TestResourceProvider_sshInstallChefClient(t *testing.T) {
2222
}),
2323

2424
Commands: map[string]bool{
25-
"sudo curl -LO https://www.chef.io/chef/install.sh 2>/dev/null && " +
26-
"sudo bash ./install.sh && sudo rm -f install.sh": true,
25+
"sudo curl -LO https://www.chef.io/chef/install.sh": true,
26+
"sudo bash ./install.sh -v ": true,
27+
"sudo rm -f install.sh": true,
2728
},
2829
},
2930

@@ -38,8 +39,9 @@ func TestResourceProvider_sshInstallChefClient(t *testing.T) {
3839
}),
3940

4041
Commands: map[string]bool{
41-
"curl -LO https://www.chef.io/chef/install.sh 2>/dev/null && " +
42-
"bash ./install.sh && rm -f install.sh": true,
42+
"curl -LO https://www.chef.io/chef/install.sh": true,
43+
"bash ./install.sh -v ": true,
44+
"rm -f install.sh": true,
4345
},
4446
},
4547

@@ -55,8 +57,9 @@ func TestResourceProvider_sshInstallChefClient(t *testing.T) {
5557
}),
5658

5759
Commands: map[string]bool{
58-
"curl --proxy http://proxy.local -LO https://www.chef.io/chef/install.sh 2>/dev/null && " +
59-
"bash ./install.sh && rm -f install.sh": true,
60+
"proxy_http='http://proxy.local' curl -LO https://www.chef.io/chef/install.sh": true,
61+
"proxy_http='http://proxy.local' bash ./install.sh -v ": true,
62+
"proxy_http='http://proxy.local' rm -f install.sh": true,
6063
},
6164
},
6265

@@ -73,8 +76,11 @@ func TestResourceProvider_sshInstallChefClient(t *testing.T) {
7376
}),
7477

7578
Commands: map[string]bool{
76-
"curl --proxy http://proxy.local --noproxy http://local.local,http://local.org -LO " +
77-
"https://www.chef.io/chef/install.sh 2>/dev/null && bash ./install.sh && " +
79+
"proxy_http='http://proxy.local' no_proxy='http://local.local,http://local.org' " +
80+
"curl -LO https://www.chef.io/chef/install.sh": true,
81+
"proxy_http='http://proxy.local' no_proxy='http://local.local,http://local.org' " +
82+
"bash ./install.sh -v ": true,
83+
"proxy_http='http://proxy.local' no_proxy='http://local.local,http://local.org' " +
7884
"rm -f install.sh": true,
7985
},
8086
},
@@ -91,8 +97,9 @@ func TestResourceProvider_sshInstallChefClient(t *testing.T) {
9197
}),
9298

9399
Commands: map[string]bool{
94-
"curl -LO https://www.chef.io/chef/install.sh 2>/dev/null && " +
95-
"bash ./install.sh -v 11.18.6 && rm -f install.sh": true,
100+
"curl -LO https://www.chef.io/chef/install.sh": true,
101+
"bash ./install.sh -v 11.18.6": true,
102+
"rm -f install.sh": true,
96103
},
97104
},
98105
}

builtin/provisioners/chef-client/test-fixtures/validator.pem renamed to builtin/provisioners/chef/test-fixtures/validator.pem

File renamed without changes.

builtin/provisioners/chef-client/winrm_provisioner.go renamed to builtin/provisioners/chef/winrm_provisioner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package chefclient
1+
package chef
22

33
import (
44
"fmt"

builtin/provisioners/chef-client/winrm_provisioner_test.go renamed to builtin/provisioners/chef/winrm_provisioner_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package chefclient
1+
package chef
22

33
import (
44
"fmt"

website/source/docs/provisioners/chef-client.html.markdown renamed to website/source/docs/provisioners/chef.html.markdown

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
---
22
layout: "docs"
3-
page_title: "Provisioner: chef-client"
4-
sidebar_current: "docs-provisioners-chef-client"
3+
page_title: "Provisioner: chef"
4+
sidebar_current: "docs-provisioners-chef"
55
description: |-
6-
The `chef-client` provisioner invokes a Chef Client run on a remote resource after first installing and configuring Chef Client on the remote resource. The `chef-client` provisioner supports both `ssh` and `winrm` type connections.
6+
The `chef` provisioner invokes a Chef Client run on a remote resource after first installing and configuring Chef Client on the remote resource. The `chef` provisioner supports both `ssh` and `winrm` type connections.
77
---
88

9-
# chef Provisioner
9+
# Chef Provisioner
1010

11-
The `chef-client` provisioner invokes a Chef Client run on a remote resource after first
12-
installing and configuring Chef Client on the remote resource. The `chef-client` provisioner
13-
supports both `ssh` and `winrm` type [connections](/docs/provisioners/connection.html).
11+
The `chef` provisioner invokes a Chef Client run on a remote resource after first installing
12+
and configuring Chef Client on the remote resource. The `chef` provisioner supports both `ssh`
13+
and `winrm` type [connections](/docs/provisioners/connection.html).
14+
15+
## Requirements
16+
17+
In order for the `chef` provisioner to work properly, you need either `cURL` (when using
18+
a `ssh` type connection) or `PowerShell 2.0` (when using a `winrm` type connection) to be
19+
available on the target machine.
1420

1521
## Example usage
1622

1723
```
1824
# Start a initial chef run on a resource
1925
resource "aws_instance" "web" {
2026
...
21-
provisioner "chef-client" {
27+
provisioner "chef" {
2228
attributes {
2329
"key" = "value"
2430
"app" {
@@ -73,7 +79,7 @@ The following arguments are supported:
7379
the organization. See the example.
7480

7581
* `skip_install (boolean)` - (Optional) Skip the installation of Chef Client on the remote
76-
machine. This assumes Chef Client is already installed when you run the `chef-client`
82+
machine. This assumes Chef Client is already installed when you run the `chef`
7783
provisioner.
7884

7985
* `ssl_verify_mode (string)` - (Optional) Use to set the verify mode for Chef Client HTTPS

0 commit comments

Comments
 (0)