Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use kubeconfig context namespace #3

Merged
merged 2 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Create and Edit Kubernetes job from cronjob template using your `$EDITOR`.
```
kj namespace name
kj namespace/name
kj name
```

This command opens the editor with the job yaml from specified cronjob.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/kitagry/kj
go 1.16

require (
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/goccy/go-yaml v1.8.9
github.com/mattn/go-tty v0.0.3
k8s.io/api v0.21.1
k8s.io/apimachinery v0.21.1
Expand Down
15 changes: 15 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
Expand All @@ -73,6 +75,15 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/goccy/go-yaml v1.8.9 h1:4AEXg2qx+/w29jXnXpMY6mTckmYu1TMoHteKuMf0HFg=
github.com/goccy/go-yaml v1.8.9/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand Down Expand Up @@ -144,9 +155,13 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
Expand Down
51 changes: 51 additions & 0 deletions kubeconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"os"

"github.com/goccy/go-yaml"
)

type Kubeconfig struct {
Contexts []KubeContexts `yaml:"contexts"`
CurrentContext string `yaml:"current-context"`
}

type KubeContexts struct {
Context KubeContext `yaml:"context"`
Name string `yaml:"name"`
}

type KubeContext struct {
Namespace string `yaml:"namespace"`
}

func loadKubeconfig(path string) (k Kubeconfig, err error) {
f, err := os.Open(path)
if err != nil {
return k, err
}
defer f.Close()

d := yaml.NewDecoder(f)
err = d.Decode(&k)
return k, err
}

func (k Kubeconfig) CurrentNamespace() string {
kc, ok := k.currentContext()
if !ok {
return ""
}

return kc.Namespace
}

func (k Kubeconfig) currentContext() (KubeContext, bool) {
for _, kc := range k.Contexts {
if kc.Name == k.CurrentContext {
return kc.Context, true
}
}
return KubeContext{}, false
}
74 changes: 74 additions & 0 deletions kubeconfig_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package main

import (
"reflect"
"testing"
)

const (
kubeconfigFilePath = "testdata/kubeconfig"
)

func TestLoadKubeConfig(t *testing.T) {
k, err := loadKubeconfig(kubeconfigFilePath)
if err != nil {
t.Fatalf("failed to load kubeconfig: %+v", err)
}

expect := Kubeconfig{
Contexts: []KubeContexts{
{
Context: KubeContext{
Namespace: "",
},
Name: "a",
},
{
Context: KubeContext{
Namespace: "nsB",
},
Name: "b",
},
},
CurrentContext: "b",
}

if !reflect.DeepEqual(k, expect) {
t.Errorf("kubeconfig expected %+v, got %+v", expect, k)
}
}

func TestKubeconfig_CurrentNamespace(t *testing.T) {
tests := map[string]struct {
currentContext string
expect string
}{
"Context has namespace": {
currentContext: "b",
expect: "nsB",
},
"Context has no namespace": {
currentContext: "a",
expect: "",
},
"Context doesn't exist": {
currentContext: "not exist context",
expect: "",
},
}

for n, tt := range tests {
t.Run(n, func(t *testing.T) {
k, err := loadKubeconfig(kubeconfigFilePath)
if err != nil {
t.Fatalf("failed to load kubeconfig: %+v", err)
}

k.CurrentContext = tt.currentContext
ns := k.CurrentNamespace()
if ns != tt.expect {
t.Errorf(`CurrentNamespace expected "%s", got "%s"`, tt.expect, ns)
}
})
}
}
16 changes: 15 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func run() int {
Usage:
%[1]s namespace name
%[1]s namespace/name
%[1]s name

Options:
`, cmdName)
Expand All @@ -66,6 +67,14 @@ Options:
return exitStatusErr
}

if namespace == "" {
kc, err := loadKubeconfig(*kubeconfig)
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", cmdName, err)
}
namespace = kc.CurrentNamespace()
}

cj, err := clientset.BatchV1beta1().CronJobs(namespace).Get(context.Background(), name, metav1.GetOptions{})
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", cmdName, err)
Expand Down Expand Up @@ -109,9 +118,14 @@ func getNamespaceAndName(s []string) (namespace, name string, ok bool) {
}

s = strings.Split(s[0], "/")
if len(s) != 2 {
if len(s) > 2 {
return "", "", false
}

if len(s) == 1 {
return "", s[0], true
}

return s[0], s[1], true
}

Expand Down
7 changes: 4 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ func TestGetNamespaceAndName(t *testing.T) {
name: "name",
ok: true,
},
// TODO: use default namespace for kubernetes
"only name is specified": {
inputs: []string{"name"},
ok: false,
inputs: []string{"name"},
namespace: "",
name: "name",
ok: true,
},
"inputs are nil": {
inputs: nil,
Expand Down
12 changes: 12 additions & 0 deletions testdata/kubeconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
contexts:
- context:
cluster: A
user: a
name: a
- context:
cluster: B
namespace: nsB
user: b
name: b
current-context: b