Skip to content

Commit

Permalink
Add warning log callback in client-go loading rules (kubernetes#117233)
Browse files Browse the repository at this point in the history
* Add warning log callback in client-go loading rules

This provides a way to consumers use their own custom warning
mechanisms instead default klog warning.

* Use typed error instead plain string

* Fix interface change in unit test
  • Loading branch information
ardaguclu authored and wangzhilong23 committed Feb 9, 2024
1 parent e2c2628 commit fe8d1bd
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
24 changes: 23 additions & 1 deletion staging/src/k8s.io/client-go/tools/clientcmd/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,28 @@ type ClientConfigLoadingRules struct {
// WarnIfAllMissing indicates whether the configuration files pointed by KUBECONFIG environment variable are present or not.
// In case of missing files, it warns the user about the missing files.
WarnIfAllMissing bool

// Warner is the warning log callback to use in case of missing files.
Warner WarningHandler
}

// WarningHandler allows to set the logging function to use
type WarningHandler func(error)

func (handler WarningHandler) Warn(err error) {
if handler == nil {
klog.V(1).Info(err)
} else {
handler(err)
}
}

type MissingConfigError struct {
Missing []string
}

func (c MissingConfigError) Error() string {
return fmt.Sprintf("Config not found: %s", strings.Join(c.Missing, ", "))
}

// ClientConfigLoadingRules implements the ClientConfigLoader interface.
Expand Down Expand Up @@ -219,7 +241,7 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
}

if rules.WarnIfAllMissing && len(missingList) > 0 && len(kubeconfigs) == 0 {
klog.Warningf("Config not found: %s", strings.Join(missingList, ", "))
rules.Warner.Warn(MissingConfigError{Missing: missingList})
}

// first merge all of our maps
Expand Down
67 changes: 66 additions & 1 deletion staging/src/k8s.io/client-go/tools/clientcmd/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package clientcmd

import (
"bytes"
"flag"
"fmt"
"os"
"path"
Expand All @@ -32,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest"
"k8s.io/klog/v2"
)

var (
Expand Down Expand Up @@ -120,14 +122,77 @@ func TestNonExistentCommandLineFile(t *testing.T) {
}

func TestToleratingMissingFiles(t *testing.T) {
envVarValue := "bogus"
loadingRules := ClientConfigLoadingRules{
Precedence: []string{"bogus1", "bogus2", "bogus3"},
Precedence: []string{"bogus1", "bogus2", "bogus3"},
WarnIfAllMissing: true,
Warner: func(err error) { klog.Warning(err) },
}

buffer := &bytes.Buffer{}

klog.LogToStderr(false)
klog.SetOutput(buffer)

_, err := loadingRules.Load()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
klog.Flush()
expectedLog := fmt.Sprintf("Config not found: %s", envVarValue)
if !strings.Contains(buffer.String(), expectedLog) {
t.Fatalf("expected log: \"%s\"", expectedLog)
}
}

func TestWarningMissingFiles(t *testing.T) {
envVarValue := "bogus"
os.Setenv(RecommendedConfigPathEnvVar, envVarValue)
loadingRules := NewDefaultClientConfigLoadingRules()

buffer := &bytes.Buffer{}

flags := &flag.FlagSet{}
klog.InitFlags(flags)
flags.Set("v", "1")
klog.LogToStderr(false)
klog.SetOutput(buffer)

_, err := loadingRules.Load()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
klog.Flush()

expectedLog := fmt.Sprintf("Config not found: %s", envVarValue)
if !strings.Contains(buffer.String(), expectedLog) {
t.Fatalf("expected log: \"%s\"", expectedLog)
}
}

func TestNoWarningMissingFiles(t *testing.T) {
envVarValue := "bogus"
os.Setenv(RecommendedConfigPathEnvVar, envVarValue)
loadingRules := NewDefaultClientConfigLoadingRules()

buffer := &bytes.Buffer{}

flags := &flag.FlagSet{}
klog.InitFlags(flags)
flags.Set("v", "0")
klog.LogToStderr(false)
klog.SetOutput(buffer)

_, err := loadingRules.Load()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
klog.Flush()

logNotExpected := fmt.Sprintf("Config not found: %s", envVarValue)
if strings.Contains(buffer.String(), logNotExpected) {
t.Fatalf("log not expected: \"%s\"", logNotExpected)
}
}

func TestErrorReadingFile(t *testing.T) {
Expand Down

0 comments on commit fe8d1bd

Please sign in to comment.