From 9d9d4541a7b4a4e7b468fc87af52b819e13e291e Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 18 Dec 2019 22:41:33 +0000 Subject: [PATCH 01/10] Introduce Broker as a kind of sink, genericize sinks in general --- pkg/dynamic/client.go | 18 +++++ pkg/dynamic/client_test.go | 15 ++-- pkg/kn/commands/flags/sink.go | 77 +++++++++++++++---- .../source/apiserver/apiserver_test.go | 14 ++-- pkg/kn/commands/source/apiserver/create.go | 6 +- .../commands/source/apiserver/create_test.go | 30 +++----- pkg/kn/commands/source/apiserver/update.go | 4 +- .../commands/source/apiserver/update_test.go | 16 ++-- pkg/kn/commands/source/cronjob/create.go | 8 +- pkg/kn/commands/source/cronjob/create_test.go | 30 +++----- .../commands/source/cronjob/cronjob_test.go | 10 +-- pkg/kn/commands/source/cronjob/update.go | 8 +- pkg/kn/commands/source/cronjob/update_test.go | 6 +- pkg/kn/commands/trigger/create.go | 6 +- pkg/kn/commands/trigger/create_test.go | 40 ++++------ pkg/kn/commands/trigger/list_test.go | 4 +- pkg/kn/commands/trigger/trigger_test.go | 11 ++- pkg/kn/commands/trigger/update.go | 5 +- pkg/kn/commands/trigger/update_test.go | 16 ++-- 19 files changed, 179 insertions(+), 145 deletions(-) diff --git a/pkg/dynamic/client.go b/pkg/dynamic/client.go index b71879d03b..c18b213610 100644 --- a/pkg/dynamic/client.go +++ b/pkg/dynamic/client.go @@ -18,8 +18,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" + "k8s.io/client-go/dynamic/fake" + + serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) const ( @@ -42,6 +46,9 @@ type KnDynamicClient interface { // ListSourceCRDs returns list of eventing sources CRDs ListSourcesTypes() (*unstructured.UnstructuredList, error) + + // RawClient returns the raw dynamic client interface + RawClient() dynamic.Interface } // knDynamicClient is a combination of client-go Dynamic client interface and namespace @@ -87,3 +94,14 @@ func (c *knDynamicClient) ListSourcesTypes() (*unstructured.UnstructuredList, er options.LabelSelector = sourcesLabels.String() return c.ListCRDs(options) } + +func (c knDynamicClient) RawClient() dynamic.Interface { + return c.client +} + +func CreateFakeKnDynamicClient(testNamespace string, objects ...runtime.Object) KnDynamicClient { + scheme := runtime.NewScheme() + scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1alpha1", Kind: "Service"}, &serving_v1alpha1.Service{}) + client := fake.NewSimpleDynamicClient(scheme, objects...) + return NewKnDynamicClient(client, testNamespace) +} diff --git a/pkg/dynamic/client_test.go b/pkg/dynamic/client_test.go index f09b8f955b..cc0952a0f6 100644 --- a/pkg/dynamic/client_test.go +++ b/pkg/dynamic/client_test.go @@ -21,8 +21,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/dynamic/fake" ) const testNamespace = "testns" @@ -43,18 +41,14 @@ func newUnstructured(name string) *unstructured.Unstructured { } } -func createFakeKnDynamicClient(objects ...runtime.Object) KnDynamicClient { - client := fake.NewSimpleDynamicClient(runtime.NewScheme(), objects...) - return NewKnDynamicClient(client, testNamespace) -} - func TestNamespace(t *testing.T) { - client := createFakeKnDynamicClient(newUnstructured("foo")) + client := CreateFakeKnDynamicClient(testNamespace, newUnstructured("foo")) assert.Equal(t, client.Namespace(), testNamespace) } func TestListCRDs(t *testing.T) { - client := createFakeKnDynamicClient( + client := CreateFakeKnDynamicClient( + testNamespace, newUnstructured("foo"), newUnstructured("bar"), ) @@ -83,7 +77,8 @@ func TestListCRDs(t *testing.T) { } func TestListSourceTypes(t *testing.T) { - client := createFakeKnDynamicClient( + client := CreateFakeKnDynamicClient( + testNamespace, newUnstructured("foo"), newUnstructured("bar"), ) diff --git a/pkg/kn/commands/flags/sink.go b/pkg/kn/commands/flags/sink.go index 734895d041..74a262dc84 100644 --- a/pkg/kn/commands/flags/sink.go +++ b/pkg/kn/commands/flags/sink.go @@ -20,9 +20,11 @@ import ( "github.com/spf13/cobra" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" + "knative.dev/pkg/apis" duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" - - "knative.dev/client/pkg/serving/v1alpha1" ) type SinkFlags struct { @@ -33,26 +35,71 @@ 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) (*duckv1beta1.Destination, error) { +var SinkPrefixes = map[string]schema.GroupVersionResource{ + "broker": { + Resource: "brokers", + Group: "eventing.knative.dev", + Version: "v1alpha1", + }, + "service": { + Resource: "services", + Group: "serving.knative.dev", + Version: "v1alpha1", + }, + // Shorthand alias for service + "svc": { + Resource: "services", + Group: "serving.knative.dev", + Version: "v1alpha1", + }, +} + +// ResolveSink returns the Destination referred to by the flags in the acceptor. +// It validates that any object the user is referring to exists. +func (i *SinkFlags) ResolveSink(client dynamic.Interface, namespace string) (*duckv1beta1.Destination, error) { if i.sink == "" { return nil, nil } - if strings.HasPrefix(i.sink, "svc:") { - serviceName := i.sink[4:] - service, err := client.GetService(serviceName) + prefix, name := parseSink(i.sink) + if prefix == "" { + // URI target + uri, err := apis.ParseURL(name) if err != nil { return nil, err } - return &duckv1beta1.Destination{ - Ref: &v1.ObjectReference{ - Kind: service.Kind, - APIVersion: service.APIVersion, - Name: service.Name, - Namespace: service.Namespace, - }, - }, nil + return &duckv1beta1.Destination{URI: uri}, nil + } + typ, ok := SinkPrefixes[prefix] + if !ok { + return nil, fmt.Errorf("Not supported sink type: %s", i.sink) + } + obj, err := client.Resource(typ).Namespace(namespace).Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err } - return nil, fmt.Errorf("Not supported sink type: %s", i.sink) + return &duckv1beta1.Destination{ + Ref: &v1.ObjectReference{ + Kind: obj.GetKind(), + APIVersion: obj.GetAPIVersion(), + Name: obj.GetName(), + Namespace: namespace, + }, + }, nil + +} + +// parseSink takes the string given by the user into the prefix and the name of +// the object. If the user put a URI instead, the prefix is empty and the name +// is the whole URI. +func parseSink(sink string) (string, string) { + parts := strings.SplitN(sink, ":", 2) + if len(parts) == 1 { + return "svc", parts[0] + } else if parts[0] == "http" || parts[0] == "https" { + return "", sink + } else { + return parts[0], parts[1] + } } diff --git a/pkg/kn/commands/source/apiserver/apiserver_test.go b/pkg/kn/commands/source/apiserver/apiserver_test.go index 09777f2472..cc210ccf9d 100644 --- a/pkg/kn/commands/source/apiserver/apiserver_test.go +++ b/pkg/kn/commands/source/apiserver/apiserver_test.go @@ -19,12 +19,12 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/clientcmd" + kn_dynamic "knative.dev/client/pkg/dynamic" "knative.dev/eventing/pkg/apis/sources/v1alpha1" duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" knsource_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1" "knative.dev/client/pkg/kn/commands" - knserving_v1alpha1 "knative.dev/client/pkg/serving/v1alpha1" ) const testNamespace = "default" @@ -55,14 +55,14 @@ current-context: x } } -func executeAPIServerSourceCommand(apiServerSourceClient knsource_v1alpha1.KnAPIServerSourcesClient, servingClient knserving_v1alpha1.KnServingClient, args ...string) (string, error) { +func executeAPIServerSourceCommand(apiServerSourceClient knsource_v1alpha1.KnAPIServerSourcesClient, dynamicClient kn_dynamic.KnDynamicClient, args ...string) (string, error) { knParams := &commands.KnParams{} knParams.ClientConfig = blankConfig output := new(bytes.Buffer) knParams.Output = output - knParams.NewServingClient = func(namespace string) (knserving_v1alpha1.KnServingClient, error) { - return servingClient, nil + knParams.NewDynamicClient = func(namespace string) (kn_dynamic.KnDynamicClient, error) { + return dynamicClient, nil } cmd := NewAPIServerCommand(knParams) @@ -92,8 +92,10 @@ func createAPIServerSource(name, resourceKind, resourceVersion, serviceAccount, sink := &duckv1beta1.Destination{ Ref: &corev1.ObjectReference{ - Kind: "Service", - Name: service, + Kind: "Service", + Name: service, + APIVersion: "serving.knative.dev/v1alpha1", + Namespace: "default", }} return knsource_v1alpha1.NewAPIServerSourceBuilder(name). diff --git a/pkg/kn/commands/source/apiserver/create.go b/pkg/kn/commands/source/apiserver/create.go index 797fd1054c..7ae1f9bee4 100644 --- a/pkg/kn/commands/source/apiserver/create.go +++ b/pkg/kn/commands/source/apiserver/create.go @@ -51,13 +51,11 @@ func NewAPIServerCreateCommand(p *commands.KnParams) *cobra.Command { namespace := apiSourceClient.Namespace() - // create Serving client for resolving service sink - servingClient, err := p.NewServingClient(namespace) + dynamicClient, err := p.NewDynamicClient(namespace) if err != nil { return err } - - objectRef, err := sinkFlags.ResolveSink(servingClient) + objectRef, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) if err != nil { return fmt.Errorf( "cannot create ApiServerSource '%s' in namespace '%s' "+ diff --git a/pkg/kn/commands/source/apiserver/create_test.go b/pkg/kn/commands/source/apiserver/create_test.go index 176e17c1cc..a848f13c93 100644 --- a/pkg/kn/commands/source/apiserver/create_test.go +++ b/pkg/kn/commands/source/apiserver/create_test.go @@ -15,51 +15,41 @@ package apiserver import ( - "errors" "testing" "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kn_dynamic "knative.dev/client/pkg/dynamic" knsources_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1" - knserving_client "knative.dev/client/pkg/serving/v1alpha1" "knative.dev/client/pkg/util" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) func TestCreateApiServerSource(t *testing.T) { - + testsvc := &serving_v1alpha1.Service{ + TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, + ObjectMeta: metav1.ObjectMeta{Name: "testsvc", Namespace: "default"}, + } + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", testsvc) apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t) - servingClient := knserving_client.NewMockKnServiceClient(t) - - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("testsvc", &serving_v1alpha1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service"}, - ObjectMeta: metav1.ObjectMeta{Name: "testsvc"}, - }, nil) apiServerRecorder := apiServerClient.Recorder() apiServerRecorder.CreateAPIServerSource(createAPIServerSource("testsource", "Event", "v1", "testsa", "Ref", "testsvc", false), nil) - out, err := executeAPIServerSourceCommand(apiServerClient, servingClient, "create", "testsource", "--resource", "Event:v1:false", "--service-account", "testsa", "--sink", "svc:testsvc", "--mode", "Ref") + out, err := executeAPIServerSourceCommand(apiServerClient, dynamicClient, "create", "testsource", "--resource", "Event:v1:false", "--service-account", "testsa", "--sink", "svc:testsvc", "--mode", "Ref") assert.NilError(t, err, "ApiServer source should be created") util.ContainsAll(out, "created", "default", "testsource") apiServerRecorder.Validate() - servingRecorder.Validate() } func TestSinkNotFoundError(t *testing.T) { - servingClient := knserving_client.NewMockKnServiceClient(t) + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t) - - errorMsg := "cannot create ApiServerSource 'testsource' in namespace 'default' because: no Service svc found" - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("testsvc", nil, errors.New("no Service svc found")) - - out, err := executeAPIServerSourceCommand(apiServerClient, servingClient, "create", "testsource", "--resource", "Event:v1:false", "--service-account", "testsa", "--sink", "svc:testsvc", "--mode", "Ref") + errorMsg := "cannot create ApiServerSource 'testsource' in namespace 'default' because services.serving.knative.dev \"testsvc\" not found" + out, err := executeAPIServerSourceCommand(apiServerClient, dynamicClient, "create", "testsource", "--resource", "Event:v1:false", "--service-account", "testsa", "--sink", "svc:testsvc", "--mode", "Ref") assert.Error(t, err, errorMsg) assert.Assert(t, util.ContainsAll(out, errorMsg, "Usage")) - servingRecorder.Validate() } func TestNoSinkError(t *testing.T) { diff --git a/pkg/kn/commands/source/apiserver/update.go b/pkg/kn/commands/source/apiserver/update.go index e51ba091ad..d8231da6db 100644 --- a/pkg/kn/commands/source/apiserver/update.go +++ b/pkg/kn/commands/source/apiserver/update.go @@ -49,7 +49,7 @@ func NewAPIServerUpdateCommand(p *commands.KnParams) *cobra.Command { return err } - servingClient, err := p.NewServingClient(namespace) + dynamicClient, err := p.NewDynamicClient(namespace) if err != nil { return err } @@ -82,7 +82,7 @@ func NewAPIServerUpdateCommand(p *commands.KnParams) *cobra.Command { } if cmd.Flags().Changed("sink") { - objectRef, err := sinkFlags.ResolveSink(servingClient) + objectRef, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) if err != nil { return err } diff --git a/pkg/kn/commands/source/apiserver/update_test.go b/pkg/kn/commands/source/apiserver/update_test.go index a8df007ad3..87b0bbe352 100644 --- a/pkg/kn/commands/source/apiserver/update_test.go +++ b/pkg/kn/commands/source/apiserver/update_test.go @@ -22,33 +22,29 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" + kn_dynamic "knative.dev/client/pkg/dynamic" knsources_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1" - knserving_client "knative.dev/client/pkg/serving/v1alpha1" "knative.dev/client/pkg/util" ) func TestApiServerSourceUpdate(t *testing.T) { apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t) - servingClient := knserving_client.NewMockKnServiceClient(t) + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, + ObjectMeta: metav1.ObjectMeta{Name: "svc2", Namespace: "default"}, + }) apiServerRecorder := apiServerClient.Recorder() - servingRecorder := servingClient.Recorder() present := createAPIServerSource("testsource", "Event", "v1", "testsa1", "Ref", "svc1", false) apiServerRecorder.GetAPIServerSource("testsource", present, nil) - servingRecorder.GetService("svc2", &serving_v1alpha1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service"}, - ObjectMeta: metav1.ObjectMeta{Name: "svc2"}, - }, nil) - updated := createAPIServerSource("testsource", "Event", "v1", "testsa2", "Ref", "svc2", false) apiServerRecorder.UpdateAPIServerSource(updated, nil) - output, err := executeAPIServerSourceCommand(apiServerClient, servingClient, "update", "testsource", "--service-account", "testsa2", "--sink", "svc:svc2") + output, err := executeAPIServerSourceCommand(apiServerClient, dynamicClient, "update", "testsource", "--service-account", "testsa2", "--sink", "svc:svc2") assert.NilError(t, err) assert.Assert(t, util.ContainsAll(output, "testsource", "updated", "default")) apiServerRecorder.Validate() - servingRecorder.Validate() } diff --git a/pkg/kn/commands/source/cronjob/create.go b/pkg/kn/commands/source/cronjob/create.go index 84c7e1beef..fb423ebc08 100644 --- a/pkg/kn/commands/source/cronjob/create.go +++ b/pkg/kn/commands/source/cronjob/create.go @@ -49,12 +49,16 @@ func NewCronJobCreateCommand(p *commands.KnParams) *cobra.Command { return err } - servingClient, err := p.NewServingClient(cronSourceClient.Namespace()) + namespace, err := p.GetNamespace(cmd) + if err != nil { + return err + } + dynamicClient, err := p.NewDynamicClient(namespace) if err != nil { return err } - destination, err := sinkFlags.ResolveSink(servingClient) + destination, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) if err != nil { return err } diff --git a/pkg/kn/commands/source/cronjob/create_test.go b/pkg/kn/commands/source/cronjob/create_test.go index badb05c843..513541f47c 100644 --- a/pkg/kn/commands/source/cronjob/create_test.go +++ b/pkg/kn/commands/source/cronjob/create_test.go @@ -15,52 +15,44 @@ package cronjob import ( - "errors" "testing" "gotest.tools/assert" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kn_dynamic "knative.dev/client/pkg/dynamic" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" v1alpha12 "knative.dev/client/pkg/eventing/sources/v1alpha1" - knservingclient "knative.dev/client/pkg/serving/v1alpha1" "knative.dev/client/pkg/util" ) func TestSimpleCreateCronJobSource(t *testing.T) { + mysvc := &serving_v1alpha1.Service{ + TypeMeta: v1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, + ObjectMeta: v1.ObjectMeta{Name: "mysvc", Namespace: "default"}, + } + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", mysvc) - servingClient := knservingclient.NewMockKnServiceClient(t) cronjobClient := v1alpha12.NewMockKnCronJobSourceClient(t) - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("mysvc", &serving_v1alpha1.Service{ - TypeMeta: v1.TypeMeta{Kind: "Service"}, - ObjectMeta: v1.ObjectMeta{Name: "mysvc"}, - }, nil) - cronJobRecorder := cronjobClient.Recorder() cronJobRecorder.CreateCronJobSource(createCronJobSource("testsource", "* * * * */2", "maxwell", "mysvc"), nil) - out, err := executeCronJobSourceCommand(cronjobClient, servingClient, "create", "--sink", "svc:mysvc", "--schedule", "* * * * */2", "--data", "maxwell", "testsource") + out, err := executeCronJobSourceCommand(cronjobClient, dynamicClient, "create", "--sink", "svc:mysvc", "--schedule", "* * * * */2", "--data", "maxwell", "testsource") assert.NilError(t, err, "Source should have been created") util.ContainsAll(out, "created", "default", "testsource") cronJobRecorder.Validate() - servingRecorder.Validate() } func TestNoSinkError(t *testing.T) { - servingClient := knservingclient.NewMockKnServiceClient(t) cronjobClient := v1alpha12.NewMockKnCronJobSourceClient(t) - errorMsg := "no Service mysvc found" - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("mysvc", nil, errors.New(errorMsg)) + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") - out, err := executeCronJobSourceCommand(cronjobClient, servingClient, "create", "--sink", "svc:mysvc", "--schedule", "* * * * */2", "--data", "maxwell", "testsource") - assert.Error(t, err, errorMsg) - assert.Assert(t, util.ContainsAll(out, errorMsg, "Usage")) - servingRecorder.Validate() + out, err := executeCronJobSourceCommand(cronjobClient, dynamicClient, "create", "--sink", "svc:mysvc", "--schedule", "* * * * */2", "--data", "maxwell", "testsource") + assert.Error(t, err, "services.serving.knative.dev \"mysvc\" not found") + assert.Assert(t, util.ContainsAll(out, "Usage")) } func TestNoSinkGivenError(t *testing.T) { diff --git a/pkg/kn/commands/source/cronjob/cronjob_test.go b/pkg/kn/commands/source/cronjob/cronjob_test.go index e5afa17dd6..8a61cf1095 100644 --- a/pkg/kn/commands/source/cronjob/cronjob_test.go +++ b/pkg/kn/commands/source/cronjob/cronjob_test.go @@ -22,9 +22,9 @@ import ( "knative.dev/eventing/pkg/apis/sources/v1alpha1" "knative.dev/pkg/apis/duck/v1beta1" + kn_dynamic "knative.dev/client/pkg/dynamic" source_client_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1" "knative.dev/client/pkg/kn/commands" - serving_client_v1alpha1 "knative.dev/client/pkg/serving/v1alpha1" ) // Helper methods @@ -54,14 +54,14 @@ current-context: x } } -func executeCronJobSourceCommand(cronJobSourceClient source_client_v1alpha1.KnCronJobSourcesClient, servingClient serving_client_v1alpha1.KnServingClient, args ...string) (string, error) { +func executeCronJobSourceCommand(cronJobSourceClient source_client_v1alpha1.KnCronJobSourcesClient, dynamicClient kn_dynamic.KnDynamicClient, args ...string) (string, error) { knParams := &commands.KnParams{} knParams.ClientConfig = blankConfig output := new(bytes.Buffer) knParams.Output = output - knParams.NewServingClient = func(namespace string) (serving_client_v1alpha1.KnServingClient, error) { - return servingClient, nil + knParams.NewDynamicClient = func(namespace string) (kn_dynamic.KnDynamicClient, error) { + return dynamicClient, nil } cmd := NewCronJobCommand(knParams) @@ -84,7 +84,7 @@ func cleanupCronJobMockClient() { func createCronJobSource(name, schedule, data, service string) *v1alpha1.CronJobSource { sink := &v1beta1.Destination{ - Ref: &corev1.ObjectReference{Name: service, Kind: "Service"}, + Ref: &corev1.ObjectReference{Name: service, Kind: "Service", Namespace: "default", APIVersion: "serving.knative.dev/v1alpha1"}, } return source_client_v1alpha1.NewCronJobSourceBuilder(name).Schedule(schedule).Data(data).Sink(sink).Build() } diff --git a/pkg/kn/commands/source/cronjob/update.go b/pkg/kn/commands/source/cronjob/update.go index 3741a3b5b2..388378b426 100644 --- a/pkg/kn/commands/source/cronjob/update.go +++ b/pkg/kn/commands/source/cronjob/update.go @@ -48,7 +48,11 @@ func NewCronJobUpdateCommand(p *commands.KnParams) *cobra.Command { return err } - servingClient, err := p.NewServingClient(cronSourceClient.Namespace()) + namespace, err := p.GetNamespace(cmd) + if err != nil { + return err + } + dynamicClient, err := p.NewDynamicClient(namespace) if err != nil { return err } @@ -66,7 +70,7 @@ func NewCronJobUpdateCommand(p *commands.KnParams) *cobra.Command { b.Data(cronUpdateFlags.data) } if cmd.Flags().Changed("sink") { - destination, err := sinkFlags.ResolveSink(servingClient) + destination, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) if err != nil { return err } diff --git a/pkg/kn/commands/source/cronjob/update_test.go b/pkg/kn/commands/source/cronjob/update_test.go index b01821cd67..aeee77cac1 100644 --- a/pkg/kn/commands/source/cronjob/update_test.go +++ b/pkg/kn/commands/source/cronjob/update_test.go @@ -43,8 +43,10 @@ func TestSimpleUpdate(t *testing.T) { Data: "maxwell", Sink: &v1beta1.Destination{ Ref: &corev1.ObjectReference{ - Kind: "Service", - Name: "mysvc", + Kind: "Service", + Name: "mysvc", + Namespace: "default", + APIVersion: "serving.knative.dev/v1alpha1", }, }, }, diff --git a/pkg/kn/commands/trigger/create.go b/pkg/kn/commands/trigger/create.go index 93f7d1a055..ac24adf474 100644 --- a/pkg/kn/commands/trigger/create.go +++ b/pkg/kn/commands/trigger/create.go @@ -50,17 +50,17 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command { return err } - eventingClient, err := p.NewEventingClient(namespace) + dynamicClient, err := p.NewDynamicClient(namespace) if err != nil { return err } - servingClient, err := p.NewServingClient(namespace) + eventingClient, err := p.NewEventingClient(namespace) if err != nil { return err } - objectRef, err := sinkFlags.ResolveSink(servingClient) + objectRef, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) if err != nil { return fmt.Errorf( "cannot create trigger '%s' in namespace '%s' "+ diff --git a/pkg/kn/commands/trigger/create_test.go b/pkg/kn/commands/trigger/create_test.go index b8d9a4ff2a..2541cca7d1 100644 --- a/pkg/kn/commands/trigger/create_test.go +++ b/pkg/kn/commands/trigger/create_test.go @@ -15,14 +15,13 @@ package trigger import ( - "errors" "fmt" "testing" "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kn_dynamic "knative.dev/client/pkg/dynamic" eventing_client "knative.dev/client/pkg/eventing/v1alpha1" - knserving_client "knative.dev/client/pkg/serving/v1alpha1" "knative.dev/client/pkg/util" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) @@ -33,39 +32,32 @@ var ( func TestTriggerCreate(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - servingClient := knserving_client.NewMockKnServiceClient(t) - - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("mysvc", &serving_v1alpha1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service"}, - ObjectMeta: metav1.ObjectMeta{Name: "mysvc"}, - }, nil) + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, + ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, + }) eventingRecorder := eventingClient.Recorder() eventingRecorder.CreateTrigger(createTrigger("default", triggerName, map[string]string{"type": "dev.knative.foo"}, "mybroker", "mysvc"), nil) - out, err := executeTriggerCommand(eventingClient, servingClient, "create", triggerName, "--broker", "mybroker", + out, err := executeTriggerCommand(eventingClient, dynamicClient, "create", triggerName, "--broker", "mybroker", "--filter", "type=dev.knative.foo", "--sink", "svc:mysvc") assert.NilError(t, err, "Trigger should be created") util.ContainsAll(out, "Trigger", triggerName, "created", "namespace", "default") eventingRecorder.Validate() - servingRecorder.Validate() } func TestSinkNotFoundError(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - servingClient := knserving_client.NewMockKnServiceClient(t) + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") - errorMsg := fmt.Sprintf("cannot create trigger '%s' in namespace 'default' because: no Service mysvc found", triggerName) - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("mysvc", nil, errors.New("no Service mysvc found")) + errorMsg := fmt.Sprintf("cannot create trigger '%s' in namespace 'default' because services.serving.knative.dev \"mysvc\" not found", triggerName) - out, err := executeTriggerCommand(eventingClient, servingClient, "create", triggerName, "--broker", "mybroker", + out, err := executeTriggerCommand(eventingClient, dynamicClient, "create", triggerName, "--broker", "mybroker", "--filter", "type=dev.knative.foo", "--sink", "svc:mysvc") assert.Error(t, err, errorMsg) assert.Assert(t, util.ContainsAll(out, errorMsg, "Usage")) - servingRecorder.Validate() } func TestNoSinkError(t *testing.T) { @@ -84,22 +76,18 @@ func TestNoFilterError(t *testing.T) { func TestTriggerCreateMultipleFilter(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - servingClient := knserving_client.NewMockKnServiceClient(t) - - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("mysvc", &serving_v1alpha1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service"}, - ObjectMeta: metav1.ObjectMeta{Name: "mysvc"}, - }, nil) + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, + ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, + }) eventingRecorder := eventingClient.Recorder() eventingRecorder.CreateTrigger(createTrigger("default", triggerName, map[string]string{"type": "dev.knative.foo", "source": "event.host"}, "mybroker", "mysvc"), nil) - out, err := executeTriggerCommand(eventingClient, servingClient, "create", triggerName, "--broker", "mybroker", + out, err := executeTriggerCommand(eventingClient, dynamicClient, "create", triggerName, "--broker", "mybroker", "--filter", "type=dev.knative.foo", "--filter", "source=event.host", "--sink", "svc:mysvc") assert.NilError(t, err, "Trigger should be created") util.ContainsAll(out, "Trigger", triggerName, "created", "namespace", "default") eventingRecorder.Validate() - servingRecorder.Validate() } diff --git a/pkg/kn/commands/trigger/list_test.go b/pkg/kn/commands/trigger/list_test.go index 1b355d6b3b..f89c4e7bbc 100644 --- a/pkg/kn/commands/trigger/list_test.go +++ b/pkg/kn/commands/trigger/list_test.go @@ -44,7 +44,7 @@ func TestTriggerList(t *testing.T) { triggerList := &v1alpha1.TriggerList{Items: []v1alpha1.Trigger{*trigger1, *trigger2, *trigger3}} eventingRecorder.ListTriggers(triggerList, nil) - output, err := executeTriggerCommand(eventingClient, servingClient, "list") + output, err := executeTriggerCommand(eventingClient, nil, "list") assert.NilError(t, err) outputLines := strings.Split(output, "\n") @@ -85,7 +85,7 @@ func TestTriggerListAllNamespace(t *testing.T) { triggerList := &v1alpha1.TriggerList{Items: []v1alpha1.Trigger{*trigger1, *trigger2, *trigger3}} eventingRecorder.ListTriggers(triggerList, nil) - output, err := executeTriggerCommand(eventingClient, servingClient, "list", "--all-namespaces") + output, err := executeTriggerCommand(eventingClient, nil, "list", "--all-namespaces") assert.NilError(t, err) outputLines := strings.Split(output, "\n") diff --git a/pkg/kn/commands/trigger/trigger_test.go b/pkg/kn/commands/trigger/trigger_test.go index 6cff17b761..907e419fba 100644 --- a/pkg/kn/commands/trigger/trigger_test.go +++ b/pkg/kn/commands/trigger/trigger_test.go @@ -20,13 +20,15 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/clientcmd" + kn_dynamic "knative.dev/client/pkg/dynamic" + "knative.dev/client/pkg/kn/commands" + "knative.dev/eventing/pkg/apis/eventing/v1alpha1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" eventc_v1alpha1 "knative.dev/client/pkg/eventing/v1alpha1" "knative.dev/client/pkg/kn/commands" - serving_client_v1alpha1 "knative.dev/client/pkg/serving/v1alpha1" ) // Helper methods @@ -54,15 +56,16 @@ current-context: x } } -func executeTriggerCommand(triggerClient eventc_v1alpha1.KnEventingClient, servingClient serving_client_v1alpha1.KnServingClient, args ...string) (string, error) { +func executeTriggerCommand(triggerClient eventc_v1alpha1.KnEventingClient, dynamicClient kn_dynamic.KnDynamicClient, args ...string) (string, error) { knParams := &commands.KnParams{} knParams.ClientConfig = blankConfig output := new(bytes.Buffer) knParams.Output = output - knParams.NewServingClient = func(namespace string) (serving_client_v1alpha1.KnServingClient, error) { - return servingClient, nil + knParams.NewDynamicClient = func(namespace string) (kn_dynamic.KnDynamicClient, error) { + return dynamicClient, nil } + knParams.NewEventingClient = func(namespace string) (eventc_v1alpha1.KnEventingClient, error) { return triggerClient, nil } diff --git a/pkg/kn/commands/trigger/update.go b/pkg/kn/commands/trigger/update.go index 5545197d80..9efdb6082c 100644 --- a/pkg/kn/commands/trigger/update.go +++ b/pkg/kn/commands/trigger/update.go @@ -60,8 +60,7 @@ func NewTriggerUpdateCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - - servingClient, err := p.NewServingClient(namespace) + dynamicClient, err := p.NewDynamicClient(namespace) if err != nil { return err } @@ -91,7 +90,7 @@ func NewTriggerUpdateCommand(p *commands.KnParams) *cobra.Command { } } if cmd.Flags().Changed("sink") { - destination, err := sinkFlags.ResolveSink(servingClient) + destination, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) if err != nil { return err } diff --git a/pkg/kn/commands/trigger/update_test.go b/pkg/kn/commands/trigger/update_test.go index 0fba1db8a0..6ff9043ae4 100644 --- a/pkg/kn/commands/trigger/update_test.go +++ b/pkg/kn/commands/trigger/update_test.go @@ -20,21 +20,18 @@ import ( "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kn_dynamic "knative.dev/client/pkg/dynamic" eventing_client "knative.dev/client/pkg/eventing/v1alpha1" - knserving_client "knative.dev/client/pkg/serving/v1alpha1" "knative.dev/client/pkg/util" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) func TestTriggerUpdate(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - servingClient := knserving_client.NewMockKnServiceClient(t) - - servingRecorder := servingClient.Recorder() - servingRecorder.GetService("mysvc", &serving_v1alpha1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service"}, - ObjectMeta: metav1.ObjectMeta{Name: "mysvc"}, - }, nil) + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, + ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, + }) eventingRecorder := eventingClient.Recorder() present := createTrigger("default", triggerName, map[string]string{"type": "dev.knative.foo"}, "mybroker", "mysvc") @@ -42,13 +39,12 @@ func TestTriggerUpdate(t *testing.T) { eventingRecorder.GetTrigger(triggerName, present, nil) eventingRecorder.UpdateTrigger(updated, nil) - out, err := executeTriggerCommand(eventingClient, servingClient, "update", triggerName, + out, err := executeTriggerCommand(eventingClient, dynamicClient, "update", triggerName, "--filter", "type=dev.knative.new", "--sink", "svc:mysvc") assert.NilError(t, err, "Trigger should be updated") util.ContainsAll(out, "Trigger", triggerName, "updated", "namespace", "default") eventingRecorder.Validate() - servingRecorder.Validate() } func TestTriggerUpdateWithError(t *testing.T) { From b07ad45eddf203021550d5d3479f70df04ac08e2 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 18 Dec 2019 23:16:47 +0000 Subject: [PATCH 02/10] loltest --- pkg/dynamic/client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/dynamic/client.go b/pkg/dynamic/client.go index c18b213610..4b5bb43d91 100644 --- a/pkg/dynamic/client.go +++ b/pkg/dynamic/client.go @@ -23,6 +23,7 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic/fake" + eventing_v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) @@ -102,6 +103,7 @@ func (c knDynamicClient) RawClient() dynamic.Interface { func CreateFakeKnDynamicClient(testNamespace string, objects ...runtime.Object) KnDynamicClient { scheme := runtime.NewScheme() scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1alpha1", Kind: "Service"}, &serving_v1alpha1.Service{}) + scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "eventing.knative.dev", Version: "v1alpha1", Kind: "Broker"}, &eventing_v1alpha1.Broker{}) client := fake.NewSimpleDynamicClient(scheme, objects...) return NewKnDynamicClient(client, testNamespace) } From 0f57676fa348e142244aabe27876d5c6975195bf Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 18 Dec 2019 23:29:52 +0000 Subject: [PATCH 03/10] Fix tests for mergeout --- pkg/kn/commands/source/apiserver/create_test.go | 2 +- pkg/kn/commands/trigger/create_test.go | 2 +- pkg/kn/commands/trigger/trigger_test.go | 12 +++++------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/pkg/kn/commands/source/apiserver/create_test.go b/pkg/kn/commands/source/apiserver/create_test.go index a848f13c93..275e4e3497 100644 --- a/pkg/kn/commands/source/apiserver/create_test.go +++ b/pkg/kn/commands/source/apiserver/create_test.go @@ -46,7 +46,7 @@ func TestCreateApiServerSource(t *testing.T) { func TestSinkNotFoundError(t *testing.T) { dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t) - errorMsg := "cannot create ApiServerSource 'testsource' in namespace 'default' because services.serving.knative.dev \"testsvc\" not found" + errorMsg := "cannot create ApiServerSource 'testsource' in namespace 'default' because: services.serving.knative.dev \"testsvc\" not found" out, err := executeAPIServerSourceCommand(apiServerClient, dynamicClient, "create", "testsource", "--resource", "Event:v1:false", "--service-account", "testsa", "--sink", "svc:testsvc", "--mode", "Ref") assert.Error(t, err, errorMsg) assert.Assert(t, util.ContainsAll(out, errorMsg, "Usage")) diff --git a/pkg/kn/commands/trigger/create_test.go b/pkg/kn/commands/trigger/create_test.go index 2541cca7d1..9561cba752 100644 --- a/pkg/kn/commands/trigger/create_test.go +++ b/pkg/kn/commands/trigger/create_test.go @@ -52,7 +52,7 @@ func TestSinkNotFoundError(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") - errorMsg := fmt.Sprintf("cannot create trigger '%s' in namespace 'default' because services.serving.knative.dev \"mysvc\" not found", triggerName) + errorMsg := fmt.Sprintf("cannot create trigger '%s' in namespace 'default' because: services.serving.knative.dev \"mysvc\" not found", triggerName) out, err := executeTriggerCommand(eventingClient, dynamicClient, "create", triggerName, "--broker", "mybroker", "--filter", "type=dev.knative.foo", "--sink", "svc:mysvc") diff --git a/pkg/kn/commands/trigger/trigger_test.go b/pkg/kn/commands/trigger/trigger_test.go index 907e419fba..9c09d00db4 100644 --- a/pkg/kn/commands/trigger/trigger_test.go +++ b/pkg/kn/commands/trigger/trigger_test.go @@ -19,16 +19,12 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/clientcmd" - kn_dynamic "knative.dev/client/pkg/dynamic" + eventc_v1alpha1 "knative.dev/client/pkg/eventing/v1alpha1" "knative.dev/client/pkg/kn/commands" - "knative.dev/eventing/pkg/apis/eventing/v1alpha1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" - - eventc_v1alpha1 "knative.dev/client/pkg/eventing/v1alpha1" - "knative.dev/client/pkg/kn/commands" ) // Helper methods @@ -90,8 +86,10 @@ func createTrigger(namespace string, name string, filters map[string]string, bro triggerBuilder.Subscriber(&duckv1.Destination{ Ref: &corev1.ObjectReference{ - Name: svcname, - Kind: "Service", + Name: svcname, + Kind: "Service", + Namespace: "default", + APIVersion: "serving.knative.dev/v1alpha1", }, }) return triggerBuilder.Build() From 6299bc4a6310500e494e218ca85624e36494bb04 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 18 Dec 2019 23:34:49 +0000 Subject: [PATCH 04/10] the test file I forgot --- pkg/kn/commands/flags/sink_test.go | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 pkg/kn/commands/flags/sink_test.go diff --git a/pkg/kn/commands/flags/sink_test.go b/pkg/kn/commands/flags/sink_test.go new file mode 100644 index 0000000000..d58f2f8a5e --- /dev/null +++ b/pkg/kn/commands/flags/sink_test.go @@ -0,0 +1,76 @@ +// 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 ( + "testing" + + "gotest.tools/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kn_dynamic "knative.dev/client/pkg/dynamic" + eventing_v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + "knative.dev/pkg/apis" + duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" + serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" +) + +type resolveCase struct { + sink string + destination *duckv1beta1.Destination + errContents string +} + +func TestResolve(t *testing.T) { + targetExampleCom, err := apis.ParseURL("http://target.example.com") + mysvc := &serving_v1alpha1.Service{ + TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, + ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, + } + defaultBroker := &eventing_v1alpha1.Broker{ + TypeMeta: metav1.TypeMeta{Kind: "Broker", APIVersion: "eventing.knative.dev/v1alpha1"}, + ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}, + } + + assert.NilError(t, err) + cases := []resolveCase{ + {"svc:mysvc", &duckv1beta1.Destination{ + Ref: &v1.ObjectReference{Kind: "Service", + APIVersion: "serving.knative.dev/v1alpha1", + Name: "mysvc", + Namespace: "default"}}, ""}, + {"svc:absent", nil, "\"absent\" not found"}, + {"broker:default", &duckv1beta1.Destination{ + Ref: &v1.ObjectReference{Kind: "Broker", + APIVersion: "eventing.knative.dev/v1alpha1", + Name: "default", + Namespace: "default", + }}, ""}, + {"http://target.example.com", &duckv1beta1.Destination{ + URI: targetExampleCom, + }, ""}, + } + dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", mysvc, defaultBroker) + for _, c := range cases { + i := &SinkFlags{c.sink} + result, err := i.ResolveSink(dynamicClient.RawClient(), "default") + if c.destination != nil { + assert.DeepEqual(t, result, c.destination) + assert.NilError(t, err) + } else { + assert.ErrorContains(t, err, c.errContents) + } + } +} From 570971094382a78665a26ca8efc4242733c1013f Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 18 Dec 2019 23:52:06 +0000 Subject: [PATCH 05/10] docstrings --- pkg/dynamic/client.go | 1 + pkg/kn/commands/flags/sink.go | 1 + 2 files changed, 2 insertions(+) diff --git a/pkg/dynamic/client.go b/pkg/dynamic/client.go index 4b5bb43d91..dba658fe27 100644 --- a/pkg/dynamic/client.go +++ b/pkg/dynamic/client.go @@ -100,6 +100,7 @@ func (c knDynamicClient) RawClient() dynamic.Interface { return c.client } +// CreateFakeKnDynamicClient gives you a dynamic client for testing contianing the given objects. func CreateFakeKnDynamicClient(testNamespace string, objects ...runtime.Object) KnDynamicClient { scheme := runtime.NewScheme() scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1alpha1", Kind: "Service"}, &serving_v1alpha1.Service{}) diff --git a/pkg/kn/commands/flags/sink.go b/pkg/kn/commands/flags/sink.go index 74a262dc84..3f5948cd32 100644 --- a/pkg/kn/commands/flags/sink.go +++ b/pkg/kn/commands/flags/sink.go @@ -35,6 +35,7 @@ func (i *SinkFlags) Add(cmd *cobra.Command) { cmd.Flags().StringVarP(&i.sink, "sink", "s", "", "Addressable sink for events") } +// SinkPrefixes maps prefixes used for sinks to their GroupVersionResources. var SinkPrefixes = map[string]schema.GroupVersionResource{ "broker": { Resource: "brokers", From 201ef84b8d981f77111d65e3846313684c6ae253 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 22 Dec 2019 21:35:41 +0000 Subject: [PATCH 06/10] Move fake dynamic client into seprate file --- pkg/dynamic/client.go | 14 -------- pkg/dynamic/client_test.go | 21 ++++++++++-- pkg/dynamic/fake/fake.go | 34 +++++++++++++++++++ pkg/kn/commands/flags/sink_test.go | 4 +-- .../commands/source/apiserver/create_test.go | 6 ++-- .../commands/source/apiserver/update_test.go | 4 +-- pkg/kn/commands/source/cronjob/create_test.go | 6 ++-- pkg/kn/commands/trigger/create_test.go | 8 ++--- pkg/kn/commands/trigger/update_test.go | 4 +-- 9 files changed, 68 insertions(+), 33 deletions(-) create mode 100644 pkg/dynamic/fake/fake.go diff --git a/pkg/dynamic/client.go b/pkg/dynamic/client.go index dba658fe27..35d5ca52bc 100644 --- a/pkg/dynamic/client.go +++ b/pkg/dynamic/client.go @@ -18,13 +18,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "k8s.io/client-go/dynamic/fake" - - eventing_v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" - serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) const ( @@ -99,12 +94,3 @@ func (c *knDynamicClient) ListSourcesTypes() (*unstructured.UnstructuredList, er func (c knDynamicClient) RawClient() dynamic.Interface { return c.client } - -// CreateFakeKnDynamicClient gives you a dynamic client for testing contianing the given objects. -func CreateFakeKnDynamicClient(testNamespace string, objects ...runtime.Object) KnDynamicClient { - scheme := runtime.NewScheme() - scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1alpha1", Kind: "Service"}, &serving_v1alpha1.Service{}) - scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "eventing.knative.dev", Version: "v1alpha1", Kind: "Broker"}, &eventing_v1alpha1.Broker{}) - client := fake.NewSimpleDynamicClient(scheme, objects...) - return NewKnDynamicClient(client, testNamespace) -} diff --git a/pkg/dynamic/client_test.go b/pkg/dynamic/client_test.go index cc0952a0f6..96c4214b5b 100644 --- a/pkg/dynamic/client_test.go +++ b/pkg/dynamic/client_test.go @@ -21,6 +21,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + k8s_fake "k8s.io/client-go/dynamic/fake" + eventing_v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) const testNamespace = "testns" @@ -42,12 +47,12 @@ func newUnstructured(name string) *unstructured.Unstructured { } func TestNamespace(t *testing.T) { - client := CreateFakeKnDynamicClient(testNamespace, newUnstructured("foo")) + client := createFakeKnDynamicClient(testNamespace, newUnstructured("foo")) assert.Equal(t, client.Namespace(), testNamespace) } func TestListCRDs(t *testing.T) { - client := CreateFakeKnDynamicClient( + client := createFakeKnDynamicClient( testNamespace, newUnstructured("foo"), newUnstructured("bar"), @@ -77,7 +82,7 @@ func TestListCRDs(t *testing.T) { } func TestListSourceTypes(t *testing.T) { - client := CreateFakeKnDynamicClient( + client := createFakeKnDynamicClient( testNamespace, newUnstructured("foo"), newUnstructured("bar"), @@ -94,3 +99,13 @@ func TestListSourceTypes(t *testing.T) { assert.Equal(t, uList.Items[1].GetName(), "bar") }) } + +// createFakeKnDynamicClient gives you a dynamic client for testing contianing the given objects. +// See also the one in the fake package. Duplicated here to avoid a dependency loop. +func createFakeKnDynamicClient(testNamespace string, objects ...runtime.Object) KnDynamicClient { + scheme := runtime.NewScheme() + scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1alpha1", Kind: "Service"}, &serving_v1alpha1.Service{}) + scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "eventing.knative.dev", Version: "v1alpha1", Kind: "Broker"}, &eventing_v1alpha1.Broker{}) + client := k8s_fake.NewSimpleDynamicClient(scheme, objects...) + return NewKnDynamicClient(client, testNamespace) +} diff --git a/pkg/dynamic/fake/fake.go b/pkg/dynamic/fake/fake.go new file mode 100644 index 0000000000..c8f21e5dbc --- /dev/null +++ b/pkg/dynamic/fake/fake.go @@ -0,0 +1,34 @@ +// 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 fake + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + k8s_fake "k8s.io/client-go/dynamic/fake" + + "knative.dev/client/pkg/dynamic" + eventing_v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" +) + +// CreateFakeKnDynamicClient gives you a dynamic client for testing contianing the given objects. +func CreateFakeKnDynamicClient(testNamespace string, objects ...runtime.Object) dynamic.KnDynamicClient { + scheme := runtime.NewScheme() + scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1alpha1", Kind: "Service"}, &serving_v1alpha1.Service{}) + scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "eventing.knative.dev", Version: "v1alpha1", Kind: "Broker"}, &eventing_v1alpha1.Broker{}) + client := k8s_fake.NewSimpleDynamicClient(scheme, objects...) + return dynamic.NewKnDynamicClient(client, testNamespace) +} diff --git a/pkg/kn/commands/flags/sink_test.go b/pkg/kn/commands/flags/sink_test.go index d58f2f8a5e..7c5661f0d7 100644 --- a/pkg/kn/commands/flags/sink_test.go +++ b/pkg/kn/commands/flags/sink_test.go @@ -20,7 +20,7 @@ import ( "gotest.tools/assert" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - kn_dynamic "knative.dev/client/pkg/dynamic" + dynamic_fake "knative.dev/client/pkg/dynamic/fake" eventing_v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" "knative.dev/pkg/apis" duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" @@ -62,7 +62,7 @@ func TestResolve(t *testing.T) { URI: targetExampleCom, }, ""}, } - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", mysvc, defaultBroker) + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", mysvc, defaultBroker) for _, c := range cases { i := &SinkFlags{c.sink} result, err := i.ResolveSink(dynamicClient.RawClient(), "default") diff --git a/pkg/kn/commands/source/apiserver/create_test.go b/pkg/kn/commands/source/apiserver/create_test.go index 275e4e3497..880ae7c4fe 100644 --- a/pkg/kn/commands/source/apiserver/create_test.go +++ b/pkg/kn/commands/source/apiserver/create_test.go @@ -19,7 +19,7 @@ import ( "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - kn_dynamic "knative.dev/client/pkg/dynamic" + dynamic_fake "knative.dev/client/pkg/dynamic/fake" knsources_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1" "knative.dev/client/pkg/util" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" @@ -30,7 +30,7 @@ func TestCreateApiServerSource(t *testing.T) { TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, ObjectMeta: metav1.ObjectMeta{Name: "testsvc", Namespace: "default"}, } - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", testsvc) + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", testsvc) apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t) apiServerRecorder := apiServerClient.Recorder() @@ -44,7 +44,7 @@ func TestCreateApiServerSource(t *testing.T) { } func TestSinkNotFoundError(t *testing.T) { - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default") apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t) errorMsg := "cannot create ApiServerSource 'testsource' in namespace 'default' because: services.serving.knative.dev \"testsvc\" not found" out, err := executeAPIServerSourceCommand(apiServerClient, dynamicClient, "create", "testsource", "--resource", "Event:v1:false", "--service-account", "testsa", "--sink", "svc:testsvc", "--mode", "Ref") diff --git a/pkg/kn/commands/source/apiserver/update_test.go b/pkg/kn/commands/source/apiserver/update_test.go index 87b0bbe352..7c03dda00d 100644 --- a/pkg/kn/commands/source/apiserver/update_test.go +++ b/pkg/kn/commands/source/apiserver/update_test.go @@ -22,14 +22,14 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" - kn_dynamic "knative.dev/client/pkg/dynamic" + dynamic_fake "knative.dev/client/pkg/dynamic/fake" knsources_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1" "knative.dev/client/pkg/util" ) func TestApiServerSourceUpdate(t *testing.T) { apiServerClient := knsources_v1alpha1.NewMockKnAPIServerSourceClient(t) - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, ObjectMeta: metav1.ObjectMeta{Name: "svc2", Namespace: "default"}, }) diff --git a/pkg/kn/commands/source/cronjob/create_test.go b/pkg/kn/commands/source/cronjob/create_test.go index 513541f47c..2696f98d07 100644 --- a/pkg/kn/commands/source/cronjob/create_test.go +++ b/pkg/kn/commands/source/cronjob/create_test.go @@ -19,7 +19,7 @@ import ( "gotest.tools/assert" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - kn_dynamic "knative.dev/client/pkg/dynamic" + dynamic_fake "knative.dev/client/pkg/dynamic/fake" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" v1alpha12 "knative.dev/client/pkg/eventing/sources/v1alpha1" @@ -31,7 +31,7 @@ func TestSimpleCreateCronJobSource(t *testing.T) { TypeMeta: v1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, ObjectMeta: v1.ObjectMeta{Name: "mysvc", Namespace: "default"}, } - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", mysvc) + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", mysvc) cronjobClient := v1alpha12.NewMockKnCronJobSourceClient(t) @@ -48,7 +48,7 @@ func TestSimpleCreateCronJobSource(t *testing.T) { func TestNoSinkError(t *testing.T) { cronjobClient := v1alpha12.NewMockKnCronJobSourceClient(t) - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default") out, err := executeCronJobSourceCommand(cronjobClient, dynamicClient, "create", "--sink", "svc:mysvc", "--schedule", "* * * * */2", "--data", "maxwell", "testsource") assert.Error(t, err, "services.serving.knative.dev \"mysvc\" not found") diff --git a/pkg/kn/commands/trigger/create_test.go b/pkg/kn/commands/trigger/create_test.go index 9561cba752..e6d1ebace9 100644 --- a/pkg/kn/commands/trigger/create_test.go +++ b/pkg/kn/commands/trigger/create_test.go @@ -20,7 +20,7 @@ import ( "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - kn_dynamic "knative.dev/client/pkg/dynamic" + dynamic_fake "knative.dev/client/pkg/dynamic/fake" eventing_client "knative.dev/client/pkg/eventing/v1alpha1" "knative.dev/client/pkg/util" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" @@ -32,7 +32,7 @@ var ( func TestTriggerCreate(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, }) @@ -50,7 +50,7 @@ func TestTriggerCreate(t *testing.T) { func TestSinkNotFoundError(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default") + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default") errorMsg := fmt.Sprintf("cannot create trigger '%s' in namespace 'default' because: services.serving.knative.dev \"mysvc\" not found", triggerName) @@ -76,7 +76,7 @@ func TestNoFilterError(t *testing.T) { func TestTriggerCreateMultipleFilter(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, }) diff --git a/pkg/kn/commands/trigger/update_test.go b/pkg/kn/commands/trigger/update_test.go index 6ff9043ae4..31b699dfc0 100644 --- a/pkg/kn/commands/trigger/update_test.go +++ b/pkg/kn/commands/trigger/update_test.go @@ -20,7 +20,7 @@ import ( "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - kn_dynamic "knative.dev/client/pkg/dynamic" + dynamic_fake "knative.dev/client/pkg/dynamic/fake" eventing_client "knative.dev/client/pkg/eventing/v1alpha1" "knative.dev/client/pkg/util" serving_v1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" @@ -28,7 +28,7 @@ import ( func TestTriggerUpdate(t *testing.T) { eventingClient := eventing_client.NewMockKnEventingClient(t) - dynamicClient := kn_dynamic.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ + dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", &serving_v1alpha1.Service{ TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1"}, ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, }) From 541e7e784d2dfd1e93566ce7e1a3a5da8c7af557 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 22 Dec 2019 21:41:32 +0000 Subject: [PATCH 07/10] Pass whole client, not raw client, to resolve sinks --- pkg/kn/commands/flags/sink.go | 5 +++-- pkg/kn/commands/flags/sink_test.go | 2 +- pkg/kn/commands/source/apiserver/create.go | 2 +- pkg/kn/commands/source/apiserver/update.go | 2 +- pkg/kn/commands/source/cronjob/create.go | 2 +- pkg/kn/commands/source/cronjob/update.go | 2 +- pkg/kn/commands/trigger/create.go | 2 +- pkg/kn/commands/trigger/update.go | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/pkg/kn/commands/flags/sink.go b/pkg/kn/commands/flags/sink.go index 3f5948cd32..5aed55f246 100644 --- a/pkg/kn/commands/flags/sink.go +++ b/pkg/kn/commands/flags/sink.go @@ -22,7 +22,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/dynamic" + kn_dynamic "knative.dev/client/pkg/dynamic" "knative.dev/pkg/apis" duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" ) @@ -57,7 +57,8 @@ var SinkPrefixes = map[string]schema.GroupVersionResource{ // ResolveSink returns the Destination referred to by the flags in the acceptor. // It validates that any object the user is referring to exists. -func (i *SinkFlags) ResolveSink(client dynamic.Interface, namespace string) (*duckv1beta1.Destination, error) { +func (i *SinkFlags) ResolveSink(knclient kn_dynamic.KnDynamicClient, namespace string) (*duckv1beta1.Destination, error) { + client := knclient.RawClient() if i.sink == "" { return nil, nil } diff --git a/pkg/kn/commands/flags/sink_test.go b/pkg/kn/commands/flags/sink_test.go index 7c5661f0d7..b0e5f3d15a 100644 --- a/pkg/kn/commands/flags/sink_test.go +++ b/pkg/kn/commands/flags/sink_test.go @@ -65,7 +65,7 @@ func TestResolve(t *testing.T) { dynamicClient := dynamic_fake.CreateFakeKnDynamicClient("default", mysvc, defaultBroker) for _, c := range cases { i := &SinkFlags{c.sink} - result, err := i.ResolveSink(dynamicClient.RawClient(), "default") + result, err := i.ResolveSink(dynamicClient, "default") if c.destination != nil { assert.DeepEqual(t, result, c.destination) assert.NilError(t, err) diff --git a/pkg/kn/commands/source/apiserver/create.go b/pkg/kn/commands/source/apiserver/create.go index 7ae1f9bee4..6425dd1eb3 100644 --- a/pkg/kn/commands/source/apiserver/create.go +++ b/pkg/kn/commands/source/apiserver/create.go @@ -55,7 +55,7 @@ func NewAPIServerCreateCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - objectRef, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) + objectRef, err := sinkFlags.ResolveSink(dynamicClient, namespace) if err != nil { return fmt.Errorf( "cannot create ApiServerSource '%s' in namespace '%s' "+ diff --git a/pkg/kn/commands/source/apiserver/update.go b/pkg/kn/commands/source/apiserver/update.go index d8231da6db..5491192c17 100644 --- a/pkg/kn/commands/source/apiserver/update.go +++ b/pkg/kn/commands/source/apiserver/update.go @@ -82,7 +82,7 @@ func NewAPIServerUpdateCommand(p *commands.KnParams) *cobra.Command { } if cmd.Flags().Changed("sink") { - objectRef, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) + objectRef, err := sinkFlags.ResolveSink(dynamicClient, namespace) if err != nil { return err } diff --git a/pkg/kn/commands/source/cronjob/create.go b/pkg/kn/commands/source/cronjob/create.go index fb423ebc08..cee867f9e4 100644 --- a/pkg/kn/commands/source/cronjob/create.go +++ b/pkg/kn/commands/source/cronjob/create.go @@ -58,7 +58,7 @@ func NewCronJobCreateCommand(p *commands.KnParams) *cobra.Command { return err } - destination, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) + destination, err := sinkFlags.ResolveSink(dynamicClient, namespace) if err != nil { return err } diff --git a/pkg/kn/commands/source/cronjob/update.go b/pkg/kn/commands/source/cronjob/update.go index 388378b426..8e59442945 100644 --- a/pkg/kn/commands/source/cronjob/update.go +++ b/pkg/kn/commands/source/cronjob/update.go @@ -70,7 +70,7 @@ func NewCronJobUpdateCommand(p *commands.KnParams) *cobra.Command { b.Data(cronUpdateFlags.data) } if cmd.Flags().Changed("sink") { - destination, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) + destination, err := sinkFlags.ResolveSink(dynamicClient, namespace) if err != nil { return err } diff --git a/pkg/kn/commands/trigger/create.go b/pkg/kn/commands/trigger/create.go index ac24adf474..5d82b12240 100644 --- a/pkg/kn/commands/trigger/create.go +++ b/pkg/kn/commands/trigger/create.go @@ -60,7 +60,7 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command { return err } - objectRef, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) + objectRef, err := sinkFlags.ResolveSink(dynamicClient, namespace) if err != nil { return fmt.Errorf( "cannot create trigger '%s' in namespace '%s' "+ diff --git a/pkg/kn/commands/trigger/update.go b/pkg/kn/commands/trigger/update.go index 9efdb6082c..be63a63d37 100644 --- a/pkg/kn/commands/trigger/update.go +++ b/pkg/kn/commands/trigger/update.go @@ -90,7 +90,7 @@ func NewTriggerUpdateCommand(p *commands.KnParams) *cobra.Command { } } if cmd.Flags().Changed("sink") { - destination, err := sinkFlags.ResolveSink(dynamicClient.RawClient(), namespace) + destination, err := sinkFlags.ResolveSink(dynamicClient, namespace) if err != nil { return err } From bda76fa3643b998e8ef765e78a1e5d17f42a6a85 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 22 Dec 2019 21:49:45 +0000 Subject: [PATCH 08/10] one more test --- pkg/kn/commands/flags/sink_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/kn/commands/flags/sink_test.go b/pkg/kn/commands/flags/sink_test.go index b0e5f3d15a..35ea0edee7 100644 --- a/pkg/kn/commands/flags/sink_test.go +++ b/pkg/kn/commands/flags/sink_test.go @@ -51,6 +51,11 @@ func TestResolve(t *testing.T) { APIVersion: "serving.knative.dev/v1alpha1", Name: "mysvc", Namespace: "default"}}, ""}, + {"service:mysvc", &duckv1beta1.Destination{ + Ref: &v1.ObjectReference{Kind: "Service", + APIVersion: "serving.knative.dev/v1alpha1", + Name: "mysvc", + Namespace: "default"}}, ""}, {"svc:absent", nil, "\"absent\" not found"}, {"broker:default", &duckv1beta1.Destination{ Ref: &v1.ObjectReference{Kind: "Broker", From 97dd77d9f78541f33d6cecc0fbc4756a8f4ea174 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 18 Dec 2019 04:42:30 +0000 Subject: [PATCH 09/10] First experimentation --- pkg/kn/commands/trigger/create.go | 20 ++++++++++++++++++-- pkg/kn/commands/trigger/update_flags.go | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pkg/kn/commands/trigger/create.go b/pkg/kn/commands/trigger/create.go index 5d82b12240..706f228f1d 100644 --- a/pkg/kn/commands/trigger/create.go +++ b/pkg/kn/commands/trigger/create.go @@ -23,6 +23,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands/flags" + "knative.dev/client/pkg/kn/commands/source" "knative.dev/eventing/pkg/apis/eventing/v1alpha1" duckv1 "knative.dev/pkg/apis/duck/v1" ) @@ -39,11 +40,12 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command { # Create a trigger 'mytrigger' to declare a subscription to events with attribute 'type=dev.knative.foo' from default broker. The subscriber is 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 { + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { return errors.New("'trigger create' requires the name of the trigger") } name := args[0] + sourceArgs := args[1:] namespace, err := p.GetNamespace(cmd) if err != nil { @@ -84,6 +86,20 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command { Ref: objectRef.Ref, URI: objectRef.URI, } + if triggerUpdateFlags.Source != "" { + sourceCmd := source.NewSourceCommand(p) + fullSourceArgs := []string{triggerUpdateFlags.Source, "create"} + fullSourceArgs = append(fullSourceArgs, sourceArgs...) + createSource, args, err := sourceCmd.Traverse(fullSourceArgs) + if err != nil { + return err + } + fmt.Printf("SOURCE COMMAND %v\n", createSource) + err = createSource.RunE(createSource, args) + if err != nil { + return err + } + } err = eventingClient.CreateTrigger(trigger) if err != nil { diff --git a/pkg/kn/commands/trigger/update_flags.go b/pkg/kn/commands/trigger/update_flags.go index e18317b6c3..405ea06a51 100644 --- a/pkg/kn/commands/trigger/update_flags.go +++ b/pkg/kn/commands/trigger/update_flags.go @@ -44,6 +44,7 @@ func (filters *filterArray) Type() string { type TriggerUpdateFlags struct { Broker string Filters filterArray + Source string } // GetFilter to return a map type of filters @@ -88,4 +89,5 @@ func (f *TriggerUpdateFlags) GetUpdateFilters() (map[string]string, []string, er func (f *TriggerUpdateFlags) Add(cmd *cobra.Command) { cmd.Flags().StringVar(&f.Broker, "broker", "default", "Name of the Broker which the trigger associates with.") cmd.Flags().Var(&f.Filters, "filter", "Key-value pair for exact CloudEvent attribute matching against incoming events, e.g type=dev.knative.foo") + cmd.Flags().StringVar(&f.Source, "source", "", "Source of the events to use for the trigger. Creates a source instance paired to this trigger.") } From 7c71f0f2da3cf2330c6f9936923b5c5327ea87bc Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Thu, 26 Dec 2019 22:26:19 +0000 Subject: [PATCH 10/10] Checkpoint. Can create trigger and source together --- pkg/kn/commands/trigger/create.go | 17 ++++++++-------- pkg/serving/service.go | 13 ++---------- pkg/util/random/random.go | 34 +++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 pkg/util/random/random.go diff --git a/pkg/kn/commands/trigger/create.go b/pkg/kn/commands/trigger/create.go index 706f228f1d..80d44584be 100644 --- a/pkg/kn/commands/trigger/create.go +++ b/pkg/kn/commands/trigger/create.go @@ -23,7 +23,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands/flags" - "knative.dev/client/pkg/kn/commands/source" "knative.dev/eventing/pkg/apis/eventing/v1alpha1" duckv1 "knative.dev/pkg/apis/duck/v1" ) @@ -87,15 +86,17 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command { URI: objectRef.URI, } if triggerUpdateFlags.Source != "" { - sourceCmd := source.NewSourceCommand(p) - fullSourceArgs := []string{triggerUpdateFlags.Source, "create"} + fullSourceArgs := []string{ + "source", triggerUpdateFlags.Source, "create", + "--sink", fmt.Sprintf("broker:%s", triggerUpdateFlags.Broker)} fullSourceArgs = append(fullSourceArgs, sourceArgs...) - createSource, args, err := sourceCmd.Traverse(fullSourceArgs) - if err != nil { - return err + fullSourceArgs = append(fullSourceArgs, name) + root := cmd + for root.HasParent() { + root = root.Parent() } - fmt.Printf("SOURCE COMMAND %v\n", createSource) - err = createSource.RunE(createSource, args) + root.SetArgs(fullSourceArgs) + err = root.Execute() if err != nil { return err } diff --git a/pkg/serving/service.go b/pkg/serving/service.go index 06242d00a1..33a5279bac 100644 --- a/pkg/serving/service.go +++ b/pkg/serving/service.go @@ -17,10 +17,10 @@ package serving import ( "bytes" "errors" - "math/rand" "strings" "text/template" + "knative.dev/client/pkg/util/random" servingv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" ) @@ -42,22 +42,13 @@ func RevisionTemplateOfService(service *servingv1alpha1.Service) (*servingv1alph return config.DeprecatedRevisionTemplate, nil } -var charChoices = []string{ - "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", - "y", "z", -} - type revisionTemplContext struct { Service string Generation int64 } func (c *revisionTemplContext) Random(l int) string { - chars := make([]string, 0, l) - for i := 0; i < l; i++ { - chars = append(chars, charChoices[rand.Int()%len(charChoices)]) - } - return strings.Join(chars, "") + return random.Random(l) } // GenerateRevisionName returns an automatically-generated name suitable for the diff --git a/pkg/util/random/random.go b/pkg/util/random/random.go new file mode 100644 index 0000000000..3424d8e4ec --- /dev/null +++ b/pkg/util/random/random.go @@ -0,0 +1,34 @@ +// 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 random + +import ( + "math/rand" + "strings" +) + +var charChoices = []string{ + "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", + "y", "z", +} + +func Random(l int) string { + chars := make([]string, 0, l) + for i := 0; i < l; i++ { + chars = append(chars, charChoices[rand.Int()%len(charChoices)]) + } + return strings.Join(chars, "") + +}