mirror of
https://github.com/ahmetb/kubectx.git
synced 2025-06-24 14:32:24 +00:00
Add support for -u/--unset
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
parent
94e8d3b4c7
commit
c5f17b83e7
@ -18,6 +18,9 @@ type SwitchOp struct {
|
||||
Target string // '-' for back and forth, or NAME
|
||||
}
|
||||
|
||||
// UnsetOp indicates intention to remove current-context preference.
|
||||
type UnsetOp struct{}
|
||||
|
||||
// UnknownOp indicates an unsupported flag.
|
||||
type UnknownOp struct{ Args []string }
|
||||
|
||||
@ -36,6 +39,9 @@ func parseArgs(argv []string) Op {
|
||||
if v == "--current" || v == "-c" {
|
||||
return CurrentOp{}
|
||||
}
|
||||
if v == "--unset" || v == "-u" {
|
||||
return UnsetOp{}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(v, "-") && v != "-" {
|
||||
return UnknownOp{argv}
|
||||
|
@ -30,6 +30,12 @@ func Test_parseArgs_new(t *testing.T) {
|
||||
{name: "current long form",
|
||||
args: []string{"--current"},
|
||||
want: CurrentOp{}},
|
||||
{name: "unset shorthand",
|
||||
args: []string{"-u"},
|
||||
want: UnsetOp{}},
|
||||
{name: "unset long form",
|
||||
args: []string{"--unset"},
|
||||
want: UnsetOp{}},
|
||||
{name: "switch by name",
|
||||
args: []string{"foo"},
|
||||
want: SwitchOp{Target: "foo"}},
|
||||
|
52
cmd/kubectx/kubeconfig_raw.go
Normal file
52
cmd/kubectx/kubeconfig_raw.go
Normal file
@ -0,0 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func parseKubeconfigRaw(r io.Reader) (*yaml.Node, error) {
|
||||
var v yaml.Node
|
||||
if err := yaml.NewDecoder(r).Decode(&v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v.Content[0], nil
|
||||
}
|
||||
|
||||
func saveKubeconfigRaw(w io.Writer, rootNode *yaml.Node) error {
|
||||
enc := yaml.NewEncoder(w)
|
||||
enc.SetIndent(2)
|
||||
return enc.Encode(rootNode)
|
||||
}
|
||||
|
||||
func openKubeconfig() (f *os.File, rootNode *yaml.Node, err error) {
|
||||
cfgPath, err := kubeconfigPath()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "cannot determine kubeconfig path")
|
||||
}
|
||||
f, err = os.OpenFile(cfgPath, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to open file")
|
||||
}
|
||||
|
||||
kc, err := parseKubeconfigRaw(f)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, nil, errors.Wrap(err, "yaml parse error")
|
||||
}
|
||||
return f, kc, nil
|
||||
}
|
||||
|
||||
// resetFile deletes contents of a file and sets the seek
|
||||
// position to 0.
|
||||
func resetFile(f *os.File) error {
|
||||
if err := f.Truncate(0); err != nil {
|
||||
return errors.Wrap(err, "failed to truncate")
|
||||
}
|
||||
|
||||
_, err := f.Seek(0, 0)
|
||||
return errors.Wrap(err, "failed to seek")
|
||||
}
|
@ -22,6 +22,11 @@ func main() {
|
||||
printError(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
case UnsetOp:
|
||||
if err := unsetContext(); err != nil {
|
||||
printError(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
case ListOp:
|
||||
if err := printListContexts(os.Stdout); err != nil {
|
||||
printError(err.Error())
|
||||
|
@ -1,9 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@ -15,21 +12,12 @@ func switchContext(name string) (string, error) {
|
||||
return "", errors.Wrap(err, "failed to determine state file")
|
||||
}
|
||||
|
||||
cfgPath, err := kubeconfigPath()
|
||||
f, kc, err := openKubeconfig()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "cannot determine kubeconfig path")
|
||||
}
|
||||
f, err := os.OpenFile(cfgPath, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to open file")
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
kc, err := parseKubeconfigRaw(f)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "yaml parse error")
|
||||
}
|
||||
|
||||
prev := getCurrentContext(kc)
|
||||
|
||||
// TODO: add a check to ensure user can't switch to non-existing context.
|
||||
@ -41,12 +29,8 @@ func switchContext(name string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := f.Truncate(0); err != nil {
|
||||
return "", errors.Wrap(err, "failed to truncate")
|
||||
}
|
||||
|
||||
if _, err := f.Seek(0, 0); err != nil {
|
||||
return "", errors.Wrap(err, "failed to seek")
|
||||
if err := resetFile(f); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := saveKubeconfigRaw(f, kc); err != nil {
|
||||
@ -153,17 +137,3 @@ func modifyCurrentContext(rootNode *yaml.Node, name string) error {
|
||||
rootNode.Content = append(rootNode.Content, keyNode, valueNode)
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseKubeconfigRaw(r io.Reader) (*yaml.Node, error) {
|
||||
var v yaml.Node
|
||||
if err := yaml.NewDecoder(r).Decode(&v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v.Content[0], nil
|
||||
}
|
||||
|
||||
func saveKubeconfigRaw(w io.Writer, rootNode *yaml.Node) error {
|
||||
enc := yaml.NewEncoder(w)
|
||||
enc.SetIndent(2)
|
||||
return enc.Encode(rootNode)
|
||||
}
|
||||
|
34
cmd/kubectx/unset.go
Normal file
34
cmd/kubectx/unset.go
Normal file
@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func unsetContext() error {
|
||||
f, rootNode, err := openKubeconfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := modifyDocToUnsetContext(rootNode); err != nil {
|
||||
return errors.Wrap(err, "error while modifying current-context")
|
||||
}
|
||||
if err := resetFile(f); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := saveKubeconfigRaw(f, rootNode); err != nil {
|
||||
return errors.Wrap(err, "failed to save kubeconfig file after modification")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func modifyDocToUnsetContext(rootNode *yaml.Node) error {
|
||||
if rootNode.Kind != yaml.MappingNode {
|
||||
return errors.New("kubeconfig file is not a map document")
|
||||
}
|
||||
curCtxValNode := valueOf(rootNode, "current-context")
|
||||
curCtxValNode.Value = ""
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user