mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 02:11:09 +00:00
Merge pull request #107207 from ehashman/deprecate-log-sanitization
Deprecate dynamic log sanitization
This commit is contained in:
commit
22a03f893d
@ -218,7 +218,6 @@ var (
|
||||
"Logging.Options.JSON.InfoBufferSize.Quantity.i.value",
|
||||
"Logging.Options.JSON.InfoBufferSize.Quantity.s",
|
||||
"Logging.Options.JSON.SplitStream",
|
||||
"Logging.Sanitization",
|
||||
"Logging.VModule[*].FilePattern",
|
||||
"Logging.VModule[*].Verbosity",
|
||||
"Logging.Verbosity",
|
||||
|
@ -235,7 +235,6 @@ func TestSetDefaultsKubeletConfiguration(t *testing.T) {
|
||||
Logging: componentbaseconfigv1alpha1.LoggingConfiguration{
|
||||
Format: "",
|
||||
FlushFrequency: 5 * time.Second,
|
||||
Sanitization: false,
|
||||
},
|
||||
EnableSystemLogHandler: utilpointer.Bool(false),
|
||||
ShutdownGracePeriod: zeroDuration,
|
||||
@ -333,7 +332,6 @@ func TestSetDefaultsKubeletConfiguration(t *testing.T) {
|
||||
Logging: componentbaseconfigv1alpha1.LoggingConfiguration{
|
||||
Format: "text",
|
||||
FlushFrequency: 5 * time.Second,
|
||||
Sanitization: false,
|
||||
},
|
||||
EnableSystemLogHandler: utilpointer.Bool(false),
|
||||
ReservedMemory: []v1beta1.MemoryReservation{},
|
||||
@ -476,7 +474,6 @@ func TestSetDefaultsKubeletConfiguration(t *testing.T) {
|
||||
Logging: componentbaseconfigv1alpha1.LoggingConfiguration{
|
||||
Format: "json",
|
||||
FlushFrequency: 5 * time.Second,
|
||||
Sanitization: true,
|
||||
},
|
||||
EnableSystemLogHandler: utilpointer.Bool(true),
|
||||
ShutdownGracePeriod: metav1.Duration{Duration: 60 * time.Second},
|
||||
@ -623,7 +620,6 @@ func TestSetDefaultsKubeletConfiguration(t *testing.T) {
|
||||
Logging: componentbaseconfigv1alpha1.LoggingConfiguration{
|
||||
Format: "json",
|
||||
FlushFrequency: 5 * time.Second,
|
||||
Sanitization: true,
|
||||
},
|
||||
EnableSystemLogHandler: utilpointer.Bool(true),
|
||||
ShutdownGracePeriod: metav1.Duration{Duration: 60 * time.Second},
|
||||
|
@ -104,9 +104,6 @@ type LoggingConfiguration struct {
|
||||
// VModule overrides the verbosity threshold for individual files.
|
||||
// Only supported for "text" log format.
|
||||
VModule VModuleConfiguration
|
||||
// [Experimental] When enabled prevents logging of fields tagged as sensitive (passwords, keys, tokens).
|
||||
// Runtime log sanitization may introduce significant computation overhead and therefore should not be enabled in production.`)
|
||||
Sanitization bool
|
||||
// [Experimental] Options holds additional parameters that are specific
|
||||
// to the different logging formats. Only the options for the selected
|
||||
// format get used, but all of them get validated.
|
||||
|
@ -101,9 +101,6 @@ type LoggingConfiguration struct {
|
||||
// VModule overrides the verbosity threshold for individual files.
|
||||
// Only supported for "text" log format.
|
||||
VModule VModuleConfiguration `json:"vmodule,omitempty"`
|
||||
// [Experimental] When enabled prevents logging of fields tagged as sensitive (passwords, keys, tokens).
|
||||
// Runtime log sanitization may introduce significant computation overhead and therefore should not be enabled in production.`)
|
||||
Sanitization bool `json:"sanitization,omitempty"`
|
||||
// [Experimental] Options holds additional parameters that are specific
|
||||
// to the different logging formats. Only the options for the selected
|
||||
// format get used, but all of them get validated.
|
||||
|
@ -226,7 +226,6 @@ func autoConvert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in
|
||||
out.FlushFrequency = time.Duration(in.FlushFrequency)
|
||||
out.Verbosity = config.VerbosityLevel(in.Verbosity)
|
||||
out.VModule = *(*config.VModuleConfiguration)(unsafe.Pointer(&in.VModule))
|
||||
out.Sanitization = in.Sanitization
|
||||
if err := Convert_v1alpha1_FormatOptions_To_config_FormatOptions(&in.Options, &out.Options, s); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -238,7 +237,6 @@ func autoConvert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in
|
||||
out.FlushFrequency = time.Duration(in.FlushFrequency)
|
||||
out.Verbosity = uint32(in.Verbosity)
|
||||
out.VModule = *(*VModuleConfiguration)(unsafe.Pointer(&in.VModule))
|
||||
out.Sanitization = in.Sanitization
|
||||
if err := Convert_config_FormatOptions_To_v1alpha1_FormatOptions(&in.Options, &out.Options, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -71,8 +71,6 @@ func BindLoggingFlags(c *config.LoggingConfiguration, fs *pflag.FlagSet) {
|
||||
fs.DurationVar(&c.FlushFrequency, logFlushFreqFlagName, logFlushFreq, "Maximum number of seconds between log flushes")
|
||||
fs.VarP(&c.Verbosity, "v", "v", "number for the log level verbosity")
|
||||
fs.Var(&c.VModule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging (only works for text log format)")
|
||||
fs.BoolVar(&c.Sanitization, "experimental-logging-sanitization", c.Sanitization, `[Experimental] When enabled prevents logging of fields tagged as sensitive (passwords, keys, tokens).
|
||||
Runtime log sanitization may introduce significant computation overhead and therefore should not be enabled in production.`)
|
||||
|
||||
// JSON options. We only register them if "json" is a valid format. The
|
||||
// config file API however always has them.
|
||||
|
@ -36,21 +36,6 @@ Expected output:
|
||||
{"ts":1624215726270.8428,"caller":"cmd/logger.go:64","msg":"Log with sensitive key, data: {\"secret\"}\n","v":0}
|
||||
```
|
||||
|
||||
## Logging sanitization
|
||||
|
||||
```console
|
||||
go run ./staging/src/k8s.io/component-base/logs/example/cmd/logger.go --experimental-logging-sanitization
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
I0605 22:04:02.019609 3229645 logger.go:58] Log using Infof, key: value
|
||||
I0605 22:04:02.019677 3229645 logger.go:59] "Log using InfoS" key="value"
|
||||
E0605 22:04:02.019698 3229645 logger.go:61] Log using Errorf, err: fail
|
||||
E0605 22:04:02.019709 3229645 logger.go:62] "Log using ErrorS" err="fail"
|
||||
I0605 22:04:02.019714 3229645 logger.go:64] Log message has been redacted. Log argument #0 contains: [secret-key]
|
||||
```
|
||||
|
||||
## Verbosity
|
||||
|
||||
```console
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"k8s.io/component-base/config"
|
||||
"k8s.io/component-base/config/v1alpha1"
|
||||
"k8s.io/component-base/logs/registry"
|
||||
"k8s.io/component-base/logs/sanitization"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
@ -86,9 +85,6 @@ func (o *Options) apply() {
|
||||
klog.SetLogger(log)
|
||||
logrFlush = flush
|
||||
}
|
||||
if o.Config.Sanitization {
|
||||
klog.SetLogFilter(&sanitization.SanitizingFilter{})
|
||||
}
|
||||
if err := loggingFlags.Lookup("v").Value.Set(o.Config.Verbosity.String()); err != nil {
|
||||
panic(fmt.Errorf("internal error while setting klog verbosity: %v", err))
|
||||
}
|
||||
|
@ -33,14 +33,12 @@ func TestFlags(t *testing.T) {
|
||||
o.AddFlags(fs)
|
||||
fs.SetOutput(&output)
|
||||
fs.PrintDefaults()
|
||||
want := ` --experimental-logging-sanitization [Experimental] When enabled prevents logging of fields tagged as sensitive (passwords, keys, tokens).
|
||||
Runtime log sanitization may introduce significant computation overhead and therefore should not be enabled in production.
|
||||
--log-flush-frequency duration Maximum number of seconds between log flushes (default 5s)
|
||||
--logging-format string Sets the log format. Permitted formats: "text".
|
||||
Non-default formats don't honor these flags: --add-dir-header, --alsologtostderr, --log-backtrace-at, --log-dir, --log-file, --log-file-max-size, --logtostderr, --one-output, --skip-headers, --skip-log-headers, --stderrthreshold, --vmodule.
|
||||
Non-default choices are currently alpha and subject to change without warning. (default "text")
|
||||
-v, --v Level number for the log level verbosity
|
||||
--vmodule pattern=N,... comma-separated list of pattern=N settings for file-filtered logging (only works for text log format)
|
||||
want := ` --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s)
|
||||
--logging-format string Sets the log format. Permitted formats: "text".
|
||||
Non-default formats don't honor these flags: --add-dir-header, --alsologtostderr, --log-backtrace-at, --log-dir, --log-file, --log-file-max-size, --logtostderr, --one-output, --skip-headers, --skip-log-headers, --stderrthreshold, --vmodule.
|
||||
Non-default choices are currently alpha and subject to change without warning. (default "text")
|
||||
-v, --v Level number for the log level verbosity
|
||||
--vmodule pattern=N,... comma-separated list of pattern=N settings for file-filtered logging (only works for text log format)
|
||||
`
|
||||
if !assert.Equal(t, want, output.String()) {
|
||||
t.Errorf("Wrong list of flags. expect %q, got %q", want, output.String())
|
||||
@ -64,15 +62,6 @@ func TestOptions(t *testing.T) {
|
||||
args: []string{"--logging-format=text"},
|
||||
want: newOptions,
|
||||
},
|
||||
{
|
||||
name: "log sanitization",
|
||||
args: []string{"--experimental-logging-sanitization"},
|
||||
want: func() *Options {
|
||||
c := newOptions.Config.DeepCopy()
|
||||
c.Sanitization = true
|
||||
return &Options{*c}
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Unsupported log format",
|
||||
args: []string{"--logging-format=test"},
|
||||
|
@ -1,230 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sanitization
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func TestKlogIntegration(t *testing.T) {
|
||||
|
||||
fs := flag.FlagSet{}
|
||||
klog.InitFlags(&fs)
|
||||
err := fs.Set("v", "1")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to set verbosity")
|
||||
}
|
||||
err = fs.Set("logtostderr", "false")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to set verbosity")
|
||||
}
|
||||
tcs := []struct {
|
||||
name string
|
||||
fun func()
|
||||
format string
|
||||
}{
|
||||
{
|
||||
name: "Info",
|
||||
fun: func() {
|
||||
klog.Info("test ", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "V(1).Info",
|
||||
fun: func() {
|
||||
klog.V(1).Info("test ", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "Infof",
|
||||
fun: func() {
|
||||
klog.Infof("test %v", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #0 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "V(1).Infof",
|
||||
fun: func() {
|
||||
klog.V(1).Infof("test %v", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #0 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "Infoln",
|
||||
fun: func() {
|
||||
klog.Infoln("test", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "V(1).Infoln",
|
||||
fun: func() {
|
||||
klog.V(1).Infoln("test", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "InfoDepth",
|
||||
fun: func() {
|
||||
klog.InfoDepth(1, "test ", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "InfoS",
|
||||
fun: func() {
|
||||
klog.InfoS("test", "data", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] "Log message has been redacted." key="data" types=[password]`,
|
||||
},
|
||||
{
|
||||
name: "V(1).InfoS",
|
||||
fun: func() {
|
||||
klog.V(1).InfoS("test", "data", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] "Log message has been redacted." key="data" types=[password]`,
|
||||
},
|
||||
{
|
||||
name: "InfoSDepth",
|
||||
fun: func() {
|
||||
klog.InfoSDepth(1, "test", "data", datapolItem())
|
||||
},
|
||||
format: `I%s %s %d klog_test.go:%d] "Log message has been redacted." key="data" types=[password]`,
|
||||
},
|
||||
{
|
||||
name: "Warning",
|
||||
fun: func() {
|
||||
klog.Warning("test ", datapolItem())
|
||||
},
|
||||
format: `W%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "WarningDepth",
|
||||
fun: func() {
|
||||
klog.WarningDepth(1, "test ", datapolItem())
|
||||
},
|
||||
format: `W%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "Warningln",
|
||||
fun: func() {
|
||||
klog.Warningln("test", datapolItem())
|
||||
},
|
||||
format: `W%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "Warningf",
|
||||
fun: func() {
|
||||
klog.Warningf("test %d", datapolItem())
|
||||
},
|
||||
format: `W%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #0 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "Error",
|
||||
fun: func() {
|
||||
klog.Error("test ", datapolItem())
|
||||
},
|
||||
format: `E%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "ErrorDepth",
|
||||
fun: func() {
|
||||
klog.ErrorDepth(1, "test ", datapolItem())
|
||||
},
|
||||
format: `E%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "Errorln",
|
||||
fun: func() {
|
||||
klog.Errorln("test", datapolItem())
|
||||
},
|
||||
format: `E%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #1 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "Errorf",
|
||||
fun: func() {
|
||||
klog.Errorf("test %d", datapolItem())
|
||||
},
|
||||
format: `E%s %s %d klog_test.go:%d] Log message has been redacted. Log argument #0 contains: [password]`,
|
||||
},
|
||||
{
|
||||
name: "ErrorS",
|
||||
fun: func() {
|
||||
err := errors.New("fail")
|
||||
klog.ErrorS(err, "test", "data", datapolItem())
|
||||
},
|
||||
format: `E%s %s %d klog_test.go:%d] "Log message has been redacted." err="fail" key="data" types=[password]`,
|
||||
},
|
||||
{
|
||||
name: "ErrorSDepth",
|
||||
fun: func() {
|
||||
err := errors.New("fail")
|
||||
klog.ErrorSDepth(1, err, "test", "data", datapolItem())
|
||||
},
|
||||
format: `E%s %s %d klog_test.go:%d] "Log message has been redacted." err="fail" key="data" types=[password]`,
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
klog.SetOutputBySeverity("INFO", &buffer)
|
||||
defer klog.SetOutputBySeverity("INFO", nil)
|
||||
klog.SetLogFilter(&SanitizingFilter{})
|
||||
defer klog.SetLogFilter(nil)
|
||||
|
||||
tc.fun()
|
||||
var date string
|
||||
var time string
|
||||
var pid uint64
|
||||
var lineNum uint64
|
||||
|
||||
logString := normalizeKlogLine(strings.TrimSuffix(buffer.String(), "\n"))
|
||||
n, err := fmt.Sscanf(logString, tc.format, &date, &time, &pid, &lineNum)
|
||||
if n != 4 || err != nil {
|
||||
t.Errorf("log format error: %d elements, error %s:\n%s", n, err, logString)
|
||||
}
|
||||
expect := fmt.Sprintf(tc.format, date, time, pid, lineNum)
|
||||
if !assert.Equal(t, expect, logString) {
|
||||
t.Errorf("Info has wrong format \n expect:%s\n got:%s", expect, logString)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
re = regexp.MustCompile(`\s{2,}`)
|
||||
)
|
||||
|
||||
// normalizeKlogLine removes duplicate whitespaces to make lines match no matter the environment.
|
||||
// Klog padds the log header to try to maintain same width. Depending on how high the process
|
||||
// pid is it make lead to additional whitespaces.
|
||||
func normalizeKlogLine(s string) string {
|
||||
return re.ReplaceAllString(s, " ")
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sanitization
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/component-base/logs/datapol"
|
||||
)
|
||||
|
||||
const (
|
||||
datapolMsgFmt = "Log message has been redacted. Log argument #%d contains: %v"
|
||||
datapolMsg = "Log message has been redacted."
|
||||
)
|
||||
|
||||
// SanitizingFilter implements the LogFilter interface from klog with a set of functions that inspects the arguments with the datapol library
|
||||
type SanitizingFilter struct{}
|
||||
|
||||
// Filter is the filter function for the non-formatting logging functions of klog.
|
||||
func (sf *SanitizingFilter) Filter(args []interface{}) []interface{} {
|
||||
for i, v := range args {
|
||||
types := datapol.Verify(v)
|
||||
if len(types) > 0 {
|
||||
return []interface{}{fmt.Sprintf(datapolMsgFmt, i, types)}
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
// FilterF is the filter function for the formatting logging functions of klog
|
||||
func (sf *SanitizingFilter) FilterF(fmt string, args []interface{}) (string, []interface{}) {
|
||||
for i, v := range args {
|
||||
types := datapol.Verify(v)
|
||||
if len(types) > 0 {
|
||||
return datapolMsgFmt, []interface{}{i, types}
|
||||
}
|
||||
}
|
||||
return fmt, args
|
||||
|
||||
}
|
||||
|
||||
// FilterS is the filter for the structured logging functions of klog.
|
||||
func (sf *SanitizingFilter) FilterS(msg string, keysAndValues []interface{}) (string, []interface{}) {
|
||||
for i, v := range keysAndValues {
|
||||
types := datapol.Verify(v)
|
||||
if len(types) > 0 {
|
||||
if i%2 == 0 {
|
||||
return datapolMsg, []interface{}{"key_index", i, "types", types}
|
||||
}
|
||||
// since we scanned linearly we can safely log the key.
|
||||
return datapolMsg, []interface{}{"key", keysAndValues[i-1], "types", types}
|
||||
}
|
||||
}
|
||||
return msg, keysAndValues
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sanitization
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type withDatapolTag struct {
|
||||
Key string `json:"key" datapolicy:"password"`
|
||||
}
|
||||
|
||||
func datapolItem() interface{} {
|
||||
return withDatapolTag{Key: "hunter2"}
|
||||
}
|
||||
|
||||
func TestFilter(t *testing.T) {
|
||||
filter := &SanitizingFilter{}
|
||||
testcases := []struct {
|
||||
input []interface{}
|
||||
output []interface{}
|
||||
}{{
|
||||
input: []interface{}{},
|
||||
output: []interface{}{},
|
||||
}, {
|
||||
input: []interface{}{
|
||||
"nothing special", "really",
|
||||
},
|
||||
output: []interface{}{
|
||||
"nothing special", "really",
|
||||
},
|
||||
}, {
|
||||
input: []interface{}{
|
||||
datapolItem(),
|
||||
},
|
||||
output: []interface{}{
|
||||
"Log message has been redacted. Log argument #0 contains: [password]",
|
||||
},
|
||||
}, {
|
||||
input: []interface{}{
|
||||
"nothing special", datapolItem(),
|
||||
},
|
||||
output: []interface{}{
|
||||
"Log message has been redacted. Log argument #1 contains: [password]",
|
||||
},
|
||||
}}
|
||||
for _, tc := range testcases {
|
||||
output := filter.Filter(tc.input)
|
||||
if !assert.ElementsMatch(t, tc.output, output) {
|
||||
t.Errorf("Unexpected filter output for %v, want: %v, got %v", tc.input, tc.output, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterF(t *testing.T) {
|
||||
filter := &SanitizingFilter{}
|
||||
testcases := []struct {
|
||||
inputFmt string
|
||||
input []interface{}
|
||||
outputFmt string
|
||||
output []interface{}
|
||||
}{{
|
||||
inputFmt: "",
|
||||
input: []interface{}{},
|
||||
outputFmt: "",
|
||||
output: []interface{}{},
|
||||
}, {
|
||||
inputFmt: "%s: %s",
|
||||
input: []interface{}{
|
||||
"nothing special", "really",
|
||||
},
|
||||
outputFmt: "%s: %s",
|
||||
output: []interface{}{
|
||||
"nothing special", "really",
|
||||
},
|
||||
}, {
|
||||
inputFmt: "%v",
|
||||
input: []interface{}{
|
||||
datapolItem(),
|
||||
},
|
||||
outputFmt: "Log message has been redacted. Log argument #%d contains: %v",
|
||||
output: []interface{}{
|
||||
0, []string{"password"},
|
||||
},
|
||||
}, {
|
||||
inputFmt: "%v",
|
||||
input: []interface{}{
|
||||
"nothing special", datapolItem(),
|
||||
},
|
||||
outputFmt: "Log message has been redacted. Log argument #%d contains: %v",
|
||||
output: []interface{}{
|
||||
1, []string{"password"},
|
||||
},
|
||||
}}
|
||||
for _, tc := range testcases {
|
||||
outputFmt, output := filter.FilterF(tc.inputFmt, tc.input)
|
||||
correctFmt := outputFmt == tc.outputFmt
|
||||
correctArgs := assert.ElementsMatch(t, tc.output, output)
|
||||
if !correctFmt || !correctArgs {
|
||||
t.Errorf("Error while executing testcase %s, %v", tc.inputFmt, tc.input)
|
||||
}
|
||||
if !correctFmt {
|
||||
t.Errorf("Unexpected output format string want %v, got %v", tc.outputFmt, outputFmt)
|
||||
}
|
||||
if !correctArgs {
|
||||
t.Errorf("Unexpected filter output arguments want: %v, got %v", tc.output, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterS(t *testing.T) {
|
||||
filter := &SanitizingFilter{}
|
||||
testcases := []struct {
|
||||
inputMsg string
|
||||
input []interface{}
|
||||
outputMsg string
|
||||
output []interface{}
|
||||
}{{
|
||||
inputMsg: "",
|
||||
input: []interface{}{},
|
||||
outputMsg: "",
|
||||
output: []interface{}{},
|
||||
}, {
|
||||
inputMsg: "Message",
|
||||
input: []interface{}{
|
||||
"nothing special", "really",
|
||||
},
|
||||
outputMsg: "Message",
|
||||
output: []interface{}{
|
||||
"nothing special", "really",
|
||||
},
|
||||
}, {
|
||||
inputMsg: "%v",
|
||||
input: []interface{}{
|
||||
datapolItem(), "value1", "key2", "value2",
|
||||
},
|
||||
outputMsg: "Log message has been redacted.",
|
||||
output: []interface{}{
|
||||
"key_index", 0, "types", []string{"password"},
|
||||
},
|
||||
}, {
|
||||
inputMsg: "%v",
|
||||
input: []interface{}{
|
||||
"key1", "value1", datapolItem(), "value2",
|
||||
},
|
||||
outputMsg: "Log message has been redacted.",
|
||||
output: []interface{}{
|
||||
"key_index", 2, "types", []string{"password"},
|
||||
},
|
||||
}, {
|
||||
inputMsg: "%v",
|
||||
input: []interface{}{
|
||||
"key1", datapolItem(), "key2", "value2",
|
||||
},
|
||||
outputMsg: "Log message has been redacted.",
|
||||
output: []interface{}{
|
||||
"key", "key1", "types", []string{"password"},
|
||||
},
|
||||
}, {
|
||||
inputMsg: "%v",
|
||||
input: []interface{}{
|
||||
"key1", "value1", "key2", datapolItem(),
|
||||
},
|
||||
outputMsg: "Log message has been redacted.",
|
||||
output: []interface{}{
|
||||
"key", "key2", "types", []string{"password"},
|
||||
},
|
||||
}}
|
||||
for _, tc := range testcases {
|
||||
outputMsg, output := filter.FilterS(tc.inputMsg, tc.input)
|
||||
correctMsg := outputMsg == tc.outputMsg
|
||||
correctArgs := assert.ElementsMatch(t, tc.output, output)
|
||||
if !correctMsg || !correctArgs {
|
||||
t.Errorf("Error while executing testcase %s, %v", tc.inputMsg, tc.input)
|
||||
}
|
||||
if !correctMsg {
|
||||
t.Errorf("Unexpected output format string want %v, got %v", tc.outputMsg, outputMsg)
|
||||
}
|
||||
if !correctArgs {
|
||||
t.Errorf("Unexpected filter output arguments want: %v, got %v", tc.output, output)
|
||||
}
|
||||
}
|
||||
}
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -1939,12 +1939,10 @@ k8s.io/component-base/configz
|
||||
k8s.io/component-base/featuregate
|
||||
k8s.io/component-base/featuregate/testing
|
||||
k8s.io/component-base/logs
|
||||
k8s.io/component-base/logs/datapol
|
||||
k8s.io/component-base/logs/json
|
||||
k8s.io/component-base/logs/json/register
|
||||
k8s.io/component-base/logs/logreduction
|
||||
k8s.io/component-base/logs/registry
|
||||
k8s.io/component-base/logs/sanitization
|
||||
k8s.io/component-base/logs/testinit
|
||||
k8s.io/component-base/metrics
|
||||
k8s.io/component-base/metrics/legacyregistry
|
||||
|
Loading…
Reference in New Issue
Block a user