Skip to content

Commit a75ce8d

Browse files
ckcdSteven Dake
authored and
Steven Dake
committed
add selector for istioctl dashboard (istio#19191)
1 parent 84d9376 commit a75ce8d

File tree

2 files changed

+88
-9
lines changed

2 files changed

+88
-9
lines changed

istioctl/cmd/dashboard.go

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ import (
3131

3232
var (
3333
controlZport = 0
34+
35+
// label selector
36+
labelSelector = ""
3437
)
3538

3639
// port-forward to Istio System Prometheus; open browser
@@ -261,17 +264,43 @@ func envoyDashCmd() *cobra.Command {
261264
Long: `Open the Envoy admin dashboard for a sidecar`,
262265
Example: `istioctl dashboard envoy productpage-123-456.default`,
263266
RunE: func(c *cobra.Command, args []string) error {
264-
if len(args) < 1 {
267+
if labelSelector == "" && len(args) < 1 {
265268
c.Println(c.UsageString())
266-
return fmt.Errorf("specify a pod")
269+
return fmt.Errorf("specify a pod or --selector")
270+
}
271+
272+
if labelSelector != "" && len(args) > 0 {
273+
c.Println(c.UsageString())
274+
return fmt.Errorf("name cannot be provided when a selector is specified")
267275
}
268276

269-
podName, ns := handlers.InferPodInfo(args[0], handlers.HandleNamespace(namespace, defaultNamespace))
270277
client, err := clientExecFactory(kubeconfig, configContext)
271278
if err != nil {
272279
return fmt.Errorf("failed to create k8s client: %v", err)
273280
}
274281

282+
var podName, ns string
283+
if labelSelector != "" {
284+
pl, err := client.PodsForSelector(handlers.HandleNamespace(namespace, defaultNamespace), labelSelector)
285+
if err != nil {
286+
return fmt.Errorf("not able to locate pod with selector %s: %v", labelSelector, err)
287+
}
288+
289+
if len(pl.Items) < 1 {
290+
return errors.New("no pods found")
291+
}
292+
293+
if len(pl.Items) > 1 {
294+
log.Warnf("more than 1 pods fits selector: %s; will use pod: %s", labelSelector, pl.Items[0].Name)
295+
}
296+
297+
// only use the first pod in the list
298+
podName = pl.Items[0].Name
299+
ns = pl.Items[0].Namespace
300+
} else {
301+
podName, ns = handlers.InferPodInfo(args[0], handlers.HandleNamespace(namespace, defaultNamespace))
302+
}
303+
275304
fw, err := client.BuildPortForwarder(podName, ns, 0, 15000)
276305
if err != nil {
277306
return fmt.Errorf("could not build port forwarder for %s: %v", podName, err)
@@ -300,17 +329,43 @@ func controlZDashCmd() *cobra.Command {
300329
Long: `Open the ControlZ web UI for a pod in the Istio control plane`,
301330
Example: `istioctl dashboard controlz pilot-123-456.istio-system`,
302331
RunE: func(c *cobra.Command, args []string) error {
303-
if len(args) < 1 {
332+
if labelSelector == "" && len(args) < 1 {
304333
c.Println(c.UsageString())
305-
return fmt.Errorf("specify a pod")
334+
return fmt.Errorf("specify a pod or --selector")
335+
}
336+
337+
if labelSelector != "" && len(args) > 0 {
338+
c.Println(c.UsageString())
339+
return fmt.Errorf("name cannot be provided when a selector is specified")
306340
}
307341

308-
podName, ns := handlers.InferPodInfo(args[0], handlers.HandleNamespace(namespace, defaultNamespace))
309342
client, err := clientExecFactory(kubeconfig, configContext)
310343
if err != nil {
311344
return fmt.Errorf("failed to create k8s client: %v", err)
312345
}
313346

347+
var podName, ns string
348+
if labelSelector != "" {
349+
pl, err := client.PodsForSelector(handlers.HandleNamespace(namespace, defaultNamespace), labelSelector)
350+
if err != nil {
351+
return fmt.Errorf("not able to locate pod with selector %s: %v", labelSelector, err)
352+
}
353+
354+
if len(pl.Items) < 1 {
355+
return errors.New("no pods found")
356+
}
357+
358+
if len(pl.Items) > 1 {
359+
log.Warnf("more than 1 pods fits selector: %s; will use pod: %s", labelSelector, pl.Items[0].Name)
360+
}
361+
362+
// only use the first pod in the list
363+
podName = pl.Items[0].Name
364+
ns = pl.Items[0].Namespace
365+
} else {
366+
podName, ns = handlers.InferPodInfo(args[0], handlers.HandleNamespace(namespace, defaultNamespace))
367+
}
368+
314369
fw, err := client.BuildPortForwarder(podName, ns, 0, controlZport)
315370
if err != nil {
316371
return fmt.Errorf("could not build port forwarder for %s: %v", podName, err)
@@ -374,9 +429,13 @@ func dashboard() *cobra.Command {
374429
dashboardCmd.AddCommand(jaegerDashCmd())
375430
dashboardCmd.AddCommand(zipkinDashCmd())
376431

377-
dashboardCmd.AddCommand(envoyDashCmd())
432+
envoy := envoyDashCmd()
433+
envoy.PersistentFlags().StringVarP(&labelSelector, "selector", "l", "", "label selector")
434+
dashboardCmd.AddCommand(envoy)
435+
378436
controlz := controlZDashCmd()
379437
controlz.PersistentFlags().IntVar(&controlZport, "ctrlz_port", 9876, "ControlZ port")
438+
controlz.PersistentFlags().StringVarP(&labelSelector, "selector", "l", "", "label selector")
380439
dashboardCmd.AddCommand(controlz)
381440

382441
return dashboardCmd

istioctl/cmd/dashboard_test.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestDashboard(t *testing.T) {
3838
},
3939
{ // case 2
4040
args: strings.Split("dashboard controlz", " "),
41-
expectedRegexp: regexp.MustCompile(".*Error: specify a pod"),
41+
expectedRegexp: regexp.MustCompile(".*Error: specify a pod or --selector"),
4242
wantException: true,
4343
},
4444
{ // case 3
@@ -48,7 +48,7 @@ func TestDashboard(t *testing.T) {
4848
},
4949
{ // case 4
5050
args: strings.Split("dashboard envoy", " "),
51-
expectedRegexp: regexp.MustCompile(".*Error: specify a pod"),
51+
expectedRegexp: regexp.MustCompile(".*Error: specify a pod or --selector"),
5252
wantException: true,
5353
},
5454
{ // case 5
@@ -86,6 +86,26 @@ func TestDashboard(t *testing.T) {
8686
expectedOutput: "Error: (dashboard has graduated. Use `istioctl dashboard`)\n",
8787
wantException: true,
8888
},
89+
{ // case 12
90+
args: strings.Split("dashboard envoy --selector app=example", " "),
91+
expectedRegexp: regexp.MustCompile(".*no pods found"),
92+
wantException: true,
93+
},
94+
{ // case 13
95+
args: strings.Split("dashboard envoy --selector app=example pod-123456-7890", " "),
96+
expectedRegexp: regexp.MustCompile(".*Error: name cannot be provided when a selector is specified"),
97+
wantException: true,
98+
},
99+
{ // case 14
100+
args: strings.Split("dashboard controlz --selector app=example", " "),
101+
expectedRegexp: regexp.MustCompile(".*no pods found"),
102+
wantException: true,
103+
},
104+
{ // case 15
105+
args: strings.Split("dashboard controlz --selector app=example pod-123456-7890", " "),
106+
expectedRegexp: regexp.MustCompile(".*Error: name cannot be provided when a selector is specified"),
107+
wantException: true,
108+
},
89109
}
90110

91111
for i, c := range cases {

0 commit comments

Comments
 (0)