Skip to content

Commit

Permalink
add trigger list (#558)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ying Chun Guo authored and knative-prow-robot committed Dec 17, 2019
1 parent 8a9d8fc commit 60b8801
Show file tree
Hide file tree
Showing 20 changed files with 604 additions and 37 deletions.
1 change: 1 addition & 0 deletions docs/cmd/kn_trigger.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ kn trigger [flags]
* [kn trigger create](kn_trigger_create.md) - Create a trigger
* [kn trigger delete](kn_trigger_delete.md) - Delete a trigger.
* [kn trigger describe](kn_trigger_describe.md) - Describe a trigger.
* [kn trigger list](kn_trigger_list.md) - List available triggers.

47 changes: 47 additions & 0 deletions docs/cmd/kn_trigger_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## kn trigger list

List available triggers.

### Synopsis

List available triggers.

```
kn trigger list [name] [flags]
```

### Examples

```
# List all triggers
kn trigger list
# List all triggers in JSON output format
kn trigger list -o json
```

### Options

```
-A, --all-namespaces If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-h, --help help for list
-n, --namespace string Specify the namespace to operate in.
--no-headers When using the default output format, don't print headers (default: print headers).
-o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```

### Options inherited from parent commands

```
--config string kn config file (default is $HOME/.kn/config.yaml)
--kubeconfig string kubectl config file (default is $HOME/.kube/config)
--log-http log http traffic
```

### SEE ALSO

* [kn trigger](kn_trigger.md) - Trigger command group

38 changes: 37 additions & 1 deletion pkg/eventing/v1alpha1/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ package v1alpha1

import (
apis_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"k8s.io/apimachinery/pkg/runtime"
kn_errors "knative.dev/client/pkg/errors"
"knative.dev/client/pkg/util"
"knative.dev/eventing/pkg/apis/eventing/v1alpha1"
"knative.dev/eventing/pkg/client/clientset/versioned/scheme"
client_v1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1"
)

const (
nameFieldKey = "metadata.name"
)

// KnEventingClient to Eventing Sources. All methods are relative to the
// namespace specified during construction
type KnEventingClient interface {
Expand All @@ -33,6 +39,8 @@ type KnEventingClient interface {
DeleteTrigger(name string) error
// GetTrigger is used to get an instance of trigger
GetTrigger(name string) (*v1alpha1.Trigger, error)
// ListTrigger returns list of trigger CRDs
ListTriggers() (*v1alpha1.TriggerList, error)
}

// KnEventingClient is a combination of Sources client interface and namespace
Expand Down Expand Up @@ -78,7 +86,35 @@ func (c *knEventingClient) GetTrigger(name string) (*v1alpha1.Trigger, error) {
return trigger, nil
}

func (c *knEventingClient) ListTriggers() (*v1alpha1.TriggerList, error) {
triggerList, err := c.client.Triggers(c.namespace).List(apis_v1.ListOptions{})
if err != nil {
return nil, kn_errors.GetError(err)
}
triggerListNew := triggerList.DeepCopy()
err = updateTriggerGvk(triggerListNew)
if err != nil {
return nil, err
}

triggerListNew.Items = make([]v1alpha1.Trigger, len(triggerList.Items))
for idx, trigger := range triggerList.Items {
triggerClone := trigger.DeepCopy()
err := updateTriggerGvk(triggerClone)
if err != nil {
return nil, err
}
triggerListNew.Items[idx] = *triggerClone
}
return triggerListNew, nil
}

// Return the client's namespace
func (c *knEventingClient) Namespace() string {
return c.namespace
}

// update with the v1alpha1 group + version
func updateTriggerGvk(obj runtime.Object) error {
return util.UpdateGroupVersionKindWithScheme(obj, v1alpha1.SchemeGroupVersion, scheme.Scheme)
}
15 changes: 13 additions & 2 deletions pkg/eventing/v1alpha1/client_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (sr *EventingRecorder) CreateTrigger(trigger interface{}, err error) {
sr.r.Add("CreateTrigger", []interface{}{trigger}, []interface{}{trigger, err})
}

// CreateTrigger performs a previously recorded action, failing if non has been registered
// CreateTrigger performs a previously recorded action
func (c *MockKnEventingClient) CreateTrigger(trigger *v1alpha1.Trigger) (*v1alpha1.Trigger, error) {
call := c.recorder.r.VerifyCall("CreateTrigger", trigger)
return call.Result[0].(*v1alpha1.Trigger), mock.ErrorOrNil(call.Result[1])
Expand All @@ -74,7 +74,7 @@ func (sr *EventingRecorder) GetTrigger(name interface{}, trigger *v1alpha1.Trigg
sr.r.Add("GetTrigger", []interface{}{name}, []interface{}{trigger, err})
}

// GetTrigger performs a previously recorded action, failing if non has been registered
// GetTrigger performs a previously recorded action
func (c *MockKnEventingClient) GetTrigger(name string) (*v1alpha1.Trigger, error) {
call := c.recorder.r.VerifyCall("GetTrigger", name)
return call.Result[0].(*v1alpha1.Trigger), mock.ErrorOrNil(call.Result[1])
Expand All @@ -91,6 +91,17 @@ func (c *MockKnEventingClient) DeleteTrigger(name string) error {
return mock.ErrorOrNil(call.Result[0])
}

// ListTriggers records a call for ListTriggers with the expected result and error (nil if none)
func (sr *EventingRecorder) ListTriggers(triggerList *v1alpha1.TriggerList, err error) {
sr.r.Add("ListTriggers", nil, []interface{}{triggerList, err})
}

// ListTriggers performs a previously recorded action
func (c *MockKnEventingClient) ListTriggers() (*v1alpha1.TriggerList, error) {
call := c.recorder.r.VerifyCall("ListTriggers")
return call.Result[0].(*v1alpha1.TriggerList), mock.ErrorOrNil(call.Result[1])
}

// Validate validates whether every recorded action has been called
func (sr *EventingRecorder) Validate() {
sr.r.CheckThatAllRecordedMethodsHaveBeenCalled()
Expand Down
2 changes: 2 additions & 0 deletions pkg/eventing/v1alpha1/client_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ func TestMockKnClient(t *testing.T) {
recorder.GetTrigger("hello", nil, nil)
recorder.CreateTrigger(&v1alpha1.Trigger{}, nil)
recorder.DeleteTrigger("hello", nil)
recorder.ListTriggers(nil, nil)

// Call all service
client.GetTrigger("hello")
client.CreateTrigger(&v1alpha1.Trigger{})
client.DeleteTrigger("hello")
client.ListTriggers()

// Validate
recorder.Validate()
Expand Down
21 changes: 21 additions & 0 deletions pkg/eventing/v1alpha1/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,27 @@ func TestGetTrigger(t *testing.T) {
assert.ErrorContains(t, err, "errorTrigger")
}

func TestListTrigger(t *testing.T) {
serving, client := setup()

t.Run("list trigger returns a list of triggers", func(t *testing.T) {
trigger1 := newTrigger("trigger-1")
trigger2 := newTrigger("trigger-2")

serving.AddReactor("list", "triggers",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
return true, &v1alpha1.TriggerList{Items: []v1alpha1.Trigger{*trigger1, *trigger2}}, nil
})

listTriggers, err := client.ListTriggers()
assert.NilError(t, err)
assert.Assert(t, len(listTriggers.Items) == 2)
assert.Equal(t, listTriggers.Items[0].Name, "trigger-1")
assert.Equal(t, listTriggers.Items[1].Name, "trigger-2")
})
}

func newTrigger(name string) *v1alpha1.Trigger {
obj := &v1alpha1.Trigger{
ObjectMeta: metav1.ObjectMeta{
Expand Down
79 changes: 79 additions & 0 deletions pkg/kn/commands/flags/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright © 2019 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package flags

import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"knative.dev/client/pkg/kn/commands"
hprinters "knative.dev/client/pkg/printers"
)

// ListFlags composes common printer flag structs
// used in the list command.
type ListFlags struct {
GenericPrintFlags *genericclioptions.PrintFlags
HumanReadableFlags *commands.HumanPrintFlags
PrinterHandler func(h hprinters.PrintHandler)
}

// AllowedFormats is the list of formats in which data can be displayed
func (f *ListFlags) AllowedFormats() []string {
formats := f.GenericPrintFlags.AllowedFormats()
formats = append(formats, f.HumanReadableFlags.AllowedFormats()...)
return formats
}

// ToPrinter attempts to find a composed set of ListTypesFlags suitable for
// returning a printer based on current flag values.
func (f *ListFlags) ToPrinter() (hprinters.ResourcePrinter, error) {
// if there are flags specified for generic printing
if f.GenericPrintFlags.OutputFlagSpecified() {
p, err := f.GenericPrintFlags.ToPrinter()
if err != nil {
return nil, err
}
return p, nil
}

p, err := f.HumanReadableFlags.ToPrinter(f.PrinterHandler)
if err != nil {
return nil, err
}
return p, nil
}

// AddFlags receives a *cobra.Command reference and binds
// flags related to humanreadable and template printing.
func (f *ListFlags) AddFlags(cmd *cobra.Command) {
f.GenericPrintFlags.AddFlags(cmd)
f.HumanReadableFlags.AddFlags(cmd)
}

// NewListFlags returns flags associated with humanreadable,
// template, and "name" printing, with default values set.
func NewListFlags(printer func(h hprinters.PrintHandler)) *ListFlags {
return &ListFlags{
GenericPrintFlags: genericclioptions.NewPrintFlags(""),
HumanReadableFlags: commands.NewHumanPrintFlags(),
PrinterHandler: printer,
}
}

// EnsureWithNamespace ensures that humanreadable flags return
// a printer capable of printing with a "namespace" column.
func (f *ListFlags) EnsureWithNamespace() {
f.HumanReadableFlags.EnsureWithNamespace()
}
50 changes: 50 additions & 0 deletions pkg/kn/commands/flags/list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright © 2019 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package flags

import (
"testing"

"github.com/spf13/cobra"
"gotest.tools/assert"
hprinters "knative.dev/client/pkg/printers"
)

func TestListFlagsFormats(t *testing.T) {
flags := NewListFlags(nil)
formats := flags.AllowedFormats()
expected := []string{"json", "yaml", "name", "go-template", "go-template-file", "template", "templatefile", "jsonpath", "jsonpath-file", "no-headers"}
assert.DeepEqual(t, formats, expected)
}

func TestListFlags(t *testing.T) {
var cmd *cobra.Command
flags := NewListFlags(func(h hprinters.PrintHandler) {})

cmd = &cobra.Command{}
flags.AddFlags(cmd)

assert.Assert(t, flags != nil)
assert.Assert(t, cmd.Flags() != nil)

allowMissingTemplateKeys, err := cmd.Flags().GetBool("allow-missing-template-keys")
assert.NilError(t, err)
assert.Assert(t, allowMissingTemplateKeys == true)

p, err := flags.ToPrinter()
assert.NilError(t, err)
_, ok := p.(hprinters.ResourcePrinter)
assert.Check(t, ok == true)
}
1 change: 1 addition & 0 deletions pkg/kn/commands/source/apiserver/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,6 @@ func NewAPIServerCreateCommand(p *commands.KnParams) *cobra.Command {
updateFlags.Add(cmd)
sinkFlags.Add(cmd)
cmd.MarkFlagRequired("resource")
cmd.MarkFlagRequired("sink")
return cmd
}
8 changes: 7 additions & 1 deletion pkg/kn/commands/source/apiserver/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestCreateApiServerSource(t *testing.T) {
servingRecorder.Validate()
}

func TestNoSinkError(t *testing.T) {
func TestSinkNotFoundError(t *testing.T) {
servingClient := knserving_client.NewMockKnServiceClient(t)
apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t)

Expand All @@ -61,3 +61,9 @@ func TestNoSinkError(t *testing.T) {
assert.Assert(t, util.ContainsAll(out, errorMsg, "Usage"))
servingRecorder.Validate()
}

func TestNoSinkError(t *testing.T) {
apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t)
_, err := executeAPIServerSourceCommand(apiServerClient, nil, "create", "testsource", "--resource", "Event:v1:false", "--service-account", "testsa", "--mode", "Ref")
assert.ErrorContains(t, err, "required flag(s)", "sink", "not set")
}
4 changes: 2 additions & 2 deletions pkg/kn/commands/trigger/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command {

RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) != 1 {
return errors.New("'trigger create' requires the name of the trigger as single argument")
return errors.New("'trigger create' requires the name of the trigger")
}
name := args[0]

Expand Down Expand Up @@ -86,7 +86,7 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command {
commands.AddNamespaceFlags(cmd.Flags(), false)
triggerUpdateFlags.Add(cmd)
sinkFlags.Add(cmd)
cmd.MarkFlagRequired("schedule")
cmd.MarkFlagRequired("sink")

return cmd
}
Expand Down
Loading

0 comments on commit 60b8801

Please sign in to comment.