replace scrubconfig with packer.LogSecretFilter.Set
filter winrm password from logs Add new root-level packer template option, sensitive-variables, to tell us what user variables to mark sensitive.
This commit is contained in:
parent
31fcfe4bc2
commit
ff6a039d5b
|
@ -67,7 +67,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
return nil, errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(b.config, b.config.AlicloudAccessKey, b.config.AlicloudSecretKey))
|
||||
packer.LogSecretFilter.Set(b.config.AlicloudAccessKey, b.config.AlicloudSecretKey)
|
||||
log.Println(b.config)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
return warns, errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token))
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
log.Println(b.config)
|
||||
return warns, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,9 @@ WaitLoop:
|
|||
"Password (since debug is enabled): %s", s.Comm.WinRMPassword))
|
||||
}
|
||||
// store so that we can access this later during provisioning
|
||||
|
||||
commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName)
|
||||
packer.LogSecretFilter.Set(s.Comm.WinRMPassword)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ type Builder struct {
|
|||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
log.Printf("SECRET: matt")
|
||||
b.config.ctx.Funcs = awscommon.TemplateFuncs
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
|
@ -82,7 +81,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
return nil, errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token))
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
log.Println(b.config)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
// Run!
|
||||
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
|
||||
b.runner.Run(state)
|
||||
|
||||
// If there was an error, return that
|
||||
if rawErr, ok := state.GetOk("error"); ok {
|
||||
return nil, rawErr.(error)
|
||||
|
|
|
@ -96,7 +96,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
return nil, errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token))
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
log.Println(b.config)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
return nil, errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token))
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
log.Println(b.config)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -166,8 +166,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token))
|
||||
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
|
||||
log.Println(b.config)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -363,6 +363,7 @@ func setRuntimeValues(c *Config) {
|
|||
c.tmpAdminPassword = tempName.AdminPassword
|
||||
// store so that we can access this later during provisioning
|
||||
commonhelper.SetSharedState("winrm_password", c.tmpAdminPassword, c.PackerConfig.PackerBuildName)
|
||||
packer.LogSecretFilter.Set(c.tmpAdminPassword)
|
||||
|
||||
c.tmpCertificatePassword = tempName.CertificatePassword
|
||||
if c.TempComputeName == "" {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type StepSaveWinRMPassword struct {
|
||||
|
@ -15,6 +16,7 @@ type StepSaveWinRMPassword struct {
|
|||
func (s *StepSaveWinRMPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
// store so that we can access this later during provisioning
|
||||
commonhelper.SetSharedState("winrm_password", s.Password, s.BuildName)
|
||||
packer.LogSecretFilter.Set(s.Password)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
return nil, nil, errs
|
||||
}
|
||||
|
||||
common.ScrubConfig(c, c.APIToken)
|
||||
packer.LogSecretFilter.Set(c.APIToken)
|
||||
return c, nil, nil
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ func (s *StepCreateWindowsPassword) Run(_ context.Context, state multistep.State
|
|||
|
||||
if c.Comm.WinRMPassword != "" {
|
||||
state.Put("winrm_password", c.Comm.WinRMPassword)
|
||||
packer.LogSecretFilter.Set(c.Comm.WinRMPassword)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -114,6 +115,7 @@ func (s *StepCreateWindowsPassword) Run(_ context.Context, state multistep.State
|
|||
|
||||
state.Put("winrm_password", data.password)
|
||||
commonhelper.SetSharedState("winrm_password", data.password, c.PackerConfig.PackerBuildName)
|
||||
packer.LogSecretFilter.Set(data.password)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -109,7 +109,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
}
|
||||
common.ScrubConfig(c, c.Token)
|
||||
|
||||
packer.LogSecretFilter.Set(c.Token)
|
||||
return &c, nil, nil
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
b.config.InstanceName = b.config.ImageName
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(b.config, b.config.Password))
|
||||
packer.LogSecretFilter.Set(b.config.Password)
|
||||
log.Println(b.config)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ func (s *stepGetDefaultCredentials) Run(ctx context.Context, state multistep.Sta
|
|||
|
||||
// store so that we can access this later during provisioning
|
||||
commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName)
|
||||
|
||||
packer.LogSecretFilter.Set(s.Comm.WinRMPassword)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, nil, errs
|
||||
}
|
||||
common.ScrubConfig(c, c.PBUsername)
|
||||
packer.LogSecretFilter.Set(c.PBUsername)
|
||||
|
||||
return &c, nil, nil
|
||||
}
|
||||
|
|
|
@ -119,6 +119,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
|||
return nil, nil, errs
|
||||
}
|
||||
|
||||
common.ScrubConfig(c, c.Token)
|
||||
packer.LogSecretFilter.Set(c.Token)
|
||||
return c, nil, nil
|
||||
}
|
||||
|
|
|
@ -110,7 +110,6 @@ func (c *BuildCommand) Run(args []string) int {
|
|||
log.Printf("Build debug mode: %v", cfgDebug)
|
||||
log.Printf("Force build: %v", cfgForce)
|
||||
log.Printf("On error: %v", cfgOnError)
|
||||
//log.Printf("my secrets: %v", c.CoreConfig.
|
||||
|
||||
// Set the debug and force mode and prepare all the builds
|
||||
for _, b := range builds {
|
||||
|
|
|
@ -29,8 +29,6 @@ type Meta struct {
|
|||
Cache packer.Cache
|
||||
Ui packer.Ui
|
||||
Version string
|
||||
//Secrets []string
|
||||
//secrets: []string{"matt"},
|
||||
|
||||
// These are set by command-line flags
|
||||
flagBuildExcept []string
|
||||
|
|
|
@ -20,19 +20,6 @@ const PackerKeyEnv = "PACKER_KEY_INTERVAL"
|
|||
// shorter delay (e.g. 10ms) can be used on a workstation. See PackerKeyEnv.
|
||||
const PackerKeyDefault = 100 * time.Millisecond
|
||||
|
||||
// ScrubConfig is a helper that returns a string representation of
|
||||
// any struct with the given values stripped out.
|
||||
func ScrubConfig(target interface{}, values ...string) string {
|
||||
conf := fmt.Sprintf("Config: %+v", target)
|
||||
for _, value := range values {
|
||||
if value == "" {
|
||||
continue
|
||||
}
|
||||
conf = strings.Replace(conf, value, "<Filtered>", -1)
|
||||
}
|
||||
return conf
|
||||
}
|
||||
|
||||
// ChooseString returns the first non-empty value.
|
||||
func ChooseString(vals ...string) string {
|
||||
for _, el := range vals {
|
||||
|
|
|
@ -310,20 +310,3 @@ func TestFileExistsLocally(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScrubConfig(t *testing.T) {
|
||||
type Inner struct {
|
||||
Baz string
|
||||
}
|
||||
type Local struct {
|
||||
Foo string
|
||||
Bar string
|
||||
Inner
|
||||
}
|
||||
c := Local{"foo", "bar", Inner{"bar"}}
|
||||
expect := "Config: {Foo:foo Bar:<Filtered> Inner:{Baz:<Filtered>}}"
|
||||
conf := ScrubConfig(c, c.Bar)
|
||||
if conf != expect {
|
||||
t.Fatalf("got %s, expected %s", conf, expect)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ package common
|
|||
// are sent by packer, properly tagged already so mapstructure can load
|
||||
// them. Embed this structure into your configuration class to get it.
|
||||
type PackerConfig struct {
|
||||
PackerBuildName string `mapstructure:"packer_build_name"`
|
||||
PackerBuilderType string `mapstructure:"packer_builder_type"`
|
||||
PackerDebug bool `mapstructure:"packer_debug"`
|
||||
PackerForce bool `mapstructure:"packer_force"`
|
||||
PackerOnError string `mapstructure:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables"`
|
||||
PackerBuildName string `mapstructure:"packer_build_name"`
|
||||
PackerBuilderType string `mapstructure:"packer_builder_type"`
|
||||
PackerDebug bool `mapstructure:"packer_debug"`
|
||||
PackerForce bool `mapstructure:"packer_force"`
|
||||
PackerOnError string `mapstructure:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables"`
|
||||
}
|
||||
|
|
|
@ -70,12 +70,7 @@ func Run(ui packer.Ui, config *Config) (bool, error) {
|
|||
// buffers and for reading the final exit status.
|
||||
flattenedCmd := strings.Join(interpolatedCmds, " ")
|
||||
cmd := &packer.RemoteCmd{Command: flattenedCmd}
|
||||
sanitized := flattenedCmd
|
||||
if len(getWinRMPassword(config.PackerBuildName)) > 0 {
|
||||
sanitized = strings.Replace(flattenedCmd,
|
||||
getWinRMPassword(config.PackerBuildName), "*****", -1)
|
||||
}
|
||||
log.Printf("[INFO] (shell-local): starting local command: %s", sanitized)
|
||||
log.Printf("[INFO] (shell-local): starting local command: %s", flattenedCmd)
|
||||
if err := cmd.StartWithUi(comm, ui); err != nil {
|
||||
return false, fmt.Errorf(
|
||||
"Error executing script: %s\n\n"+
|
||||
|
@ -204,5 +199,6 @@ func createFlattenedEnvVars(config *Config) (string, error) {
|
|||
|
||||
func getWinRMPassword(buildName string) string {
|
||||
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
|
||||
packer.LogSecretFilter.Set(winRMPass)
|
||||
return winRMPass
|
||||
}
|
||||
|
|
|
@ -108,10 +108,11 @@ func Decode(target interface{}, config *DecodeOpts, raws ...interface{}) error {
|
|||
// detecting things like user variables from the raw configuration params.
|
||||
func DetectContext(raws ...interface{}) (*interpolate.Context, error) {
|
||||
var s struct {
|
||||
BuildName string `mapstructure:"packer_build_name"`
|
||||
BuildType string `mapstructure:"packer_builder_type"`
|
||||
TemplatePath string `mapstructure:"packer_template_path"`
|
||||
Vars map[string]string `mapstructure:"packer_user_variables"`
|
||||
BuildName string `mapstructure:"packer_build_name"`
|
||||
BuildType string `mapstructure:"packer_builder_type"`
|
||||
TemplatePath string `mapstructure:"packer_template_path"`
|
||||
Vars map[string]string `mapstructure:"packer_user_variables"`
|
||||
SensitiveVars []string `mapstructure:"packer_sensitive_variables"`
|
||||
}
|
||||
|
||||
for _, r := range raws {
|
||||
|
@ -121,10 +122,11 @@ func DetectContext(raws ...interface{}) (*interpolate.Context, error) {
|
|||
}
|
||||
|
||||
return &interpolate.Context{
|
||||
BuildName: s.BuildName,
|
||||
BuildType: s.BuildType,
|
||||
TemplatePath: s.TemplatePath,
|
||||
UserVariables: s.Vars,
|
||||
BuildName: s.BuildName,
|
||||
BuildType: s.BuildType,
|
||||
TemplatePath: s.TemplatePath,
|
||||
UserVariables: s.Vars,
|
||||
SensitiveVariables: s.SensitiveVars,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,11 @@ type Core struct {
|
|||
// CoreConfig is the structure for initializing a new Core. Once a CoreConfig
|
||||
// is used to initialize a Core, it shouldn't be re-used or modified again.
|
||||
type CoreConfig struct {
|
||||
Components ComponentFinder
|
||||
Template *template.Template
|
||||
Variables map[string]string
|
||||
Version string
|
||||
Components ComponentFinder
|
||||
Template *template.Template
|
||||
Variables map[string]string
|
||||
SensitiveVariables []string
|
||||
Version string
|
||||
}
|
||||
|
||||
// The function type used to lookup Builder implementations.
|
||||
|
@ -61,14 +62,16 @@ func NewCore(c *CoreConfig) (*Core, error) {
|
|||
variables: c.Variables,
|
||||
version: c.Version,
|
||||
}
|
||||
|
||||
if err := result.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := result.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
LogSecretFilter.Set("matt")
|
||||
//log.Printf("NewCore: %+v", result.Template.Variables["efoo"])
|
||||
for _, secret := range result.secrets {
|
||||
LogSecretFilter.Set(secret)
|
||||
}
|
||||
|
||||
// Go through and interpolate all the build names. We should be able
|
||||
// to do this at this point with the variables.
|
||||
|
@ -305,6 +308,16 @@ func (c *Core) init() error {
|
|||
c.variables[k] = def
|
||||
}
|
||||
|
||||
for _, v := range c.Template.SensitiveVariables {
|
||||
def, err := interpolate.Render(v.Default, ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"error interpolating default value for '%s': %s",
|
||||
v, err)
|
||||
}
|
||||
c.secrets = append(c.secrets, def)
|
||||
}
|
||||
|
||||
// Interpolate the push configuration
|
||||
if _, err := interpolate.RenderInterface(&c.Template.Push, c.Context()); err != nil {
|
||||
return fmt.Errorf("Error interpolating 'push': %s", err)
|
||||
|
|
|
@ -28,10 +28,11 @@ func (l *secretFilter) SetOutput(output io.Writer) {
|
|||
|
||||
func (l *secretFilter) Write(p []byte) (n int, err error) {
|
||||
for s := range l.s {
|
||||
p = bytes.Replace(p, []byte(s), []byte("<filtered>"), -1)
|
||||
if s != "" {
|
||||
p = bytes.Replace(p, []byte(s), []byte("<sensitive>"), -1)
|
||||
}
|
||||
}
|
||||
return l.w.Write(p)
|
||||
// return l.w.Write([]byte("foobar"))
|
||||
}
|
||||
|
||||
func (l *secretFilter) get() (s []string) {
|
||||
|
|
|
@ -113,7 +113,8 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
|||
return errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(p.config, p.config.AlicloudAccessKey, p.config.AlicloudSecretKey))
|
||||
packer.LogSecretFilter.Set(p.config.AlicloudAccessKey, p.config.AlicloudSecretKey)
|
||||
log.Println(p.config)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,8 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
|||
return errs
|
||||
}
|
||||
|
||||
log.Println(common.ScrubConfig(p.config, p.config.AccessKey, p.config.SecretKey, p.config.Token))
|
||||
packer.LogSecretFilter.Set(p.config.AccessKey, p.config.SecretKey, p.config.Token)
|
||||
log.Println(p.config)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -555,6 +555,7 @@ func newSigner(privKeyFile string) (*signer, error) {
|
|||
|
||||
func getWinRMPassword(buildName string) string {
|
||||
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
|
||||
packer.LogSecretFilter.Set(winRMPass)
|
||||
return winRMPass
|
||||
}
|
||||
|
||||
|
|
|
@ -481,6 +481,7 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro
|
|||
|
||||
func getWinRMPassword(buildName string) string {
|
||||
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
|
||||
packer.LogSecretFilter.Set(winRMPass)
|
||||
return winRMPass
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ type Context struct {
|
|||
// "user" function reads from.
|
||||
UserVariables map[string]string
|
||||
|
||||
// SensitiveVariables is a list of variables to sanitize.
|
||||
SensitiveVariables []string
|
||||
|
||||
// EnableEnv enables the env function
|
||||
EnableEnv bool
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
@ -23,11 +24,12 @@ type rawTemplate struct {
|
|||
MinVersion string `mapstructure:"min_packer_version"`
|
||||
Description string
|
||||
|
||||
Builders []map[string]interface{}
|
||||
Push map[string]interface{}
|
||||
PostProcessors []interface{} `mapstructure:"post-processors"`
|
||||
Provisioners []map[string]interface{}
|
||||
Variables map[string]interface{}
|
||||
Builders []map[string]interface{}
|
||||
Push map[string]interface{}
|
||||
PostProcessors []interface{} `mapstructure:"post-processors"`
|
||||
Provisioners []map[string]interface{}
|
||||
Variables map[string]interface{}
|
||||
SensitiveVariables []string `mapstructure:"sensitive-variables"`
|
||||
|
||||
RawContents []byte
|
||||
}
|
||||
|
@ -60,6 +62,12 @@ func (r *rawTemplate) Template() (*Template, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
for _, sVar := range r.SensitiveVariables {
|
||||
if sVar == k {
|
||||
result.SensitiveVariables = append(result.SensitiveVariables, &v)
|
||||
}
|
||||
}
|
||||
|
||||
result.Variables[k] = &v
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,12 @@ type Template struct {
|
|||
Description string
|
||||
MinVersion string
|
||||
|
||||
Variables map[string]*Variable
|
||||
Builders map[string]*Builder
|
||||
Provisioners []*Provisioner
|
||||
PostProcessors [][]*PostProcessor
|
||||
Push Push
|
||||
Variables map[string]*Variable
|
||||
SensitiveVariables []*Variable
|
||||
Builders map[string]*Builder
|
||||
Provisioners []*Provisioner
|
||||
PostProcessors [][]*PostProcessor
|
||||
Push Push
|
||||
|
||||
// RawContents is just the raw data for this template
|
||||
RawContents []byte
|
||||
|
|
Loading…
Reference in New Issue