Skip to content

Commit a517650

Browse files
vinamra28tekton-robot
authored andcommitted
Auto-select EventListener in describe if only one is present
- When only one EventListener is present on the cluster then it should be auto-selected when executing the `eventlistener describe` command. - When there are more than one EventListener then user will get an interactive option to select and describe it. - Created a package `pkg/eventlistener/eventlistener.go` which contains the helper functions for EventListener and also added the tests for same. - Moved the `list` function from `pkg/cmd/eventlistener/list.go` to `pkg/eventlistener/eventlistener.go`. Signed-off-by: vinamra28 <vinjain@redhat.com>
1 parent b9b76c2 commit a517650

File tree

10 files changed

+380
-25
lines changed

10 files changed

+380
-25
lines changed

pkg/cmd/eventlistener/describe.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import (
2525

2626
"github.com/spf13/cobra"
2727
"github.com/tektoncd/cli/pkg/cli"
28+
"github.com/tektoncd/cli/pkg/eventlistener"
2829
"github.com/tektoncd/cli/pkg/formatted"
30+
"github.com/tektoncd/cli/pkg/options"
2931
"github.com/tektoncd/cli/pkg/printer"
3032
"github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1"
3133
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -129,6 +131,7 @@ const describeTemplate = `{{decorate "bold" "Name"}}: {{ .EventListener.Name }}
129131

130132
func describeCommand(p cli.Params) *cobra.Command {
131133
f := cliopts.NewPrintFlags("describe")
134+
opts := &options.DescribeOptions{Params: p}
132135
eg := `Describe an EventListener of name 'foo' in namespace 'bar':
133136
134137
tkn eventlistener describe foo -n bar
@@ -146,7 +149,6 @@ or
146149
Annotations: map[string]string{
147150
"commandType": "main",
148151
},
149-
Args: cobra.MinimumNArgs(1),
150152
SilenceUsage: true,
151153
ValidArgsFunction: formatted.ParentCompletion,
152154
RunE: func(cmd *cobra.Command, args []string) error {
@@ -155,19 +157,41 @@ or
155157
Err: cmd.OutOrStderr(),
156158
}
157159

160+
cs, err := p.Clients()
161+
if err != nil {
162+
return err
163+
}
164+
158165
output, err := cmd.LocalFlags().GetString("output")
159166
if err != nil {
160167
fmt.Fprint(os.Stderr, "Error: output option not set properly \n")
161168
return err
162169
}
163170

171+
if len(args) == 0 {
172+
eventListenerNames, err := eventlistener.GetAllEventListenerNames(cs.Triggers, p.Namespace())
173+
if err != nil {
174+
return err
175+
}
176+
if len(eventListenerNames) == 1 {
177+
opts.EventListenerName = eventListenerNames[0]
178+
} else {
179+
err = askEventListenerName(opts, eventListenerNames)
180+
if err != nil {
181+
return err
182+
}
183+
}
184+
} else {
185+
opts.EventListenerName = args[0]
186+
}
187+
164188
if output != "" {
165189
if strings.ToLower(output) == "url" {
166190
return describeEventListenerOutputURL(cmd.OutOrStdout(), p, args[0])
167191
}
168192
return describeEventListenerOutput(cmd.OutOrStdout(), p, f, args[0])
169193
}
170-
return printEventListenerDescription(s, p, args[0])
194+
return printEventListenerDescription(s, p, opts.EventListenerName)
171195
},
172196
}
173197

