{"id":19723986,"url":"https://github.com/vs4vijay/lazykubectl","last_synced_at":"2025-07-14T00:07:38.036Z","repository":{"id":37034041,"uuid":"254921259","full_name":"vs4vijay/lazykubectl","owner":"vs4vijay","description":"A Terminal UI client for kubernetes","archived":false,"fork":false,"pushed_at":"2025-04-09T11:16:21.000Z","size":716,"stargazers_count":4,"open_issues_count":13,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-29T22:36:35.307Z","etag":null,"topics":["devops","docker","dockerfile","golang","golang-application","golang-library","kubectl","kubectl-plugin","kubectl-plugins","kubernetes"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vs4vijay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-04-11T17:37:54.000Z","updated_at":"2025-02-03T11:08:16.000Z","dependencies_parsed_at":"2023-01-20T12:05:35.644Z","dependency_job_id":"9ab22666-ad67-496c-b2b3-01b7dbf9346d","html_url":"https://github.com/vs4vijay/lazykubectl","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/vs4vijay/lazykubectl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vs4vijay%2Flazykubectl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vs4vijay%2Flazykubectl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vs4vijay%2Flazykubectl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vs4vijay%2Flazykubectl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vs4vijay","download_url":"https://codeload.github.com/vs4vijay/lazykubectl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vs4vijay%2Flazykubectl/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265224161,"owners_count":23730345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","docker","dockerfile","golang","golang-application","golang-library","kubectl","kubectl-plugin","kubectl-plugins","kubernetes"],"created_at":"2024-11-11T23:24:08.357Z","updated_at":"2025-07-14T00:07:38.010Z","avatar_url":"https://github.com/vs4vijay.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lazykubectl\nA Terminal UI client for kubernetes\n\n\u003e NOTE: _this project is still in an early stage_\n\n[![Release](https://github.com/vs4vijay/lazykubectl/workflows/Release/badge.svg)](https://github.com/vs4vijay/lazykubectl/releases)\n[![Release Tag](https://img.shields.io/github/tag/vs4vijay/lazykubectl.svg)](https://github.com/vs4vijay/lazykubectl/releases/latest)\n[![Go Report Card](https://goreportcard.com/badge/github.com/vs4vijay/lazykubectl)](https://goreportcard.com/report/github.com/vs4vijay/lazykubectl)\n[![Go Version](https://img.shields.io/github/go-mod/go-version/vs4vijay/lazykubectl)](https://github.com/vs4vijay/lazykubectl)\n[![GoDoc](https://godoc.org/github.com/vs4vijay/lazykubectl?status.svg)](http://godoc.org/github.com/vs4vijay/lazykubectl)\n[![Downloads](https://img.shields.io/github/downloads/vs4vijay/lazykubectl/total)](https://github.com/vs4vijay/lazykubectl/releases)\n\n---\n\n## Installation\n\n### Homebrew\n\n```\nbrew install vs4vijay/tap/lazykubectl\n```\n\n### Release Binaries\n\n- https://github.com/vs4vijay/lazykubectl/releases\n\n### Via GoBinaries\n\n```shell script\ncurl -sf https://gobinaries.com/vs4vijay/lazykubectl | sh\n```\n\n---\n\n## Running\n\n```\nlazykubectl\n```\n\n---\n\n## Screenshots\n\n![LazyKubectl Pods](_screenshots/lazykubectl_pods.png)\n\n![LazyKubectl Containers](_screenshots/lazykubectl_containers.png)\n\n![LazyKubectl Logs](_screenshots/lazykubectl_logs.png)\n\n\n---\n\n## References\n- https://pkg.go.dev/k8s.io/client-go/kubernetes?tab=doc\n- https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/\n\n---\n\n## ToDo\n- [x] Auth\n- [x] Custom Error Handler, for custom errors\n- [ ] Proper Logger\n- [x] CORS\n- [x] Validator\n- [ ] Version\n- [ ] ENV\n- Handle Up / Down Arrow\n- Stream Logs\n- Events\n- CPU\n- MEM\n- View Logs\n- Execute Shell\n\n---\n\n## License\n\n[MIT](LICENSE)\n\n---\n\n### Development Notes\n\n```go\n\n\n// Echo Error Handler\n\ne.HTTPErrorHandler = func(err error, c echo.Context) {\n    // Take required information from error and context and send it to a service like New Relic\n    fmt.Println(c.Path(), c.QueryParams(), err.Error())\n\n    switch err.(type) {\n    case orchestrator.CustomError:\n        fmt.Println(\"custom\")\n    default:\n        fmt.Println(\"normal\") // here v has type interface{}\n    }\n\n    // Call the default handler to return the HTTP response\n    e.DefaultHTTPErrorHandler(err, c)\n}\n\n\n// Docker \n\nimport (\n    \"github.com/docker/docker/client\"\n    \"github.com/docker/docker/api/types\"\n)\n\ncli, err := client.NewEnvClient()\ncli.Info(context.Background())\ncli.DiskUsage(context.Background())\ncli.ContainerList(context.Background(), types.ContainerListOptions{All: true})\n\nClient.ContainerList(context.Background(), types.ContainerListOptions{All: true})\nstream, err := c.Client.ContainerStats(context.Background(), container.ID, true)\nimages, err := c.Client.ImageList(context.Background(), types.ImageListOptions{})\nresult, err := c.Client.VolumeList(context.Background(), filters.Args{})\n\n\n\n// Kubernetes\n\nimport (\n    \"k8s.io/client-go/kubernetes\"\n    \"k8s.io/client-go/tools/clientcmd\"\n)\n\n// Various Configs\nconfig    clientcmd.ClientConfig\nrestConfig *rest.Config\n\n// Clients\nclientset  *kubernetes.Clientset\ndynamicClient \n\n// Client Config\nconfig, err = clientcmd.NewClientConfigFromBytes([]byte(manifest))\n\n// Rest Config\nrestConfig, err = clientcmd.RESTConfigFromKubeConfig([]byte(manifest))\n// OR\nrestConfig, err := config.ClientConfig()\n\n// Client\nclientset, err := kubernetes.NewForConfig(restConfig)\n\n// Dynamic Client\ndynamicClient, err := dynamic.NewForConfig(restConfig)\n\n\n\n// Default Way\nclientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(\n\t\t\u0026clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig},\n\t\t\u0026clientcmd.ConfigOverrides{CurrentContext: kubeContext})\n\nrawConfig, err := clientConfig.RawConfig()\nrawConfig.CurrentContext\n\n// List Resources\nclientset.CoreV1().Nodes().List(metav1.ListOptions{})\nclientset.CoreV1().Pods(namespace).List(metav1.ListOptions{})\n\n// Create Resources\nclientset.CoreV1().Namespaces().Create(ns)\n\n// Parse Manifest YAML\nobj, gvk, err := scheme.Codecs.UniversalDeserializer().Decode([]byte(manifest), nil, nil)\n\n\n// Create Resources (Generic Method) - Using Dynamic Client and Unstructrued\n\ngroupResources, err := restmapper.GetAPIGroupResources(clientset.Discovery())\nrm := restmapper.NewDiscoveryRESTMapper(groupResources)\n\nunstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)\nunstructuredObj := \u0026unstructured.Unstructured{Object: unstructuredMap}\n\ngvk := obj.GetObjectKind().GroupVersionKind()\ngk := schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}\n\nmapping, err := rm.RESTMapping(gk, gvk.Version)\ncreatedUnstructuredObj, err := dynamicClient.Resource(mapping.Resource).Create(unstructuredObj, metav1.CreateOptions{})\n\n\n\n// Watcher\n\nwatch, _ := api.Services(\"\").Watch(metav1.ListOptions{})\n\ngo func() {\n    for event := range watch.ResultChan() {\n        fmt.Printf(\"Type: %v\\n\", event.Type)\n        p, ok := event.Object.(*v1.Pod)\n        if !ok {\n            log.Fatal(\"unexpected type\")\n        }\n        fmt.Println(p.Status.ContainerStatuses)\n        fmt.Println(p.Status.Phase)\n    }\n}()\n\ntime.Sleep(5 * time.Second)\n\n\n// Controller\n\nhttps://engineering.bitnami.com/articles/a-deep-dive-into-kubernetes-controllers.html\nhttps://engineering.bitnami.com/articles/kubewatch-an-example-of-kubernetes-custom-controller.html\n\ncache.NewInformer\nNewSharedIndexInformer\n---\nlw := cache.NewListWatchFromClient()\nsharedInformer := cache.NewSharedInformer(lw, \u0026api.Pod{}, resyncPeriod)\n---\nfactory := informers.NewSharedInformerFactory(clientset, 0)\ninformer := factory.Core().V1().Nodes().Informer()\nstopper := make(chan struct{})\ndefer close(stopper)\ndefer runtime.HandleCrash()\ninformer.AddEventHandler(cache.ResourceEventHandlerFuncs{\n    AddFunc: onAdd,\n})\ngo informer.Run(stopper)\n\n// Informer\n\nwatchlist := cache.NewListWatchFromClient(clientset.Core().RESTClient(), \"pods\", \"\", fields.Everything())\n_, controller := cache.NewInformer(\n    watchlist,\n    \u0026v1.Pod{},\n    time.Second * 0,\n    cache.ResourceEventHandlerFuncs{\n        AddFunc: func(obj interface{}) {\n            fmt.Printf(\"add: %s \\n\", obj)\n        },\n        DeleteFunc: func(obj interface{}) {\n            fmt.Printf(\"delete: %s \\n\", obj)\n        },\n        UpdateFunc:func(oldObj, newObj interface{}) {\n            fmt.Printf(\"old: %s, new: %s \\n\", oldObj, newObj)\n        },\n    },\n)\nstop := make(chan struct{})\ngo controller.Run(stop)\n\n\n// Shared Index Informer\n\ninformer := cache.NewSharedIndexInformer(\n        \u0026cache.ListWatch{\n            ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {\n                return kubeClient.CoreV1().Pods(conf.Namespace).List(options)\n            },\n            WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {\n                return kubeClient.CoreV1().Pods(conf.Namespace).Watch(options)\n            },\n        },\n        \u0026api_v1.Pod{},\n        0, //Skip resync\n        cache.Indexers{},\n    )\n\n\n\nif v, err := g.SetView(\"help\", maxX-25, 0, maxX-1, 9); err != nil {\n    if err != gocui.ErrUnknownView {\n        return err\n    }\n    fmt.Fprintln(v, \"KEYBINDINGS\")\n    fmt.Fprintln(v, \"Space: New View\")\n    fmt.Fprintln(v, \"Tab: Next View\")\n    fmt.Fprintln(v, \"← ↑ → ↓: Move View\")\n    fmt.Fprintln(v, \"Backspace: Delete View\")\n    fmt.Fprintln(v, \"t: Set view on top\")\n    fmt.Fprintln(v, \"b: Set view on bottom\")\n    fmt.Fprintln(v, \"^C: Exit\")\n}\n\n\nfunc Loader() string {\n\tcharacters := \"|/-\\\\\"\n\tnow := time.Now()\n\tnanos := now.UnixNano()\n\tindex := nanos / 50000000 % int64(len(characters))\n\treturn characters[index : index+1]\n}\n\n\nhttps://github.com/alitari/kubexp\n\nhttps://github.com/JulienBreux/pody\n\nhttps://stackoverflow.com/questions/40975307/how-to-watch-events-on-a-kubernetes-service-using-its-go-client\n\nhttps://github.com/NetApp/trident/blob/master/k8s_client/k8s_client.go\nhttps://github.com/vladimirvivien/k8s-client-examples\nhttps://github.com/dtan4/k8stail/blob/master/tail.go\n\n\nTest Data:\n\nhttps://raw.githubusercontent.com/kubernetes/kubernetes/master/hack/testdata/recursive/pod/pod/busybox.yaml\nhttps://raw.githubusercontent.com/istio/istio/master/samples/sleep/sleep.yaml\n\n\nkubectl create clusterrolebinding dashboard-admin-sa --clusterrole=cluster-admin --serviceaccount=default:dashboard-admin-sa\n\nkubectl describe secret dashboard-admin-sa-token-kw7vn\n\nkubectl get secret $(kubectl get serviceaccount dashboard -o jsonpath=\"{.secrets[0].name}\") -o jsonpath=\"{.data.token}\" | base64 --decode\n\ncurl -fsSL https://raw.githubusercontent.com/micro/micro/master/scripts/install.sh | /bin/bash\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvs4vijay%2Flazykubectl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvs4vijay%2Flazykubectl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvs4vijay%2Flazykubectl/lists"}