Skip to content

Commit

Permalink
Add bcommand for creation of a plain trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
Daisy Guo committed Dec 9, 2019
1 parent ed25066 commit f2202d9
Show file tree
Hide file tree
Showing 15 changed files with 1,168 additions and 47 deletions.
60 changes: 60 additions & 0 deletions pkg/eventing/v1alpha1/client.go
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
}
58 changes: 58 additions & 0 deletions pkg/kn/commands/flags/sink.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// 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 (
"fmt"
"strings"

"github.com/spf13/cobra"
v1 "k8s.io/api/core/v1"
apisv1alpha1 "knative.dev/pkg/apis/v1alpha1"

"knative.dev/client/pkg/serving/v1alpha1"
)

type SinkFlags struct {
sink string
}

func (i *SinkFlags) Add(cmd *cobra.Command) {
cmd.Flags().StringVarP(&i.sink, "sink", "s", "", "Addressable sink for events")
}

func (i *SinkFlags) ResolveSink(client v1alpha1.KnServingClient) (*apisv1alpha1.Destination, error) {
if i.sink == "" {
return nil, nil
}

if strings.HasPrefix(i.sink, "svc:") {
serviceName := i.sink[4:]
service, err := client.GetService(serviceName)
if err != nil {
return nil, err
}
return &apisv1alpha1.Destination{
Ref: &v1.ObjectReference{
Kind: service.Kind,
APIVersion: service.APIVersion,
Name: service.Name,
Namespace: service.Namespace,
},
}, nil
}

return nil, fmt.Errorf("Not supported sink type: %s", i.sink)
}
116 changes: 116 additions & 0 deletions pkg/kn/commands/trigger/create.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 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"
)

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.NewClient(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 = objectRef

// 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
}
15 changes: 15 additions & 0 deletions pkg/kn/commands/trigger/create_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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
30 changes: 30 additions & 0 deletions pkg/kn/commands/trigger/trigger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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 (
"github.com/spf13/cobra"

"knative.dev/client/pkg/kn/commands"
)

func NewTriggerCommand(p *commands.KnParams) *cobra.Command {
triggerCmd := &cobra.Command{
Use: "trigger",
Short: "Event Trigger command group",
}
triggerCmd.AddCommand(NewTriggerCreateCommand(p))
return triggerCmd
}
62 changes: 62 additions & 0 deletions pkg/kn/commands/trigger/update_flag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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 (
"fmt"
"strings"

"github.com/spf13/cobra"
)

// TriggerUpdateFlags are flags for create and update a Trigger
type TriggerUpdateFlags struct {
Broker string
Filter filterArray
}

type filterArray []string

func (a *filterArray) String() string {
return "my string representation"
}

func (a *filterArray) Set(value string) error {
*a = append(*a, value)
return nil
}

func (a *filterArray) Type() string {
return "filterArray"
}

func (f *TriggerUpdateFlags) GetFilter() map[string]string {
filters := map[string]string{}
for _, item := range f.Filter {
parts := strings.Split(item, "=")
if len(parts) == 2 {
filters[parts[0]] = parts[1]
} else {
fmt.Printf("Ignore invalid filter %s", f)
}
}
return filters
}

//Add is to set parameters
func (f *TriggerUpdateFlags) Add(cmd *cobra.Command) {
cmd.Flags().StringVar(&f.Broker, "broker", "default", "Name of the Broker which the trigger associates with. Defaults to 'default' if not specified.")
cmd.Flags().Var(&f.Filter, "filter", "A key-value pair for exact CloudEvent attribute matching against incoming events, e.g type=dev.knative.foo")
}
35 changes: 35 additions & 0 deletions pkg/kn/commands/trigger/update_flag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 (
"testing"

"gotest.tools/assert"
)

func TestGetFilter(t *testing.T) {
t.Run("get multiple filters", func(t *testing.T) {
createFlag := TriggerUpdateFlags{
Filter: []string{"type=abc.edf.ghi", "attr=value"},
}
created := createFlag.GetFilter()
wanted := map[string]string{
"type": "abc.edf.ghi",
"attr": "value",
}
assert.DeepEqual(t, wanted, created)
})
}
Loading

0 comments on commit f2202d9

Please sign in to comment.