From e462a4b92eeb24321a74eeeed900e8b618a76c56 Mon Sep 17 00:00:00 2001 From: Akaame Date: Tue, 15 Mar 2022 01:30:57 +0100 Subject: [PATCH] 348: initial impl for unsetting kubens --- cmd/kubens/flags.go | 3 ++ cmd/kubens/unset.go | 48 ++++++++++++++++++++++++++++++++ internal/kubeconfig/namespace.go | 34 +++++++++++++++++++++- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 cmd/kubens/unset.go diff --git a/cmd/kubens/flags.go b/cmd/kubens/flags.go index fc3c64d..12e1a8d 100644 --- a/cmd/kubens/flags.go +++ b/cmd/kubens/flags.go @@ -51,6 +51,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 UnsupportedOp{Err: fmt.Errorf("unsupported option '%s'", v)} } diff --git a/cmd/kubens/unset.go b/cmd/kubens/unset.go new file mode 100644 index 0000000..6c5bf21 --- /dev/null +++ b/cmd/kubens/unset.go @@ -0,0 +1,48 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "io" + + "github.com/ahmetb/kubectx/internal/kubeconfig" + "github.com/ahmetb/kubectx/internal/printer" + "github.com/pkg/errors" +) + +// UnsetOp indicates intention to remove current namespace preference. +type UnsetOp struct{} + +func (u UnsetOp) Run(_, stderr io.Writer) error { + kc := new(kubeconfig.Kubeconfig).WithLoader(kubeconfig.DefaultLoader) + defer kc.Close() + if err := kc.Parse(); err != nil { + return errors.Wrap(err, "kubeconfig error") + } + ctx := kc.GetCurrentContext() + if ctx == "" { + return errors.New("current-context is not set") + } + err := kc.UnsetNamespace(ctx) + if err != nil { + return errors.Wrap(err, "could not unset namespace for the current-context") + } + if err := kc.Save(); err != nil { + return errors.Wrap(err, "failed to save kubeconfig file") + } + + err = printer.Success(stderr, "Active namespace is unset") + return err +} diff --git a/internal/kubeconfig/namespace.go b/internal/kubeconfig/namespace.go index 5c229c8..aacb75d 100644 --- a/internal/kubeconfig/namespace.go +++ b/internal/kubeconfig/namespace.go @@ -14,7 +14,11 @@ package kubeconfig -import "gopkg.in/yaml.v3" +import ( + "errors" + + "gopkg.in/yaml.v3" +) const ( defaultNamespace = "default" @@ -75,3 +79,31 @@ func (k *Kubeconfig) SetNamespace(ctxName string, ns string) error { } return nil } + +func (k *Kubeconfig) UnsetNamespace(ctxName string) error { + ctxNode, err := k.contextNode(ctxName) + if err != nil { + return err + } + + ctxBodyNode := valueOf(ctxNode, "context") + if ctxBodyNode == nil { + return errors.New("invalid context key") + } + + newKVParis := []*yaml.Node{} + if ctxBodyNode.Kind == yaml.MappingNode { + for i := 0; i < len(ctxBodyNode.Content); i++ { + ch := ctxBodyNode.Content[i] + if ch.Kind == yaml.ScalarNode && ch.Value == "namespace" { + // Skip the value belonging to `namespace` key + i++ + continue + } + newKVParis = append(newKVParis, ch) + } + } + + ctxBodyNode.Content = newKVParis + return nil +}