Skip to content

Commit

Permalink
Add command for creation of a plain trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
Daisy Guo committed Dec 12, 2019
1 parent 2c1e5dc commit 5bd6789
Show file tree
Hide file tree
Showing 28 changed files with 2,088 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/cmd/kn.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ Manage your Knative building blocks:
* [kn route](kn_route.md) - Route command group
* [kn service](kn_service.md) - Service command group
* [kn source](kn_source.md) - Event Source command group
* [kn trigger](kn_trigger.md) - Event Trigger command group
* [kn version](kn_version.md) - Prints the client version

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

Event Trigger command group

### Synopsis

Event Trigger command group

```
kn trigger [flags]
```

### Options

```
-h, --help help for trigger
```

### 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](kn.md) - Knative client
* [kn trigger create](kn_trigger_create.md) - Create a Trigger
* [kn trigger delete](kn_trigger_delete.md) - Delete a trigger.

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

Create a Trigger

### Synopsis

Create a Trigger

```
kn trigger create NAME --broker BROKER --filter KEY=VALUE --sink SINK [flags]
```

### Examples

```
# Create a Trigger 'mytrigger' which subscribes to events with attribute 'type=dev.knative.foo' from default broker and send events to service 'mysvc'
kn trigger create mytrigger --broker default --filter type=dev.knative.foo --sink svc:mysvc
```

### Options

```
--broker string Name of the Broker which the trigger associates with. Defaults to 'default' if not specified. (default "default")
--filter strings Comma seperate key-value pair for exact CloudEvent attribute matching against incoming events, e.g type=dev.knative.foo
-h, --help help for create
-n, --namespace string Specify the namespace to operate in.
-s, --sink string Addressable sink for events
```

### 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) - Event Trigger command group

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

Delete a trigger.

### Synopsis

Delete a trigger.

```
kn trigger delete NAME [flags]
```

### Examples

```
# Delete a trigger 'mytrigger' in default namespace
kn trigger delete mytrigger
```

### Options

```
-h, --help help for delete
-n, --namespace string Specify the namespace to operate in.
```

### 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) - Event Trigger command group

73 changes: 73 additions & 0 deletions pkg/eventing/v1alpha1/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// 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 v1alpha1

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

kn_errors "knative.dev/client/pkg/errors"
"knative.dev/eventing/pkg/apis/eventing/v1alpha1"
client_v1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1"
)

// KnEventingClient to Eventing Sources. All methods are relative to the
// namespace specified during construction
type KnEventingClient interface {
// Namespace in which this client is operating for
Namespace() string
// CreateTrigger is used to create an instance of Trigger
CreateTrigger(trigger *v1alpha1.Trigger) (*v1alpha1.Trigger, error)
// DeleteTrigger is used to delete an instance of Trigger
DeleteTrigger(name string) error
}

// KnEventingClient is a combination of Sources client interface and namespace
// Temporarily help to add sources dependencies
// May be changed when adding real sources features
type knEventingClient struct {
client client_v1alpha1.EventingV1alpha1Interface
namespace string
}

// NewKnEventingClient is to invoke Eventing Sources Client API to create object
func NewKnEventingClient(client client_v1alpha1.EventingV1alpha1Interface, namespace string) KnEventingClient {
return &knEventingClient{
namespace: namespace,
client: client,
}
}

//CreateTrigger is used to create an instance of Trigger
func (c *knEventingClient) CreateTrigger(trigger *v1alpha1.Trigger) (*v1alpha1.Trigger, error) {
ins, err := c.client.Triggers(c.namespace).Create(trigger)
if err != nil {
return nil, kn_errors.GetError(err)
}
return ins, nil
}

//DeleteTrigger is used to delete an instance of Trigger
func (c *knEventingClient) DeleteTrigger(name string) error {
err := c.client.Triggers(c.namespace).Delete(name, &apis_v1.DeleteOptions{})
if err != nil {
return kn_errors.GetError(err)
}
return nil
}

// Return the client's namespace
func (c *knEventingClient) Namespace() string {
return c.namespace
}
116 changes: 116 additions & 0 deletions pkg/eventing/v1alpha1/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// 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 v1alpha1

import (
"fmt"
"testing"

"gotest.tools/assert"
"k8s.io/apimachinery/pkg/runtime"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
client_testing "k8s.io/client-go/testing"
"knative.dev/eventing/pkg/apis/eventing/v1alpha1"
"knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake"
)

var testNamespace = "test-ns"

func setup() (sources fake.FakeEventingV1alpha1, client KnEventingClient) {
sources = fake.FakeEventingV1alpha1{Fake: &client_testing.Fake{}}
client = NewKnEventingClient(&sources, testNamespace)
return
}

