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