-
Notifications
You must be signed in to change notification settings - Fork 263
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add bcommand for creation of a plain trigger
- Loading branch information
Daisy Guo
committed
Dec 11, 2019
1 parent
2c1e5dc
commit 88367ed
Showing
45 changed files
with
8,316 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// 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 ( | ||
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(trigger *v1alpha1.Trigger) (*v1alpha1.Trigger, 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 | ||
} | ||
|
||
// Return the client's namespace | ||
func (c *knEventingClient) Namespace() string { | ||
return c.namespace | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// 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 trigger | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"knative.dev/client/pkg/kn/commands" | ||
"knative.dev/client/pkg/kn/commands/flags" | ||
"knative.dev/eventing/pkg/apis/eventing/v1alpha1" | ||
duckv1 "knative.dev/pkg/apis/duck/v1" | ||
) | ||
|
||
func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command { | ||
var triggerUpdateFlags TriggerUpdateFlags | ||
var sinkFlags flags.SinkFlags | ||
|
||
cmd := &cobra.Command{ | ||
Use: "create NAME --broker BROKER --filter KEY=VALUE --sink SINK", | ||
Short: "Create a Trigger", | ||
Example: ` | ||
# 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`, | ||
|
||
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") | ||
} | ||
name := args[0] | ||
|
||
// get namespace | ||
namespace, err := p.GetNamespace(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// get client | ||
eventingClient, err := p.NewEventingClient(namespace) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// resolve sink | ||
servingClient, err := p.NewServingClient(namespace) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
objectRef, err := sinkFlags.ResolveSink(servingClient) | ||
if err != nil { | ||
return fmt.Errorf( | ||
"cannot create Trigger '%s' in namespace '%s' "+ | ||
"because %s", name, namespace, err) | ||
} | ||
|
||
// construct Trigger | ||
trigger := constructTrigger(name, namespace, triggerUpdateFlags) | ||
trigger.Spec.Subscriber = &duckv1.Destination{ | ||
Ref: objectRef.Ref, | ||
URI: objectRef.URI, | ||
} | ||
|
||
// create | ||
_, err = eventingClient.CreateTrigger(trigger) | ||
if err != nil { | ||
return fmt.Errorf( | ||
"cannot create Trigger '%s' in namespace '%s' "+ | ||
"because %s", name, namespace, err) | ||
} | ||
fmt.Fprintf(cmd.OutOrStdout(), "Trigger '%s' successfully created in namespace '%s'.\n", args[0], namespace) | ||
return nil | ||
}, | ||
} | ||
commands.AddNamespaceFlags(cmd.Flags(), false) | ||
triggerUpdateFlags.Add(cmd) | ||
sinkFlags.Add(cmd) | ||
cmd.MarkFlagRequired("schedule") | ||
|
||
return cmd | ||
} | ||
|
||
// constructTrigger is to create an instance of v1alpha1.Trigger | ||
func constructTrigger(name string, namespace string, flags TriggerUpdateFlags) *v1alpha1.Trigger { | ||
|
||
trigger := v1alpha1.Trigger{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: name, | ||
Namespace: namespace, | ||
}, | ||
Spec: v1alpha1.TriggerSpec{ | ||
Broker: flags.Broker, | ||
}, | ||
} | ||
|
||
filters := flags.GetFilter() | ||
if filters != nil { | ||
triggerFilterAttributes := v1alpha1.TriggerFilterAttributes(filters) | ||
trigger.Spec.Filter = &v1alpha1.TriggerFilter{ | ||
Attributes: &triggerFilterAttributes, | ||
} | ||
} | ||
|
||
return &trigger | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
// 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 trigger | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"testing" | ||
|
||
"gotest.tools/assert" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
client_testing "k8s.io/client-go/testing" | ||
"knative.dev/client/pkg/kn/commands" | ||
"knative.dev/client/pkg/util" | ||
"knative.dev/eventing/pkg/apis/eventing/v1alpha1" | ||
duckv1 "knative.dev/pkg/apis/duck/v1" | ||
) | ||
|
||
var ( | ||
triggerName = "foo" | ||
) | ||
|
||
func fakeTriggerCreate(args []string) ( | ||
action client_testing.Action, | ||
tr *v1alpha1.Trigger, | ||
output string, | ||
err error) { | ||
knParams := &commands.KnParams{} | ||
cmd, fakeClient, buf := commands.CreateEventingTestKnCommand(NewTriggerCommand(knParams), knParams) | ||
fakeClient.AddReactor("create", "triggers", | ||
func(a client_testing.Action) (bool, runtime.Object, error) { | ||
createAction, ok := a.(client_testing.CreateAction) | ||
action = createAction | ||
if !ok { | ||
return true, nil, fmt.Errorf("wrong kind of action %v", a) | ||
} | ||
tr, ok = createAction.GetObject().(*v1alpha1.Trigger) | ||
if !ok { | ||
return true, nil, errors.New("was passed the wrong object") | ||
} | ||
return true, tr, nil | ||
}) | ||
cmd.SetArgs(args) | ||
err = cmd.Execute() | ||
if err != nil { | ||
output = err.Error() | ||
return | ||
} | ||
output = buf.String() | ||
return | ||
} | ||
|
||
func TestTriggerCreate(t *testing.T) { | ||
action, created, output, err := fakeTriggerCreate([]string{ | ||
"trigger", "create", triggerName, "--broker", "mybroker", | ||
"--filter", "type=dev.knative.foo", "--sink", "svc:mysvc"}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} else if !action.Matches("create", "triggers") { | ||
t.Fatalf("Bad action %v", action) | ||
} | ||
|
||
//construct a wanted instance | ||
wanted := &v1alpha1.Trigger{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: triggerName, | ||
Namespace: commands.FakeNamespace, | ||
}, | ||
Spec: v1alpha1.TriggerSpec{ | ||
Broker: "mybroker", | ||
Filter: &v1alpha1.TriggerFilter{ | ||
Attributes: &v1alpha1.TriggerFilterAttributes{ | ||
"type": "dev.knative.foo", | ||
}, | ||
}, | ||
Subscriber: &duckv1.Destination{ | ||
Ref: &corev1.ObjectReference{ | ||
Kind: "Service", | ||
APIVersion: "serving.knative.dev/v1alpha1", | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
//assert equal | ||
assert.DeepEqual(t, wanted, created) | ||
assert.Check(t, util.ContainsAll(output, "Trigger", triggerName, "created", "namespace", commands.FakeNamespace)) | ||
} | ||
|
||
func TestTriggerCreateWithoutBroker(t *testing.T) { | ||
action, created, output, err := fakeTriggerCreate([]string{ | ||
"trigger", "create", triggerName, | ||
"--filter", "type=dev.knative.foo", "--sink", "svc:mysvc"}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} else if !action.Matches("create", "triggers") { | ||
t.Fatalf("Bad action %v", action) | ||
} | ||
|
||
//construct a wanted instance | ||
wanted := &v1alpha1.Trigger{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: triggerName, | ||
Namespace: commands.FakeNamespace, | ||
}, | ||
Spec: v1alpha1.TriggerSpec{ | ||
Broker: "default", | ||
Filter: &v1alpha1.TriggerFilter{ | ||
Attributes: &v1alpha1.TriggerFilterAttributes{ | ||
"type": "dev.knative.foo", | ||
}, | ||
}, | ||
Subscriber: &duckv1.Destination{ | ||
Ref: &corev1.ObjectReference{ | ||
Kind: "Service", | ||
APIVersion: "serving.knative.dev/v1alpha1", | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
//assert equal | ||
assert.DeepEqual(t, wanted, created) | ||
assert.Check(t, util.ContainsAll(output, "Trigger", triggerName, "created", "namespace", commands.FakeNamespace)) | ||
} | ||
|
||
func TestTriggerCreateMultipleFilter(t *testing.T) { | ||
action, created, output, err := fakeTriggerCreate([]string{ | ||
"trigger", "create", triggerName, | ||
"--filter", "type=dev.knative.foo", "--filter", "source=event.host", | ||
"--sink", "svc:mysvc"}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} else if !action.Matches("create", "triggers") { | ||
t.Fatalf("Bad action %v", action) | ||
} | ||
|
||
//construct a wanted instance | ||
wanted := &v1alpha1.Trigger{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: triggerName, | ||
Namespace: commands.FakeNamespace, | ||
}, | ||
Spec: v1alpha1.TriggerSpec{ | ||
Broker: "default", | ||
Filter: &v1alpha1.TriggerFilter{ | ||
Attributes: &v1alpha1.TriggerFilterAttributes{ | ||
"type": "dev.knative.foo", | ||
"source": "event.host", | ||
}, | ||
}, | ||
Subscriber: &duckv1.Destination{ | ||
Ref: &corev1.ObjectReference{ | ||
Kind: "Service", | ||
APIVersion: "serving.knative.dev/v1alpha1", | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
//assert equal | ||
assert.DeepEqual(t, wanted, created) | ||
assert.Check(t, util.ContainsAll(output, "Trigger", triggerName, "created", "namespace", commands.FakeNamespace)) | ||
} |
Oops, something went wrong.