Integrate ctx swap, check for wrong ctx names

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
Ahmet Alp Balkan 2020-04-10 14:41:57 -07:00
parent 8aaefb8a94
commit ff6326c122
No known key found for this signature in database
GPG Key ID: 441833503E604E2C
2 changed files with 70 additions and 12 deletions

View File

@ -20,13 +20,15 @@ func main() {
case ListOp:
printListContexts(os.Stdout)
case SwitchOp:
var newCtx string
var err error
if v.Target == "-" {
// TODO implement swap
panic("not implemented")
}
newCtx, err := switchContext(v.Target)
newCtx, err = swapContext()
} else {
newCtx, err = switchContext(v.Target)
}
if err != nil {
printError("faield to switch context: %v", err)
printError("failed to switch context: %v", err)
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "Switched to context %q.\n", newCtx)
@ -40,5 +42,5 @@ func main() {
}
func printError(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, color.RedString("error: "+format+"\n"), args...)
fmt.Fprintf(os.Stderr, color.RedString("error: ")+format+"\n", args...)
}

View File

@ -32,11 +32,16 @@ func switchContext(name string) (string, error) {
prev := getCurrentContext(kc)
// TODO: add a check to ensure user can't switch to non-existing context.
if !checkContextExists(kc, name) {
return "", errors.Errorf("no context exists with the name: %q", name)
}
if err := modifyCurrentContext(kc, name); err != nil {
return "", err
}
if err := f.Truncate(0); err != nil {
if err := f.Truncate(0); err != nil {
return "", errors.Wrap(err, "failed to truncate")
}
@ -57,6 +62,58 @@ func switchContext(name string) (string, error) {
return name, nil
}
func checkContextExists(rootNode *yaml.Node, name string) bool {
contexts := valueOf(rootNode, "contexts")
if contexts == nil {
return false
}
if contexts.Kind != yaml.SequenceNode {
return false
}
var ctxNames []string
for _, ctx := range contexts.Content {
nameVal := valueOf(ctx, "name")
if nameVal != nil {
ctxNames = append(ctxNames, nameVal.Value)
}
}
for _, v := range ctxNames {
if v == name {
return true
}
}
return false
}
func valueOf(mapNode *yaml.Node, key string) *yaml.Node {
if mapNode.Kind != yaml.MappingNode {
return nil
}
for i, ch := range mapNode.Content {
if i%2 == 0 && ch.Kind == yaml.ScalarNode && ch.Value == key {
return mapNode.Content[i+1]
}
}
return nil
}
// swapContext switches to previously switch context.
func swapContext() (string, error) {
stateFile, err := kubectxFilePath()
if err != nil {
return "", errors.Wrap(err, "failed to determine state file")
}
prev, err := readLastContext(stateFile)
if err != nil {
return "", errors.Wrap(err, "failed to read previous context file")
}
if prev == "" {
return "", errors.New("no previous context found")
}
return switchContext(prev)
}
// getCurrentContext returns "current-context" value in given
// kubeconfig object Node, or returns "" if not found.
@ -64,12 +121,11 @@ func getCurrentContext(rootNode *yaml.Node) string {
if rootNode.Kind != yaml.MappingNode {
return ""
}
for i, ch := range rootNode.Content {
if i%2 == 0 && ch.Value == "current-context" {
return rootNode.Content[i+1].Value
}
v := valueOf(rootNode, "current-context")
if v == nil {
return ""
}
return ""
return v.Value
}
func modifyCurrentContext(rootNode *yaml.Node, name string) error {