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  }