mirror of
https://github.com/ahmetb/kubectx.git
synced 2026-03-13 01:12:12 +00:00
Compare commits
7 Commits
v0.9.0
...
better-ns-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd1849d8df | ||
|
|
0141ee19d2 | ||
|
|
401188fefd | ||
|
|
01bd237baa | ||
|
|
956d5953c2 | ||
|
|
4425628f91 | ||
|
|
f2021bb08b |
@@ -15,6 +15,9 @@ builds:
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
goarm: [6, 7]
|
||||
- id: kubens
|
||||
main: ./cmd/kubens
|
||||
binary: kubens
|
||||
@@ -26,9 +29,18 @@ builds:
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
goarm: [6, 7]
|
||||
archives:
|
||||
- id: kubectx-archive
|
||||
name_template: "kubectx_{{ .Tag }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
name_template: |-
|
||||
kubectx_{{ .Tag }}_{{ .Os }}_{{ .Arch -}}
|
||||
{{- with .Arm -}}
|
||||
{{- if (eq . "6") -}}hf
|
||||
{{- else -}}v{{- . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
builds:
|
||||
- kubectx
|
||||
replacements:
|
||||
@@ -39,7 +51,13 @@ archives:
|
||||
format: zip
|
||||
files: ["LICENSE"]
|
||||
- id: kubens-archive
|
||||
name_template: "kubens_{{ .Tag }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
name_template: |-
|
||||
kubens_{{ .Tag }}_{{ .Os }}_{{ .Arch -}}
|
||||
{{- with .Arm -}}
|
||||
{{- if (eq . "6") -}}hf
|
||||
{{- else -}}v{{- . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
builds:
|
||||
- kubens
|
||||
replacements:
|
||||
@@ -49,12 +67,6 @@ archives:
|
||||
- goos: windows
|
||||
format: zip
|
||||
files: ["LICENSE"]
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
algorithm: sha256
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/ahmetb/kubectx/internal/cmdutil"
|
||||
"github.com/ahmetb/kubectx/internal/env"
|
||||
"github.com/ahmetb/kubectx/internal/printer"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
type Op interface {
|
||||
@@ -15,15 +16,15 @@ type Op interface {
|
||||
}
|
||||
|
||||
func main() {
|
||||
cmdutil.PrintDeprecatedEnvWarnings(os.Stderr, os.Environ())
|
||||
cmdutil.PrintDeprecatedEnvWarnings(color.Error, os.Environ())
|
||||
|
||||
op := parseArgs(os.Args[1:])
|
||||
if err := op.Run(os.Stdout, os.Stderr); err != nil {
|
||||
printer.Error(os.Stderr, err.Error())
|
||||
if err := op.Run(color.Output, color.Error); err != nil {
|
||||
printer.Error(color.Error, err.Error())
|
||||
|
||||
if _, ok := os.LookupEnv(env.EnvDebug); ok {
|
||||
// print stack trace in verbose mode
|
||||
fmt.Fprintf(os.Stderr, "[DEBUG] error: %+v\n", err)
|
||||
fmt.Fprintf(color.Error, "[DEBUG] error: %+v\n", err)
|
||||
}
|
||||
defer os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ func (op InteractiveSwitchOp) Run(_, stderr io.Writer) error {
|
||||
}
|
||||
name, err := switchNamespace(kc, choice)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to switch context")
|
||||
return errors.Wrap(err, "failed to switch namespace")
|
||||
}
|
||||
printer.Success(stderr, "Switched to context %s.", printer.SuccessColor.Sprint(name))
|
||||
printer.Success(stderr, "Active namespace is %q.", printer.SuccessColor.Sprint(name))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -40,5 +40,5 @@ func selfName() string {
|
||||
if strings.HasPrefix(me, pluginPrefix) {
|
||||
return "kubectl " + strings.TrimPrefix(me, pluginPrefix)
|
||||
}
|
||||
return "kubectx"
|
||||
return "kubens"
|
||||
}
|
||||
|
||||
@@ -54,15 +54,7 @@ func queryNamespaces(kc *kubeconfig.Kubeconfig) ([]string, error) {
|
||||
return []string{"ns1", "ns2"}, nil
|
||||
}
|
||||
|
||||
b, err := kc.Bytes()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to convert in-memory kubeconfig to yaml")
|
||||
}
|
||||
cfg, err := clientcmd.RESTConfigFromKubeConfig(b)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialize config")
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(cfg)
|
||||
clientset, err := newKubernetesClientSet(kc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialize k8s REST client")
|
||||
}
|
||||
@@ -87,3 +79,15 @@ func queryNamespaces(kc *kubeconfig.Kubeconfig) ([]string, error) {
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func newKubernetesClientSet(kc *kubeconfig.Kubeconfig) (*kubernetes.Clientset, error) {
|
||||
b, err := kc.Bytes()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to convert in-memory kubeconfig to yaml")
|
||||
}
|
||||
cfg, err := clientcmd.RESTConfigFromKubeConfig(b)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialize config")
|
||||
}
|
||||
return kubernetes.NewForConfig(cfg)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/ahmetb/kubectx/internal/cmdutil"
|
||||
"github.com/ahmetb/kubectx/internal/env"
|
||||
"github.com/ahmetb/kubectx/internal/printer"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
type Op interface {
|
||||
@@ -15,14 +16,14 @@ type Op interface {
|
||||
}
|
||||
|
||||
func main() {
|
||||
cmdutil.PrintDeprecatedEnvWarnings(os.Stderr, os.Environ())
|
||||
cmdutil.PrintDeprecatedEnvWarnings(color.Error, os.Environ())
|
||||
op := parseArgs(os.Args[1:])
|
||||
if err := op.Run(os.Stdout, os.Stderr); err != nil {
|
||||
printer.Error(os.Stderr, err.Error())
|
||||
if err := op.Run(color.Output, color.Error); err != nil {
|
||||
printer.Error(color.Error, err.Error())
|
||||
|
||||
if _, ok := os.LookupEnv(env.EnvDebug); ok {
|
||||
// print stack trace in verbose mode
|
||||
fmt.Fprintf(os.Stderr, "[DEBUG] error: %+v\n", err)
|
||||
fmt.Fprintf(color.Error, "[DEBUG] error: %+v\n", err)
|
||||
}
|
||||
defer os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/ahmetb/kubectx/internal/cmdutil"
|
||||
)
|
||||
@@ -18,7 +20,14 @@ type NSFile struct {
|
||||
|
||||
func NewNSFile(ctx string) NSFile { return NSFile{dir: defaultDir, ctx: ctx} }
|
||||
|
||||
func (f NSFile) path() string { return filepath.Join(f.dir, f.ctx) }
|
||||
func (f NSFile) path() string {
|
||||
fn := f.ctx
|
||||
if isWindows() {
|
||||
// bug 230: eks clusters contain ':' in ctx name, not a valid file name for win32
|
||||
fn = strings.ReplaceAll(fn, ":", "__")
|
||||
}
|
||||
return filepath.Join(f.dir, fn)
|
||||
}
|
||||
|
||||
// Load reads the previous namespace setting, or returns empty if not exists.
|
||||
func (f NSFile) Load() (string, error) {
|
||||
@@ -40,3 +49,11 @@ func (f NSFile) Save(value string) error {
|
||||
}
|
||||
return ioutil.WriteFile(f.path(), []byte(value), 0644)
|
||||
}
|
||||
|
||||
// isWindows determines if the process is running on windows OS.
|
||||
func isWindows() bool {
|
||||
if os.Getenv("_FORCE_GOOS") == "windows" { // for testing
|
||||
return true
|
||||
}
|
||||
return runtime.GOOS == "windows"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@ package main
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ahmetb/kubectx/internal/testutil"
|
||||
)
|
||||
|
||||
func TestNSFile(t *testing.T) {
|
||||
@@ -36,3 +40,28 @@ func TestNSFile(t *testing.T) {
|
||||
t.Fatalf("Load()=%q; expected=%q", v, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNSFile_path_windows(t *testing.T) {
|
||||
defer testutil.WithEnvVar("_FORCE_GOOS", "windows")()
|
||||
fp := NewNSFile("a:b:c").path()
|
||||
|
||||
if expected := "a__b__c"; !strings.HasSuffix(fp, expected) {
|
||||
t.Fatalf("file did not have expected ending %q: %s", expected, fp)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_isWindows(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("won't test this case on windows")
|
||||
}
|
||||
|
||||
got := isWindows()
|
||||
if got {
|
||||
t.Fatalf("isWindows() returned true for %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
defer testutil.WithEnvVar("_FORCE_GOOS", "windows")()
|
||||
if !isWindows() {
|
||||
t.Fatalf("isWindows() failed to detect windows with env override.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
errors2 "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/ahmetb/kubectx/internal/cmdutil"
|
||||
"github.com/ahmetb/kubectx/internal/kubeconfig"
|
||||
@@ -75,14 +78,20 @@ func switchNamespace(kc *kubeconfig.Kubeconfig, ns string) (string, error) {
|
||||
}
|
||||
|
||||
func namespaceExists(kc *kubeconfig.Kubeconfig, ns string) (bool, error) {
|
||||
nses, err := queryNamespaces(kc)
|
||||
// for tests
|
||||
if os.Getenv("_MOCK_NAMESPACES") != "" {
|
||||
return ns == "ns1" || ns == "ns2", nil
|
||||
}
|
||||
|
||||
clientset, err := newKubernetesClientSet(kc)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, errors.Wrap(err, "failed to initialize k8s REST client")
|
||||
}
|
||||
for _, v := range nses {
|
||||
if v == ns {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
namespace, err := clientset.CoreV1().Namespaces().Get(ns, metav1.GetOptions{})
|
||||
if errors2.IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, nil
|
||||
return namespace != nil, errors.Wrapf(err, "failed to query "+
|
||||
"namespace %q from k8s API", ns)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user