Add creating ApiServerSource event source to Client (#415)

This commit is contained in:
Ying Chun Guo 2019-12-10 19:52:46 +08:00 committed by Knative Prow Robot
parent 8e010d0cbd
commit 003dba3616
19 changed files with 945 additions and 7 deletions

View File

@ -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
docs/cmd/kn_source.md Normal file
View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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"
)
@ -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
@ -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

View File

@ -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
}

View File

@ -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)
}

View File

@ -0,0 +1,31 @@
// 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 apiserver
import (
"github.com/spf13/cobra"
"knative.dev/client/pkg/kn/commands"
)
func NewApiServerCommand(p *commands.KnParams) *cobra.Command {
apiServerImporterCmd := &cobra.Command{
Use: "apiserver",
Short: "Kubernetes API Server Event Source command group",
}
apiServerImporterCmd.AddCommand(NewApiServerCreateCommand(p))
apiServerImporterCmd.AddCommand(NewApiServerDeleteCommand(p))
return apiServerImporterCmd
}

View File

@ -0,0 +1,110 @@
// 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 apiserver
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/sources/v1alpha1"
)
func NewApiServerCreateCommand(p *commands.KnParams) *cobra.Command {
var apiServerUpdateFlags ApiServerSourceUpdateFlags
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "create NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE",
Short: "Create an ApiServerSource, which watches for Kubernetes events and forwards them to a sink",
Example: `
# 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`,
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) != 1 {
return errors.New("'source apiserver create' requires the name of the source as single argument")
}
name := args[0]
// get namespace
namespace, err := p.GetNamespace(cmd)
if err != nil {
return err
}
// get client
sourcesClient, err := p.NewSourcesClient(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 ApiServerSource '%s' in namespace '%s' "+
"because %s", name, namespace, err)
}
// construct ApiServerSource
apisrvsrc := constructApiServerSource(name, namespace, apiServerUpdateFlags)
apisrvsrc.Spec.Sink = objectRef
// create
_, err = sourcesClient.CreateApiServerSource(apisrvsrc)
if err != nil {
return fmt.Errorf(
"cannot create ApiServerSource '%s' in namespace '%s' "+
"because %s", name, namespace, err)
}
fmt.Fprintf(cmd.OutOrStdout(), "ApiServerSource '%s' successfully created in namespace '%s'.\n", args[0], namespace)
return nil
},
}
commands.AddNamespaceFlags(cmd.Flags(), false)
apiServerUpdateFlags.Add(cmd)
sinkFlags.Add(cmd)
cmd.MarkFlagRequired("schedule")
return cmd
}
// constructApiServerSource is to create an instance of v1alpha1.ApiServerSource
func constructApiServerSource(name string, namespace string, apiServerFlags ApiServerSourceUpdateFlags) *v1alpha1.ApiServerSource {
source := v1alpha1.ApiServerSource{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: v1alpha1.ApiServerSourceSpec{
Resources: apiServerFlags.GetApiServerResourceArray(),
ServiceAccountName: apiServerFlags.ServiceAccountName,
Mode: apiServerFlags.Mode,
},
}
return &source
}

View File

@ -0,0 +1,89 @@
// 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 apiserver
import (
"strconv"
"strings"
"github.com/spf13/cobra"
sources_v1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1"
)
const (
ApiVersionSplitChar = ":"
DefaultApiVersion = "v1"
)
// ApiServerSourceUpdateFlags are flags for create and update a ApiServerSource
type ApiServerSourceUpdateFlags struct {
ServiceAccountName string
Mode string
Resources []string
}
// GetApiServerResourceArray is to return an array of ApiServerResource from a string. A sample is Event:v1:true,Pod:v2:false
func (f *ApiServerSourceUpdateFlags) GetApiServerResourceArray() []sources_v1alpha1.ApiServerResource {
var resourceList []sources_v1alpha1.ApiServerResource
for _, r := range f.Resources {
version, kind, controller := getValidResource(r)
resourceRef := sources_v1alpha1.ApiServerResource{
APIVersion: version,
Kind: kind,
Controller: controller,
}
resourceList = append(resourceList, resourceRef)
}
return resourceList
}
func getValidResource(resource string) (string, string, bool) {
var version = DefaultApiVersion // v1 as default
var isController = false //false as default
var err error
parts := strings.Split(resource, ApiVersionSplitChar)
kind := parts[0]
if len(parts) >= 2 {
version = parts[1]
}
if len(parts) >= 3 {
isController, err = strconv.ParseBool(parts[2])
if err != nil {
isController = false
}
}
return version, kind, isController
}
//Add is to set parameters
func (f *ApiServerSourceUpdateFlags) Add(cmd *cobra.Command) {
cmd.Flags().StringVar(&f.ServiceAccountName,
"service-account",
"",
"Name of the service account to use to run this source")
cmd.Flags().StringVar(&f.Mode,
"mode",
"Ref",
`The mode the receive adapter controller runs under:,
"Ref" sends only the reference to the resource,
"Resource" send the full resource.`)
cmd.Flags().StringSliceVar(&f.Resources,
"resource",
nil,
`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. `)
}

