This fixes issue #4881 by adding an option to fetch the Chef SSL
certificates.
This commit is contained in:
Sander van Harmelen 2016-02-04 15:31:24 +01:00
parent da927fcd08
commit 79e2642dab
3 changed files with 139 additions and 38 deletions

View File

@ -29,10 +29,12 @@ const (
firstBoot = "first-boot.json"
logfileDir = "logfiles"
linuxChefCmd = "chef-client"
linuxKnifeCmd = "knife"
linuxConfDir = "/etc/chef"
secretKey = "encrypted_data_bag_secret"
validationKey = "validation.pem"
windowsChefCmd = "cmd /c chef-client"
windowsKnifeCmd = "cmd /c knife"
windowsConfDir = "C:/chef"
)
@ -78,6 +80,7 @@ type Provisioner struct {
ClientOptions []string `mapstructure:"client_options"`
DisableReporting bool `mapstructure:"disable_reporting"`
Environment string `mapstructure:"environment"`
FetchChefCertificates bool `mapstructure:"fetch_chef_certificates"`
LogToFile bool `mapstructure:"log_to_file"`
UsePolicyfile bool `mapstructure:"use_policyfile"`
PolicyGroup string `mapstructure:"policy_group"`
@ -100,6 +103,7 @@ type Provisioner struct {
installChefClient func(terraform.UIOutput, communicator.Communicator) error
createConfigFiles func(terraform.UIOutput, communicator.Communicator) error
fetchChefCertificates func(terraform.UIOutput, communicator.Communicator) error
runChefClient func(terraform.UIOutput, communicator.Communicator) error
useSudo bool
@ -138,11 +142,13 @@ func (r *ResourceProvisioner) Apply(
case "linux":
p.installChefClient = p.linuxInstallChefClient
p.createConfigFiles = p.linuxCreateConfigFiles
p.fetchChefCertificates = p.fetchChefCertificatesFunc(linuxChefCmd, linuxConfDir)
p.runChefClient = p.runChefClientFunc(linuxChefCmd, linuxConfDir)
p.useSudo = !p.PreventSudo && s.Ephemeral.ConnInfo["user"] != "root"
case "windows":
p.installChefClient = p.windowsInstallChefClient
p.createConfigFiles = p.windowsCreateConfigFiles
p.fetchChefCertificates = p.fetchChefCertificatesFunc(windowsChefCmd, windowsConfDir)
p.runChefClient = p.runChefClientFunc(windowsChefCmd, windowsConfDir)
p.useSudo = false
default:
@ -176,6 +182,13 @@ func (r *ResourceProvisioner) Apply(
return err
}
if p.FetchChefCertificates {
o.Output("Fetch Chef certificates...")
if err := p.fetchChefCertificates(o, comm); err != nil {
return err
}
}
o.Output("Starting initial Chef-Client run...")
if err := p.runChefClient(o, comm); err != nil {
return err
@ -343,6 +356,17 @@ func retryFunc(timeout time.Duration, f func() error) error {
}
}
func (p *Provisioner) fetchChefCertificatesFunc(
knifeCmd string,
confDir string) func(terraform.UIOutput, communicator.Communicator) error {
return func(o terraform.UIOutput, comm communicator.Communicator) error {
clientrb := path.Join(confDir, clienrb)
cmd := fmt.Sprintf("%s ssl fetch -c %s", knifeCmd, clientrb)
return p.runCommand(o, comm, cmd)
}
}
func (p *Provisioner) runChefClientFunc(
chefCmd string,
confDir string) func(terraform.UIOutput, communicator.Communicator) error {

View File

@ -148,3 +148,76 @@ func TestResourceProvider_runChefClient(t *testing.T) {
}
}
}
func TestResourceProvider_fetchChefCertificates(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
KnifeCmd string
ConfDir string
Commands map[string]bool
}{
"Sudo": {
Config: testConfig(t, map[string]interface{}{
"fetch_chef_certificates": true,
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"validation_client_name": "validator",
"validation_key_path": "test-fixtures/validator.pem",
}),
KnifeCmd: linuxKnifeCmd,
ConfDir: linuxConfDir,
Commands: map[string]bool{
fmt.Sprintf(`sudo %s ssl fetch -c %s`,
linuxKnifeCmd,
path.Join(linuxConfDir, "client.rb")): true,
},
},
"NoSudo": {
Config: testConfig(t, map[string]interface{}{
"fetch_chef_certificates": true,
"node_name": "nodename1",
"prevent_sudo": true,
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"validation_client_name": "validator",
"validation_key_path": "test-fixtures/validator.pem",
}),
KnifeCmd: windowsKnifeCmd,
ConfDir: windowsConfDir,
Commands: map[string]bool{
fmt.Sprintf(`%s ssl fetch -c %s`,
windowsKnifeCmd,
path.Join(windowsConfDir, "client.rb")): true,
},
},
}
r := new(ResourceProvisioner)
o := new(terraform.MockUIOutput)
c := new(communicator.MockCommunicator)
for k, tc := range cases {
c.Commands = tc.Commands
p, err := r.decodeConfig(tc.Config)
if err != nil {
t.Fatalf("Error: %v", err)
}
p.fetchChefCertificates = p.fetchChefCertificatesFunc(tc.KnifeCmd, tc.ConfDir)
p.useSudo = !p.PreventSudo
err = p.fetchChefCertificates(o, c)
if err != nil {
t.Fatalf("Test %q failed: %v", k, err)
}
}
}

View File

@ -59,7 +59,7 @@ The following arguments are supported:
interpolation function](/docs/configuration/interpolation.html#file_path_).
* `client_options (array)` - (Optional) A list of optional Chef Client configuration
options. See the Chef Client [documentation](https://docs.chef.io/config_rb_client.html) for all available options.
options. See the [Chef Client ](https://docs.chef.io/config_rb_client.html) documentation for all available options.
* `disable_reporting (boolean)` - (Optional) If true the Chef Client will not try to send
reporting data (used by Chef Reporting) to the Chef Server (defaults false)
@ -67,6 +67,10 @@ The following arguments are supported:
* `environment (string)` - (Optional) The Chef environment the new node will be joining
(defaults `_default`).
* `fetch_chef_certificates (boolean)` (Optional) If true the SSL certificates configured
on your Chef server will be fetched and trusted. See the knife [ssl_fetch](https://docs.chef.io/knife_ssl_fetch.html)
documentation for more details.
* `log_to_file (boolean)` - (Optional) If true, the output of the initial Chef Client run
will be logged to a local file instead of the console. The file will be created in a
subdirectory called `logfiles` created in your current directory. The filename will be