diff --git a/README.md b/README.md index 87e8f47..ff2b390 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,15 @@ Active namespace is "kube-system". $ kubens - Context "test" set. Active namespace is "default". + +# change the active namespace even if it doesn't exist +$ kubens not-found-namespace --force +Context "test" set. +Active namespace is "not-found-namespace". +--- +$ kubens not-found-namespace --f +Context "test" set. +Active namespace is "not-found-namespace". ``` If you have [`fzf`](https://github.com/junegunn/fzf) installed, you can also diff --git a/cmd/kubens/flags.go b/cmd/kubens/flags.go index fc3c64d..f25c655 100644 --- a/cmd/kubens/flags.go +++ b/cmd/kubens/flags.go @@ -33,15 +33,23 @@ func (op UnsupportedOp) Run(_, _ io.Writer) error { // parseArgs looks at flags (excl. executable name, i.e. argv[0]) // and decides which operation should be taken. func parseArgs(argv []string) Op { - if len(argv) == 0 { + n := len(argv) + + if n == 0 { if cmdutil.IsInteractiveMode(os.Stdout) { return InteractiveSwitchOp{SelfCmd: os.Args[0]} } return ListOp{} } - if len(argv) == 1 { + if n == 1 || n == 2 { v := argv[0] + force := false + + if n == 2 { + force = argv[1] == "--force" || argv[1] == "-f" + } + if v == "--help" || v == "-h" { return HelpOp{} } @@ -54,7 +62,7 @@ func parseArgs(argv []string) Op { if strings.HasPrefix(v, "-") && v != "-" { return UnsupportedOp{Err: fmt.Errorf("unsupported option '%s'", v)} } - return SwitchOp{Target: argv[0]} + return SwitchOp{Target: argv[0], Force: force} } return UnsupportedOp{Err: fmt.Errorf("too many arguments")} } diff --git a/cmd/kubens/fzf.go b/cmd/kubens/fzf.go index 8a49770..f093398 100644 --- a/cmd/kubens/fzf.go +++ b/cmd/kubens/fzf.go @@ -65,7 +65,7 @@ func (op InteractiveSwitchOp) Run(_, stderr io.Writer) error { if choice == "" { return errors.New("you did not choose any of the options") } - name, err := switchNamespace(kc, choice) + name, err := switchNamespace(kc, choice, false) if err != nil { return errors.Wrap(err, "failed to switch namespace") } diff --git a/cmd/kubens/help.go b/cmd/kubens/help.go index 1337b0b..de9c044 100644 --- a/cmd/kubens/help.go +++ b/cmd/kubens/help.go @@ -35,6 +35,8 @@ func printUsage(out io.Writer) error { help := `USAGE: %PROG% : list the namespaces in the current context %PROG% : change the active namespace of current context + %PROG% --force : force change the active namespace of current context (even if it doesn't exist) + %PROG% --f : force change the active namespace of current context (even if it doesn't exist) %PROG% - : switch to the previous namespace in this context %PROG% -c, --current : show the current namespace %PROG% -h,--help : show this message diff --git a/cmd/kubens/switch.go b/cmd/kubens/switch.go index 7568683..bcf2a70 100644 --- a/cmd/kubens/switch.go +++ b/cmd/kubens/switch.go @@ -29,6 +29,7 @@ import ( type SwitchOp struct { Target string // '-' for back and forth, or NAME + Force bool // force switch even if the namespace doesn't exist } func (s SwitchOp) Run(_, stderr io.Writer) error { @@ -38,7 +39,7 @@ func (s SwitchOp) Run(_, stderr io.Writer) error { return errors.Wrap(err, "kubeconfig error") } - toNS, err := switchNamespace(kc, s.Target) + toNS, err := switchNamespace(kc, s.Target, s.Force) if err != nil { return err } @@ -46,7 +47,7 @@ func (s SwitchOp) Run(_, stderr io.Writer) error { return err } -func switchNamespace(kc *kubeconfig.Kubeconfig, ns string) (string, error) { +func switchNamespace(kc *kubeconfig.Kubeconfig, ns string, force bool) (string, error) { ctx := kc.GetCurrentContext() if ctx == "" { return "", errors.New("current-context is not set") @@ -69,12 +70,14 @@ func switchNamespace(kc *kubeconfig.Kubeconfig, ns string) (string, error) { ns = prev } - ok, err := namespaceExists(kc, ns) - if err != nil { - return "", errors.Wrap(err, "failed to query if namespace exists (is cluster accessible?)") - } - if !ok { - return "", errors.Errorf("no namespace exists with name \"%s\"", ns) + if !force { + ok, err := namespaceExists(kc, ns) + if err != nil { + return "", errors.Wrap(err, "failed to query if namespace exists (is cluster accessible?)") + } + if !ok { + return "", errors.Errorf("no namespace exists with name \"%s\"", ns) + } } if err := kc.SetNamespace(ctx, ns); err != nil {