func TestDeleteTrigger(t *testing.T) {
var name = "new-trigger"
server, client := setup()

objNew := newTrigger(name)

server.AddReactor("create", "triggers",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
name := a.(client_testing.CreateAction).GetObject().(metav1.Object).GetName()
if name == objNew.Name {
objNew.Generation = 2
return true, objNew, nil
}
return true, nil, fmt.Errorf("error while creating trigger %s", name)
})

t.Run("create trigger without error", func(t *testing.T) {
ins, err := client.CreateTrigger(objNew)
assert.NilError(t, err)
assert.Equal(t, ins.Name, name)
assert.Equal(t, ins.Namespace, testNamespace)
})

t.Run("create trigger with an error returns an error object", func(t *testing.T) {
_, err := client.CreateTrigger(newTrigger("unknown"))
assert.ErrorContains(t, err, "unknown")
})
}

func TestCreateTrigger(t *testing.T) {
var name = "new-trigger"
server, client := setup()

objNew := newTrigger(name)

server.AddReactor("create", "triggers",
func(a client_testing.Action) (bool, runtime.Object, error) {
assert.Equal(t, testNamespace, a.GetNamespace())
name := a.(client_testing.CreateAction).GetObject().(metav1.Object).GetName()
if name == objNew.Name {
objNew.Generation = 2
return true, objNew, nil
}
return true, nil, fmt.Errorf("error while creating trigger %s", name)
})

t.Run("create trigger without error", func(t *testing.T) {
ins, err := client.CreateTrigger(objNew)
assert.NilError(t, err)
assert.Equal(t, ins.Name, name)
assert.Equal(t, ins.Namespace, testNamespace)
})

t.Run("create trigger with an error returns an error object", func(t *testing.T) {
_, err := client.CreateTrigger(newTrigger("unknown"))
assert.ErrorContains(t, err, "unknown")
})
}

func newTrigger(name string) *v1alpha1.Trigger {
obj := &v1alpha1.Trigger{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: testNamespace,
},
Spec: v1alpha1.TriggerSpec{
Broker: "default",
Filter: &v1alpha1.TriggerFilter{
Attributes: &v1alpha1.TriggerFilterAttributes{
"type": "foo",
},
},
},
}
obj.Name = name
obj.Namespace = testNamespace
return obj
}
21 changes: 21 additions & 0 deletions pkg/kn/commands/testing_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import (
dynamic_fake "k8s.io/client-go/dynamic/fake"
dynamic_kn "knative.dev/client/pkg/dynamic"
sources_client "knative.dev/client/pkg/eventing/sources/v1alpha1"
eventing_client "knative.dev/client/pkg/eventing/v1alpha1"
eventing_fake "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake"
sources_fake "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/fake"
)

Expand Down Expand Up @@ -78,6 +80,25 @@ func CreateSourcesTestKnCommand(cmd *cobra.Command, knParams *KnParams) (*cobra.
return knCommand, fakeEventing, buf
}

// CreateEventingTestKnCommand helper for creating test commands
func CreateEventingTestKnCommand(cmd *cobra.Command, knParams *KnParams) (*cobra.Command, *eventing_fake.FakeEventingV1alpha1, *bytes.Buffer) {
buf := new(bytes.Buffer)
// create fake serving client because the sink of source depends on serving client
fakeServing := &fake.FakeServingV1alpha1{&client_testing.Fake{}}
knParams.NewServingClient = func(namespace string) (v1alpha1.KnServingClient, error) {
return v1alpha1.NewKnServingClient(fakeServing, FakeNamespace), nil
}
// create fake sources client
fakeEventing := &eventing_fake.FakeEventingV1alpha1{&client_testing.Fake{}}
knParams.Output = buf
knParams.NewEventingClient = func(namespace string) (eventing_client.KnEventingClient, error) {
return eventing_client.NewKnEventingClient(fakeEventing, FakeNamespace), nil
}
knParams.fixedCurrentNamespace = FakeNamespace
knCommand := NewKnTestCommand(cmd, knParams)
return knCommand, fakeEventing, buf
}

// CreateDynamicTestKnCommand helper for creating test commands using dynamic client
func CreateDynamicTestKnCommand(cmd *cobra.Command, knParams *KnParams, objects ...runtime.Object) (*cobra.Command, *dynamic_fake.FakeDynamicClient, *bytes.Buffer) {
buf := new(bytes.Buffer)
Expand Down
Loading

0 comments on commit 5bd6789

Please sign in to comment.