do not fail on non-existing kubeconfig files

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
Ahmet Alp Balkan 2020-04-16 19:55:34 -07:00
parent 0e50f15393
commit 68b842f39b
No known key found for this signature in database
GPG Key ID: 441833503E604E2C
7 changed files with 47 additions and 7 deletions

View File

@ -13,6 +13,7 @@ import (
"github.com/mattn/go-isatty" "github.com/mattn/go-isatty"
"github.com/ahmetb/kubectx/internal/env" "github.com/ahmetb/kubectx/internal/env"
"github.com/ahmetb/kubectx/internal/kubeconfig"
"github.com/ahmetb/kubectx/internal/printer" "github.com/ahmetb/kubectx/internal/printer"
) )
@ -21,6 +22,17 @@ type InteractiveSwitchOp struct {
} }
func (op InteractiveSwitchOp) Run(_, stderr io.Writer) error { func (op InteractiveSwitchOp) Run(_, stderr io.Writer) error {
// parse kubeconfig just to see if it can be loaded
kc := new(kubeconfig.Kubeconfig).WithLoader(defaultLoader)
if err := kc.Parse(); err != nil {
if isENOENT(err) {
printer.Warning(stderr, "kubeconfig file not found")
return nil
}
return errors.Wrap(err, "kubeconfig error")
}
kc.Close()
cmd := exec.Command("fzf", "--ansi", "--no-preview") cmd := exec.Command("fzf", "--ansi", "--no-preview")
var out bytes.Buffer var out bytes.Buffer
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin

View File

@ -33,7 +33,7 @@ func (*StandardKubeconfigLoader) Load() (kubeconfig.ReadWriteResetCloser, error)
f, err := os.OpenFile(cfgPath, os.O_RDWR, 0) f, err := os.OpenFile(cfgPath, os.O_RDWR, 0)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, errors.Errorf("kubeconfig file not found at %s", cfgPath) return nil, errors.Wrap(err, "kubeconfig file not found")
} }
return nil, errors.Wrap(err, "failed to open file") return nil, errors.Wrap(err, "failed to open file")
} }

View File

@ -6,8 +6,9 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
)
"github.com/ahmetb/kubectx/internal/kubeconfig"
)
func withTestVar(key, value string) func() { func withTestVar(key, value string) func() {
// TODO(ahmetb) this method is currently duplicated // TODO(ahmetb) this method is currently duplicated
@ -131,6 +132,18 @@ func Test_kubeconfigPath_envOvverideDoesNotSupportPathSeparator(t *testing.T) {
} }
} }
func TestStandardKubeconfigLoader_returnsNotFoundErr(t *testing.T) {
defer withTestVar("KUBECONFIG", "foo")()
kc := new(kubeconfig.Kubeconfig).WithLoader(defaultLoader)
err := kc.Parse()
if err == nil {
t.Fatal("expected err")
}
if !isENOENT(err) {
t.Fatalf("expected ENOENT error; got=%v", err)
}
}
func testfile(t *testing.T, contents string) (path string, cleanup func()) { func testfile(t *testing.T, contents string) (path string, cleanup func()) {
t.Helper() t.Helper()

View File

@ -3,6 +3,7 @@ package main
import ( import (
"fmt" "fmt"
"io" "io"
"os"
"facette.io/natsort" "facette.io/natsort"
"github.com/fatih/color" "github.com/fatih/color"
@ -15,10 +16,14 @@ import (
// ListOp describes listing contexts. // ListOp describes listing contexts.
type ListOp struct{} type ListOp struct{}
func (_ ListOp) Run(stdout, _ io.Writer) error { func (_ ListOp) Run(stdout, stderr io.Writer) error {
kc := new(kubeconfig.Kubeconfig).WithLoader(defaultLoader) kc := new(kubeconfig.Kubeconfig).WithLoader(defaultLoader)
defer kc.Close() defer kc.Close()
if err := kc.Parse(); err != nil { if err := kc.Parse(); err != nil {
if isENOENT(err) {
printer.Warning(stderr, "kubeconfig file not found")
return nil
}
return errors.Wrap(err, "kubeconfig error") return errors.Wrap(err, "kubeconfig error")
} }
@ -45,3 +50,14 @@ func (_ ListOp) Run(stdout, _ io.Writer) error {
} }
return nil return nil
} }
// isENOENT determines if the underlying error is os.IsNotExist. Right now
// errors from github.com/pkg/errors doesn't work with os.IsNotExist.
func isENOENT(err error) bool {
for e := err; e != nil; e = errors.Unwrap(e) {
if os.IsNotExist(e) {
return true
}
}
return false
}

1
go.mod
View File

@ -7,7 +7,6 @@ require (
github.com/fatih/color v1.9.0 github.com/fatih/color v1.9.0
github.com/google/go-cmp v0.4.0 github.com/google/go-cmp v0.4.0
github.com/mattn/go-isatty v0.0.12 github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-tty v0.0.3 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
) )

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bats #!/usr/bin/env bats
COMMAND="$BATS_TEST_DIRNAME/../kubectx" COMMAND="${COMMAND:-$BATS_TEST_DIRNAME/../kubectx}"
load common load common
@ -29,7 +29,7 @@ load common
run ${COMMAND} run ${COMMAND}
echo "$output" echo "$output"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
[[ "$output" = "" ]] [[ "$output" = "warning: kubeconfig file not found" ]]
} }
@test "get one context and list contexts" { @test "get one context and list contexts" {

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bats #!/usr/bin/env bats
COMMAND="${BATS_TEST_DIRNAME}/../kubens" COMMAND="${COMMAND:-$BATS_TEST_DIRNAME/../kubens}"
export KUBECTL="$BATS_TEST_DIRNAME/../test/mock-kubectl" export KUBECTL="$BATS_TEST_DIRNAME/../test/mock-kubectl"
load common load common