github.com/jenkins-x/jx/v2@v2.1.155/pkg/kube/log_masker.go (about) 1 package kube 2 3 import ( 4 "strings" 5 6 corev1 "k8s.io/api/core/v1" 7 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 "k8s.io/client-go/kubernetes" 9 ) 10 11 // LogMasker replaces words in a log from a set of secrets 12 type LogMasker struct { 13 ReplaceWords map[string]string 14 } 15 16 // NewLogMasker creates a new LogMasker loading secrets from the given namespace 17 func NewLogMasker(kubeClient kubernetes.Interface, ns string) (*LogMasker, error) { 18 masker := &LogMasker{} 19 resourceList, err := kubeClient.CoreV1().Secrets(ns).List(metav1.ListOptions{}) 20 if err != nil { 21 return masker, err 22 } 23 for _, s := range resourceList.Items { 24 secret := s 25 masker.LoadSecret(&secret) 26 } 27 return masker, nil 28 } 29 30 // NewLogMaskerFromMap creates a new LogMasker with all the string values in a tree of map 31 func NewLogMaskerFromMap(m map[string]interface{}) *LogMasker { 32 masker := &LogMasker{ 33 ReplaceWords: map[string]string{}, 34 } 35 masker.replaceMapValues(m) 36 return masker 37 } 38 39 // LoadSecrets loads the secrets into the log masker 40 func (m *LogMasker) LoadSecrets(kubeClient kubernetes.Interface, ns string) error { 41 resourceList, err := kubeClient.CoreV1().Secrets(ns).List(metav1.ListOptions{}) 42 if err != nil { 43 return err 44 } 45 for _, s := range resourceList.Items { 46 secret := s 47 m.LoadSecret(&secret) 48 } 49 return nil 50 } 51 52 // LoadSecret loads the secret data into the log masker 53 func (m *LogMasker) LoadSecret(secret *corev1.Secret) { 54 if m.ReplaceWords == nil { 55 m.ReplaceWords = map[string]string{} 56 } 57 58 if secret.Data != nil { 59 for _, v := range secret.Data { 60 if v != nil && len(v) > 0 { 61 // key := string(k) 62 value := string(v) 63 64 m.ReplaceWords[value] = m.replaceValue(value) 65 } 66 } 67 } 68 } 69 70 // MaskLog returns the text with all of the secrets masked out 71 func (m *LogMasker) MaskLog(text string) string { 72 answer := text 73 for k, v := range m.ReplaceWords { 74 answer = strings.Replace(answer, k, v, -1) 75 } 76 return answer 77 } 78 79 // MaskLogData masks the log data 80 func (m *LogMasker) MaskLogData(logData []byte) []byte { 81 text := m.MaskLog(string(logData)) 82 return []byte(text) 83 } 84 85 // replaceMapValues adds all the string values in the given map to the replacer words 86 func (m *LogMasker) replaceMapValues(values map[string]interface{}) { 87 for _, value := range values { 88 childMap, ok := value.(map[string]interface{}) 89 if ok { 90 m.replaceMapValues(childMap) 91 continue 92 } 93 text, ok := value.(string) 94 if ok { 95 m.ReplaceWords[text] = m.replaceValue(text) 96 } 97 } 98 } 99 100 func (m *LogMasker) replaceValue(value string) string { 101 return strings.Repeat("*", len(value)) 102 }