Skip to content

Commit

Permalink
Add creating ApiServerSource event source to Client (#415)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ying Chun Guo authored and knative-prow-robot committed Dec 10, 2019
1 parent 8e010d0 commit 003dba3
Show file tree
Hide file tree
Showing 19 changed files with 945 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/cmd/kn.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ Manage your Knative building blocks:
* [kn revision](kn_revision.md) - Revision command group
* [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 version](kn_version.md) - Prints the client version

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

Event Source command group

### Synopsis

Event Source command group

```
kn source [flags]
```

### Options

```
-h, --help help for source
```

### 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 source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group

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

Kubernetes API Server Event Source command group

### Synopsis

Kubernetes API Server Event Source command group

```
kn source apiserver [flags]
```

### Options

```
-h, --help help for apiserver
```

### 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 source](kn_source.md) - Event Source command group
* [kn source apiserver create](kn_source_apiserver_create.md) - Create an ApiServerSource, which watches for Kubernetes events and forwards them to a sink
* [kn source apiserver delete](kn_source_apiserver_delete.md) - Delete an ApiServerSource.

47 changes: 47 additions & 0 deletions docs/cmd/kn_source_apiserver_create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## kn source apiserver create

Create an ApiServerSource, which watches for Kubernetes events and forwards them to a sink

### Synopsis

Create an ApiServerSource, which watches for Kubernetes events and forwards them to a sink

```
kn source apiserver create NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE [flags]
```

### Examples

```
# Create an ApiServerSource 'k8sevents' which consumes Kubernetes events and sends message to service 'mysvc' as a cloudevent
kn source apiserver create k8sevents --resource Event --service-account myaccountname --sink svc:mysvc
```

### Options

```
-h, --help help for create
--mode string The mode the receive adapter controller runs under:,
"Ref" sends only the reference to the resource,
"Resource" send the full resource. (default "Ref")
-n, --namespace string Specify the namespace to operate in.
--resource strings Comma seperate Kind:APIVersion:isController list, e.g. Event:v1:true.
"APIVersion" and "isControler" can be omitted.
"APIVersion" is "v1" by default, "isController" is "false" by default.
--service-account string Name of the service account to use to run this source
-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 source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group

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

Delete an ApiServerSource.

### Synopsis

Delete an ApiServerSource.

```
kn source apiserver delete NAME [flags]
```

### Examples

```
# Delete an ApiServerSource 'k8sevents' in default namespace
kn source apiserver delete k8sevents
```

### 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 source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group

25 changes: 25 additions & 0 deletions pkg/eventing/sources/v1alpha1/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
package v1alpha1

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

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

Expand All @@ -23,6 +27,12 @@ import (
type KnSourcesClient interface {
// Namespace in which this client is operating for
Namespace() string

// Get an ApiServerSource by object
CreateApiServerSource(apisvrsrc *v1alpha1.ApiServerSource) (*v1alpha1.ApiServerSource, error)

// Delete an ApiServerSource by name
DeleteApiServerSource(name string) error
}

// knSourcesClient is a combination of Sources client interface and namespace
Expand All @@ -41,6 +51,21 @@ func NewKnSourcesClient(client client_v1alpha1.SourcesV1alpha1Interface, namespa
}
}

//CreateApiServerSource is used to create an instance of ApiServerSource
func (c *knSourcesClient) CreateApiServerSource(apisvrsrc *v1alpha1.ApiServerSource) (*v1alpha1.ApiServerSource, error) {
ins, err := c.client.ApiServerSources(c.namespace).Create(apisvrsrc)
if err != nil {
return nil, kn_errors.GetError(err)
}
return ins, nil
}

//DeleteApiServerSource is used to create an instance of ApiServerSource
func (c *knSourcesClient) DeleteApiServerSource(name string) error {
err := c.client.ApiServerSources(c.namespace).Delete(name, &apis_v1.DeleteOptions{})
return err
}

// Return the client's namespace
func (c *knSourcesClient) Namespace() string {
return c.namespace
Expand Down
108 changes: 108 additions & 0 deletions pkg/eventing/sources/v1alpha1/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// 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/sources/v1alpha1"
"knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/fake"
)

var testNamespace = "test-ns"

func setup() (sources fake.FakeSourcesV1alpha1, client KnSourcesClient) {
sources = fake.FakeSourcesV1alpha1{Fake: &client_testing.Fake{}}
client = NewKnSourcesClient(&sources, testNamespace)
return
}

func TestDeleteApiServerSource(t *testing.T) {
var srcName = "new-src"
sourcesServer, client := setup()

apisourceNew := newApiServerSource(srcName)

sourcesServer.AddReactor("create", "apiserversources",
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 == apisourceNew.Name {
apisourceNew.Generation = 2
return true, apisourceNew, nil
}
return true, nil, fmt.Errorf("error while creating apiserversource %s", name)
})

t.Run("create apiserversource without error", func(t *testing.T) {
ins, err := client.CreateApiServerSource(apisourceNew)
assert.NilError(t, err)
assert.Equal(t, ins.Name, srcName)
assert.Equal(t, ins.Namespace, testNamespace)
})

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

func TestCreateApiServerSource(t *testing.T) {
var srcName = "new-src"
sourcesServer, client := setup()

apisourceNew := newApiServerSource(srcName)

sourcesServer.AddReactor("create", "apiserversources",
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 == apisourceNew.Name {
apisourceNew.Generation = 2
return true, apisourceNew, nil
}
return true, nil, fmt.Errorf("error while creating apiserversource %s", name)
})

t.Run("create apiserversource without error", func(t *testing.T) {
ins, err := client.CreateApiServerSource(apisourceNew)
assert.NilError(t, err)
assert.Equal(t, ins.Name, srcName)
assert.Equal(t, ins.Namespace, testNamespace)
})

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

func newApiServerSource(name string) *v1alpha1.ApiServerSource {
src := &v1alpha1.ApiServerSource{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: testNamespace,
},
}
src.Name = name
src.Namespace = testNamespace
return src
}
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)
}
Loading

0 comments on commit 003dba3

Please sign in to comment.