Skip to content
This repository has been archived by the owner on Sep 8, 2022. It is now read-only.

Commit

Permalink
Merge pull request #3 from postfinance/substring-match
Browse files Browse the repository at this point in the history
implement substring match
  • Loading branch information
djboris9 authored Sep 17, 2019
2 parents b85a04e + 3b74c7a commit 77aae41
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dist/
/dist
38 changes: 28 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,51 @@
[![Release](https://img.shields.io/github/release/postfinance/kubectl-ctx.svg?style=for-the-badge)](https://github.com/postfinance/kubectl-ctx/releases/latest)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge)](/LICENSE.md)
[![Go Report Card](https://img.shields.io/badge/GOREPORT-A%2B-brightgreen.svg?style=for-the-badge)](https://goreportcard.com/report/github.com/postfinance/kubectl-ctx)
# kubectl ctx plugin
Simple Plugin to display/change the current kube context in your KUBECONFIG.

# Build/Installation
## Build from source
go version >= 1.11 with modules support enabled is required to build the plugin from source
```bash
export GO111MODULES=on
go build
```

## Installation
# Installation
Pre-compiled statically linked binaries are available on the [releases page](https://github.com/postfinance/kubectl-ctx/releases).
Binary must be placed anywhere in `$PATH` named `kubectl-ctx` with execute permissions.
For further information, see the offical documentation on plugins [here](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/).

# Compatibility
Known to work on Windows and Linux. Requires kubectl >= 1.12 (tested with 1.12).
Known to work on Windows and Linux. Requires kubectl >= 1.12 (tested with versions >1.12).

# Examples
For all the examples, assume you have the following contexts.
```
foo
bar
baz
localhost
```
## display contexts
Current context is displayed in a different color.
```bash
$ kubectl ctx
bar
baz
foo
localhost
```

Substring matching can be used to display contexts. For example if you are searching a context named `ba` simply type:
```bash
$ kubectl ctx ba
bar
baz
```

## change current context
You can switch the context by providing an exact name:
```bash
$ kubectl ctx foo
current context set to "foo"
```

But it's also possible to switch to the `localhost` context by typing a substring (as long as it is a unique name), for example:
```bash
$ kubectl ctx local
current context set to "localhost"
```
66 changes: 33 additions & 33 deletions cmd/ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package cmd
import (
"fmt"
"sort"
"strings"

"github.com/fatih/color"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)

var (
Expand All @@ -25,7 +26,7 @@ var (
// in a user's KUBECONFIG
type CtxOptions struct {
configFlags *genericclioptions.ConfigFlags
rawConfig api.Config
rawConfig clientcmdapi.Config
args []string

userSpecifiedContext string
Expand All @@ -37,7 +38,7 @@ type CtxOptions struct {
// NewCtxOptions provides an instance of CtxOptions with default values
func NewCtxOptions(streams genericclioptions.IOStreams) *CtxOptions {
return &CtxOptions{
configFlags: genericclioptions.NewConfigFlags(),
configFlags: genericclioptions.NewConfigFlags(true),
IOStreams: streams,
}
}
Expand All @@ -55,16 +56,10 @@ func NewCtxCmd(streams genericclioptions.IOStreams) *cobra.Command {
if err := opt.Complete(c, args); err != nil {
return err
}

if err := opt.Validate(); err != nil {
return err
}

if err := opt.Run(); err != nil {
return err
}

return nil
return opt.Run()
},
}
return cmd
Expand Down Expand Up @@ -101,45 +96,50 @@ func (o *CtxOptions) Validate() error {
return nil
}

// Run lists all available contexts in a user's KUBECONFIG or updates the current
// context if the user passed one.
// Run lists all available contexts in a user's KUBECONFIG or updates the curren context if
// the user passed one.
func (o *CtxOptions) Run() error {
if len(o.userSpecifiedContext) > 0 {
if err := o.changeCurrentCtx(); err != nil {
return err
selected := []string{}
for _, ctx := range o.availableContexts {
if ctx == o.userSpecifiedContext {
selected = []string{ctx}
break
}
if strings.Contains(ctx, o.userSpecifiedContext) {
selected = append(selected, ctx)
}
} else {
o.printContexts()
}
return nil
}

func (o *CtxOptions) changeCurrentCtx() error {
currentCtx := o.rawConfig.CurrentContext
newCtx := o.userSpecifiedContext

// check if the user provided context exists
if _, ok := o.rawConfig.Contexts[newCtx]; !ok {
return fmt.Errorf("can't change context to \"%s\", context not found in KUBECONFIG", newCtx)
switch len(selected) {
case 0:
return fmt.Errorf("can't change context to %q, context not found in KUBECONFIG", o.userSpecifiedContext)
case 1:
return o.changeCurrentCtx(selected[0])
default:
o.printContexts(selected)
return nil
}
}

func (o *CtxOptions) changeCurrentCtx(newCtx string) error {
currentCtx := o.rawConfig.CurrentContext
if currentCtx != newCtx {
o.rawConfig.CurrentContext = newCtx
if err := clientcmd.ModifyConfig(clientcmd.NewDefaultPathOptions(), o.rawConfig, true); err != nil {
return err
}
fmt.Fprintf(o.Out, "current context set to \"%s\"\n", newCtx)
fmt.Fprintf(o.Out, "current context set to %q\n", newCtx)
}
return nil
}

// prints each context in a user's KUBECONFIG, the current context is printed
// in red
func (o *CtxOptions) printContexts() {
// prints each context in a user's KUBECONFIG, the current context is printed in red.
func (o *CtxOptions) printContexts(contexts []string) {
red := color.New(color.FgRed)
for _, ctx := range o.availableContexts {
if ctx == o.rawConfig.CurrentContext {
red.Fprintf(o.Out, "%s\n", ctx)
currentCtx := o.rawConfig.CurrentContext
for _, ctx := range contexts {
if ctx == currentCtx {
red.Fprintf(o.Out, "%s\n", currentCtx)
} else {
fmt.Fprintf(o.Out, "%s\n", ctx)
}
Expand Down
37 changes: 8 additions & 29 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,35 +1,14 @@
module github.com/postfinance/kubectl-ctx

go 1.13

require (
github.com/evanphx/json-patch v4.1.0+incompatible // indirect
github.com/Azure/go-autorest v11.1.2+incompatible // indirect
github.com/fatih/color v1.7.0
github.com/ghodss/yaml v1.0.0 // indirect
github.com/gogo/protobuf v1.1.1 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/protobuf v1.2.0 // indirect
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c // indirect
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect
github.com/googleapis/gnostic v0.2.0 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/json-iterator/go v1.1.5 // indirect
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/spf13/cobra v0.0.3
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-isatty v0.0.9 // indirect
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.3
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4 // indirect
golang.org/x/net v0.0.0-20181003013248-f5e5bdd77824 // indirect
golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced // indirect
golang.org/x/sys v0.0.0-20181003145944-af653ce8b74f // indirect
golang.org/x/text v0.3.0 // indirect
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.2.1 // indirect
k8s.io/api v0.0.0-20180925152912-a191abe0b71e // indirect
k8s.io/apimachinery v0.0.0-20181003114359-ed5594dcf47b // indirect
k8s.io/cli-runtime v0.0.0-20180927155026-de4bd7443b42
k8s.io/client-go v9.0.0-invalid+incompatible
k8s.io/cli-runtime v0.0.0-20190831080432-9d670f2021f4
k8s.io/client-go v0.0.0-20190831074946-3fe2abece89e
)
Loading

0 comments on commit 77aae41

Please sign in to comment.