Elevated support for chef-client provisioner

Fixes #4661
This commit is contained in:
Matt Dainty 2018-12-13 10:25:12 +00:00
parent 19bd28cd72
commit 451709b956
2 changed files with 53 additions and 0 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/common/uuid"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/provisioner" "github.com/hashicorp/packer/provisioner"
@ -50,6 +51,8 @@ type Config struct {
ChefEnvironment string `mapstructure:"chef_environment"` ChefEnvironment string `mapstructure:"chef_environment"`
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"`
ElevatedPassword string `mapstructure:"elevated_password"`
EncryptedDataBagSecretPath string `mapstructure:"encrypted_data_bag_secret_path"` EncryptedDataBagSecretPath string `mapstructure:"encrypted_data_bag_secret_path"`
ExecuteCommand string `mapstructure:"execute_command"` ExecuteCommand string `mapstructure:"execute_command"`
GuestOSType string `mapstructure:"guest_os_type"` GuestOSType string `mapstructure:"guest_os_type"`
@ -76,6 +79,7 @@ type Config struct {
type Provisioner struct { type Provisioner struct {
config Config config Config
communicator packer.Communicator
guestOSTypeConfig guestOSTypeConfig guestOSTypeConfig guestOSTypeConfig
guestCommands *provisioner.GuestCommands guestCommands *provisioner.GuestCommands
} }
@ -94,6 +98,10 @@ type ConfigTemplate struct {
ValidationKeyPath string ValidationKeyPath string
} }
type EnvVarsTemplate struct {
WinRMPassword string
}
type ExecuteTemplate struct { type ExecuteTemplate struct {
ConfigPath string ConfigPath string
JsonPath string JsonPath string
@ -111,6 +119,12 @@ type KnifeTemplate struct {
} }
func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Prepare(raws ...interface{}) error {
// Create passthrough for winrm password so we can fill it in once we know
// it
p.config.ctx.Data = &EnvVarsTemplate{
WinRMPassword: `{{.WinRMPassword}}`,
}
err := config.Decode(&p.config, &config.DecodeOpts{ err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true, Interpolate: true,
InterpolateContext: &p.config.ctx, InterpolateContext: &p.config.ctx,
@ -221,6 +235,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
p.communicator = comm
nodeName := p.config.NodeName nodeName := p.config.NodeName
if nodeName == "" { if nodeName == "" {
nodeName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) nodeName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
@ -551,6 +567,13 @@ func (p *Provisioner) executeChef(ui packer.Ui, comm packer.Communicator, config
return err return err
} }
if p.config.ElevatedUser != "" {
command, err = provisioner.GenerateElevatedRunner(command, p)
if err != nil {
return err
}
}
ui.Message(fmt.Sprintf("Executing Chef: %s", command)) ui.Message(fmt.Sprintf("Executing Chef: %s", command))
cmd := &packer.RemoteCmd{ cmd := &packer.RemoteCmd{
@ -676,6 +699,31 @@ func (p *Provisioner) processJsonUserVars() (map[string]interface{}, error) {
return result, nil return result, nil
} }
func getWinRMPassword(buildName string) string {
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
packer.LogSecretFilter.Set(winRMPass)
return winRMPass
}
func (p *Provisioner) Communicator() packer.Communicator {
return p.communicator
}
func (p *Provisioner) ElevatedUser() string {
return p.config.ElevatedUser
}
func (p *Provisioner) ElevatedPassword() string {
// Replace ElevatedPassword for winrm users who used this feature
p.config.ctx.Data = &EnvVarsTemplate{
WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
}
elevatedPassword, _ := interpolate.Render(p.config.ElevatedPassword, &p.config.ctx)
return elevatedPassword
}
var DefaultConfigTemplate = ` var DefaultConfigTemplate = `
log_level :info log_level :info
log_location STDOUT log_location STDOUT

View File

@ -51,6 +51,11 @@ configuration is actually required.
should use a custom configuration template. See the dedicated "Chef should use a custom configuration template. See the dedicated "Chef
Configuration" section below for more details. Configuration" section below for more details.
- `elevated_user` and `elevated_password` (string) - If specified, Chef will
be run with elevated privileges using the given Windows user. See the
[powershell](/docs/provisionders/powershell.html) provisioner for the full
details.
- `encrypted_data_bag_secret_path` (string) - The path to the file containing - `encrypted_data_bag_secret_path` (string) - The path to the file containing
the secret for encrypted data bags. By default, this is empty, so no secret the secret for encrypted data bags. By default, this is empty, so no secret
will be available. will be available.