View File

@ -0,0 +1,105 @@
// 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 apiserver
import (
"testing"
"gotest.tools/assert"
sources_v1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1"
)
func TestGetApiServerResourceArray(t *testing.T) {
t.Run("get single apiserver resource", func(t *testing.T) {
createFlag := ApiServerSourceUpdateFlags{
ServiceAccountName: "test-sa",
Mode: "Ref",
Resources: []string{"Service:serving.knative.dev/v1alpha1:true"},
}
created := createFlag.GetApiServerResourceArray()
wanted := []sources_v1alpha1.ApiServerResource{{
APIVersion: "serving.knative.dev/v1alpha1",
Kind: "Service",
Controller: true,
}}
assert.DeepEqual(t, wanted, created)
// default isController
createFlag = ApiServerSourceUpdateFlags{
ServiceAccountName: "test-sa",
Mode: "Ref",
Resources: []string{"Service:serving.knative.dev/v1alpha1"},
}
created = createFlag.GetApiServerResourceArray()
wanted = []sources_v1alpha1.ApiServerResource{{
APIVersion: "serving.knative.dev/v1alpha1",
Kind: "Service",
Controller: false,
}}
assert.DeepEqual(t, wanted, created)
// default api version and isController
createFlag = ApiServerSourceUpdateFlags{
ServiceAccountName: "test-sa",
Mode: "Ref",
Resources: []string{"Service"},
}
created = createFlag.GetApiServerResourceArray()
wanted = []sources_v1alpha1.ApiServerResource{{
APIVersion: "v1",
Kind: "Service",
Controller: false,
}}
assert.DeepEqual(t, wanted, created)
})
t.Run("get multiple apiserver resources", func(t *testing.T) {
createFlag := ApiServerSourceUpdateFlags{
ServiceAccountName: "test-sa",
Mode: "Resource",
Resources: []string{"Event:v1:true", "Pod:v2:false"},
}
created := createFlag.GetApiServerResourceArray()
wanted := []sources_v1alpha1.ApiServerResource{{
APIVersion: "v1",
Kind: "Event",
Controller: true,
}, {
APIVersion: "v2",
Kind: "Pod",
Controller: false,
}}
assert.DeepEqual(t, wanted, created)
// default api version and isController
createFlag = ApiServerSourceUpdateFlags{
ServiceAccountName: "test-sa",
Mode: "Resource",
Resources: []string{"Event", "Pod"},
}
created = createFlag.GetApiServerResourceArray()
wanted = []sources_v1alpha1.ApiServerResource{{
APIVersion: "v1",
Kind: "Event",
Controller: false,
}, {
APIVersion: "v1",
Kind: "Pod",
Controller: false,
}}
assert.DeepEqual(t, wanted, created)
})
}

View File

