github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/azure/common/dump_config.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/reflectwalk" 6 "reflect" 7 "strings" 8 ) 9 10 type walker struct { 11 depth int 12 say func(string) 13 } 14 15 func newDumpConfig(say func(string)) *walker { 16 return &walker{ 17 depth: 0, 18 say: say, 19 } 20 } 21 22 func (s *walker) Enter(l reflectwalk.Location) error { 23 s.depth += 1 24 return nil 25 } 26 27 func (s *walker) Exit(l reflectwalk.Location) error { 28 s.depth -= 1 29 return nil 30 } 31 32 func (s *walker) Struct(v reflect.Value) error { 33 return nil 34 } 35 36 func (s *walker) StructField(f reflect.StructField, v reflect.Value) error { 37 if !s.shouldDump(v) { 38 return nil 39 } 40 41 switch v.Kind() { 42 case reflect.String: 43 s.say(fmt.Sprintf("%s=%s", f.Name, s.formatValue(f.Name, v.String()))) 44 } 45 46 return nil 47 } 48 49 func (s *walker) shouldDump(v reflect.Value) bool { 50 return s.depth == 2 && v.IsValid() && v.CanInterface() 51 } 52 53 func (s *walker) formatValue(name, value string) string { 54 if s.isMaskable(name) { 55 return strings.Repeat("*", len(value)) 56 } 57 58 return value 59 } 60 61 func (s *walker) isMaskable(name string) bool { 62 up := strings.ToUpper(name) 63 return strings.Contains(up, "SECRET") || strings.Contains(up, "PASSWORD") 64 } 65 66 func DumpConfig(config interface{}, say func(string)) { 67 walker := newDumpConfig(say) 68 reflectwalk.Walk(config, walker) 69 }