diff --git a/docs/cmd/kn.md b/docs/cmd/kn.md index fa5b1f0ba..7d0203822 100644 --- a/docs/cmd/kn.md +++ b/docs/cmd/kn.md @@ -26,6 +26,7 @@ Find more information about Knative at: https://knative.dev * [kn completion](kn_completion.md) - Output shell completion code * [kn container](kn_container.md) - Manage service's containers (experimental) * [kn domain](kn_domain.md) - Manage domain mappings +* [kn eventtype](kn_eventtype.md) - Manage eventtypes * [kn options](kn_options.md) - Print the list of flags inherited by all commands * [kn plugin](kn_plugin.md) - Manage kn plugins * [kn revision](kn_revision.md) - Manage service revisions diff --git a/docs/cmd/kn_eventtype.md b/docs/cmd/kn_eventtype.md new file mode 100644 index 000000000..ddb76fcc5 --- /dev/null +++ b/docs/cmd/kn_eventtype.md @@ -0,0 +1,32 @@ +## kn eventtype + +Manage eventtypes + +``` +kn eventtype +``` + +### Options + +``` + -h, --help help for eventtype +``` + +### Options inherited from parent commands + +``` + --cluster string name of the kubeconfig cluster to use + --config string kn configuration file (default: ~/.config/kn/config.yaml) + --context string name of the kubeconfig context to use + --kubeconfig string kubectl configuration file (default: ~/.kube/config) + --log-http log http traffic +``` + +### SEE ALSO + +* [kn](kn.md) - kn manages Knative Serving and Eventing resources +* [kn eventtype create](kn_eventtype_create.md) - Create eventtype +* [kn eventtype delete](kn_eventtype_delete.md) - Delete eventtype +* [kn eventtype describe](kn_eventtype_describe.md) - Describe eventtype +* [kn eventtype list](kn_eventtype_list.md) - List eventtypes + diff --git a/docs/cmd/kn_eventtype_create.md b/docs/cmd/kn_eventtype_create.md new file mode 100644 index 000000000..adf39dbee --- /dev/null +++ b/docs/cmd/kn_eventtype_create.md @@ -0,0 +1,44 @@ +## kn eventtype create + +Create eventtype + +``` +kn eventtype create +``` + +### Examples + +``` + + # Create eventtype 'myeventtype' of type example.type in the current namespace + kn eventtype create myeventtype --type example.type + + # Create eventtype 'myeventtype' of type example.type in the 'myproject' namespace + kn eventtype create myeventtype --namespace myproject -t example.type + +``` + +### Options + +``` + -b, --broker string Cloud Event broker + -h, --help help for create + -n, --namespace string Specify the namespace to operate in. + --source string Cloud Event source + -t, --type string Cloud Event type +``` + +### Options inherited from parent commands + +``` + --cluster string name of the kubeconfig cluster to use + --config string kn configuration file (default: ~/.config/kn/config.yaml) + --context string name of the kubeconfig context to use + --kubeconfig string kubectl configuration file (default: ~/.kube/config) + --log-http log http traffic +``` + +### SEE ALSO + +* [kn eventtype](kn_eventtype.md) - Manage eventtypes + diff --git a/docs/cmd/kn_eventtype_delete.md b/docs/cmd/kn_eventtype_delete.md new file mode 100644 index 000000000..d5e52f35a --- /dev/null +++ b/docs/cmd/kn_eventtype_delete.md @@ -0,0 +1,41 @@ +## kn eventtype delete + +Delete eventtype + +``` +kn eventtype delete +``` + +### Examples + +``` + + # Delete eventtype 'myeventtype' in the current namespace + kn eventtype delete myeventtype + + # Delete eventtype 'myeventtype' in the 'myproject' namespace + kn eventtype delete myeventtype --namespace myproject + +``` + +### Options + +``` + -h, --help help for delete + -n, --namespace string Specify the namespace to operate in. +``` + +### Options inherited from parent commands + +``` + --cluster string name of the kubeconfig cluster to use + --config string kn configuration file (default: ~/.config/kn/config.yaml) + --context string name of the kubeconfig context to use + --kubeconfig string kubectl configuration file (default: ~/.kube/config) + --log-http log http traffic +``` + +### SEE ALSO + +* [kn eventtype](kn_eventtype.md) - Manage eventtypes + diff --git a/docs/cmd/kn_eventtype_describe.md b/docs/cmd/kn_eventtype_describe.md new file mode 100644 index 000000000..40c350e56 --- /dev/null +++ b/docs/cmd/kn_eventtype_describe.md @@ -0,0 +1,47 @@ +## kn eventtype describe + +Describe eventtype + +``` +kn eventtype describe +``` + +### Examples + +``` + + # Describe eventtype 'myeventtype' in the current namespace + kn eventtype describe myeventtype + + # Describe eventtype 'myeventtype' in the 'myproject' namespace + kn eventtype describe myeventtype --namespace myproject + + # Describe eventtype 'myeventtype' in YAML format + kn eventtype describe myeventtype -o yaml +``` + +### Options + +``` + --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) + -h, --help help for describe + -n, --namespace string Specify the namespace to operate in. + -o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file. + --show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format. + --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. +``` + +### Options inherited from parent commands + +``` + --cluster string name of the kubeconfig cluster to use + --config string kn configuration file (default: ~/.config/kn/config.yaml) + --context string name of the kubeconfig context to use + --kubeconfig string kubectl configuration file (default: ~/.kube/config) + --log-http log http traffic +``` + +### SEE ALSO + +* [kn eventtype](kn_eventtype.md) - Manage eventtypes + diff --git a/docs/cmd/kn_eventtype_list.md b/docs/cmd/kn_eventtype_list.md new file mode 100644 index 000000000..e673f50f5 --- /dev/null +++ b/docs/cmd/kn_eventtype_list.md @@ -0,0 +1,46 @@ +## kn eventtype list + +List eventtypes + +``` +kn eventtype list +``` + +### Examples + +``` + + # List all eventtypes + kn eventtype list + + # List all eventtypes in JSON output format + kn eventtype list -o json +``` + +### Options + +``` + -A, --all-namespaces If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace. + --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) + -h, --help help for list + -n, --namespace string Specify the namespace to operate in. + --no-headers When using the default output format, don't print headers (default: print headers). + -o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file. + --show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format. + --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. +``` + +### Options inherited from parent commands + +``` + --cluster string name of the kubeconfig cluster to use + --config string kn configuration file (default: ~/.config/kn/config.yaml) + --context string name of the kubeconfig context to use + --kubeconfig string kubectl configuration file (default: ~/.kube/config) + --log-http log http traffic +``` + +### SEE ALSO + +* [kn eventtype](kn_eventtype.md) - Manage eventtypes + diff --git a/lib/test/eventtype.go b/lib/test/eventtype.go new file mode 100644 index 000000000..8c2cb4843 --- /dev/null +++ b/lib/test/eventtype.go @@ -0,0 +1,60 @@ +// Copyright 2021 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 test + +import ( + "gotest.tools/v3/assert" + "knative.dev/client/pkg/util" +) + +// EventtypeCreate creates an eventtype with the given name. +func EventtypeCreate(r *KnRunResultCollector, name, cetype string) { + out := r.KnTest().Kn().Run("eventtype", "create", name, "--type", cetype) + r.AssertNoError(out) + assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "Eventtype", name, "created", "namespace", r.KnTest().Kn().Namespace())) +} + +// EventtypeDelete deletes an eventtype with the given name. +func EventtypeDelete(r *KnRunResultCollector, name string) { + out := r.KnTest().Kn().Run("eventtype", "delete", name) + r.AssertNoError(out) + assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "Eventtype", name, "deleted", "namespace", r.KnTest().Kn().Namespace())) +} + +// EventtypeList verifies listing eventtypes in the given namespace +func EventtypeList(r *KnRunResultCollector, eventtypes ...string) { + out := r.KnTest().Kn().Run("eventtype", "list") + r.AssertNoError(out) + assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, eventtypes...)) +} + +// EventtypeDescribe describes an eventtype with the given name. +func EventtypeDescribe(r *KnRunResultCollector, name string) { + out := r.KnTest().Kn().Run("eventtype", "describe", name) + r.AssertNoError(out) + assert.Check(r.T(), util.ContainsAll(out.Stdout, name, r.KnTest().Kn().Namespace(), "Ready", "BrokerReady")) +} + +func EventtypeCreateWithBrokerSource(r *KnRunResultCollector, name, cetype, broker, source string) { + out := r.KnTest().Kn().Run("eventtype", "create", name, "--type", cetype, "--broker", broker, "--source", source) + r.AssertNoError(out) + assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "Eventtype", name, "created", "namespace", r.KnTest().Kn().Namespace())) +} + +func EventtypeCreateWithSourceError(r *KnRunResultCollector, name, cetype, source string) { + out := r.KnTest().Kn().Run("eventtype", "create", name, "--type", cetype, "--source", source) + r.AssertError(out) + assert.Check(r.T(), util.ContainsAll(out.Stderr, name, "invalid", "control character")) +} diff --git a/pkg/eventing/v1beta1/client.go b/pkg/eventing/v1beta1/client.go new file mode 100644 index 000000000..39bb5d983 --- /dev/null +++ b/pkg/eventing/v1beta1/client.go @@ -0,0 +1,165 @@ +// Copyright © 2022 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 v1beta1 + +import ( + "context" + + apis_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kn_errors "knative.dev/client/pkg/errors" + "knative.dev/client/pkg/util" + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1" + "knative.dev/pkg/apis" +) + +// KnEventingV1Beta1Client to Eventing Sources. All methods are relative to the +// namespace specified during construction +type KnEventingV1Beta1Client interface { + // Namespace in which this client is operating for + Namespace() string + // ListEventtypes is used to list eventtypes + ListEventtypes(ctx context.Context) (*eventingv1beta1.EventTypeList, error) + // GetEventtype is used to describe an eventtype + GetEventtype(ctx context.Context, name string) (*eventingv1beta1.EventType, error) + // CreateEventtype is used to create an eventtype + CreateEventtype(ctx context.Context, eventtype *eventingv1beta1.EventType) error + // DeleteEventtype is used to delete an eventtype + DeleteEventtype(ctx context.Context, name string) error +} + +// KnEventingV1Beta1Client is a client for eventing v1beta1 resources +type knEventingV1Beta1Client struct { + client beta1.EventingV1beta1Interface + namespace string +} + +// NewKnEventingV1Beta1Client is to invoke Eventing Types Client API to create object +func NewKnEventingV1Beta1Client(client beta1.EventingV1beta1Interface, namespace string) KnEventingV1Beta1Client { + return &knEventingV1Beta1Client{ + client: client, + namespace: namespace, + } +} + +func updateEventingBeta1GVK(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, eventingv1beta1.SchemeGroupVersion, scheme.Scheme) +} + +func (c *knEventingV1Beta1Client) Namespace() string { + return c.namespace +} + +func (c *knEventingV1Beta1Client) ListEventtypes(ctx context.Context) (*eventingv1beta1.EventTypeList, error) { + eventTypeList, err := c.client.EventTypes(c.namespace).List(ctx, apis_v1.ListOptions{}) + if err != nil { + return nil, kn_errors.GetError(err) + } + listNew := eventTypeList.DeepCopy() + err = updateEventingBeta1GVK(listNew) + if err != nil { + return nil, err + } + + listNew.Items = make([]eventingv1beta1.EventType, len(eventTypeList.Items)) + for idx, eventType := range eventTypeList.Items { + clone := eventType.DeepCopy() + err := updateEventingBeta1GVK(clone) + if err != nil { + return nil, err + } + listNew.Items[idx] = *clone + } + return listNew, nil +} + +func (c *knEventingV1Beta1Client) GetEventtype(ctx context.Context, name string) (*eventingv1beta1.EventType, error) { + eventType, err := c.client.EventTypes(c.namespace).Get(ctx, name, apis_v1.GetOptions{}) + if err != nil { + return nil, kn_errors.GetError(err) + } + err = updateEventingBeta1GVK(eventType) + if err != nil { + return nil, err + } + return eventType, nil +} + +func (c *knEventingV1Beta1Client) DeleteEventtype(ctx context.Context, name string) error { + err := c.client.EventTypes(c.namespace).Delete(ctx, name, apis_v1.DeleteOptions{}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +func (c *knEventingV1Beta1Client) CreateEventtype(ctx context.Context, eventtype *eventingv1beta1.EventType) error { + _, err := c.client.EventTypes(c.namespace).Create(ctx, eventtype, apis_v1.CreateOptions{}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +// EventtypeBuilder is for building the eventtype +type EventtypeBuilder struct { + eventtype *eventingv1beta1.EventType +} + +// NewEventtypeBuilder for building eventtype object +func NewEventtypeBuilder(name string) *EventtypeBuilder { + return &EventtypeBuilder{eventtype: &eventingv1beta1.EventType{ + ObjectMeta: apis_v1.ObjectMeta{ + Name: name, + }, + }} +} + +// WithGvk add the GVK coordinates for read tests +func (e *EventtypeBuilder) WithGvk() *EventtypeBuilder { + _ = updateEventingBeta1GVK(e.eventtype) + return e +} + +// Namespace for eventtype builder +func (e *EventtypeBuilder) Namespace(ns string) *EventtypeBuilder { + e.eventtype.Namespace = ns + return e +} + +// Type for eventtype builder +func (e *EventtypeBuilder) Type(ceType string) *EventtypeBuilder { + e.eventtype.Spec.Type = ceType + return e +} + +// Source for eventtype builder +func (e *EventtypeBuilder) Source(source *apis.URL) *EventtypeBuilder { + e.eventtype.Spec.Source = source + return e +} + +// Broker for eventtype builder +func (e *EventtypeBuilder) Broker(broker string) *EventtypeBuilder { + e.eventtype.Spec.Broker = broker + return e +} + +// Build to return an instance of eventtype object +func (e *EventtypeBuilder) Build() *eventingv1beta1.EventType { + return e.eventtype +} diff --git a/pkg/eventing/v1beta1/client_mock.go b/pkg/eventing/v1beta1/client_mock.go new file mode 100644 index 000000000..24d2ffcc6 --- /dev/null +++ b/pkg/eventing/v1beta1/client_mock.go @@ -0,0 +1,106 @@ +// Copyright © 2022 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 v1beta1 + +import ( + "context" + "testing" + + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + + "knative.dev/client/pkg/util/mock" +) + +// MockKnEventingV1beta1Client is a combine of test object and recorder +type MockKnEventingV1beta1Client struct { + t *testing.T + recorder *EventingV1beta1Recorder +} + +// NewMockKnEventingV1beta1Client returns a new mock instance which you need to record for +func NewMockKnEventingV1beta1Client(t *testing.T, ns ...string) *MockKnEventingV1beta1Client { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnEventingV1beta1Client{ + t: t, + recorder: &EventingV1beta1Recorder{mock.NewRecorder(t, namespace)}, + } +} + +// Ensure that the interface is implemented +var _ KnEventingV1Beta1Client = &MockKnEventingV1beta1Client{} + +// EventingV1beta1Recorder is recorder for eventingv1beta1 objects +type EventingV1beta1Recorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnEventingV1beta1Client) Recorder() *EventingV1beta1Recorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnEventingV1beta1Client) Namespace() string { + return c.recorder.r.Namespace() +} + +// ListEventtypes records a call for ListEventtypes with the expected result and error (nil if none) +func (sr *EventingV1beta1Recorder) ListEventtypes(eventtypeList *eventingv1beta1.EventTypeList, err error) { + sr.r.Add("ListEventtypes", nil, []interface{}{eventtypeList, err}) +} + +func (c *MockKnEventingV1beta1Client) ListEventtypes(ctx context.Context) (*eventingv1beta1.EventTypeList, error) { + call := c.recorder.r.VerifyCall("ListEventtypes") + return call.Result[0].(*eventingv1beta1.EventTypeList), mock.ErrorOrNil(call.Result[1]) +} + +// GetEventtype records a call for GetEventtype with the expected result and error (nil if none) +func (sr *EventingV1beta1Recorder) GetEventtype(name string, eventtype *eventingv1beta1.EventType, err error) { + sr.r.Add("GetEventtype", []interface{}{name}, []interface{}{eventtype, err}) +} + +// GetEventtypes records a call for GetEventtype with the expected object or error. Either eventtype or err should be nil +func (c *MockKnEventingV1beta1Client) GetEventtype(ctx context.Context, name string) (*eventingv1beta1.EventType, error) { + call := c.recorder.r.VerifyCall("GetEventtype", name) + return call.Result[0].(*eventingv1beta1.EventType), mock.ErrorOrNil(call.Result[1]) +} + +// CreateEventtype records a call for CreateEventtype with the expected error +func (sr *EventingV1beta1Recorder) CreateEventtype(eventtype interface{}, err error) { + sr.r.Add("CreateEventtype", []interface{}{eventtype}, []interface{}{err}) +} + +func (c *MockKnEventingV1beta1Client) CreateEventtype(ctx context.Context, eventtype *eventingv1beta1.EventType) error { + call := c.recorder.r.VerifyCall("CreateEventtype", eventtype) + return mock.ErrorOrNil(call.Result[0]) +} + +// DeleteEventtype records a call for DeleteEventtype with the expected error +func (sr *EventingV1beta1Recorder) DeleteEventtype(name interface{}, err error) { + sr.r.Add("DeleteEventtype", []interface{}{name}, []interface{}{err}) +} + +func (c *MockKnEventingV1beta1Client) DeleteEventtype(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeleteEventtype", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// Validate validates whether every recorded action has been called +func (sr *EventingV1beta1Recorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/pkg/eventing/v1beta1/client_mock_test.go b/pkg/eventing/v1beta1/client_mock_test.go new file mode 100644 index 000000000..01da096ac --- /dev/null +++ b/pkg/eventing/v1beta1/client_mock_test.go @@ -0,0 +1,41 @@ +// Copyright © 2022 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 v1beta1 + +import ( + "context" + "testing" + + "knative.dev/eventing/pkg/apis/eventing/v1beta1" +) + +func TestMockKnClient(t *testing.T) { + client := NewMockKnEventingV1beta1Client(t, "test-ns") + + recorder := client.Recorder() + + recorder.CreateEventtype(&v1beta1.EventType{}, nil) + recorder.GetEventtype("eventtype-name", &v1beta1.EventType{}, nil) + recorder.DeleteEventtype("eventtype-name", nil) + recorder.ListEventtypes(&v1beta1.EventTypeList{}, nil) + + ctx := context.Background() + client.CreateEventtype(ctx, &v1beta1.EventType{}) + client.GetEventtype(ctx, "eventtype-name") + client.DeleteEventtype(ctx, "eventtype-name") + client.ListEventtypes(ctx) + + recorder.Validate() +} diff --git a/pkg/eventing/v1beta1/client_test.go b/pkg/eventing/v1beta1/client_test.go new file mode 100644 index 000000000..857154625 --- /dev/null +++ b/pkg/eventing/v1beta1/client_test.go @@ -0,0 +1,180 @@ +// Copyright © 2022 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 v1beta1 + +import ( + "context" + "fmt" + "testing" + + "gotest.tools/v3/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + client_testing "k8s.io/client-go/testing" + "knative.dev/eventing/pkg/apis/eventing/v1beta1" + "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake" + "knative.dev/pkg/apis" +) + +const ( + testNamespace = "test-ns" + testBroker = "test-broker" + testSource = "test.source" + testType = "test-type" + testName = "test-eventtype" + errName = "error-eventtype" +) + +func setup(ns string) (fakeSvr fake.FakeEventingV1beta1, client KnEventingV1Beta1Client) { + fakeE := fake.FakeEventingV1beta1{Fake: &client_testing.Fake{}} + cli := NewKnEventingV1Beta1Client(&fakeE, ns) + return fakeE, cli +} + +func TestNamespace(t *testing.T) { + _, client := setup(testNamespace) + assert.Equal(t, testNamespace, client.Namespace()) +} + +func TestBuilder(t *testing.T) { + et := newEventtypeWithSourceBroker(testName, testSource, testBroker) + assert.Equal(t, et.Name, testName) + assert.Equal(t, et.Spec.Broker, testBroker) + source := et.Spec.Source + assert.Assert(t, source != nil) + assert.Equal(t, source.String(), testSource) +} + +func TestKnEventingV1Beta1Client_CreateEventtype(t *testing.T) { + server, client := setup(testNamespace) + + server.AddReactor("create", "eventtypes", + 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 == errName { + return true, nil, fmt.Errorf("error while creating eventtype %s", name) + } + return true, nil, nil + }) + ctx := context.Background() + + t.Run("create eventtype successfully", func(t *testing.T) { + objNew := newEventtype(testName) + err := client.CreateEventtype(ctx, objNew) + assert.NilError(t, err) + }) + t.Run("create eventtype with source and broker successfully", func(t *testing.T) { + objNew := newEventtypeWithSourceBroker(testName, testSource, testBroker) + err := client.CreateEventtype(ctx, objNew) + assert.NilError(t, err) + }) + t.Run("create eventtype with error", func(t *testing.T) { + objNew := newEventtype(errName) + err := client.CreateEventtype(ctx, objNew) + assert.ErrorContains(t, err, "error while creating eventtype") + }) +} + +func TestKnEventingV1Beta1Client_DeleteEventtype(t *testing.T) { + server, client := setup(testNamespace) + + server.AddReactor("delete", "eventtypes", + func(a client_testing.Action) (bool, runtime.Object, error) { + assert.Equal(t, testNamespace, a.GetNamespace()) + + name := a.(client_testing.DeleteAction).GetName() + if name == errName { + return true, nil, fmt.Errorf("error while deleting eventtype %s", name) + } + return true, nil, nil + }) + ctx := context.Background() + + t.Run("delete eventtype successfully", func(t *testing.T) { + err := client.DeleteEventtype(ctx, testName) + assert.NilError(t, err) + }) + t.Run("delete eventtype with error", func(t *testing.T) { + err := client.DeleteEventtype(ctx, errName) + assert.ErrorContains(t, err, "error while deleting eventtype") + }) +} + +func TestKnEventingV1Beta1Client_GetEventtype(t *testing.T) { + server, client := setup(testNamespace) + + server.AddReactor("get", "eventtypes", + func(a client_testing.Action) (bool, runtime.Object, error) { + assert.Equal(t, testNamespace, a.GetNamespace()) + + name := a.(client_testing.GetAction).GetName() + if name == errName { + return true, nil, fmt.Errorf("error while getting eventtype %s", name) + } + return true, newEventtype(testName), nil + }) + ctx := context.Background() + + t.Run("get eventtype successfully", func(t *testing.T) { + et, err := client.GetEventtype(ctx, testName) + assert.NilError(t, err) + assert.Equal(t, et.Name, testName) + }) + t.Run("get eventtype with error", func(t *testing.T) { + _, err := client.GetEventtype(ctx, errName) + assert.ErrorContains(t, err, "error while getting eventtype") + }) +} + +func TestKnEventingV1Beta1Client_ListEventtypes(t *testing.T) { + server, client := setup(testNamespace) + + server.AddReactor("list", "eventtypes", + func(a client_testing.Action) (bool, runtime.Object, error) { + assert.Equal(t, testNamespace, a.GetNamespace()) + + return true, &v1beta1.EventTypeList{Items: []v1beta1.EventType{ + *newEventtype("eventtype-1"), + *newEventtype("eventtype-2")}}, nil + }) + ctx := context.Background() + + list, err := client.ListEventtypes(ctx) + assert.NilError(t, err) + assert.Assert(t, list != nil) + assert.Equal(t, len(list.Items), 2) + assert.Equal(t, list.Items[0].Name, "eventtype-1") + assert.Equal(t, list.Items[1].Name, "eventtype-2") +} + +func newEventtypeWithSourceBroker(name string, source string, broker string) *v1beta1.EventType { + url, _ := apis.ParseURL(source) + return NewEventtypeBuilder(name). + Namespace(testNamespace). + WithGvk(). + Type(testType). + Source(url). + Broker(broker). + Build() +} + +func newEventtype(name string) *v1beta1.EventType { + return NewEventtypeBuilder(name). + Namespace(testNamespace). + Type(testType). + Build() +} diff --git a/pkg/kn/commands/completion_helper.go b/pkg/kn/commands/completion_helper.go index d1816a5d7..82b6eef75 100644 --- a/pkg/kn/commands/completion_helper.go +++ b/pkg/kn/commands/completion_helper.go @@ -41,6 +41,7 @@ var ( "service": completeService, "subscription": completeSubscription, "trigger": completeTrigger, + "eventtype": completeEventtype, } ) @@ -427,3 +428,31 @@ func completeSubscription(config *completionConfig) (suggestions []string) { } return } + +func completeEventtype(config *completionConfig) (suggestions []string) { + suggestions = make([]string, 0) + if len(config.args) != 0 { + return + } + namespace, err := config.params.GetNamespace(config.command) + if err != nil { + return + } + + client, err := config.params.NewEventingV1beta1Client(namespace) + if err != nil { + return + } + + eventTypeList, err := client.ListEventtypes(config.command.Context()) + if err != nil { + return + } + for _, sug := range eventTypeList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} diff --git a/pkg/kn/commands/completion_helper_test.go b/pkg/kn/commands/completion_helper_test.go index 0422bd26b..66c1daee7 100644 --- a/pkg/kn/commands/completion_helper_test.go +++ b/pkg/kn/commands/completion_helper_test.go @@ -26,11 +26,13 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/clientcmd" + clienteventingv1beta1 "knative.dev/client/pkg/eventing/v1beta1" v1beta1 "knative.dev/client/pkg/messaging/v1" clientv1alpha1 "knative.dev/client/pkg/serving/v1alpha1" clientsourcesv1 "knative.dev/client/pkg/sources/v1" "knative.dev/client/pkg/sources/v1beta2" - v12 "knative.dev/eventing/pkg/apis/messaging/v1" + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1" sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" sourcesv1fake "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1/fake" @@ -44,6 +46,7 @@ import ( eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1/fake" + beta1fake "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake" servingv1 "knative.dev/serving/pkg/apis/serving/v1" "knative.dev/serving/pkg/apis/serving/v1alpha1" servingv1fake "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1/fake" @@ -335,53 +338,79 @@ var ( ) var ( - testChannel1 = v12.Channel{ + testChannel1 = messagingv1.Channel{ TypeMeta: metav1.TypeMeta{ Kind: "Channel", APIVersion: "messaging.knative.dev/v1", }, ObjectMeta: metav1.ObjectMeta{Name: "test-channel-1", Namespace: testNs}, } - testChannel2 = v12.Channel{ + testChannel2 = messagingv1.Channel{ TypeMeta: metav1.TypeMeta{ Kind: "Channel", APIVersion: "messaging.knative.dev/v1", }, ObjectMeta: metav1.ObjectMeta{Name: "test-channel-2", Namespace: testNs}, } - testChannel3 = v12.Channel{ + testChannel3 = messagingv1.Channel{ TypeMeta: metav1.TypeMeta{ Kind: "Channel", APIVersion: "messaging.knative.dev/v1", }, ObjectMeta: metav1.ObjectMeta{Name: "test-channel-3", Namespace: testNs}, } - testNsChannels = []v12.Channel{testChannel1, testChannel2, testChannel3} + testNsChannels = []messagingv1.Channel{testChannel1, testChannel2, testChannel3} ) var ( - testSubscription1 = v12.Subscription{ + testSubscription1 = messagingv1.Subscription{ TypeMeta: metav1.TypeMeta{ Kind: "Subscription", APIVersion: "messaging.knative.dev/v1", }, ObjectMeta: metav1.ObjectMeta{Name: "test-subscription-1", Namespace: testNs}, } - testSubscription2 = v12.Subscription{ + testSubscription2 = messagingv1.Subscription{ TypeMeta: metav1.TypeMeta{ Kind: "Subscription", APIVersion: "messaging.knative.dev/v1", }, ObjectMeta: metav1.ObjectMeta{Name: "test-subscription-2", Namespace: testNs}, } - testSubscription3 = v12.Subscription{ + testSubscription3 = messagingv1.Subscription{ TypeMeta: metav1.TypeMeta{ Kind: "Subscription", APIVersion: "messaging.knative.dev/v1", }, ObjectMeta: metav1.ObjectMeta{Name: "test-subscription-3", Namespace: testNs}, } - testNsSubscriptions = []v12.Subscription{testSubscription1, testSubscription2, testSubscription3} + testNsSubscriptions = []messagingv1.Subscription{testSubscription1, testSubscription2, testSubscription3} +) + +var ( + testEventtype1 = eventingv1beta1.EventType{ + TypeMeta: metav1.TypeMeta{ + Kind: "EventType", + APIVersion: "eventing.knative.dev/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{Name: "test-eventtype-1", Namespace: testNs}, + } + testEventtype2 = eventingv1beta1.EventType{ + TypeMeta: metav1.TypeMeta{ + Kind: "EventType", + APIVersion: "eventing.knative.dev/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{Name: "test-eventtype-2", Namespace: testNs}, + } + testEventtype3 = eventingv1beta1.EventType{ + TypeMeta: metav1.TypeMeta{ + Kind: "EventType", + APIVersion: "eventing.knative.dev/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{Name: "test-eventtype-3", Namespace: testNs}, + } + testEventtypes = []eventingv1beta1.EventType{testEventtype1, testEventtype2, testEventtype3} + fakeEventingBeta1Client = &beta1fake.FakeEventingV1beta1{Fake: &clienttesting.Fake{}} ) var knParams = initialiseKnParams() @@ -424,6 +453,9 @@ current-context: x NewSourcesV1beta2Client: func(namespace string) (v1beta2.KnSourcesClient, error) { return v1beta2.NewKnSourcesClient(fakeSourcesV1Beta2, namespace), nil }, + NewEventingV1beta1Client: func(namespace string) (clienteventingv1beta1.KnEventingV1Beta1Client, error) { + return clienteventingv1beta1.NewKnEventingV1Beta1Client(fakeEventingBeta1Client, namespace), nil + }, ClientConfig: blankConfig, } } @@ -1299,14 +1331,14 @@ func TestResourceNameCompletionFuncChannel(t *testing.T) { completionFunc := ResourceNameCompletionFunc(knParams) channelClient := v1beta1.NewMockKnChannelsClient(t) - channelClient.Recorder().ListChannel(&v12.ChannelList{Items: testNsChannels}, nil) - channelClient.Recorder().ListChannel(&v12.ChannelList{Items: testNsChannels}, nil) + channelClient.Recorder().ListChannel(&messagingv1.ChannelList{Items: testNsChannels}, nil) + channelClient.Recorder().ListChannel(&messagingv1.ChannelList{Items: testNsChannels}, nil) - channelClient.Recorder().ListChannel(&v12.ChannelList{Items: testNsChannels}, nil) - channelClient.Recorder().ListChannel(&v12.ChannelList{Items: testNsChannels}, nil) + channelClient.Recorder().ListChannel(&messagingv1.ChannelList{Items: testNsChannels}, nil) + channelClient.Recorder().ListChannel(&messagingv1.ChannelList{Items: testNsChannels}, nil) - channelClient.Recorder().ListChannel(&v12.ChannelList{}, fmt.Errorf("error listing channels")) - channelClient.Recorder().ListChannel(&v12.ChannelList{}, fmt.Errorf("error listing channels")) + channelClient.Recorder().ListChannel(&messagingv1.ChannelList{}, fmt.Errorf("error listing channels")) + channelClient.Recorder().ListChannel(&messagingv1.ChannelList{}, fmt.Errorf("error listing channels")) messagingClient := &mockMessagingClient{channelClient, nil} @@ -1385,14 +1417,14 @@ func TestResourceNameCompletionFuncSubscription(t *testing.T) { completionFunc := ResourceNameCompletionFunc(knParams) subscriptionsClient := v1beta1.NewMockKnSubscriptionsClient(t) - subscriptionsClient.Recorder().ListSubscription(&v12.SubscriptionList{Items: testNsSubscriptions}, nil) - subscriptionsClient.Recorder().ListSubscription(&v12.SubscriptionList{Items: testNsSubscriptions}, nil) + subscriptionsClient.Recorder().ListSubscription(&messagingv1.SubscriptionList{Items: testNsSubscriptions}, nil) + subscriptionsClient.Recorder().ListSubscription(&messagingv1.SubscriptionList{Items: testNsSubscriptions}, nil) - subscriptionsClient.Recorder().ListSubscription(&v12.SubscriptionList{Items: testNsSubscriptions}, nil) - subscriptionsClient.Recorder().ListSubscription(&v12.SubscriptionList{Items: testNsSubscriptions}, nil) + subscriptionsClient.Recorder().ListSubscription(&messagingv1.SubscriptionList{Items: testNsSubscriptions}, nil) + subscriptionsClient.Recorder().ListSubscription(&messagingv1.SubscriptionList{Items: testNsSubscriptions}, nil) - subscriptionsClient.Recorder().ListSubscription(&v12.SubscriptionList{}, fmt.Errorf("error listing channels")) - subscriptionsClient.Recorder().ListSubscription(&v12.SubscriptionList{}, fmt.Errorf("error listing channels")) + subscriptionsClient.Recorder().ListSubscription(&messagingv1.SubscriptionList{}, fmt.Errorf("error listing channels")) + subscriptionsClient.Recorder().ListSubscription(&messagingv1.SubscriptionList{}, fmt.Errorf("error listing channels")) messagingClient := &mockMessagingClient{nil, subscriptionsClient} @@ -1467,6 +1499,83 @@ func TestResourceNameCompletionFuncSubscription(t *testing.T) { subscriptionsClient.Recorder().Validate() } +func TestResourceNameCompletionFuncEventtype(t *testing.T) { + completionFunc := ResourceNameCompletionFunc(knParams) + + fakeEventingBeta1Client.AddReactor("list", "eventtypes", func(a clienttesting.Action) (bool, runtime.Object, error) { + if a.GetNamespace() == errorNs { + return true, nil, errors.NewInternalError(fmt.Errorf("unable to list eventtypes")) + } + return true, &eventingv1beta1.EventTypeList{Items: testEventtypes}, nil + }) + + tests := []testType{ + { + "Empty suggestions when non-zero args", + testNs, + knParams, + []string{"xyz"}, + "", + "eventtype", + }, + { + "Empty suggestions when no namespace flag", + "", + knParams, + nil, + "", + "eventtype", + }, + { + "Suggestions when test-ns namespace set", + testNs, + knParams, + nil, + "", + "eventtype", + }, + { + "Empty suggestions when toComplete is not a prefix", + testNs, + knParams, + nil, + "xyz", + "eventtype", + }, + { + "Empty suggestions when error during list operation", + errorNs, + knParams, + nil, + "", + "eventtype", + }, + } + for _, tt := range tests { + cmd := getResourceCommandWithTestSubcommand(tt.resource, tt.namespace != "", tt.resource != "no-parent") + t.Run(tt.name, func(t *testing.T) { + config := &completionConfig{ + params: tt.p, + command: cmd, + args: tt.args, + toComplete: tt.toComplete, + } + expectedFunc := resourceToFuncMap[tt.resource] + if expectedFunc == nil { + expectedFunc = func(config *completionConfig) []string { + return []string{} + } + } + cmd.Flags().Set("namespace", tt.namespace) + actualSuggestions, actualDirective := completionFunc(cmd, tt.args, tt.toComplete) + expectedSuggestions := expectedFunc(config) + expectedDirective := cobra.ShellCompDirectiveNoFileComp + assert.DeepEqual(t, actualSuggestions, expectedSuggestions) + assert.Equal(t, actualDirective, expectedDirective) + }) + } +} + func getResourceCommandWithTestSubcommand(resource string, addNamespace, addSubcommand bool) *cobra.Command { testCommand := &cobra.Command{ Use: resource, diff --git a/pkg/kn/commands/eventtype/create.go b/pkg/kn/commands/eventtype/create.go new file mode 100644 index 000000000..5f2b4d2af --- /dev/null +++ b/pkg/kn/commands/eventtype/create.go @@ -0,0 +1,93 @@ +/* +Copyright 2022 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 eventtype + +import ( + "errors" + "fmt" + + "github.com/spf13/cobra" + clienteventingv1beta1 "knative.dev/client/pkg/eventing/v1beta1" + "knative.dev/client/pkg/kn/commands" + knflags "knative.dev/client/pkg/kn/commands/flags" + "knative.dev/pkg/apis" +) + +var createExample = ` + # Create eventtype 'myeventtype' of type example.type in the current namespace + kn eventtype create myeventtype --type example.type + + # Create eventtype 'myeventtype' of type example.type in the 'myproject' namespace + kn eventtype create myeventtype --namespace myproject -t example.type +` + +// NewEventtypeCreateCommand represents command to describe the details of an eventtype instance +func NewEventtypeCreateCommand(p *commands.KnParams) *cobra.Command { + + var eventtypeFlags knflags.EventtypeFlags + cmd := &cobra.Command{ + Use: "create", + Short: "Create eventtype", + Example: createExample, + RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) != 1 { + return errors.New("'eventtype create' requires the eventtype name given as single argument") + } + name := args[0] + + namespace, err := p.GetNamespace(cmd) + if err != nil { + return eventtypeCreateError(name, namespace, err) + } + + eventingV1Beta1Client, err := p.NewEventingV1beta1Client(namespace) + if err != nil { + return err + } + var source *apis.URL + if eventtypeFlags.Source != "" { + source, err = apis.ParseURL(eventtypeFlags.Source) + if err != nil { + return eventtypeCreateError(name, namespace, err) + } + } + eventtype := clienteventingv1beta1.NewEventtypeBuilder(name). + Namespace(namespace). + Type(eventtypeFlags.Type). + Source(source). + Broker(eventtypeFlags.Broker). + Build() + + err = eventingV1Beta1Client.CreateEventtype(cmd.Context(), eventtype) + if err != nil { + return eventtypeCreateError(name, namespace, err) + } + fmt.Fprintf(cmd.OutOrStdout(), "Eventtype '%s' successfully created in namespace '%s'.\n", args[0], namespace) + return nil + }, + } + commands.AddNamespaceFlags(cmd.Flags(), false) + + eventtypeFlags.Add(cmd) + return cmd +} + +func eventtypeCreateError(name string, namespace string, err error) error { + return fmt.Errorf( + "cannot create eventtype '%s' in namespace '%s' "+ + "because: %s", name, namespace, err) +} diff --git a/pkg/kn/commands/eventtype/create_test.go b/pkg/kn/commands/eventtype/create_test.go new file mode 100644 index 000000000..b62264621 --- /dev/null +++ b/pkg/kn/commands/eventtype/create_test.go @@ -0,0 +1,111 @@ +/* +Copyright 2022 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 eventtype + +import ( + "fmt" + "testing" + + "gotest.tools/v3/assert" + "knative.dev/client/pkg/eventing/v1beta1" + "knative.dev/client/pkg/util" + "knative.dev/pkg/apis" +) + +func TestEventTypeCreate(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + eventingRecorder := eventingClient.Recorder() + eventingRecorder.CreateEventtype(createEventtype(eventtypeName, cetype, testNs), nil) + + out, err := executeEventtypeCommand(eventingClient, "create", eventtypeName, "--type", cetype, "--namespace", testNs) + assert.NilError(t, err, "Eventtype should be created") + assert.Assert(t, util.ContainsAll(out, "Eventtype", eventtypeName, "created", "namespace", testNs)) + + // Create eventtype without namespace flag set + eventingRecorder.CreateEventtype(createEventtype(eventtypeName, cetype, "default"), nil) + out, err = executeEventtypeCommand(eventingClient, "create", eventtypeName, "--type", cetype) + + assert.NilError(t, err, "Eventtype should be created") + assert.Assert(t, util.ContainsAll(out, "Eventtype", eventtypeName, "created", "namespace", "default")) + + eventingRecorder.Validate() +} + +func TestEventTypeCreateWithoutTypeError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + _, err := executeEventtypeCommand(eventingClient, "create", eventtypeName, "--namespace", testNs) + assert.Assert(t, util.ContainsAll(err.Error(), "required", "flag(s)", "type", "not", "set")) +} + +func TestEventTypeCreateWithoutNameError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + _, err := executeEventtypeCommand(eventingClient, "create", "--namespace", testNs, "--type", cetype) + assert.Assert(t, util.ContainsAll(err.Error(), "requires", "eventtype", "name")) +} + +func TestEventTypeCreateWithSource(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + url, _ := apis.ParseURL(testSource) + eventingRecorder := eventingClient.Recorder() + eventingRecorder.CreateEventtype(createEventtypeWithSource(eventtypeName, cetype, testNs, url), nil) + + out, err := executeEventtypeCommand(eventingClient, "create", eventtypeName, "--type", cetype, "--source", testSource, "--namespace", testNs) + + assert.NilError(t, err, "Eventtype should be created") + assert.Assert(t, util.ContainsAll(out, "Eventtype", eventtypeName, "created", "namespace", testNs)) + + eventingRecorder.Validate() + +} + +func TestEventTypeCreateWithSourceError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + _, err := executeEventtypeCommand(eventingClient, "create", eventtypeName, "--type", cetype, "--source", testSourceError, "--namespace", testNs) + + assert.ErrorContains(t, err, "cannot create eventtype") + assert.Assert(t, util.ContainsAll(err.Error(), "invalid", "character", "URL")) +} + +func TestEventTypeCreateWithBroker(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + eventingRecorder := eventingClient.Recorder() + eventingRecorder.CreateEventtype(createEventtypeWithBroker(eventtypeName, cetype, testBroker, testNs), nil) + + out, err := executeEventtypeCommand(eventingClient, "create", eventtypeName, "--type", cetype, "--namespace", testNs, "--broker", testBroker) + assert.NilError(t, err, "Eventtype should be created") + assert.Assert(t, util.ContainsAll(out, "Eventtype", eventtypeName, "created", "namespace", testNs)) + + eventingRecorder.Validate() +} + +func TestEventTypeCreateWithError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + eventingRecorder := eventingClient.Recorder() + eventingRecorder.CreateEventtype(createEventtype(eventtypeName, cetype, testNs), fmt.Errorf("mock-error")) + + _, err := executeEventtypeCommand(eventingClient, "create", eventtypeName, "--type", cetype, "--namespace", testNs) + + assert.ErrorContains(t, err, "cannot create eventtype") + assert.Assert(t, util.ContainsAll(err.Error(), "mock-error")) + + eventingRecorder.Validate() +} diff --git a/pkg/kn/commands/eventtype/delete.go b/pkg/kn/commands/eventtype/delete.go new file mode 100644 index 000000000..b3497d0ad --- /dev/null +++ b/pkg/kn/commands/eventtype/delete.go @@ -0,0 +1,70 @@ +/* +Copyright 2022 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 eventtype + +import ( + "errors" + "fmt" + + "github.com/spf13/cobra" + "knative.dev/client/pkg/kn/commands" +) + +var deleteExample = ` + # Delete eventtype 'myeventtype' in the current namespace + kn eventtype delete myeventtype + + # Delete eventtype 'myeventtype' in the 'myproject' namespace + kn eventtype delete myeventtype --namespace myproject +` + +// NewEventtypeDeleteCommand represents command to describe the details of an eventtype instance +func NewEventtypeDeleteCommand(p *commands.KnParams) *cobra.Command { + + cmd := &cobra.Command{ + Use: "delete", + Short: "Delete eventtype", + Example: deleteExample, + ValidArgsFunction: commands.ResourceNameCompletionFunc(p), + RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) != 1 { + return errors.New("'eventtype delete' requires the eventtype name given as single argument") + } + name := args[0] + + namespace, err := p.GetNamespace(cmd) + if err != nil { + return err + } + + eventingV1Beta1Client, err := p.NewEventingV1beta1Client(namespace) + if err != nil { + return err + } + err = eventingV1Beta1Client.DeleteEventtype(cmd.Context(), name) + if err != nil { + return fmt.Errorf( + "cannot delete eventtype '%s' in namespace '%s' "+ + "because: %s", name, namespace, err) + } + fmt.Fprintf(cmd.OutOrStdout(), "Eventtype '%s' successfully deleted in namespace '%s'.\n", args[0], namespace) + return nil + }, + } + commands.AddNamespaceFlags(cmd.Flags(), false) + return cmd +} diff --git a/pkg/kn/commands/eventtype/delete_test.go b/pkg/kn/commands/eventtype/delete_test.go new file mode 100644 index 000000000..9d2aaa539 --- /dev/null +++ b/pkg/kn/commands/eventtype/delete_test.go @@ -0,0 +1,63 @@ +/* +Copyright 2022 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 eventtype + +import ( + "fmt" + "testing" + + "gotest.tools/v3/assert" + "knative.dev/client/pkg/eventing/v1beta1" + "knative.dev/client/pkg/util" +) + +func TestEventtypeDelete(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + eventingRecorder := eventingClient.Recorder() + eventingRecorder.DeleteEventtype(eventtypeName, nil) + + out, err := executeEventtypeCommand(eventingClient, "delete", eventtypeName, "--namespace", testNs) + + assert.NilError(t, err, "Eventtype should be deleted") + assert.Assert(t, util.ContainsAll(out, "Eventtype", eventtypeName, "successfully", "deleted", "namespace", testNs)) + + eventingRecorder.Validate() +} + +func TestEventtypeDeleteWithError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, "default") + + eventingRecorder := eventingClient.Recorder() + eventingRecorder.DeleteEventtype(eventtypeName, fmt.Errorf("mock-error")) + + _, err := executeEventtypeCommand(eventingClient, "delete", eventtypeName) + + assert.ErrorContains(t, err, "cannot delete eventtype") + assert.Assert(t, util.ContainsAll(err.Error(), "mock-error")) + + eventingRecorder.Validate() +} + +func TestEventtypeDeleteWithNameMissingError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, "default") + + _, err := executeEventtypeCommand(eventingClient, "delete") + + assert.ErrorContains(t, err, "eventtype delete") + assert.Assert(t, util.ContainsAll(err.Error(), "eventtype", "delete", "requires", "name")) +} diff --git a/pkg/kn/commands/eventtype/describe.go b/pkg/kn/commands/eventtype/describe.go new file mode 100644 index 000000000..ef10f7f66 --- /dev/null +++ b/pkg/kn/commands/eventtype/describe.go @@ -0,0 +1,110 @@ +/* +Copyright 2022 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 eventtype + +import ( + "errors" + "fmt" + "io" + "strings" + + "github.com/spf13/cobra" + "k8s.io/cli-runtime/pkg/genericclioptions" + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + + "knative.dev/client/pkg/kn/commands" + "knative.dev/client/pkg/printers" +) + +var describeExample = ` + # Describe eventtype 'myeventtype' in the current namespace + kn eventtype describe myeventtype + + # Describe eventtype 'myeventtype' in the 'myproject' namespace + kn eventtype describe myeventtype --namespace myproject + + # Describe eventtype 'myeventtype' in YAML format + kn eventtype describe myeventtype -o yaml` + +// NewEventtypeDescribeCommand represents command to describe the details of an eventtype instance +func NewEventtypeDescribeCommand(p *commands.KnParams) *cobra.Command { + + // For machine readable output + machineReadablePrintFlags := genericclioptions.NewPrintFlags("") + + cmd := &cobra.Command{ + Use: "describe", + Short: "Describe eventtype", + Example: describeExample, + ValidArgsFunction: commands.ResourceNameCompletionFunc(p), + RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) != 1 { + return errors.New("'eventtype describe' requires the eventtype name given as single argument") + } + name := args[0] + + namespace, err := p.GetNamespace(cmd) + if err != nil { + return err + } + + eventingV1Beta1Client, err := p.NewEventingV1beta1Client(namespace) + if err != nil { + return err + } + + eventtype, err := eventingV1Beta1Client.GetEventtype(cmd.Context(), name) + if err != nil { + return err + } + + out := cmd.OutOrStdout() + + if machineReadablePrintFlags.OutputFlagSpecified() { + printer, err := machineReadablePrintFlags.ToPrinter() + if err != nil { + return err + } + return printer.PrintObj(eventtype, out) + } + return describeEventtype(out, eventtype, false) + }, + } + commands.AddNamespaceFlags(cmd.Flags(), false) + machineReadablePrintFlags.AddFlags(cmd) + cmd.Flag("output").Usage = fmt.Sprintf("Output format. One of: %s.", strings.Join(machineReadablePrintFlags.AllowedFormats(), "|")) + return cmd +} + +// describeEventtype prints eventtype details to the provided output writer +func describeEventtype(out io.Writer, eventtype *eventingv1beta1.EventType, printDetails bool) error { + var source string + if eventtype.Spec.Source != nil { + source = eventtype.Spec.Source.String() + } + dw := printers.NewPrefixWriter(out) + commands.WriteMetadata(dw, &eventtype.ObjectMeta, printDetails) + dw.WriteAttribute("Source", source) + dw.WriteAttribute("Broker", eventtype.Spec.Broker) + dw.WriteLine() + dw.WriteLine() + commands.WriteConditions(dw, eventtype.Status.Conditions, printDetails) + if err := dw.Flush(); err != nil { + return err + } + return nil +} diff --git a/pkg/kn/commands/eventtype/describe_test.go b/pkg/kn/commands/eventtype/describe_test.go new file mode 100644 index 000000000..05a2713fe --- /dev/null +++ b/pkg/kn/commands/eventtype/describe_test.go @@ -0,0 +1,136 @@ +/* +Copyright 2022 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 eventtype + +import ( + "encoding/json" + "fmt" + "testing" + + "gotest.tools/v3/assert" + "gotest.tools/v3/assert/cmp" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/client/pkg/eventing/v1beta1" + "knative.dev/client/pkg/util" + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +func TestEventtypeDescribe(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + eventingRecorder := eventingClient.Recorder() + eventingRecorder.GetEventtype(eventtypeName, getEventtype(eventtypeName, testNs), nil) + + out, err := executeEventtypeCommand(eventingClient, "describe", eventtypeName, "--namespace", testNs) + + assert.NilError(t, err) + + assert.Assert(t, cmp.Regexp(fmt.Sprintf("Name:\\s+%s", eventtypeName), out)) + assert.Assert(t, cmp.Regexp(fmt.Sprintf("Namespace:\\s+%s", testNs), out)) + assert.Assert(t, cmp.Regexp(fmt.Sprintf("Source:\\s+%s", testSource), out)) + assert.Assert(t, cmp.Regexp(fmt.Sprintf("Broker:\\s+%s", testBroker), out)) + + assert.Assert(t, util.ContainsAll(out, "Conditions:", "Ready", "BrokerReady", "BrokerExists")) + + eventingRecorder.Validate() +} + +func TestEventtypeDescribeError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + eventingRecorder := eventingClient.Recorder() + eventingRecorder.GetEventtype(eventtypeName, getEventtype(eventtypeName, testNs), fmt.Errorf("mock-error")) + + _, err := executeEventtypeCommand(eventingClient, "describe", eventtypeName, "--namespace", testNs) + + assert.Error(t, err, "mock-error") + + eventingRecorder.Validate() +} + +func TestEventtypeDescribeWithNameMissingWithError(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + _, err := executeEventtypeCommand(eventingClient, "describe", "--namespace", testNs) + + assert.ErrorContains(t, err, "eventtype describe") + assert.Assert(t, util.ContainsAll(err.Error(), "requires", "eventtype", "name")) +} + +func TestEventtypeDescribeMachineReadable(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + eventingRecorder := eventingClient.Recorder() + + eventtype := getEventtype(eventtypeName, testNs) + + // json + eventingRecorder.GetEventtype(eventtypeName, eventtype, nil) + out, err := executeEventtypeCommand(eventingClient, "describe", eventtypeName, "--namespace", testNs, "-o", "json") + + assert.NilError(t, err) + result := &eventingv1beta1.EventType{} + err = json.Unmarshal([]byte(out), result) + assert.NilError(t, err) + assert.DeepEqual(t, eventtype, result) + + // yaml + eventingRecorder.GetEventtype(eventtypeName, eventtype, nil) + out, err = executeEventtypeCommand(eventingClient, "describe", eventtypeName, "--namespace", testNs, "-o", "yaml") + + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(out, "kind: EventType", "spec:", "status:", "metadata:")) + + eventingRecorder.Validate() +} + +func getEventtype(name string, ns string) *eventingv1beta1.EventType { + source, _ := apis.ParseURL(testSource) + return &eventingv1beta1.EventType{ + TypeMeta: metav1.TypeMeta{ + Kind: "EventType", + APIVersion: eventingv1beta1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: ns, + }, + Spec: eventingv1beta1.EventTypeSpec{ + Type: cetype, + Source: source, + Broker: testBroker, + }, + Status: eventingv1beta1.EventTypeStatus{ + Status: duckv1.Status{ + Conditions: duckv1.Conditions{ + apis.Condition{ + Type: "BrokerExists", + Status: "True", + }, + apis.Condition{ + Type: "BrokerReady", + Status: "True", + }, + apis.Condition{ + Type: "Ready", + Status: "True", + }, + }, + }, + }, + } +} diff --git a/pkg/kn/commands/eventtype/eventtype.go b/pkg/kn/commands/eventtype/eventtype.go new file mode 100644 index 000000000..4e2ab0ca2 --- /dev/null +++ b/pkg/kn/commands/eventtype/eventtype.go @@ -0,0 +1,37 @@ +/* +Copyright 2022 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 eventtype + +import ( + "github.com/spf13/cobra" + + "knative.dev/client/pkg/kn/commands" +) + +// NewEventTypeCommand represents event type management commands +func NewEventTypeCommand(p *commands.KnParams) *cobra.Command { + eventCmd := &cobra.Command{ + Use: "eventtype", + Short: "Manage eventtypes", + Aliases: []string{"eventtypes"}, + } + eventCmd.AddCommand(NewEventtypeListCommand(p)) + eventCmd.AddCommand(NewEventtypeDescribeCommand(p)) + eventCmd.AddCommand(NewEventtypeCreateCommand(p)) + eventCmd.AddCommand(NewEventtypeDeleteCommand(p)) + return eventCmd +} diff --git a/pkg/kn/commands/eventtype/eventtype_test.go b/pkg/kn/commands/eventtype/eventtype_test.go new file mode 100644 index 000000000..3ac4a98aa --- /dev/null +++ b/pkg/kn/commands/eventtype/eventtype_test.go @@ -0,0 +1,94 @@ +/* +Copyright 2022 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 eventtype + +import ( + "bytes" + + "k8s.io/client-go/tools/clientcmd" + "knative.dev/client/pkg/eventing/v1beta1" + "knative.dev/client/pkg/kn/commands" + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + "knative.dev/pkg/apis" +) + +// Helper methods +var blankConfig clientcmd.ClientConfig + +const ( + eventtypeName = "foo" + testNs = "test-ns" + cetype = "foo.type" + testSource = "https://test-source.com" + testSourceError = "bad-source\b" + testBroker = "test-broker" +) + +func init() { + var err error + blankConfig, err = clientcmd.NewClientConfigFromBytes([]byte(`kind: Config +version: v1 +users: +- name: u +clusters: +- name: c + cluster: + server: example.com +contexts: +- name: x + context: + user: u + cluster: c +current-context: x +`)) + if err != nil { + panic(err) + } +} + +func createEventtype(eventtypeName, ceType, namespace string) *eventingv1beta1.EventType { + return v1beta1.NewEventtypeBuilder(eventtypeName).Namespace(namespace).Type(ceType).Build() +} + +func createEventtypeWithSource(eventtypeName, ceType, namespace string, source *apis.URL) *eventingv1beta1.EventType { + return v1beta1.NewEventtypeBuilder(eventtypeName).Namespace(namespace).Type(ceType).Source(source).Build() +} + +func createEventtypeWithBroker(name, cetype, broker, namespace string) *eventingv1beta1.EventType { + return v1beta1.NewEventtypeBuilder(eventtypeName).Namespace(namespace).Type(cetype).Broker(broker).Build() +} + +func executeEventtypeCommand(client *v1beta1.MockKnEventingV1beta1Client, args ...string) (string, error) { + + knParams := &commands.KnParams{} + knParams.ClientConfig = blankConfig + + output := new(bytes.Buffer) + knParams.Output = output + + knParams.NewEventingV1beta1Client = func(namespace string) (v1beta1.KnEventingV1Beta1Client, error) { + return client, nil + } + + cmd := NewEventTypeCommand(knParams) + cmd.SetArgs(args) + cmd.SetOut(output) + + err := cmd.Execute() + + return output.String(), err +} diff --git a/pkg/kn/commands/eventtype/list.go b/pkg/kn/commands/eventtype/list.go new file mode 100644 index 000000000..86115f7de --- /dev/null +++ b/pkg/kn/commands/eventtype/list.go @@ -0,0 +1,135 @@ +/* +Copyright 2022 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 eventtype + +import ( + "fmt" + + "github.com/spf13/cobra" + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + + metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" + "k8s.io/apimachinery/pkg/runtime" + + "knative.dev/client/pkg/kn/commands" + "knative.dev/client/pkg/kn/commands/flags" + hprinters "knative.dev/client/pkg/printers" +) + +var listExample = ` + # List all eventtypes + kn eventtype list + + # List all eventtypes in JSON output format + kn eventtype list -o json` + +// NewEventtypeListCommand represents command to list all eventtypes +func NewEventtypeListCommand(p *commands.KnParams) *cobra.Command { + listFlags := flags.NewListPrintFlags(ListHandlers) + + cmd := &cobra.Command{ + Use: "list", + Short: "List eventtypes", + Aliases: []string{"ls"}, + Example: listExample, + RunE: func(cmd *cobra.Command, args []string) (err error) { + namespace, err := p.GetNamespace(cmd) + if err != nil { + return err + } + + eventingV1Beta1Client, err := p.NewEventingV1beta1Client(namespace) + if err != nil { + return err + } + + eventTypeList, err := eventingV1Beta1Client.ListEventtypes(cmd.Context()) + if err != nil { + return err + } + if !listFlags.GenericPrintFlags.OutputFlagSpecified() && len(eventTypeList.Items) == 0 { + fmt.Fprintf(cmd.OutOrStdout(), "No eventtypes found.\n") + return nil + } + + // empty namespace indicates all-namespaces flag is specified + if namespace == "" { + listFlags.EnsureWithNamespace() + } + + err = listFlags.Print(eventTypeList, cmd.OutOrStdout()) + if err != nil { + return err + } + return nil + }, + } + commands.AddNamespaceFlags(cmd.Flags(), true) + listFlags.AddFlags(cmd) + return cmd +} + +// ListHandlers handles printing human readable table for `kn eventtype list` command's output +func ListHandlers(h hprinters.PrintHandler) { + eventTypeColumnDefinitions := []metav1beta1.TableColumnDefinition{ + {Name: "Namespace", Type: "string", Description: "Namespace of the EventType instance", Priority: 0}, + {Name: "Name", Type: "string", Description: "Name of the EventType instance", Priority: 1}, + {Name: "Type", Type: "string", Description: "Type of the EventType instance", Priority: 1}, + {Name: "Source", Type: "string", Description: "Source of the EventType instance", Priority: 1}, + {Name: "Broker", Type: "string", Description: "Broker of the EventType instance", Priority: 1}, + {Name: "Age", Type: "string", Description: "Age of the EventType instance", Priority: 1}, + {Name: "Ready", Type: "string", Description: "Ready state of the EventType instance", Priority: 1}, + } + h.TableHandler(eventTypeColumnDefinitions, printEventType) + h.TableHandler(eventTypeColumnDefinitions, printEventTypeList) +} + +// printEventTypeList populates the eventtype list table rows +func printEventTypeList(eventTypeList *eventingv1beta1.EventTypeList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) { + rows := make([]metav1beta1.TableRow, 0, len(eventTypeList.Items)) + + for i := range eventTypeList.Items { + eventType := &eventTypeList.Items[i] + r, err := printEventType(eventType, options) + if err != nil { + return nil, err + } + rows = append(rows, r...) + } + return rows, nil +} + +// printEventType populates the eventtype table rows +func printEventType(eventType *eventingv1beta1.EventType, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) { + name := eventType.Name + age := commands.TranslateTimestampSince(eventType.CreationTimestamp) + cetype := eventType.Spec.Type + source := eventType.Spec.Source + broker := eventType.Spec.Broker + ready := commands.ReadyCondition(eventType.Status.Conditions) + + row := metav1beta1.TableRow{ + Object: runtime.RawExtension{Object: eventType}, + } + + if options.AllNamespaces { + row.Cells = append(row.Cells, eventType.Namespace) + } + + row.Cells = append(row.Cells, name, cetype, source, broker, age, ready) + return []metav1beta1.TableRow{row}, nil +} diff --git a/pkg/kn/commands/eventtype/list_test.go b/pkg/kn/commands/eventtype/list_test.go new file mode 100644 index 000000000..61b92f48b --- /dev/null +++ b/pkg/kn/commands/eventtype/list_test.go @@ -0,0 +1,100 @@ +/* +Copyright 2022 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 eventtype + +import ( + "encoding/json" + "strings" + "testing" + + "gotest.tools/v3/assert" + "knative.dev/client/pkg/eventing/v1beta1" + "knative.dev/client/pkg/util" + eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +func TestEventtypeList(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + eventingRecorder := eventingClient.Recorder() + + eventtype1 := getEventtype("foo1", testNs) + eventtype2 := getEventtype("foo2", testNs) + eventtype3 := getEventtype("foo3", testNs) + + eventtypeList := &eventingv1beta1.EventTypeList{Items: []eventingv1beta1.EventType{*eventtype1, *eventtype2, *eventtype3}} + + util.UpdateGroupVersionKindWithScheme(eventtypeList, eventingv1beta1.SchemeGroupVersion, scheme.Scheme) + + t.Run("default output", func(t *testing.T) { + eventingRecorder.ListEventtypes(eventtypeList, nil) + + output, err := executeEventtypeCommand(eventingClient, "list") + assert.NilError(t, err) + + outputLines := strings.Split(output, "\n") + assert.Check(t, util.ContainsAll(outputLines[0], "NAME", "T", "SOURCE", "BROKER", "AGE", "READY")) + assert.Check(t, util.ContainsAll(outputLines[1], "foo1", cetype, testBroker, testSource, "True")) + assert.Check(t, util.ContainsAll(outputLines[2], "foo2", cetype, testBroker, testSource, "True")) + assert.Check(t, util.ContainsAll(outputLines[3], "foo3", cetype, testBroker, testSource, "True")) + + eventingRecorder.Validate() + }) + + t.Run("json format output", func(t *testing.T) { + eventingRecorder.ListEventtypes(eventtypeList, nil) + + output, err := executeEventtypeCommand(eventingClient, "list", "-o", "json") + assert.NilError(t, err) + + result := eventingv1beta1.EventTypeList{} + err = json.Unmarshal([]byte(output), &result) + assert.NilError(t, err) + assert.DeepEqual(t, eventtypeList.Items, result.Items) + + eventingRecorder.Validate() + }) + + t.Run("all namespaces", func(t *testing.T) { + eventingRecorder.ListEventtypes(eventtypeList, nil) + + output, err := executeEventtypeCommand(eventingClient, "list", "--all-namespaces") + assert.NilError(t, err) + + outputLines := strings.Split(output, "\n") + assert.Check(t, util.ContainsAll(outputLines[0], "NAMESPACE", "NAME", "T", "SOURCE", "BROKER", "AGE", "READY")) + assert.Check(t, util.ContainsAll(outputLines[1], "foo1", testNs, cetype, testBroker, testSource, "True")) + assert.Check(t, util.ContainsAll(outputLines[2], "foo2", testNs, cetype, testBroker, testSource, "True")) + assert.Check(t, util.ContainsAll(outputLines[3], "foo3", testNs, cetype, testBroker, testSource, "True")) + + eventingRecorder.Validate() + }) +} + +func TestEventtypeListEmpty(t *testing.T) { + eventingClient := v1beta1.NewMockKnEventingV1beta1Client(t, testNs) + + eventingRecorder := eventingClient.Recorder() + + eventingRecorder.ListEventtypes(&eventingv1beta1.EventTypeList{}, nil) + output, err := executeEventtypeCommand(eventingClient, "list") + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(output, "No", "eventtypes", "found")) + + eventingRecorder.Validate() +} diff --git a/pkg/kn/commands/flags/eventtype.go b/pkg/kn/commands/flags/eventtype.go new file mode 100644 index 000000000..353383302 --- /dev/null +++ b/pkg/kn/commands/flags/eventtype.go @@ -0,0 +1,30 @@ +// Copyright © 2022 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 "github.com/spf13/cobra" + +type EventtypeFlags struct { + Type string + Source string + Broker string +} + +func (e *EventtypeFlags) Add(cmd *cobra.Command) { + cmd.Flags().StringVarP(&e.Type, "type", "t", "", "Cloud Event type") + cmd.Flags().StringVar(&e.Source, "source", "", "Cloud Event source") + cmd.Flags().StringVarP(&e.Broker, "broker", "b", "", "Cloud Event broker") + cmd.MarkFlagRequired("type") +} diff --git a/pkg/kn/commands/flags/eventtype_test.go b/pkg/kn/commands/flags/eventtype_test.go new file mode 100644 index 000000000..617a64ede --- /dev/null +++ b/pkg/kn/commands/flags/eventtype_test.go @@ -0,0 +1,50 @@ +// Copyright © 2022 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" + + "github.com/spf13/cobra" + "gotest.tools/v3/assert" +) + +func TestEventtypeFlags_Add(t *testing.T) { + eventtypeCmd := &cobra.Command{ + Use: "kn", + Short: "Eventtype test kn command", + Run: func(cmd *cobra.Command, args []string) {}, + } + + eventtypeFlags := &EventtypeFlags{} + eventtypeFlags.Add(eventtypeCmd) + + eventtypeCmd.SetArgs([]string{"--type", "cetype", "--broker", "example-broker", "--source", "example.source"}) + eventtypeCmd.Execute() + + flagList := eventtypeCmd.Flags() + + val, err := flagList.GetString("type") + assert.NilError(t, err) + assert.Equal(t, val, "cetype") + + val, err = flagList.GetString("broker") + assert.NilError(t, err) + assert.Equal(t, val, "example-broker") + + val, err = flagList.GetString("source") + assert.NilError(t, err) + assert.Equal(t, val, "example.source") +} diff --git a/pkg/kn/commands/types.go b/pkg/kn/commands/types.go index f999cf114..eaec4f5fb 100644 --- a/pkg/kn/commands/types.go +++ b/pkg/kn/commands/types.go @@ -25,6 +25,7 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" eventingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1" + eventingv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1" messagingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" sourcesv1client "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1" sourcesv1beta2client "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1beta2" @@ -36,6 +37,7 @@ import ( clientdynamic "knative.dev/client/pkg/dynamic" knerrors "knative.dev/client/pkg/errors" clienteventingv1 "knative.dev/client/pkg/eventing/v1" + clienteventingv1beta1 "knative.dev/client/pkg/eventing/v1beta1" clientmessagingv1 "knative.dev/client/pkg/messaging/v1" clientservingv1 "knative.dev/client/pkg/serving/v1" clientservingv1alpha1 "knative.dev/client/pkg/serving/v1alpha1" @@ -58,6 +60,7 @@ type KnParams struct { NewEventingClient func(namespace string) (clienteventingv1.KnEventingClient, error) NewMessagingClient func(namespace string) (clientmessagingv1.KnMessagingClient, error) NewDynamicClient func(namespace string) (clientdynamic.KnDynamicClient, error) + NewEventingV1beta1Client func(namespace string) (clienteventingv1beta1.KnEventingV1Beta1Client, error) // General global options LogHTTP bool @@ -98,6 +101,10 @@ func (params *KnParams) Initialize() { if params.NewSourcesV1beta2Client == nil { params.NewSourcesV1beta2Client = params.newSourcesClientV1beta2 } + + if params.NewEventingV1beta1Client == nil { + params.NewEventingV1beta1Client = params.newEventingV1Beta1Client + } } func (params *KnParams) newServingClient(namespace string) (clientservingv1.KnServingClient, error) { @@ -160,6 +167,16 @@ func (params *KnParams) newEventingClient(namespace string) (clienteventingv1.Kn return clienteventingv1.NewKnEventingClient(client, namespace), nil } +func (params *KnParams) newEventingV1Beta1Client(namespace string) (clienteventingv1beta1.KnEventingV1Beta1Client, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, _ := eventingv1beta1.NewForConfig(restConfig) + return clienteventingv1beta1.NewKnEventingV1Beta1Client(client, namespace), nil +} + func (params *KnParams) newMessagingClient(namespace string) (clientmessagingv1.KnMessagingClient, error) { restConfig, err := params.RestConfig() if err != nil { diff --git a/pkg/kn/commands/types_test.go b/pkg/kn/commands/types_test.go index 932624714..938f89bea 100644 --- a/pkg/kn/commands/types_test.go +++ b/pkg/kn/commands/types_test.go @@ -447,6 +447,7 @@ func TestInitialize(t *testing.T) { assert.Assert(t, params.NewEventingClient != nil) assert.Assert(t, params.NewMessagingClient != nil) assert.Assert(t, params.NewDynamicClient != nil) + assert.Assert(t, params.NewEventingV1beta1Client != nil) basic, err := clientcmd.NewClientConfigFromBytes([]byte(BASIC_KUBECONFIG)) if err != nil { @@ -474,4 +475,8 @@ func TestInitialize(t *testing.T) { sourcesClient, err := params.NewSourcesClient("mockNamespace") assert.NilError(t, err) assert.Assert(t, sourcesClient != nil) + + eventingBeta1Client, err := params.NewEventingV1beta1Client("mockNamespace") + assert.NilError(t, err) + assert.Assert(t, eventingBeta1Client != nil) } diff --git a/pkg/kn/root/root.go b/pkg/kn/root/root.go index a9147e66f..4dc2f831f 100644 --- a/pkg/kn/root/root.go +++ b/pkg/kn/root/root.go @@ -23,6 +23,7 @@ import ( "text/template" "knative.dev/client/pkg/kn/commands/container" + "knative.dev/client/pkg/kn/commands/eventtype" "knative.dev/client/pkg/kn/commands/domain" @@ -108,6 +109,7 @@ Find more information about Knative at: https://knative.dev`, rootName), trigger.NewTriggerCommand(p), channel.NewChannelCommand(p), subscription.NewSubscriptionCommand(p), + eventtype.NewEventTypeCommand(p), }, }, { diff --git a/test/e2e/eventtype_test.go b/test/e2e/eventtype_test.go new file mode 100644 index 000000000..917239106 --- /dev/null +++ b/test/e2e/eventtype_test.go @@ -0,0 +1,75 @@ +// Copyright © 2022 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. + +//go:build e2e && !serving +// +build e2e,!serving + +package e2e + +import ( + "testing" + + "gotest.tools/v3/assert" + "knative.dev/client/lib/test" + "knative.dev/client/pkg/util" +) + +const ( + testName = "test-eventtype" + testName1 = "test-eventtype-1" + testName2 = "test-eventtype-2" + testName3 = "test-eventtype-3" + testType = "test.type" + testBroker = "test-broker" + testSource = "test.source.com" + testSourceBad = "test.source.com\b" +) + +func TestEventtype(t *testing.T) { + t.Parallel() + it, err := test.NewKnTest() + assert.NilError(t, err) + defer func() { + assert.NilError(t, it.Teardown()) + }() + + r := test.NewKnRunResultCollector(t, it) + defer r.DumpIfFailed() + + t.Log("create eventtype, list, describe, and delete it") + test.EventtypeCreate(r, testName, testType) + test.EventtypeList(r, testName) + test.EventtypeDescribe(r, testName) + test.EventtypeDelete(r, testName) + verifyEventtypeNotfound(r, testName) + + t.Log("create eventtype with broker and source") + test.EventtypeCreateWithBrokerSource(r, testName, testType, testBroker, testSource) + test.EventtypeList(r, testName) + + t.Log("create multiple eventtypes and list them") + test.EventtypeCreate(r, testName1, testType) + test.EventtypeCreate(r, testName2, testType) + test.EventtypeCreate(r, testName3, testType) + test.EventtypeList(r, testName1, testName2, testName3) + + t.Log("create eventtype with invalid source") + test.EventtypeCreateWithSourceError(r, testName, testType, testSourceBad) +} + +func verifyEventtypeNotfound(r *test.KnRunResultCollector, name string) { + out := r.KnTest().Kn().Run("eventtype", "describe", name) + r.AssertError(out) + assert.Check(r.T(), util.ContainsAll(out.Stderr, name, "not found")) +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/doc.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/doc.go new file mode 100644 index 000000000..8d5037f07 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2021 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta1 diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/eventing_client.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/eventing_client.go new file mode 100644 index 000000000..9787f6e43 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/eventing_client.go @@ -0,0 +1,89 @@ +/* +Copyright 2021 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + rest "k8s.io/client-go/rest" + v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +type EventingV1beta1Interface interface { + RESTClient() rest.Interface + EventTypesGetter +} + +// EventingV1beta1Client is used to interact with features provided by the eventing.knative.dev group. +type EventingV1beta1Client struct { + restClient rest.Interface +} + +func (c *EventingV1beta1Client) EventTypes(namespace string) EventTypeInterface { + return newEventTypes(c, namespace) +} + +// NewForConfig creates a new EventingV1beta1Client for the given config. +func NewForConfig(c *rest.Config) (*EventingV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &EventingV1beta1Client{client}, nil +} + +// NewForConfigOrDie creates a new EventingV1beta1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *EventingV1beta1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new EventingV1beta1Client for the given RESTClient. +func New(c rest.Interface) *EventingV1beta1Client { + return &EventingV1beta1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1beta1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *EventingV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/eventtype.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/eventtype.go new file mode 100644 index 000000000..a085376f9 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/eventtype.go @@ -0,0 +1,195 @@ +/* +Copyright 2021 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" + scheme "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +// EventTypesGetter has a method to return a EventTypeInterface. +// A group's client should implement this interface. +type EventTypesGetter interface { + EventTypes(namespace string) EventTypeInterface +} + +// EventTypeInterface has methods to work with EventType resources. +type EventTypeInterface interface { + Create(ctx context.Context, eventType *v1beta1.EventType, opts v1.CreateOptions) (*v1beta1.EventType, error) + Update(ctx context.Context, eventType *v1beta1.EventType, opts v1.UpdateOptions) (*v1beta1.EventType, error) + UpdateStatus(ctx context.Context, eventType *v1beta1.EventType, opts v1.UpdateOptions) (*v1beta1.EventType, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.EventType, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.EventTypeList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.EventType, err error) + EventTypeExpansion +} + +// eventTypes implements EventTypeInterface +type eventTypes struct { + client rest.Interface + ns string +} + +// newEventTypes returns a EventTypes +func newEventTypes(c *EventingV1beta1Client, namespace string) *eventTypes { + return &eventTypes{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the eventType, and returns the corresponding eventType object, and an error if there is any. +func (c *eventTypes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.EventType, err error) { + result = &v1beta1.EventType{} + err = c.client.Get(). + Namespace(c.ns). + Resource("eventtypes"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of EventTypes that match those selectors. +func (c *eventTypes) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.EventTypeList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.EventTypeList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("eventtypes"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested eventTypes. +func (c *eventTypes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("eventtypes"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a eventType and creates it. Returns the server's representation of the eventType, and an error, if there is any. +func (c *eventTypes) Create(ctx context.Context, eventType *v1beta1.EventType, opts v1.CreateOptions) (result *v1beta1.EventType, err error) { + result = &v1beta1.EventType{} + err = c.client.Post(). + Namespace(c.ns). + Resource("eventtypes"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eventType). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a eventType and updates it. Returns the server's representation of the eventType, and an error, if there is any. +func (c *eventTypes) Update(ctx context.Context, eventType *v1beta1.EventType, opts v1.UpdateOptions) (result *v1beta1.EventType, err error) { + result = &v1beta1.EventType{} + err = c.client.Put(). + Namespace(c.ns). + Resource("eventtypes"). + Name(eventType.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eventType). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *eventTypes) UpdateStatus(ctx context.Context, eventType *v1beta1.EventType, opts v1.UpdateOptions) (result *v1beta1.EventType, err error) { + result = &v1beta1.EventType{} + err = c.client.Put(). + Namespace(c.ns). + Resource("eventtypes"). + Name(eventType.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eventType). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the eventType and deletes it. Returns an error if one occurs. +func (c *eventTypes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("eventtypes"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *eventTypes) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("eventtypes"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched eventType. +func (c *eventTypes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.EventType, err error) { + result = &v1beta1.EventType{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("eventtypes"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/doc.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/doc.go new file mode 100644 index 000000000..d5a46ef55 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2021 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/fake_eventing_client.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/fake_eventing_client.go new file mode 100644 index 000000000..0a6b788fc --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/fake_eventing_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2021 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1" +) + +type FakeEventingV1beta1 struct { + *testing.Fake +} + +func (c *FakeEventingV1beta1) EventTypes(namespace string) v1beta1.EventTypeInterface { + return &FakeEventTypes{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeEventingV1beta1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/fake_eventtype.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/fake_eventtype.go new file mode 100644 index 000000000..7d47cc795 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake/fake_eventtype.go @@ -0,0 +1,142 @@ +/* +Copyright 2021 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" +) + +// FakeEventTypes implements EventTypeInterface +type FakeEventTypes struct { + Fake *FakeEventingV1beta1 + ns string +} + +var eventtypesResource = schema.GroupVersionResource{Group: "eventing.knative.dev", Version: "v1beta1", Resource: "eventtypes"} + +var eventtypesKind = schema.GroupVersionKind{Group: "eventing.knative.dev", Version: "v1beta1", Kind: "EventType"} + +// Get takes name of the eventType, and returns the corresponding eventType object, and an error if there is any. +func (c *FakeEventTypes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.EventType, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(eventtypesResource, c.ns, name), &v1beta1.EventType{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.EventType), err +} + +// List takes label and field selectors, and returns the list of EventTypes that match those selectors. +func (c *FakeEventTypes) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.EventTypeList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(eventtypesResource, eventtypesKind, c.ns, opts), &v1beta1.EventTypeList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.EventTypeList{ListMeta: obj.(*v1beta1.EventTypeList).ListMeta} + for _, item := range obj.(*v1beta1.EventTypeList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested eventTypes. +func (c *FakeEventTypes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(eventtypesResource, c.ns, opts)) + +} + +// Create takes the representation of a eventType and creates it. Returns the server's representation of the eventType, and an error, if there is any. +func (c *FakeEventTypes) Create(ctx context.Context, eventType *v1beta1.EventType, opts v1.CreateOptions) (result *v1beta1.EventType, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(eventtypesResource, c.ns, eventType), &v1beta1.EventType{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.EventType), err +} + +// Update takes the representation of a eventType and updates it. Returns the server's representation of the eventType, and an error, if there is any. +func (c *FakeEventTypes) Update(ctx context.Context, eventType *v1beta1.EventType, opts v1.UpdateOptions) (result *v1beta1.EventType, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(eventtypesResource, c.ns, eventType), &v1beta1.EventType{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.EventType), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeEventTypes) UpdateStatus(ctx context.Context, eventType *v1beta1.EventType, opts v1.UpdateOptions) (*v1beta1.EventType, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(eventtypesResource, "status", c.ns, eventType), &v1beta1.EventType{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.EventType), err +} + +// Delete takes name of the eventType and deletes it. Returns an error if one occurs. +func (c *FakeEventTypes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(eventtypesResource, c.ns, name), &v1beta1.EventType{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeEventTypes) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(eventtypesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.EventTypeList{}) + return err +} + +// Patch applies the patch and returns the patched eventType. +func (c *FakeEventTypes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.EventType, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(eventtypesResource, c.ns, name, pt, data, subresources...), &v1beta1.EventType{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.EventType), err +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/generated_expansion.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/generated_expansion.go new file mode 100644 index 000000000..245a728f6 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2021 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +type EventTypeExpansion interface{} diff --git a/vendor/modules.txt b/vendor/modules.txt index 171b29935..536c824f0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -765,6 +765,8 @@ knative.dev/eventing/pkg/apis/sources/v1beta2 knative.dev/eventing/pkg/client/clientset/versioned/scheme knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1 knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1/fake +knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1 +knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1 knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1 knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1/fake