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  }