Merge pull request #7653 from aaronwalker/chef_license_acceptance

adds support for accepting the chef license
This commit is contained in:
Megan Marsh 2019-05-24 11:12:09 -07:00 committed by GitHub
commit 6f560bef0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 145 additions and 2 deletions

View File

@ -50,6 +50,7 @@ type Config struct {
Json map[string]interface{} Json map[string]interface{}
ChefEnvironment string `mapstructure:"chef_environment"` ChefEnvironment string `mapstructure:"chef_environment"`
ChefLicense string `mapstructure:"chef_license"`
ClientKey string `mapstructure:"client_key"` ClientKey string `mapstructure:"client_key"`
ConfigTemplate string `mapstructure:"config_template"` ConfigTemplate string `mapstructure:"config_template"`
ElevatedUser string `mapstructure:"elevated_user"` ElevatedUser string `mapstructure:"elevated_user"`
@ -87,6 +88,7 @@ type Provisioner struct {
type ConfigTemplate struct { type ConfigTemplate struct {
ChefEnvironment string ChefEnvironment string
ChefLicense string
ClientKey string ClientKey string
EncryptedDataBagSecretPath string EncryptedDataBagSecretPath string
NodeName string NodeName string
@ -194,6 +196,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
errs, fmt.Errorf("server_url must be set")) errs, fmt.Errorf("server_url must be set"))
} }
if p.config.SkipInstall == false && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
if p.config.ChefLicense == "" {
p.config.ChefLicense = "accept-silent"
}
}
if p.config.EncryptedDataBagSecretPath != "" { if p.config.EncryptedDataBagSecretPath != "" {
pFileInfo, err := os.Stat(p.config.EncryptedDataBagSecretPath) pFileInfo, err := os.Stat(p.config.EncryptedDataBagSecretPath)
@ -283,6 +291,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
nodeName, nodeName,
serverUrl, serverUrl,
p.config.ClientKey, p.config.ClientKey,
p.config.ChefLicense,
encryptedDataBagSecretPath, encryptedDataBagSecretPath,
remoteValidationKeyPath, remoteValidationKeyPath,
p.config.ValidationClientName, p.config.ValidationClientName,
@ -355,6 +364,7 @@ func (p *Provisioner) createConfig(
nodeName string, nodeName string,
serverUrl string, serverUrl string,
clientKey string, clientKey string,
chefLicense string,
encryptedDataBagSecretPath, encryptedDataBagSecretPath,
remoteKeyPath string, remoteKeyPath string,
validationClientName string, validationClientName string,
@ -388,6 +398,7 @@ func (p *Provisioner) createConfig(
NodeName: nodeName, NodeName: nodeName,
ServerUrl: serverUrl, ServerUrl: serverUrl,
ClientKey: clientKey, ClientKey: clientKey,
ChefLicense: chefLicense,
ValidationKeyPath: remoteKeyPath, ValidationKeyPath: remoteKeyPath,
ValidationClientName: validationClientName, ValidationClientName: validationClientName,
ChefEnvironment: chefEnvironment, ChefEnvironment: chefEnvironment,
@ -730,6 +741,7 @@ log_level :info
log_location STDOUT log_location STDOUT
chef_server_url "{{.ServerUrl}}" chef_server_url "{{.ServerUrl}}"
client_key "{{.ClientKey}}" client_key "{{.ClientKey}}"
chef_license "{{.ChefLicense}}"
{{if ne .EncryptedDataBagSecretPath ""}} {{if ne .EncryptedDataBagSecretPath ""}}
encrypted_data_bag_secret "{{.EncryptedDataBagSecretPath}}" encrypted_data_bag_secret "{{.EncryptedDataBagSecretPath}}"
{{end}} {{end}}

View File

@ -138,6 +138,59 @@ func TestProvisionerPrepare_serverUrl(t *testing.T) {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
} }
func TestProvisionerPrepare_chefLicense(t *testing.T) {
var p Provisioner
// Test not set
config := testConfig()
err := p.Prepare(config)
if err != nil {
t.Fatal("should error")
}
if p.config.ChefLicense != "accept-silent" {
t.Fatalf("unexpected: %#v", p.config.ChefLicense)
}
// Test set
config = testConfig()
config["chef_license"] = "accept"
p = Provisioner{}
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ChefLicense != "accept" {
t.Fatalf("unexpected: %#v", p.config.ChefLicense)
}
// Test set skipInstall true
config = testConfig()
config["skip_install"] = true
p = Provisioner{}
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ChefLicense != "" {
t.Fatalf("unexpected: %#v", "empty string")
}
// Test set installCommand true
config = testConfig()
config["install_command"] = "install chef"
p = Provisioner{}
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ChefLicense != "" {
t.Fatalf("unexpected: %#v", "empty string")
}
}
func TestProvisionerPrepare_encryptedDataBagSecretPath(t *testing.T) { func TestProvisionerPrepare_encryptedDataBagSecretPath(t *testing.T) {
var err error var err error

View File

@ -43,6 +43,7 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
ChefEnvironment string `mapstructure:"chef_environment"` ChefEnvironment string `mapstructure:"chef_environment"`
ChefLicense string `mapstructure:"chef_license"`
ConfigTemplate string `mapstructure:"config_template"` ConfigTemplate string `mapstructure:"config_template"`
CookbookPaths []string `mapstructure:"cookbook_paths"` CookbookPaths []string `mapstructure:"cookbook_paths"`
RolesPath string `mapstructure:"roles_path"` RolesPath string `mapstructure:"roles_path"`
@ -76,6 +77,7 @@ type ConfigTemplate struct {
RolesPath string RolesPath string
EnvironmentsPath string EnvironmentsPath string
ChefEnvironment string ChefEnvironment string
ChefLicense string
// Templates don't support boolean statements until Go 1.2. In the // Templates don't support boolean statements until Go 1.2. In the
// mean time, we do this. // mean time, we do this.
@ -144,6 +146,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.StagingDir = p.guestOSTypeConfig.stagingDir p.config.StagingDir = p.guestOSTypeConfig.stagingDir
} }
if p.config.SkipInstall == false && p.config.InstallCommand == p.guestOSTypeConfig.installCommand {
if p.config.ChefLicense == "" {
p.config.ChefLicense = "accept-silent"
}
}
var errs *packer.MultiError var errs *packer.MultiError
if p.config.ConfigTemplate != "" { if p.config.ConfigTemplate != "" {
fi, err := os.Stat(p.config.ConfigTemplate) fi, err := os.Stat(p.config.ConfigTemplate)
@ -283,7 +291,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
} }
} }
configPath, err := p.createConfig(ui, comm, cookbookPaths, rolesPath, dataBagsPath, encryptedDataBagSecretPath, environmentsPath, p.config.ChefEnvironment) configPath, err := p.createConfig(ui, comm, cookbookPaths, rolesPath, dataBagsPath, encryptedDataBagSecretPath, environmentsPath, p.config.ChefEnvironment, p.config.ChefLicense)
if err != nil { if err != nil {
return fmt.Errorf("Error creating Chef config file: %s", err) return fmt.Errorf("Error creating Chef config file: %s", err)
} }
@ -324,7 +332,7 @@ func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, dst str
return comm.Upload(dst, f, nil) return comm.Upload(dst, f, nil)
} }
func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, localCookbooks []string, rolesPath string, dataBagsPath string, encryptedDataBagSecretPath string, environmentsPath string, chefEnvironment string) (string, error) { func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, localCookbooks []string, rolesPath string, dataBagsPath string, encryptedDataBagSecretPath string, environmentsPath string, chefEnvironment string, chefLicense string) (string, error) {
ui.Message("Creating configuration file 'solo.rb'") ui.Message("Creating configuration file 'solo.rb'")
cookbook_paths := make([]string, len(p.config.RemoteCookbookPaths)+len(localCookbooks)) cookbook_paths := make([]string, len(p.config.RemoteCookbookPaths)+len(localCookbooks))
@ -365,6 +373,7 @@ func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, local
HasEncryptedDataBagSecretPath: encryptedDataBagSecretPath != "", HasEncryptedDataBagSecretPath: encryptedDataBagSecretPath != "",
HasEnvironmentsPath: environmentsPath != "", HasEnvironmentsPath: environmentsPath != "",
ChefEnvironment: chefEnvironment, ChefEnvironment: chefEnvironment,
ChefLicense: chefLicense,
} }
configString, err := interpolate.Render(tpl, &p.config.ctx) configString, err := interpolate.Render(tpl, &p.config.ctx)
if err != nil { if err != nil {
@ -569,6 +578,7 @@ func (p *Provisioner) processJsonUserVars() (map[string]interface{}, error) {
} }
var DefaultConfigTemplate = ` var DefaultConfigTemplate = `
chef_license "{{.ChefLicense}}"
cookbook_path [{{.CookbookPaths}}] cookbook_path [{{.CookbookPaths}}]
{{if .HasRolesPath}} {{if .HasRolesPath}}
role_path "{{.RolesPath}}" role_path "{{.RolesPath}}"

View File

@ -35,6 +35,59 @@ func TestProvisionerPrepare_chefEnvironment(t *testing.T) {
t.Fatalf("unexpected: %#v", p.config.ChefEnvironment) t.Fatalf("unexpected: %#v", p.config.ChefEnvironment)
} }
} }
func TestProvisionerPrepare_chefLicense(t *testing.T) {
var p Provisioner
// Test not set
config := testConfig()
err := p.Prepare(config)
if err != nil {
t.Fatal("should error")
}
if p.config.ChefLicense != "accept-silent" {
t.Fatalf("unexpected: %#v", p.config.ChefLicense)
}
// Test set
config = testConfig()
config["chef_license"] = "accept"
p = Provisioner{}
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ChefLicense != "accept" {
t.Fatalf("unexpected: %#v", p.config.ChefLicense)
}
// Test set skipInstall true
config = testConfig()
config["skip_install"] = true
p = Provisioner{}
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ChefLicense != "" {
t.Fatalf("unexpected: %#v", "empty string")
}
// Test set installCommand true
config = testConfig()
config["install_command"] = "install chef"
p = Provisioner{}
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ChefLicense != "" {
t.Fatalf("unexpected: %#v", "empty string")
}
}
func TestProvisionerPrepare_configTemplate(t *testing.T) { func TestProvisionerPrepare_configTemplate(t *testing.T) {
var err error var err error

View File

@ -44,6 +44,12 @@ configuration is actually required.
- `chef_environment` (string) - The name of the chef\_environment sent to the - `chef_environment` (string) - The name of the chef\_environment sent to the
Chef server. By default this is empty and will not use an environment. Chef server. By default this is empty and will not use an environment.
- `chef_license` (string) - As of Chef v15, Chef requires users to accept a
license. Defaults to `accept-silent` when `skip_install` is false and
`install_command` is unset. Possible values are `accept`,
`accept-silent` and `accept-no-persist`. For details see [Accepting the
Chef License](https://docs.chef.io/chef_license_accept.html).
- `config_template` (string) - Path to a template that will be used for the - `config_template` (string) - Path to a template that will be used for the
Chef configuration file. By default Packer only sets configuration it needs Chef configuration file. By default Packer only sets configuration it needs
to match the settings set in the provisioner configuration. If you need to to match the settings set in the provisioner configuration. If you need to
@ -159,6 +165,7 @@ log_level :info
log_location STDOUT log_location STDOUT
chef_server_url "{{.ServerUrl}}" chef_server_url "{{.ServerUrl}}"
client_key "{{.ClientKey}}" client_key "{{.ClientKey}}"
chef_license "{{.ChefLicense}}"
{{if ne .EncryptedDataBagSecretPath ""}} {{if ne .EncryptedDataBagSecretPath ""}}
encrypted_data_bag_secret "{{.EncryptedDataBagSecretPath}}" encrypted_data_bag_secret "{{.EncryptedDataBagSecretPath}}"
{{end}} {{end}}
@ -192,6 +199,7 @@ This template is a [configuration template](/docs/templates/engine.html) and
has a set of variables available to use: has a set of variables available to use:
- `ChefEnvironment` - The Chef environment name. - `ChefEnvironment` - The Chef environment name.
- `ChefLicense` - The Chef license acceptance value.
- `EncryptedDataBagSecretPath` - The path to the secret key file to decrypt - `EncryptedDataBagSecretPath` - The path to the secret key file to decrypt
encrypted data bags. encrypted data bags.
- `NodeName` - The node name set in the configuration. - `NodeName` - The node name set in the configuration.

View File

@ -40,6 +40,12 @@ configuration is actually required, but at least `run_list` is recommended.
- `chef_environment` (string) - The name of the `chef_environment` sent to - `chef_environment` (string) - The name of the `chef_environment` sent to
the Chef server. By default this is empty and will not use an environment the Chef server. By default this is empty and will not use an environment
- `chef_license` (string) - As of Chef v15, Chef requires users to accept a
license. Defaults to `accept-silent` when `skip_install` is false and
`install_command` is unset. Possible values are `accept`,
`accept-silent` and `accept-no-persist`. For details see [Accepting the
Chef License](https://docs.chef.io/chef_license_accept.html).
- `config_template` (string) - Path to a template that will be used for the - `config_template` (string) - Path to a template that will be used for the
Chef configuration file. By default Packer only sets configuration it needs Chef configuration file. By default Packer only sets configuration it needs
to match the settings set in the provisioner configuration. If you need to to match the settings set in the provisioner configuration. If you need to
@ -131,6 +137,7 @@ has a set of variables available to use:
- `ChefEnvironment` - The current enabled environment. Only non-empty if the - `ChefEnvironment` - The current enabled environment. Only non-empty if the
environment path is set. environment path is set.
- `ChefLicense` - The Chef license acceptance value.
- `CookbookPaths` is the set of cookbook paths ready to embedded directly - `CookbookPaths` is the set of cookbook paths ready to embedded directly
into a Ruby array to configure Chef. into a Ruby array to configure Chef.
- `DataBagsPath` is the path to the data bags folder. - `DataBagsPath` is the path to the data bags folder.