@ -0,0 +1,102 @@
// 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 apiserver
import (
"errors"
"fmt"
"testing"
"gotest.tools/assert"
v1 "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/sources/v1alpha1"
apisv1alpha1 "knative.dev/pkg/apis/v1alpha1"
)
var (
testApiServerSrcName = "foo"
)
func fakeApiServerSourceCreate(args []string, withExistingService bool, sync bool) (
action client_testing.Action,
src *v1alpha1.ApiServerSource,
output string,
err error) {
knParams := &commands.KnParams{}
cmd, fakeSource, buf := commands.CreateSourcesTestKnCommand(NewApiServerCommand(knParams), knParams)
fakeSource.AddReactor("create", "apiserversources",
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)
}
src, ok = createAction.GetObject().(*v1alpha1.ApiServerSource)
if !ok {
return true, nil, errors.New("was passed the wrong object")
}
return true, src, nil
})
cmd.SetArgs(args)
err = cmd.Execute()
if err != nil {
output = err.Error()
return
}
output = buf.String()
return
}
func TestApiServerSourceCreate(t *testing.T) {
action, created, output, err := fakeApiServerSourceCreate([]string{
"apiserver", "create", testApiServerSrcName, "--resource", "Event:v1:true", "--service-account", "myaccountname", "--sink", "svc:mysvc"}, true, false)
if err != nil {
t.Fatal(err)
} else if !action.Matches("create", "apiserversources") {
t.Fatalf("Bad action %v", action)
}
//construct a wanted instance
wanted := &v1alpha1.ApiServerSource{
ObjectMeta: metav1.ObjectMeta{
Name: testApiServerSrcName,
Namespace: commands.FakeNamespace,
},
Spec: v1alpha1.ApiServerSourceSpec{
Resources: []v1alpha1.ApiServerResource{{
APIVersion: "v1",
Kind: "Event",
Controller: true,
}},
ServiceAccountName: "myaccountname",
Mode: "Ref",
Sink: &apisv1alpha1.Destination{
Ref: &v1.ObjectReference{
Kind: "Service",
APIVersion: "serving.knative.dev/v1alpha1",
},
},
},
}
//assert equal
assert.DeepEqual(t, wanted, created)
assert.Check(t, util.ContainsAll(output, "ApiServerSource", testApiServerSrcName, "created", "namespace", commands.FakeNamespace))
}

View File

@ -0,0 +1,59 @@
// 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 apiserver
import (
"errors"
"fmt"
"github.com/spf13/cobra"
"knative.dev/client/pkg/kn/commands"
)
// NewRevisionDeleteCommand represent 'revision delete' command
func NewApiServerDeleteCommand(p *commands.KnParams) *cobra.Command {
ApiServerDeleteCommand := &cobra.Command{
Use: "delete NAME",
Short: "Delete an ApiServerSource.",
Example: `
# Delete an ApiServerSource 'k8sevents' in default namespace
kn source apiserver delete k8sevents`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return errors.New("'source apiserver delete' requires the name of the source as single argument")
}
name := args[0]
namespace, err := p.GetNamespace(cmd)
if err != nil {
return err
}
sourcesClient, err := p.NewSourcesClient(namespace)
if err != nil {
return err
}
err = sourcesClient.DeleteApiServerSource(name)
if err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "ApiServerSource '%s' deleted in namespace '%s'.\n", args[0], namespace)
return nil
},
}
commands.AddNamespaceFlags(ApiServerDeleteCommand.Flags(), false)
return ApiServerDeleteCommand
}

View File

@ -0,0 +1,61 @@
// 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 apiserver
import (
"testing"
"gotest.tools/assert"
"k8s.io/apimachinery/pkg/runtime"
client_testing "k8s.io/client-go/testing"
"knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/util"
)
func fakeServiceDelete(args []string) (action client_testing.Action, name string, output string, err error) {
knParams := &commands.KnParams{}
cmd, fakeSource, buf := commands.CreateSourcesTestKnCommand(NewApiServerCommand(knParams), knParams)
fakeSource.AddReactor("delete", "apiserversources",
func(a client_testing.Action) (bool, runtime.Object, error) {
deleteAction, _ := a.(client_testing.DeleteAction)
action = deleteAction
name = deleteAction.GetName()
return true, nil, nil
})
cmd.SetArgs(args)
err = cmd.Execute()
if err != nil {
return
}
output = buf.String()
return
}
func TestServiceDelete(t *testing.T) {
srcName := "src-12345"
action, name, output, err := fakeServiceDelete([]string{"apiserver", "delete", srcName})
if err != nil {
t.Error(err)
return
}
if action == nil {
t.Errorf("No action")
} else if !action.Matches("delete", "apiserversources") {
t.Errorf("Bad action %v", action)
} else if name != srcName {
t.Errorf("Bad service name returned after delete.")
}
assert.Check(t, util.ContainsAll(output, "ApiServerSource", srcName, "deleted", "namespace", commands.FakeNamespace))
}

View File

@ -0,0 +1,32 @@
// 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 source
import (
"github.com/spf13/cobra"
"knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/kn/commands/source/apiserver"
)
func NewSourceCommand(p *commands.KnParams) *cobra.Command {
sourceCmd := &cobra.Command{
Use: "source",
Short: "Event Source command group",
}
//sourceCmd.AddCommand(cron.NewCronCommand(p))
sourceCmd.AddCommand(apiserver.NewApiServerCommand(p))
return sourceCmd
}

View File

