Update redacting functionality to redact all sensitive info in config when printing with view (#109189)

* Add RedactSecrets function

* Move RedactSecrets method to existing RawBytesData case

* Update TestRedactSecrets to use new pattern of os.CreateTemp()

Kubernetes-commit: e721272d10dd6c4d85ff613182ba0eaddcec9272
This commit is contained in:
Marly Puckett
2022-11-08 06:16:25 -08:00
committed by Kubernetes Publisher
parent 4b1a9fdfb5
commit 769443557e
4 changed files with 145 additions and 17 deletions

View File

@@ -23,6 +23,8 @@ import (
"os"
"path"
"path/filepath"
"reflect"
"strings"
)
func init() {
@@ -81,21 +83,21 @@ func MinifyConfig(config *Config) error {
}
var (
redactedBytes []byte
dataOmittedBytes []byte
redactedBytes []byte
)
// Flatten redacts raw data entries from the config object for a human-readable view.
// ShortenConfig redacts raw data entries from the config object for a human-readable view.
func ShortenConfig(config *Config) {
// trick json encoder into printing a human readable string in the raw data
// trick json encoder into printing a human-readable string in the raw data
// by base64 decoding what we want to print. Relies on implementation of
// http://golang.org/pkg/encoding/json/#Marshal using base64 to encode []byte
for key, authInfo := range config.AuthInfos {
if len(authInfo.ClientKeyData) > 0 {
authInfo.ClientKeyData = redactedBytes
authInfo.ClientKeyData = dataOmittedBytes
}
if len(authInfo.ClientCertificateData) > 0 {
authInfo.ClientCertificateData = redactedBytes
authInfo.ClientCertificateData = dataOmittedBytes
}
if len(authInfo.Token) > 0 {
authInfo.Token = "REDACTED"
@@ -110,7 +112,7 @@ func ShortenConfig(config *Config) {
}
}
// Flatten changes the config object into a self contained config (useful for making secrets)
// FlattenConfig changes the config object into a self-contained config (useful for making secrets)
func FlattenConfig(config *Config) error {
for key, authInfo := range config.AuthInfos {
baseDir, err := MakeAbs(path.Dir(authInfo.LocationOfOrigin), "")
@@ -188,3 +190,77 @@ func MakeAbs(path, base string) (string, error) {
}
return filepath.Join(base, path), nil
}
// RedactSecrets replaces any sensitive values with REDACTED
func RedactSecrets(config *Config) error {
return redactSecrets(reflect.ValueOf(config), false)
}
func redactSecrets(curr reflect.Value, redact bool) error {
redactedBytes = []byte("REDACTED")
if !curr.IsValid() {
return nil
}
actualCurrValue := curr
if curr.Kind() == reflect.Ptr {
actualCurrValue = curr.Elem()
}
switch actualCurrValue.Kind() {
case reflect.Map:
for _, v := range actualCurrValue.MapKeys() {
err := redactSecrets(actualCurrValue.MapIndex(v), false)
if err != nil {
return err
}
}
return nil
case reflect.String:
if redact {
if !actualCurrValue.IsZero() {
actualCurrValue.SetString("REDACTED")
}
}
return nil
case reflect.Slice:
if actualCurrValue.Type() == reflect.TypeOf([]byte{}) && redact {
if !actualCurrValue.IsNil() {
actualCurrValue.SetBytes(redactedBytes)
}
return nil
}
for i := 0; i < actualCurrValue.Len(); i++ {
err := redactSecrets(actualCurrValue.Index(i), false)
if err != nil {
return err
}
}
return nil
case reflect.Struct:
for fieldIndex := 0; fieldIndex < actualCurrValue.NumField(); fieldIndex++ {
currFieldValue := actualCurrValue.Field(fieldIndex)
currFieldType := actualCurrValue.Type().Field(fieldIndex)
currYamlTag := currFieldType.Tag.Get("datapolicy")
currFieldTypeYamlName := strings.Split(currYamlTag, ",")[0]
if currFieldTypeYamlName != "" {
err := redactSecrets(currFieldValue, true)
if err != nil {
return err
}
} else {
err := redactSecrets(currFieldValue, false)
if err != nil {
return err
}
}
}
return nil
default:
return nil
}
}