@@ -296,3 +320,15 @@ func isBindingNameExist(bindings []*v1alpha1.EventListenerBinding) bool {
296320
func isTemplateRefExist(templates *v1alpha1.EventListenerTemplate) bool {
297321
return templates.Ref != nil
298322
}
323+
324+
func askEventListenerName(opts *options.DescribeOptions, eventListenerNames []string) error {
325+
if len(eventListenerNames) == 0 {
326+
return fmt.Errorf("no EventListeners found")
327+
}
328+
err := opts.Ask(options.ResourceNameEventListener, eventListenerNames)
329+
if err != nil {
330+
return err
331+
}
332+
333+
return nil
334+
}

pkg/cmd/eventlistener/describe_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,42 @@ func TestEventListenerDescribe_OutputStatusURL_WithNoURL(t *testing.T) {
430430
test.AssertOutput(t, "Error: "+err.Error()+"\n", out)
431431
}
432432

433+
func TestEventListenerDescribe_AutoSelect(t *testing.T) {
434+
triggerTemplateRef := "tt1"
435+
els := []*v1alpha1.EventListener{
436+
{
437+
ObjectMeta: metav1.ObjectMeta{
438+
Name: "el1",
439+
Namespace: "ns",
440+
},
441+
Spec: v1alpha1.EventListenerSpec{
442+
Triggers: []v1alpha1.EventListenerTrigger{
443+
{
444+
Template: &v1alpha1.TriggerSpecTemplate{
445+
Ref: &triggerTemplateRef,
446+
APIVersion: "v1alpha1",
447+
},
448+
},
449+
},
450+
},
451+
},
452+
}
453+
454+
cs := test.SeedTestResources(t, triggertest.Resources{EventListeners: els, Namespaces: []*corev1.Namespace{{
455+
ObjectMeta: metav1.ObjectMeta{
456+
Name: "ns",
457+
},
458+
}}})
459+
p := &test.Params{Triggers: cs.Triggers, Kube: cs.Kube}
460+
461+
eventListener := Command(p)
462+
out, err := test.ExecuteCommand(eventListener, "desc", "-n", "ns")
463+
if err != nil {
464+
t.Errorf("Error expected here")
465+
}
466+
golden.Assert(t, out, fmt.Sprintf("%s.golden", t.Name()))
467+
}
468+
433469
func executeEventListenerCommand(t *testing.T, els []*v1alpha1.EventListener) {
434470
cs := test.SeedTestResources(t, triggertest.Resources{EventListeners: els, Namespaces: []*corev1.Namespace{{
435471
ObjectMeta: metav1.ObjectMeta{

pkg/cmd/eventlistener/list.go

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,17 @@
1515
package eventlistener
1616

1717
import (
18-
"context"
1918
"errors"
2019
"fmt"
2120
"text/tabwriter"
2221

2322
"github.com/spf13/cobra"
2423
"github.com/tektoncd/cli/pkg/cli"
24+
"github.com/tektoncd/cli/pkg/eventlistener"
2525
"github.com/tektoncd/cli/pkg/formatted"
2626
"github.com/tektoncd/cli/pkg/printer"
2727
"github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1"
28-
"github.com/tektoncd/triggers/pkg/client/clientset/versioned"
2928
corev1 "k8s.io/api/core/v1"
30-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31-
"k8s.io/apimachinery/pkg/runtime/schema"
3229
cliopts "k8s.io/cli-runtime/pkg/genericclioptions"
3330
)
3431

@@ -73,7 +70,7 @@ or
7370
namespace = ""
7471
}
7572

76-
els, err := list(cs.Triggers, namespace)
73+
els, err := eventlistener.List(cs.Triggers, namespace)
7774
if err != nil {
7875
if opts.AllNamespaces {
7976
return fmt.Errorf("failed to list EventListeners from all namespaces: %v", err)
@@ -108,23 +105,6 @@ or
108105
return c
109106
}
110107

111-
func list(client versioned.Interface, namespace string) (*v1alpha1.EventListenerList, error) {
112-
els, err := client.TriggersV1alpha1().EventListeners(namespace).List(context.Background(), metav1.ListOptions{})
113-
if err != nil {
114-
return nil, err
115-
}
116-
117-
// NOTE: this is required for -o json|yaml to work properly since
118-
// tektoncd go client fails to set these; probably a bug
119-
els.GetObjectKind().SetGroupVersionKind(
120-
schema.GroupVersionKind{
121-
Version: "triggers.tekton.dev/v1alpha1",
122-
Kind: "EventListenerList",
123-
})
124-
125-
return els, nil
126-
}
127-
128108
func printFormatted(s *cli.Stream, els *v1alpha1.EventListenerList, p cli.Params, allNamespaces bool, noHeaders bool) error {
129109
if len(els.Items) == 0 {
130110
fmt.Fprintln(s.Err, emptyMsg)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Name: el1
2+
Namespace: ns
3+
4+
EventListenerTriggers
5+
6+
TEMPLATE REF APIVERSION
7+
tt1 v1alpha1
8+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Error: requires at least 1 arg(s), only received 0
1+
Error: no EventListeners found

pkg/eventlistener/eventlistener.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright © 2021 The Tekton Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package eventlistener
16+
17+
import (
18+
"context"
19+
20+
"github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1"
21+
"github.com/tektoncd/triggers/pkg/client/clientset/versioned"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/runtime/schema"
24+
)
25+
26+
func GetAllEventListenerNames(client versioned.Interface, namespace string) ([]string, error) {
27+
28+
ps, err := List(client, namespace)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
ret := []string{}
34+
for _, item := range ps.Items {
35+
ret = append(ret, item.ObjectMeta.Name)
36+
}
37+
return ret, nil
38+
}
39+
40+
func List(client versioned.Interface, namespace string) (*v1alpha1.EventListenerList, error) {
41+
els, err := client.TriggersV1alpha1().EventListeners(namespace).List(context.Background(), metav1.ListOptions{})
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
// NOTE: this is required for -o json|yaml to work properly since
47+
// tektoncd go client fails to set these; probably a bug
48+
els.GetObjectKind().SetGroupVersionKind(
49+
schema.GroupVersionKind{
50+
Version: "triggers.tekton.dev/v1alpha1",
51+
Kind: "EventListenerList",
52+
})
53+
54+
return els, nil
55+
}

0 commit comments

Comments
 (0)