Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Commit

Permalink
Watch namespaces and resources (#15)
Browse files Browse the repository at this point in the history
* init ns & resources

* init ns & resources

* wip scroll

* change yaml pkg

* fix podSelect bug

* tidy nsView

* render basic cluster-info

* add health to cluster-info

* add arrow scroll to infoView

* Render jobs, deployments, secrets, configmaps

* Render services resource

* reRender resourceView on tab click

Co-authored-by: yolossn <nssvlr@gmail.com>
  • Loading branch information
GnaneshKunal and yolossn committed Sep 13, 2020
1 parent debf45e commit b5a5aff
Show file tree
Hide file tree
Showing 13 changed files with 896 additions and 37 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ module github.com/yolossn/lazykubernetes
go 1.13

require (
github.com/common-nighthawk/go-figure v0.0.0-20200609044655-c4b36f998cf2
github.com/go-errors/errors v1.1.1 // indirect
github.com/imdario/mergo v0.3.8 // indirect
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/olekukonko/tablewriter v0.0.4
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
k8s.io/api v0.19.0
k8s.io/apimachinery v0.19.0
k8s.io/client-go v0.19.0
sigs.k8s.io/yaml v1.2.0

)
19 changes: 4 additions & 15 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/common-nighthawk/go-figure v0.0.0-20200609044655-c4b36f998cf2 h1:tjT4Jp4gxECvsJcYpAMtW2I3YqzBTPuB67OejxXs86s=
github.com/common-nighthawk/go-figure v0.0.0-20200609044655-c4b36f998cf2/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -103,8 +105,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5 h1:tE0w3tuL/bj1o5VMhjjE0ep6i7Fva+RYjKcMFcniJEY=
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe h1:qsVhCf2RFyyKIUe/+gJblbCpXMUki9rZrHuEctg6M/E=
Expand Down Expand Up @@ -309,37 +311,24 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/api v0.19.0 h1:XyrFIJqTYZJ2DU7FBE/bSPz7b1HvbVBuBf07oeo6eTc=
k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw=
k8s.io/api v0.19.1 h1:oZf4bYsBdjC49PdTwNfLmrfUFCwKUi94HY/+emXI8Qw=
k8s.io/api v0.19.1/go.mod h1:+u/k4/K/7vp4vsfdT7dyl8Oxk1F26Md4g5F26Tu85PU=
k8s.io/apimachinery v0.19.0 h1:gjKnAda/HZp5k4xQYjL0K/Yb66IvNqjthCb03QlKpaQ=
k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
k8s.io/apimachinery v0.19.1 h1:cwsxZazM/LA9aUsBaL4bRS5ygoM6bYp8dFk22DSYQa4=
k8s.io/apimachinery v0.19.1/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
k8s.io/client-go v0.19.0 h1:1+0E0zfWFIWeyRhQYWzimJOyAk2UT7TiARaLNwJCf7k=
k8s.io/client-go v0.19.0/go.mod h1:H9E/VT95blcFQnlyShFgnFT9ZnJOAceiUHM3MlRC+mU=
k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o=
k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kubernetes v1.19.1 h1:3Gdl9EtBiV3SYuzml1915nFLVxlx08L6bRz1b07C60k=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20200821003339-5e75c0163111 h1:AChSIFe1D4vQ5XkklbH491v1ONSmnt8fnb235DsAw1U=
k8s.io/utils v0.0.0-20200821003339-5e75c0163111/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
Expand Down
102 changes: 101 additions & 1 deletion pkg/client/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import (
"path/filepath"
"time"

v1Core "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"k8s.io/apimachinery/pkg/version"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
)
Expand Down Expand Up @@ -37,6 +40,10 @@ func Newk8s() (*K8s, error) {
return &K8s{clientset}, nil
}

func (k *K8s) GetServerInfo() (*version.Info, error) {
return k.client.DiscoveryClient.ServerVersion()
}

type NamespaceInfo struct {
Name string
Status string
Expand All @@ -59,6 +66,34 @@ func (k *K8s) ListNamespace() ([]NamespaceInfo, error) {
return ns, nil
}

// TODO: Verify timeout and handle it
func (k *K8s) WatchNamespace() (watch.Interface, error) {
ctx := context.TODO()
opts := v1.ListOptions{}
wi, err := k.client.CoreV1().Namespaces().Watch(ctx, opts)
if err != nil {
return nil, err
}
return wi, nil
}

func (k *K8s) GetNamespace(ns string) (*v1Core.Namespace, error) {
ctx := context.TODO()
opts := v1.GetOptions{}
return k.client.CoreV1().Namespaces().Get(ctx, ns, opts)
}

func (k *K8s) WatchPods(namespace string) (watch.Interface, error) {
ctx := context.TODO()
opts := v1.ListOptions{}

wi, err := k.client.CoreV1().Pods(namespace).Watch(ctx, opts)
if err != nil {
return nil, err
}
return wi, nil
}

type PodInfo struct {
Name string
Namespace string
Expand All @@ -70,6 +105,7 @@ type PodInfo struct {
}

func (k *K8s) ListPods(namespace string) ([]PodInfo, error) {

ctx := context.TODO()
opts := v1.ListOptions{}
pods, _ := k.client.CoreV1().Pods(namespace).List(ctx, opts)
Expand Down Expand Up @@ -102,6 +138,23 @@ func (k *K8s) ListPods(namespace string) ([]PodInfo, error) {
return podList, nil
}

func (k *K8s) DescribePod(ns string, podname string) (*v1Core.Pod, error) {
ctx := context.TODO()
opts := v1.GetOptions{}

out, err := k.client.CoreV1().Pods(ns).Get(ctx, podname, opts)
if err != nil {
return nil, err
}
return out, nil
}

func (k *K8s) StreamPodLogs(ns string, podname string) *restclient.Request {
opts := &v1Core.PodLogOptions{Follow: true}
request := k.client.CoreV1().Pods(ns).GetLogs(podname, opts)
return request
}

type JobInfo struct {
Name string
Namespace string
Expand Down Expand Up @@ -164,6 +217,53 @@ func (k *K8s) ListDeployments(namespace string) ([]DeploymentInfo, error) {
return deploymentList, nil
}

type ServiceInfoPort struct {
Name string
Protocol string
Port int32
TargetPort int32
}

type ServiceInfo struct {
Name string
Namespace string
Type string
ClusterIP string
ExternalIP string
Ports []ServiceInfoPort
CreatedAt time.Time
}

func (k *K8s) ListServices(namespace string) ([]ServiceInfo, error) {
ctx := context.TODO()
opts := v1.ListOptions{}
services, _ := k.client.CoreV1().Services(namespace).List(ctx, opts)
serviceList := []ServiceInfo{}
for _, service := range services.Items {
serviceInfoPorts := []ServiceInfoPort{}
for _, sPort := range service.Spec.Ports {
serviceInfoPort := ServiceInfoPort{
Name: sPort.Name,
Protocol: string(sPort.Protocol),
Port: int32(sPort.Port),
TargetPort: sPort.TargetPort.IntVal,
}
serviceInfoPorts = append(serviceInfoPorts, serviceInfoPort)
}
s := ServiceInfo{
Name: service.ObjectMeta.Name,
Namespace: service.ObjectMeta.Namespace,
Type: string(service.Spec.Type),
ClusterIP: service.Spec.ClusterIP,
ExternalIP: "<Not-Implemented>", // TODO: Implement external ip
Ports: serviceInfoPorts,
CreatedAt: service.ObjectMeta.CreationTimestamp.Time,
}
serviceList = append(serviceList, s)
}
return serviceList, nil
}

type StatefulsetInfo struct {
Name string
Namespace string
Expand Down
32 changes: 30 additions & 2 deletions pkg/gui/cluster.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
package gui

import "github.com/jesseduffield/gocui"
import (
"fmt"

"github.com/jesseduffield/gocui"
"github.com/yolossn/lazykubernetes/pkg/utils"
)

func (gui *Gui) getClusterInfoView() *gocui.View {
v, _ := gui.g.View("cluster-info")
return v
}

func (gui *Gui) onClusterInfoClick(g *gocui.Gui, v *gocui.View) error {

Expand All @@ -9,6 +19,24 @@ func (gui *Gui) onClusterInfoClick(g *gocui.Gui, v *gocui.View) error {
}

infoView := gui.getInfoView()
infoView.Tabs = []string{"Info"}
infoView.Clear()
out := utils.GetLazykubernetesArt()
fmt.Fprintln(infoView, out)
return nil
}

func (gui *Gui) reRenderClusterInfo() error {

clusterView := gui.getClusterInfoView()

info, err := gui.k8sClient.GetServerInfo()
if err != nil {
clusterView.Clear()
fmt.Fprintf(clusterView, "Health: %s", "🔴")
return nil
}

clusterView.Clear()
fmt.Fprintf(clusterView, "Version: %s.%s\nplatform: %s\nHealth: %s", info.Major, info.Minor, info.Platform, "🟢")
return nil
}

0 comments on commit b5a5aff

Please sign in to comment.