@ -60,6 +60,12 @@ func CreateTestKnCommand(cmd *cobra.Command, knParams *KnParams) (*cobra.Command
// CreateSourcesTestKnCommand helper for creating test commands
func CreateSourcesTestKnCommand(cmd *cobra.Command, knParams *KnParams) (*cobra.Command, *sources_fake.FakeSourcesV1alpha1, *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 := &sources_fake.FakeSourcesV1alpha1{&client_testing.Fake{}}
knParams.Output = buf
knParams.NewSourcesClient = func(namespace string) (sources_client.KnSourcesClient, error) {

View File

@ -35,6 +35,7 @@ import (
"knative.dev/client/pkg/kn/commands/revision"
"knative.dev/client/pkg/kn/commands/route"
"knative.dev/client/pkg/kn/commands/service"
"knative.dev/client/pkg/kn/commands/source"
"knative.dev/client/pkg/kn/commands/version"
"knative.dev/client/pkg/kn/flags"
)
@ -142,6 +143,7 @@ func NewKnCommand(params ...commands.KnParams) *cobra.Command {
rootCmd.AddCommand(route.NewRouteCommand(p))
rootCmd.AddCommand(completion.NewCompletionCommand(p))
rootCmd.AddCommand(version.NewVersionCommand(p))
rootCmd.AddCommand(source.NewSourceCommand(p))
// Deal with empty and unknown sub command groups
EmptyAndUnknownSubCommands(rootCmd)

14
vendor/modules.txt vendored
View File

@ -357,8 +357,8 @@ gotest.tools/internal/source
gotest.tools/internal/difflib
# k8s.io/api v0.0.0-20191016110246-af539daaa43a
k8s.io/api/core/v1
k8s.io/api/authentication/v1
k8s.io/api/apps/v1
k8s.io/api/authentication/v1
k8s.io/api/admissionregistration/v1beta1
k8s.io/api/apps/v1beta1
k8s.io/api/apps/v1beta2
@ -437,9 +437,9 @@ k8s.io/apimachinery/pkg/version
k8s.io/apimachinery/pkg/runtime/serializer/protobuf
k8s.io/apimachinery/pkg/runtime/serializer/recognizer
k8s.io/apimachinery/pkg/util/clock
k8s.io/apimachinery/pkg/util/framer
k8s.io/apimachinery/pkg/util/cache
k8s.io/apimachinery/pkg/util/diff
k8s.io/apimachinery/pkg/util/framer
k8s.io/apimachinery/pkg/apis/meta/internalversion
# k8s.io/cli-runtime v0.0.0-20191016113937-7693ce2cae74
k8s.io/cli-runtime/pkg/genericclioptions
@ -475,9 +475,9 @@ k8s.io/client-go/tools/metrics
k8s.io/client-go/transport
k8s.io/client-go/util/cert
k8s.io/client-go/util/flowcontrol
k8s.io/client-go/tools/cache
k8s.io/client-go/tools/clientcmd/api/v1
k8s.io/client-go/dynamic
k8s.io/client-go/tools/cache
k8s.io/client-go/kubernetes/scheme
k8s.io/client-go/third_party/forked/golang/template
k8s.io/client-go/pkg/apis/clientauthentication
@ -621,12 +621,12 @@ k8s.io/utils/integer
k8s.io/utils/buffer
k8s.io/utils/trace
# knative.dev/eventing v0.10.0
knative.dev/eventing/pkg/apis/sources/v1alpha1
knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1
knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/fake
knative.dev/eventing/pkg/apis/sources/v1alpha1
knative.dev/eventing/pkg/client/clientset/versioned/scheme
knative.dev/eventing/pkg/apis/duck
knative.dev/eventing/pkg/apis/sources
knative.dev/eventing/pkg/client/clientset/versioned/scheme
knative.dev/eventing/pkg/apis/eventing/v1alpha1
knative.dev/eventing/pkg/apis/messaging/v1alpha1
knative.dev/eventing/pkg/apis/duck/v1alpha1
@ -635,13 +635,13 @@ knative.dev/eventing/pkg/apis/messaging
# knative.dev/pkg v0.0.0-20191107185656-884d50f09454
knative.dev/pkg/apis
knative.dev/pkg/apis/duck/v1
knative.dev/pkg/apis/v1alpha1
knative.dev/pkg/ptr
knative.dev/pkg/kmeta
knative.dev/pkg/kmp
knative.dev/pkg/apis/duck
knative.dev/pkg/apis/v1alpha1
knative.dev/pkg/profiling
knative.dev/pkg/apis/duck/v1alpha1
knative.dev/pkg/kmeta
knative.dev/pkg/configmap
knative.dev/pkg/logging
knative.dev/pkg/network