mirror of
https://github.com/ahmetb/kubectx.git
synced 2025-07-04 02:56:12 +00:00
use kyaml filters
This commit is contained in:
parent
6013c023be
commit
eee058119b
@ -15,7 +15,8 @@
|
|||||||
package kubeconfig
|
package kubeconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"errors"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,60 +25,34 @@ func (k *Kubeconfig) DeleteContextEntry(deleteName string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := contexts.PipeE(
|
||||||
i := -1
|
yaml.ElementSetter{
|
||||||
for j, ctxNode := range contexts.Content {
|
Keys: []string{"name"},
|
||||||
nameNode := valueOf(ctxNode, "name")
|
Values: []string{deleteName},
|
||||||
if nameNode != nil && nameNode.Kind == yaml.ScalarNode && nameNode.Value == deleteName {
|
},
|
||||||
i = j
|
); err != nil {
|
||||||
break
|
return err
|
||||||
}
|
|
||||||
}
|
|
||||||
if i >= 0 {
|
|
||||||
copy(contexts.Content[i:], contexts.Content[i+1:])
|
|
||||||
contexts.Content[len(contexts.Content)-1] = nil
|
|
||||||
contexts.Content = contexts.Content[:len(contexts.Content)-1]
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) ModifyCurrentContext(name string) error {
|
func (k *Kubeconfig) ModifyCurrentContext(name string) error {
|
||||||
currentCtxNode := valueOf(k.rootNode, "current-context")
|
if err := k.config.PipeE(yaml.SetField("current-context", yaml.NewScalarRNode(name))); err != nil {
|
||||||
if currentCtxNode != nil {
|
return err
|
||||||
currentCtxNode.Value = name
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if current-context field doesn't exist, create new field
|
|
||||||
keyNode := &yaml.Node{
|
|
||||||
Kind: yaml.ScalarNode,
|
|
||||||
Value: "current-context",
|
|
||||||
Tag: "!!str"}
|
|
||||||
valueNode := &yaml.Node{
|
|
||||||
Kind: yaml.ScalarNode,
|
|
||||||
Value: name,
|
|
||||||
Tag: "!!str"}
|
|
||||||
k.rootNode.Content = append(k.rootNode.Content, keyNode, valueNode)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) ModifyContextName(old, new string) error {
|
func (k *Kubeconfig) ModifyContextName(old, new string) error {
|
||||||
contexts, err := k.contextsNode()
|
context, err := k.config.Pipe(yaml.Lookup("contexts", "[name="+old+"]"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if context == nil {
|
||||||
var changed bool
|
return errors.New("\"contexts\" entry is nil")
|
||||||
for _, contextNode := range contexts.Content {
|
|
||||||
nameNode := valueOf(contextNode, "name")
|
|
||||||
if nameNode.Kind == yaml.ScalarNode && nameNode.Value == old {
|
|
||||||
nameNode.Value = new
|
|
||||||
changed = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
if err := context.PipeE(yaml.SetField("name", yaml.NewScalarRNode(new))); err != nil {
|
||||||
if !changed {
|
return err
|
||||||
return errors.New("no changes were made")
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -19,48 +19,40 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (k *Kubeconfig) contextsNode() (*yaml.Node, error) {
|
func (k *Kubeconfig) contextsNode() (*yaml.RNode, error) {
|
||||||
contexts := valueOf(k.rootNode, "contexts")
|
contexts, err := k.config.Pipe(yaml.Get("contexts"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if contexts == nil {
|
if contexts == nil {
|
||||||
return nil, errors.New("\"contexts\" entry is nil")
|
return nil, errors.New("\"contexts\" entry is nil")
|
||||||
} else if contexts.Kind != yaml.SequenceNode {
|
} else if contexts.YNode().Kind != yaml.SequenceNode {
|
||||||
return nil, errors.New("\"contexts\" is not a sequence node")
|
return nil, errors.New("\"contexts\" is not a sequence node")
|
||||||
}
|
}
|
||||||
return contexts, nil
|
return contexts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) contextNode(name string) (*yaml.Node, error) {
|
func (k *Kubeconfig) contextNode(name string) (*yaml.RNode, error) {
|
||||||
contexts, err := k.contextsNode()
|
context, err := k.config.Pipe(yaml.Lookup("contexts", "[name="+name+"]"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if context == nil {
|
||||||
for _, contextNode := range contexts.Content {
|
|
||||||
nameNode := valueOf(contextNode, "name")
|
|
||||||
if nameNode.Kind == yaml.ScalarNode && nameNode.Value == name {
|
|
||||||
return contextNode, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, errors.Errorf("context with name \"%s\" not found", name)
|
return nil, errors.Errorf("context with name \"%s\" not found", name)
|
||||||
}
|
}
|
||||||
|
return context, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) ContextNames() []string {
|
func (k *Kubeconfig) ContextNames() []string {
|
||||||
contexts := valueOf(k.rootNode, "contexts")
|
contexts, err := k.config.Pipe(yaml.Get("contexts"))
|
||||||
if contexts == nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if contexts.Kind != yaml.SequenceNode {
|
names, err := contexts.ElementValues("name")
|
||||||
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return names
|
||||||
var ctxNames []string
|
|
||||||
for _, ctx := range contexts.Content {
|
|
||||||
nameVal := valueOf(ctx, "name")
|
|
||||||
if nameVal != nil {
|
|
||||||
ctxNames = append(ctxNames, nameVal.Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ctxNames
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) ContextExists(name string) bool {
|
func (k *Kubeconfig) ContextExists(name string) bool {
|
||||||
@ -72,15 +64,3 @@ func (k *Kubeconfig) ContextExists(name string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
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
|
|
||||||
}
|
|
||||||
|
@ -14,18 +14,26 @@
|
|||||||
|
|
||||||
package kubeconfig
|
package kubeconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
// GetCurrentContext returns "current-context" value in given
|
// GetCurrentContext returns "current-context" value in given
|
||||||
// kubeconfig object Node, or returns "" if not found.
|
// kubeconfig object Node, or returns "" if not found.
|
||||||
func (k *Kubeconfig) GetCurrentContext() string {
|
func (k *Kubeconfig) GetCurrentContext() string {
|
||||||
v := valueOf(k.rootNode, "current-context")
|
v, err := k.config.Pipe(yaml.Get("current-context"))
|
||||||
if v == nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return v.Value
|
str, err := v.String()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) UnsetCurrentContext() error {
|
func (k *Kubeconfig) UnsetCurrentContext() error {
|
||||||
curCtxValNode := valueOf(k.rootNode, "current-context")
|
return k.config.PipeE(yaml.SetField("current-context", yaml.NewStringRNode("")))
|
||||||
curCtxValNode.Value = ""
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ type Kubeconfig struct {
|
|||||||
loader Loader
|
loader Loader
|
||||||
|
|
||||||
f ReadWriteResetCloser
|
f ReadWriteResetCloser
|
||||||
rootNode *yaml.Node
|
config *yaml.RNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) WithLoader(l Loader) *Kubeconfig {
|
func (k *Kubeconfig) WithLoader(l Loader) *Kubeconfig {
|
||||||
@ -65,15 +65,19 @@ func (k *Kubeconfig) Parse() error {
|
|||||||
if err := yaml.NewDecoder(f).Decode(&v); err != nil {
|
if err := yaml.NewDecoder(f).Decode(&v); err != nil {
|
||||||
return errors.Wrap(err, "failed to decode")
|
return errors.Wrap(err, "failed to decode")
|
||||||
}
|
}
|
||||||
k.rootNode = v.Content[0]
|
k.config = yaml.NewRNode(&v)
|
||||||
if k.rootNode.Kind != yaml.MappingNode {
|
if k.config.YNode().Kind != yaml.MappingNode {
|
||||||
return errors.New("kubeconfig file is not a map document")
|
return errors.New("kubeconfig file is not a map document")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) Bytes() ([]byte, error) {
|
func (k *Kubeconfig) Bytes() ([]byte, error) {
|
||||||
return yaml.Marshal(k.rootNode)
|
str, err := k.config.String()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []byte(str), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) Save() error {
|
func (k *Kubeconfig) Save() error {
|
||||||
@ -82,5 +86,5 @@ func (k *Kubeconfig) Save() error {
|
|||||||
}
|
}
|
||||||
enc := yaml.NewEncoder(k.f)
|
enc := yaml.NewEncoder(k.f)
|
||||||
enc.SetIndent(0)
|
enc.SetIndent(0)
|
||||||
return enc.Encode(k.rootNode)
|
return enc.Encode(k.config.YNode())
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,11 @@
|
|||||||
|
|
||||||
package kubeconfig
|
package kubeconfig
|
||||||
|
|
||||||
import "sigs.k8s.io/kustomize/kyaml/yaml"
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultNamespace = "default"
|
defaultNamespace = "default"
|
||||||
@ -25,53 +29,27 @@ func (k *Kubeconfig) NamespaceOfContext(contextName string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
ctxBody := valueOf(ctx, "context")
|
namespace, err := ctx.Pipe(yaml.Lookup("context", "namespace"))
|
||||||
if ctxBody == nil {
|
if namespace == nil || err != nil {
|
||||||
return defaultNamespace, nil
|
return defaultNamespace, err
|
||||||
}
|
}
|
||||||
ns := valueOf(ctxBody, "namespace")
|
nsStr, err := namespace.String()
|
||||||
if ns == nil || ns.Value == "" {
|
if nsStr == "" || err != nil {
|
||||||
return defaultNamespace, nil
|
return defaultNamespace, err
|
||||||
}
|
}
|
||||||
return ns.Value, nil
|
return strings.TrimSpace(nsStr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kubeconfig) SetNamespace(ctxName string, ns string) error {
|
func (k *Kubeconfig) SetNamespace(ctxName string, ns string) error {
|
||||||
ctxNode, err := k.contextNode(ctxName)
|
ctx, err := k.contextNode(ctxName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := ctx.PipeE(
|
||||||
var ctxBodyNodeWasEmpty bool // actual namespace value is in contexts[index].context.namespace, but .context might not exist
|
yaml.LookupCreate(yaml.MappingNode, "context"),
|
||||||
ctxBodyNode := valueOf(ctxNode, "context")
|
yaml.SetField("namespace", yaml.NewStringRNode(ns)),
|
||||||
if ctxBodyNode == nil {
|
); err != nil {
|
||||||
ctxBodyNodeWasEmpty = true
|
return err
|
||||||
ctxBodyNode = &yaml.Node{
|
|
||||||
Kind: yaml.MappingNode,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsNode := valueOf(ctxBodyNode, "namespace")
|
|
||||||
if nsNode != nil {
|
|
||||||
nsNode.Value = ns
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
keyNode := &yaml.Node{
|
|
||||||
Kind: yaml.ScalarNode,
|
|
||||||
Value: "namespace",
|
|
||||||
Tag: "!!str"}
|
|
||||||
valueNode := &yaml.Node{
|
|
||||||
Kind: yaml.ScalarNode,
|
|
||||||
Value: ns,
|
|
||||||
Tag: "!!str"}
|
|
||||||
ctxBodyNode.Content = append(ctxBodyNode.Content, keyNode, valueNode)
|
|
||||||
if ctxBodyNodeWasEmpty {
|
|
||||||
ctxNode.Content = append(ctxNode.Content, &yaml.Node{
|
|
||||||
Kind: yaml.ScalarNode,
|
|
||||||
Value: "context",
|
|
||||||
Tag: "!!str",
|
|
||||||
}, ctxBodyNode)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user