Skip to content

Commit 5d3c190

Browse files
ybelMekksindrerh2Reasonable-Solutions
committed
chore(debug): clean up code
Co-authored-by: Sindre Rødseth Hansen <[email protected]> Co-authored-by: Carl Hedgren <[email protected]>
1 parent b1f213a commit 5d3c190

File tree

4 files changed

+51
-45
lines changed

4 files changed

+51
-45
lines changed

cmd/debugcmd/debugcmd.go

+25-14
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ package debugcmd
22

33
import (
44
"fmt"
5+
"k8s.io/client-go/kubernetes"
56

67
"github.com/nais/cli/pkg/debug"
78
"github.com/nais/cli/pkg/k8s"
89
"github.com/urfave/cli/v2"
910
)
1011

1112
const (
12-
namespaceFlagName = "namespace"
1313
contextFlagName = "context"
1414
debugImageDefault = "europe-north1-docker.pkg.dev/nais-io/nais/images/debug:latest"
1515
)
@@ -18,7 +18,9 @@ func Command() *cli.Command {
1818
return &cli.Command{
1919
Name: "debug",
2020
Usage: "Create and attach to a debug container",
21-
ArgsUsage: "appname",
21+
ArgsUsage: "workloadname [namespace]",
22+
Description: "Create and attach to a debug container to your specified workload in the current namespace or a specified namespace to \n" +
23+
"debug your workload. The debug container is based on the debug image '" + debugImageDefault + "'.",
2224
Subcommands: []*cli.Command{
2325
tidyCommand(),
2426
},
@@ -34,13 +36,7 @@ func Command() *cli.Command {
3436
},
3537
Action: func(cCtx *cli.Context) error {
3638
cfg := makeConfig(cCtx)
37-
cluster := cCtx.String(contextFlagName)
38-
client := k8s.SetupControllerRuntimeClient(k8s.WithKubeContext(cluster))
39-
if cfg.Namespace == "" {
40-
cfg.Namespace = client.CurrentNamespace
41-
}
42-
43-
clientset, err := k8s.SetupClientGo(cluster)
39+
clientset, err := setupClient(cfg, cCtx)
4440
if err != nil {
4541
return err
4642
}
@@ -54,6 +50,21 @@ func Command() *cli.Command {
5450
}
5551
}
5652

53+
func setupClient(cfg *debug.Config, cCtx *cli.Context) (kubernetes.Interface, error) {
54+
cluster := cCtx.String(contextFlagName)
55+
client := k8s.SetupControllerRuntimeClient(k8s.WithKubeContext(cluster))
56+
if cfg.Namespace == "" {
57+
cfg.Namespace = client.CurrentNamespace
58+
}
59+
60+
clientset, err := k8s.SetupClientGo(cluster)
61+
if err != nil {
62+
return nil, err
63+
}
64+
return clientset, nil
65+
66+
}
67+
5768
func kubeConfigFlag() *cli.StringFlag {
5869
return &cli.StringFlag{
5970
Name: contextFlagName,
@@ -63,13 +74,13 @@ func kubeConfigFlag() *cli.StringFlag {
6374
}
6475
}
6576

66-
func makeConfig(cCtx *cli.Context) debug.Config {
77+
func makeConfig(cCtx *cli.Context) *debug.Config {
6778
appName := cCtx.Args().First()
6879
namespace := cCtx.Args().Get(1)
6980

70-
return debug.Config{
71-
AppName: appName,
72-
Namespace: namespace,
73-
DebugImage: debugImageDefault,
81+
return &debug.Config{
82+
WorkloadName: appName,
83+
Namespace: namespace,
84+
DebugImage: debugImageDefault,
7485
}
7586
}

cmd/debugcmd/tidycmd.go

+5-13
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import (
44
"fmt"
55

66
"github.com/nais/cli/pkg/debug"
7-
"github.com/nais/cli/pkg/k8s"
87
"github.com/urfave/cli/v2"
98
)
109

1110
func tidyCommand() *cli.Command {
1211
return &cli.Command{
13-
Name: "tidy",
14-
Usage: "Clean up ephemeral containers and debug pods",
15-
ArgsUsage: "appname",
12+
Name: "tidy",
13+
Usage: "Clean up debug containers and debug pods from your workload",
14+
Description: "Remove debug containers created by the debug command, the pods will be deleted automatically",
15+
ArgsUsage: "workloadname [namespace]",
1616
Flags: []cli.Flag{
1717
kubeConfigFlag(),
1818
},
@@ -25,15 +25,7 @@ func tidyCommand() *cli.Command {
2525
},
2626
Action: func(cCtx *cli.Context) error {
2727
cfg := makeConfig(cCtx)
28-
cluster := cCtx.String(contextFlagName)
29-
namespace := cCtx.String(namespaceFlagName)
30-
client := k8s.SetupControllerRuntimeClient(k8s.WithKubeContext(cluster))
31-
cfg.Namespace = client.CurrentNamespace
32-
if namespace != "" {
33-
cfg.Namespace = namespace
34-
}
35-
36-
clientset, err := k8s.SetupClientGo(cluster)
28+
clientset, err := setupClient(cfg, cCtx)
3729
if err != nil {
3830
return err
3931
}

pkg/debug/debug.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,33 @@ import (
1616
type Debug struct {
1717
ctx context.Context
1818
client kubernetes.Interface
19-
cfg Config
19+
cfg *Config
2020
}
2121

2222
type Config struct {
23-
Namespace string
24-
Context string
25-
AppName string
26-
DebugImage string
23+
Namespace string
24+
Context string
25+
WorkloadName string
26+
DebugImage string
2727
}
2828

29-
func Setup(client kubernetes.Interface, cfg Config) *Debug {
29+
func Setup(client kubernetes.Interface, cfg *Config) *Debug {
3030
return &Debug{
3131
ctx: context.Background(),
3232
client: client,
3333
cfg: cfg,
3434
}
3535
}
3636

37-
func (d *Debug) getPods() (*core_v1.PodList, error) {
37+
func (d *Debug) getPodsForWorkload() (*core_v1.PodList, error) {
3838
var podList *core_v1.PodList
3939
var err error
4040
podList, err = d.client.CoreV1().Pods(d.cfg.Namespace).List(d.ctx, metav1.ListOptions{
41-
LabelSelector: fmt.Sprintf("app.kubernetes.io/name=%s", d.cfg.AppName),
41+
LabelSelector: fmt.Sprintf("app.kubernetes.io/name=%s", d.cfg.WorkloadName),
4242
})
4343
if len(podList.Items) == 0 {
4444
podList, err = d.client.CoreV1().Pods(d.cfg.Namespace).List(d.ctx, metav1.ListOptions{
45-
LabelSelector: fmt.Sprintf("app=%s", d.cfg.AppName),
45+
LabelSelector: fmt.Sprintf("app=%s", d.cfg.WorkloadName),
4646
})
4747
}
4848
if err != nil {
@@ -76,11 +76,13 @@ func (d *Debug) debugPod(podName string) error {
7676
return fmt.Errorf("command failed: %v", err)
7777
}
7878

79+
fmt.Printf("Run 'nais debug tidy %s' to clean up debug containers, this will delete pod(s) with debug containers \n", d.cfg.WorkloadName)
80+
7981
return nil
8082
}
8183

8284
func (d *Debug) Debug() error {
83-
pods, err := d.getPods()
85+
pods, err := d.getPodsForWorkload()
8486
if err != nil {
8587
return err
8688
}

pkg/debug/tidy.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package debug
22

33
import (
4+
"errors"
45
"fmt"
56
"strings"
67

@@ -9,7 +10,7 @@ import (
910
)
1011

1112
func (d *Debug) Tidy() error {
12-
pods, err := d.getPods()
13+
pods, err := d.getPodsForWorkload()
1314
if err != nil {
1415
return err
1516
}
@@ -20,24 +21,25 @@ func (d *Debug) Tidy() error {
2021
}
2122

2223
if len(podNames) == 0 {
23-
fmt.Println("No pods found.")
24+
fmt.Println("No pods found")
2425
return nil
2526
}
2627

27-
deleted := 0
28+
epHConTotal := 0
2829
for _, pod := range pods.Items {
2930
if len(pod.Spec.EphemeralContainers) == 0 {
3031
continue
3132
}
3233

34+
epHConTotal += len(pod.Spec.EphemeralContainers)
3335
prompt := promptui.Prompt{
34-
Label: fmt.Sprintf("Do you want to delete pod %s", pod.Name),
36+
Label: fmt.Sprintf("Pod '%s' contains '%d' debug container(s), do you want to clean up", pod.Name, len(pod.Spec.EphemeralContainers)),
3537
IsConfirm: true,
3638
}
3739

3840
answer, err := prompt.Run()
3941
if err != nil {
40-
if err == promptui.ErrAbort {
42+
if errors.Is(err, promptui.ErrAbort) {
4143
fmt.Printf("Skipping deletion for pod: %s\n", pod.Name)
4244
continue
4345
}
@@ -50,16 +52,15 @@ func (d *Debug) Tidy() error {
5052
if err := d.client.CoreV1().Pods(d.cfg.Namespace).Delete(d.ctx, pod.Name, metav1.DeleteOptions{}); err != nil {
5153
fmt.Printf("Failed to delete pod %s: %v\n", pod.Name, err)
5254
} else {
53-
deleted++
5455
fmt.Println("Deleted pod:", pod.Name)
5556
}
5657
} else {
5758
fmt.Println("Skipped pod:", pod.Name)
5859
}
5960
}
6061

61-
if deleted == 0 {
62-
fmt.Println("No pods with ephemeral containers found.")
62+
if epHConTotal == 0 {
63+
fmt.Printf("Workload '%s' does not contain any debug containers\n", d.cfg.WorkloadName)
6364
}
6465
return nil
6566
}

0 commit comments

Comments
 (0)