forked from bjarneo/ku
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
152 lines (139 loc) · 4.05 KB
/
Copy pathmain.go
File metadata and controls
152 lines (139 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Command ku is a terminal UI for Kubernetes: browse any resource, view and
// edit objects, follow logs, and switch namespaces and contexts, all from the
// keyboard. It uses your default kubeconfig.
package main
import (
"context"
"flag"
"fmt"
"os"
"time"
"github.com/bjarneo/ku/internal/k8s"
"github.com/bjarneo/ku/internal/ui"
"github.com/bjarneo/ku/internal/upgrade"
)
// version is set at build time with -ldflags "-X main.version=vX.Y.Z".
var version = "dev"
func main() {
if len(os.Args) > 1 && os.Args[1] == "upgrade" {
if err := runUpgrade(os.Args[2:]); err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
return
}
if len(os.Args) > 1 && os.Args[1] == "config" {
if err := runConfig(os.Args[2:]); err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
return
}
var (
ctxFlag, nsFlag, resFlag, themeFlag, kubeconfigFlag string
checkFlag, versionFlag, devFlag, editFlag bool
)
flag.StringVar(&ctxFlag, "context", "", "kubeconfig context to use (default: current-context)")
flag.StringVar(&nsFlag, "namespace", "", "initial namespace (empty = all namespaces)")
flag.StringVar(&nsFlag, "n", "", "initial namespace (shorthand)")
flag.StringVar(&resFlag, "resource", "", "initial resource, e.g. pods, deploy, svc")
flag.StringVar(&themeFlag, "theme", "", "color theme: ansi (default) or tokyonight")
flag.StringVar(&kubeconfigFlag, "kubeconfig", "", "path to the kubeconfig file (default: $KUBECONFIG or ~/.kube/config)")
flag.BoolVar(&devFlag, "dev", false, "developer view: hide cluster admin resources and node ops")
flag.BoolVar(&editFlag, "edit", false, "start in edit mode; default is read-only, toggle from the command palette")
flag.BoolVar(&checkFlag, "check", false, "run a read-only connectivity check and exit")
flag.BoolVar(&versionFlag, "version", false, "print version and exit")
flag.Parse()
switch {
case versionFlag:
fmt.Println("ku", version)
return
case checkFlag:
if err := check(ctxFlag, kubeconfigFlag, nsFlag, resFlag); err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
return
}
if err := ui.Run(ui.Options{
Context: ctxFlag,
Namespace: nsFlag,
Resource: resFlag,
Theme: themeFlag,
Kubeconfig: kubeconfigFlag,
Version: version,
Dev: devFlag,
Edit: editFlag,
}); err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
}
func runUpgrade(args []string) error {
if len(args) == 0 {
return upgrade.Run(version)
}
switch args[0] {
case "--help", "-h", "help":
fmt.Println("usage: ku upgrade")
return nil
default:
return fmt.Errorf("usage: ku upgrade")
}
}
// check performs a read-only listing to validate connectivity and discovery
// without starting the UI. Useful in non-interactive environments.
func check(ctxName, kubeconfig, ns, resQuery string) error {
if resQuery == "" {
resQuery = "pods"
}
cl, err := k8s.NewClient(ctxName, kubeconfig)
if err != nil {
return err
}
fmt.Printf("context: %s\nhost: %s\nnamespace: %q\nresources: %d discovered\n",
cl.ContextName, cl.Host, cl.Namespace, len(cl.Registry().All()))
ri, ok := cl.Registry().Resolve(resQuery)
if !ok {
return fmt.Errorf("unknown resource %q", resQuery)
}
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
tbl, err := cl.ListTable(ctx, ri, ns, "")
if err != nil {
return err
}
fmt.Printf("listed %s: %d columns, %d rows\n", ri.Key(), len(tbl.Columns), len(tbl.Rows))
return nil
}
// runConfig handles the `ku config <subcommand>` family.
func runConfig(args []string) error {
sub := ""
if len(args) > 0 {
sub = args[0]
}
switch sub {
case "init":
force := false
for _, a := range args[1:] {
if a == "--force" || a == "-f" {
force = true
}
}
path, err := ui.WriteDefaultConfig(force)
if err != nil {
return err
}
fmt.Println("wrote", path)
return nil
case "path":
path, err := ui.ConfigPath()
if err != nil {
return err
}
fmt.Println(path)
return nil
default:
return fmt.Errorf("usage: ku config <init [--force] | path>")
}
}