diff --git a/cmd/kn/main_test.go b/cmd/kn/main_test.go index 3b016fc79b..066582c92d 100644 --- a/cmd/kn/main_test.go +++ b/cmd/kn/main_test.go @@ -26,10 +26,10 @@ import ( "github.com/spf13/cobra" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" "knative.dev/client/pkg/kn/config" "knative.dev/client/pkg/kn/root" - "knative.dev/client/pkg/util" ) func TestValidatePlugin(t *testing.T) { diff --git a/go.mod b/go.mod index d27efa9c9d..44c74fe918 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,11 @@ module knative.dev/client go 1.21 +// TODO: remove when https://github.com/knative/client-pkg/pull/177 is merged +replace knative.dev/client-pkg => github.com/cardil/knative-client-pkg v0.0.0-20240416095801-87f6a5d7889a + +//replace knative.dev/client-pkg => ../knative-client-pkg + require ( github.com/google/go-cmp v0.6.0 github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -15,7 +20,7 @@ require ( golang.org/x/term v0.18.0 gotest.tools/v3 v3.3.0 k8s.io/api v0.29.2 - k8s.io/apiextensions-apiserver v0.29.2 + k8s.io/apiextensions-apiserver v0.29.2 // indirect k8s.io/apimachinery v0.29.2 k8s.io/cli-runtime v0.29.2 k8s.io/client-go v0.29.2 diff --git a/go.sum b/go.sum index 2e5d331c6d..3118d08192 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/cardil/knative-client-pkg v0.0.0-20240416095801-87f6a5d7889a h1:jca8T6JyUYzMkB6OeaJ1R1ETAFyjIiuIN8XNeO7eBUY= +github.com/cardil/knative-client-pkg v0.0.0-20240416095801-87f6a5d7889a/go.mod h1:PYodo1bmKTrxnNCfLJa6a8wdg3QQH0XTOPlZJwrY64A= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= @@ -839,8 +841,6 @@ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/A k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -knative.dev/client-pkg v0.0.0-20240327121233-6984d81a90ec h1:gG8AzUJDHrYONInTv0wm1gSPzWp3n8tooewl+yGpe/I= -knative.dev/client-pkg v0.0.0-20240327121233-6984d81a90ec/go.mod h1:PYodo1bmKTrxnNCfLJa6a8wdg3QQH0XTOPlZJwrY64A= knative.dev/eventing v0.40.1-0.20240327131403-47543259ceba h1:uX9UsYNHJQDpqVSMVijhSljmCSLZm5ocPdQJ4jrkyig= knative.dev/eventing v0.40.1-0.20240327131403-47543259ceba/go.mod h1:19sfPiy4dK2jBIHgszOTk43qOvfCXz1GTIncRY3trB8= knative.dev/hack v0.0.0-20240327150553-47368d631660 h1:tW6NgyjMnSXBS75+k+Xh5uNiLhJ9TFswS9hrkC3OQOc= diff --git a/lib/printing/describe.go b/lib/printing/describe.go index 66467d01af..c2f27cfd92 100644 --- a/lib/printing/describe.go +++ b/lib/printing/describe.go @@ -19,7 +19,7 @@ package printing import ( "fmt" - "knative.dev/client/pkg/printers" + "knative.dev/client-pkg/pkg/printers" duckv1 "knative.dev/pkg/apis/duck/v1" ) diff --git a/pkg/dynamic/client_mock_test.go b/pkg/dynamic/client_mock_test.go deleted file mode 100644 index 74f1c523b4..0000000000 --- a/pkg/dynamic/client_mock_test.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dynamic - -import ( - "context" - "testing" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/dynamic/fake" - "knative.dev/client/pkg/util/mock" -) - -func TestMockKnDynamicClient(t *testing.T) { - - client := NewMockKnDynamicClient(t) - - recorder := client.Recorder() - - recorder.ListCRDs(mock.Any(), nil, nil) - recorder.ListSourcesTypes(nil, nil) - recorder.ListSources(mock.Any(), nil, nil) - recorder.ListChannelsTypes(nil, nil) - recorder.RawClient(&fake.FakeDynamicClient{}) - recorder.ListSourcesUsingGVKs(mock.Any(), mock.Any(), nil, nil) - recorder.ListChannelsUsingGVKs(mock.Any(), mock.Any(), nil, nil) - - ctx := context.Background() - client.ListCRDs(ctx, metav1.ListOptions{}) - client.ListSourcesTypes(ctx) - client.ListChannelsTypes(ctx) - client.ListSources(ctx, WithTypeFilter("blub")) - client.RawClient() - client.ListSourcesUsingGVKs(ctx, &[]schema.GroupVersionKind{}, WithTypeFilter("blub")) - client.ListChannelsUsingGVKs(ctx, &[]schema.GroupVersionKind{}, WithTypeFilter("blub")) - - // Validate - recorder.Validate() -} diff --git a/pkg/dynamic/client_test.go b/pkg/dynamic/client_test.go deleted file mode 100644 index 9e4a52f012..0000000000 --- a/pkg/dynamic/client_test.go +++ /dev/null @@ -1,378 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dynamic - -import ( - "context" - "strings" - "testing" - - "gotest.tools/v3/assert" - - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - - eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" - "knative.dev/eventing/pkg/apis/messaging" - messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" - sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1" - sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" - dynamicclientfake "knative.dev/pkg/injection/clients/dynamicclient/fake" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" - - "knative.dev/client/pkg/util" -) - -const testNamespace = "current" - -func TestNamespace(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace, newSourceCRDObj("foo")) - assert.Equal(t, client.Namespace(), testNamespace) -} - -func TestListCRDs(t *testing.T) { - client := createFakeKnDynamicClient( - testNamespace, - newSourceCRDObj("foo"), - newSourceCRDObj("bar"), - ) - assert.Check(t, client.RawClient() != nil) - - t.Run("List CRDs with match", func(t *testing.T) { - options := metav1.ListOptions{} - uList, err := client.ListCRDs(context.Background(), options) - assert.NilError(t, err) - assert.Equal(t, len(uList.Items), 2) - }) - - t.Run("List CRDs without match", func(t *testing.T) { - options := metav1.ListOptions{} - sourcesLabels := labels.Set{"duck.knative.dev/source": "true1"} - options.LabelSelector = sourcesLabels.String() - uList, err := client.ListCRDs(context.Background(), options) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, len(uList.Items), 0) - }) -} - -func TestListSourceTypes(t *testing.T) { - client := createFakeKnDynamicClient( - testNamespace, - newSourceCRDObj("foo"), - newSourceCRDObj("bar"), - ) - - t.Run("List source types", func(t *testing.T) { - uList, err := client.ListSourcesTypes(context.Background()) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, len(uList.Items), 2) - // List of objects is returned in sorted order according to the (ns first, then name) - assert.Equal(t, uList.Items[0].GetName(), "bar") - assert.Equal(t, uList.Items[1].GetName(), "foo") - }) -} - -func TestListSources(t *testing.T) { - t.Run("No GVRs set", func(t *testing.T) { - obj := newSourceCRDObj("foo") - client := createFakeKnDynamicClient(testNamespace, obj) - assert.Check(t, client.RawClient() != nil) - _, err := client.ListSources(context.Background()) - assert.Check(t, err != nil) - assert.Check(t, util.ContainsAll(err.Error(), "can't", "find", "source", "kind", "CRD")) - }) - - t.Run("sources not installed", func(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace) - _, err := client.ListSources(context.Background()) - assert.Check(t, err != nil) - assert.Check(t, util.ContainsAll(err.Error(), "no sources", "found", "backend", "verify", "installation")) - }) - - t.Run("source list empty", func(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace, - newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1beta2", "PingSource"), - ) - sources, err := client.ListSources(context.Background()) - assert.NilError(t, err) - assert.Equal(t, len(sources.Items), 0) - }) - - t.Run("source list non empty", func(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace, - newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1beta2", "PingSource"), - newSourceCRDObjWithSpec("apiserversources", "sources.knative.dev", "v1", "ApiServerSource"), - newSourceUnstructuredObj("p1", "sources.knative.dev/v1beta2", "PingSource"), - newSourceUnstructuredObj("a1", "sources.knative.dev/v1", "ApiServerSource"), - ) - sources, err := client.ListSources(context.Background(), WithTypeFilter("pingsource"), WithTypeFilter("ApiServerSource")) - assert.NilError(t, err) - assert.Equal(t, len(sources.Items), 2) - assert.DeepEqual(t, sources.GroupVersionKind(), schema.GroupVersionKind{Group: sourceListGroup, Version: sourceListVersion, Kind: sourceListKind}) - }) -} - -func TestListSourcesUsingGVKs(t *testing.T) { - t.Run("No GVKs given", func(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace) - assert.Check(t, client.RawClient() != nil) - s, err := client.ListSourcesUsingGVKs(context.Background(), nil) - assert.NilError(t, err) - assert.Check(t, s == nil) - }) - - t.Run("source list with given GVKs", func(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace, - newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1beta2", "PingSource"), - newSourceCRDObjWithSpec("apiserversources", "sources.knative.dev", "v1", "ApiServerSource"), - newSourceUnstructuredObj("p1", "sources.knative.dev/v1beta2", "PingSource"), - newSourceUnstructuredObj("a1", "sources.knative.dev/v1", "ApiServerSource"), - ) - assert.Check(t, client.RawClient() != nil) - gvks := []schema.GroupVersionKind{ - {Group: "sources.knative.dev", Version: "v1beta2", Kind: "PingSource"}, - {Group: "sources.knative.dev", Version: "v1", Kind: "ApiServerSource"}, - } - - s, err := client.ListSourcesUsingGVKs(context.Background(), &gvks) - assert.NilError(t, err) - if s == nil { - t.Fatal("s = nil, want not nil") - } - assert.Equal(t, len(s.Items), 2) - assert.DeepEqual(t, s.GroupVersionKind(), schema.GroupVersionKind{Group: sourceListGroup, Version: sourceListVersion, Kind: sourceListKind}) - - // withType - s, err = client.ListSourcesUsingGVKs(context.Background(), &gvks, WithTypeFilter("PingSource")) - assert.NilError(t, err) - if s == nil { - t.Fatal("s = nil, want not nil") - } - assert.Equal(t, len(s.Items), 1) - assert.DeepEqual(t, s.GroupVersionKind(), schema.GroupVersionKind{Group: sourceListGroup, Version: sourceListVersion, Kind: sourceListKind}) - }) - -} - -// createFakeKnDynamicClient gives you a dynamic client for testing containing the given objects. -// See also the one in the fake package. Duplicated here to avoid a dependency loop. -func createFakeKnDynamicClient(testNamespace string, objects ...runtime.Object) KnDynamicClient { - scheme := runtime.NewScheme() - servingv1.AddToScheme(scheme) - eventingv1.AddToScheme(scheme) - messagingv1.AddToScheme(scheme) - sourcesv1.AddToScheme(scheme) - sourcesv1beta2.AddToScheme(scheme) - apiextensionsv1.AddToScheme(scheme) - _, dynamicClient := dynamicclientfake.With(context.TODO(), scheme, objects...) - return NewKnDynamicClient(dynamicClient, testNamespace) -} - -func newSourceCRDObj(name string) *unstructured.Unstructured { - obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": crdGroup + "/" + crdVersion, - "kind": crdKind, - "metadata": map[string]interface{}{ - "namespace": testNamespace, - "name": name, - }, - }, - } - obj.SetLabels(labels.Set{sourcesLabelKey: sourcesLabelValue}) - return obj -} - -func newSourceCRDObjWithSpec(name, group, version, kind string) *unstructured.Unstructured { - obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": crdGroup + "/" + crdVersion, - "kind": crdKind, - "metadata": map[string]interface{}{ - "namespace": testNamespace, - "name": name, - }, - }, - } - - obj.Object["spec"] = map[string]interface{}{ - "group": group, - "version": version, - "names": map[string]interface{}{ - "kind": kind, - "plural": strings.ToLower(kind) + "s", - }, - } - obj.SetLabels(labels.Set{sourcesLabelKey: sourcesLabelValue}) - return obj -} - -func newSourceUnstructuredObj(name, apiVersion, kind string) *unstructured.Unstructured { - return &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": apiVersion, - "kind": kind, - "metadata": map[string]interface{}{ - "namespace": "current", - "name": name, - }, - "spec": map[string]interface{}{ - "sink": map[string]interface{}{ - "ref": map[string]interface{}{ - "kind": "Service", - "name": "foo", - }, - }, - }, - }, - } -} - -func newChannelCRDObj(name string) *unstructured.Unstructured { - obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": crdGroup + "/" + crdVersion, - "kind": crdKind, - "metadata": map[string]interface{}{ - "namespace": testNamespace, - "name": name, - }, - }, - } - obj.SetLabels(labels.Set{messaging.SubscribableDuckVersionAnnotation: channelLabelValue}) - return obj -} - -func newChannelCRDObjWithSpec(name, group, version, kind string) *unstructured.Unstructured { - obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": crdGroup + "/" + crdVersion, - "kind": crdKind, - "metadata": map[string]interface{}{ - "namespace": testNamespace, - "name": name, - }, - }, - } - - obj.Object["spec"] = map[string]interface{}{ - "group": group, - "version": version, - "names": map[string]interface{}{ - "kind": kind, - "plural": strings.ToLower(kind) + "s", - }, - } - obj.SetLabels(labels.Set{messaging.SubscribableDuckVersionAnnotation: channelLabelValue}) - return obj -} - -func newChannelUnstructuredObj(name, apiVersion, kind string) *unstructured.Unstructured { - return &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": apiVersion, - "kind": kind, - "metadata": map[string]interface{}{ - "namespace": "current", - "name": name, - }, - "spec": map[string]interface{}{ - "sink": map[string]interface{}{ - "ref": map[string]interface{}{ - "name": "foo", - }, - }, - }, - }, - } -} -func TestListChannelsTypes(t *testing.T) { - t.Run("List channel types", func(t *testing.T) { - client := createFakeKnDynamicClient( - testNamespace, - newChannelCRDObjWithSpec("Channel", "messaging.knative.dev", "v1", "Channel"), - newChannelCRDObjWithSpec("InMemoryChannel", "messaging.knative.dev", "v1", "InMemoryChannel"), - ) - - uList, err := client.ListChannelsTypes(context.Background()) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, len(uList.Items), 1) - assert.Equal(t, uList.Items[0].GetName(), "InMemoryChannel") - }) - - t.Run("List channel types error", func(t *testing.T) { - client := createFakeKnDynamicClient( - testNamespace, - newChannelCRDObj("foo"), - ) - uList, err := client.ListChannelsTypes(context.Background()) - assert.Check(t, err == nil) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, len(uList.Items), 1) - assert.Equal(t, uList.Items[0].GetName(), "foo") - }) -} - -func TestListChannelsUsingGVKs(t *testing.T) { - t.Run("No GVKs given", func(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace) - assert.Check(t, client.RawClient() != nil) - s, err := client.ListChannelsUsingGVKs(context.Background(), nil) - assert.NilError(t, err) - assert.Check(t, s == nil) - }) - - t.Run("channel list with given GVKs", func(t *testing.T) { - client := createFakeKnDynamicClient(testNamespace, - newChannelCRDObjWithSpec("InMemoryChannel", "messaging.knative.dev", "v1", "InMemoryChannel"), - newChannelUnstructuredObj("i1", "messaging.knative.dev/v1", "InMemoryChannel"), - ) - assert.Check(t, client.RawClient() != nil) - gv := schema.GroupVersion{Group: "messaging.knative.dev", Version: "v1"} - gvks := []schema.GroupVersionKind{gv.WithKind("InMemoryChannel")} - - s, err := client.ListChannelsUsingGVKs(context.Background(), &gvks) - assert.NilError(t, err) - if s == nil { - t.Fatal("s = nil, want not nil") - } - assert.Equal(t, len(s.Items), 1) - assert.DeepEqual(t, s.GroupVersionKind(), schema.GroupVersionKind{Group: messaging.GroupName, Version: channelListVersion, Kind: channelListKind}) - - // withType - s, err = client.ListChannelsUsingGVKs(context.Background(), &gvks, WithTypeFilter("InMemoryChannel")) - assert.NilError(t, err) - if s == nil { - t.Fatal("s = nil, want not nil") - } - assert.Equal(t, len(s.Items), 1) - assert.DeepEqual(t, s.GroupVersionKind(), schema.GroupVersionKind{Group: messaging.GroupName, Version: channelListVersion, Kind: channelListKind}) - }) - -} diff --git a/pkg/dynamic/lib_test.go b/pkg/dynamic/lib_test.go deleted file mode 100644 index d5130afa71..0000000000 --- a/pkg/dynamic/lib_test.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright © 2020 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 dynamic - -import ( - "testing" - - "gotest.tools/v3/assert" - "k8s.io/apimachinery/pkg/runtime/schema" - - "knative.dev/client/pkg/util" -) - -func TestKindFromUnstructured(t *testing.T) { - kind, err := kindFromUnstructured( - newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1alpha1", "PingSource"), - ) - assert.NilError(t, err) - assert.Equal(t, kind, "PingSource") - _, err = kindFromUnstructured(newSourceCRDObj("foo")) - assert.Check(t, err != nil) -} - -func TestGVRFromUnstructured(t *testing.T) { - obj := newSourceCRDObj("foo") - - obj.Object["spec"] = map[string]interface{}{} - _, err := gvrFromUnstructured(obj) - assert.Check(t, err != nil) - assert.Check(t, util.ContainsAll(err.Error(), "can't", "find", "group")) - - obj.Object["spec"] = map[string]interface{}{ - "group": "sources.knative.dev", - } - _, err = gvrFromUnstructured(obj) - assert.Check(t, err != nil) - assert.Check(t, util.ContainsAll(err.Error(), "can't", "find", "version")) - - // with deprecated CRD field spec version - obj.Object["spec"] = map[string]interface{}{ - "group": "sources.knative.dev", - "version": "v1alpha1", - } - _, err = gvrFromUnstructured(obj) - assert.Check(t, err != nil) - assert.Check(t, util.ContainsAll(err.Error(), "can't", "find", "resource")) - - // with CRD field spec versions - obj.Object["spec"] = map[string]interface{}{ - "group": "sources.knative.dev", - "versions": []interface{}{ - map[string]interface{}{"name": "v1alpha1", "served": true}, - }, - } - _, err = gvrFromUnstructured(obj) - assert.Check(t, err != nil) - assert.Check(t, util.ContainsAll(err.Error(), "can't", "find", "resource")) - - obj.Object["spec"] = map[string]interface{}{ - "group": "sources.knative.dev", - "versions": []interface{}{ - map[string]interface{}{}, - }, - } - _, err = gvrFromUnstructured(obj) - assert.Check(t, err != nil) - assert.Check(t, util.ContainsAll(err.Error(), "can't", "find", "version")) -} - -func TestUnstructuredCRDFromGVK(t *testing.T) { - u := UnstructuredCRDFromGVK(schema.GroupVersionKind{Group: "sources.knative.dev", Version: "v1", Kind: "ApiServerSource"}) - g, err := groupFromUnstructured(u) - assert.NilError(t, err) - assert.Equal(t, g, "sources.knative.dev") - - v, err := versionFromUnstructured(u) - assert.NilError(t, err) - assert.Equal(t, v, "v1") - - k, err := kindFromUnstructured(u) - assert.NilError(t, err) - assert.Equal(t, k, "ApiServerSource") - - r, err := resourceFromUnstructured(u) - assert.NilError(t, err) - assert.Equal(t, r, "apiserversources") -} diff --git a/pkg/errors/errors_test.go b/pkg/errors/errors_test.go deleted file mode 100644 index ba94738f75..0000000000 --- a/pkg/errors/errors_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package errors - -import ( - "testing" - - "knative.dev/client/pkg/util" - - "gotest.tools/v3/assert" -) - -func TestNewInvalidCRD(t *testing.T) { - err := NewInvalidCRD("serving.knative.dev") - assert.Assert(t, util.ContainsAll(err.Error(), "no or newer Knative Serving API found on the backend", "please verify the installation", "update", "'kn'")) - - err = NewInvalidCRD("eventing") - assert.Assert(t, util.ContainsAll(err.Error(), "no or newer Knative Eventing API found on the backend", "please verify the installation", "update", "'kn'")) - - err = NewInvalidCRD("") - assert.Assert(t, util.ContainsAll(err.Error(), "no or newer Knative API found on the backend", "please verify the installation", "update", "'kn'")) -} diff --git a/pkg/errors/factory_test.go b/pkg/errors/factory_test.go deleted file mode 100644 index 48f834d3b1..0000000000 --- a/pkg/errors/factory_test.go +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package errors - -import ( - "errors" - "fmt" - "testing" - - servingv1 "knative.dev/serving/pkg/apis/serving/v1" - - "gotest.tools/v3/assert" - api_errors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -type mockErrType struct{} - -func (err mockErrType) Error() string { - return "mock error message" -} -func (err mockErrType) Status() metav1.Status { - return metav1.Status{} -} - -func TestKnErrorsStatusErrors(t *testing.T) { - cases := []struct { - Name string - Schema schema.GroupResource - StatusError func(schema.GroupResource) *api_errors.StatusError - ExpectedMsg string - Validate func(t *testing.T, err error, msg string) - }{ - { - Name: "Should get a missing serving api error", - Schema: schema.GroupResource{ - Group: "serving.knative.dev", - Resource: "service", - }, - StatusError: func(resource schema.GroupResource) *api_errors.StatusError { - statusError := api_errors.NewNotFound(resource, "serv") - statusError.Status().Details.Causes = []v1.StatusCause{ - { - Type: "UnexpectedServerResponse", - Message: "404 page not found", - }, - } - return statusError - }, - ExpectedMsg: "no or newer Knative Serving API found on the backend, please verify the installation or update the 'kn' client", - Validate: func(t *testing.T, err error, msg string) { - assert.Error(t, err, msg) - }, - }, - { - Name: "Should get the default not found error", - Schema: schema.GroupResource{ - Group: "serving.knative.dev", - Resource: "service", - }, - StatusError: func(resource schema.GroupResource) *api_errors.StatusError { - return api_errors.NewNotFound(resource, "serv") - }, - ExpectedMsg: "service.serving.knative.dev \"serv\" not found", - Validate: func(t *testing.T, err error, msg string) { - assert.Error(t, err, msg) - }, - }, - { - Name: "Should return the original error", - Schema: schema.GroupResource{ - Group: "serving.knative.dev", - Resource: "service", - }, - StatusError: func(resource schema.GroupResource) *api_errors.StatusError { - return api_errors.NewAlreadyExists(resource, "serv") - }, - ExpectedMsg: "service.serving.knative.dev \"serv\" already exists", - Validate: func(t *testing.T, err error, msg string) { - assert.Error(t, err, msg) - }, - }, - } - - for _, tc := range cases { - tc := tc - t.Run(tc.Name, func(t *testing.T) { - t.Parallel() - statusError := tc.StatusError(tc.Schema) - err := GetError(statusError) - tc.Validate(t, err, tc.ExpectedMsg) - }) - } -} - -func TestKnErrors(t *testing.T) { - cases := []struct { - Name string - Error error - ExpectedMsg string - }{ - { - Name: "no kubeconfig provided", - Error: errors.New("invalid configuration: no configuration has been provided"), - ExpectedMsg: "no kubeconfig has been provided, please use a valid configuration to connect to the cluster", - }, - { - Name: "i/o timeout", - Error: errors.New("Get https://api.example.com:27435/apis/foo/bar: dial tcp 192.168.1.1:27435: i/o timeout"), - ExpectedMsg: "error connecting to the cluster, please verify connection at: 192.168.1.1:27435: i/o timeout", - }, - { - Name: "no route to host", - Error: errors.New("Get https://192.168.39.141:8443/apis/foo/bar: dial tcp 192.168.39.141:8443: connect: no route to host"), - ExpectedMsg: "error connecting to the cluster, please verify connection at: 192.168.39.141:8443: connect: no route to host", - }, - { - Name: "no route to host without dial tcp string", - Error: errors.New("no route to host 192.168.1.1"), - ExpectedMsg: "error connecting to the cluster: no route to host 192.168.1.1", - }, - { - Name: "foo error which cant be converted to APIStatus", - Error: errors.New("foo error"), - ExpectedMsg: "foo error", - }, - } - for _, tc := range cases { - tc := tc - t.Run(tc.Name, func(t *testing.T) { - t.Parallel() - err := GetError(tc.Error) - assert.Error(t, err, tc.ExpectedMsg) - }) - } -} - -func TestIsForbiddenError(t *testing.T) { - cases := []struct { - Name string - Error error - Forbidden bool - }{ - { - Name: "forbidden error", - Error: api_errors.NewForbidden(schema.GroupResource{Group: "apiextensions.k8s.io", Resource: "CustomResourceDefinition"}, "", nil), - Forbidden: true, - }, - { - Name: "non forbidden error", - Error: errors.New("panic"), - Forbidden: false, - }, - } - for _, tc := range cases { - err := tc.Error - forbidden := tc.Forbidden - t.Run(tc.Name, func(t *testing.T) { - t.Parallel() - assert.Equal(t, IsForbiddenError(GetError(err)), forbidden) - }) - } -} - -func TestNilError(t *testing.T) { - assert.NilError(t, GetError(nil), nil) -} - -func TestIsInternalError(t *testing.T) { - cases := []struct { - Name string - Error error - Internal bool - }{ - { - Name: "internal error with connection refused", - Error: api_errors.NewInternalError(fmt.Errorf("failed calling webhook \"webhook.serving.knative.dev\": Post \"https://webhook.knative-serving.svc:443/defaulting?timeout=10s\": dial tcp 10.96.27.233:443: connect: connection refused")), - Internal: true, - }, - { - Name: "internal error with context deadline exceeded", - Error: api_errors.NewInternalError(fmt.Errorf("failed calling webhook \"webhook.serving.knative.dev\": Post https://webhook.knative-serving.svc:443/defaulting?timeout=10s: context deadline exceeded")), - Internal: true, - }, - { - Name: "internal error with i/o timeout", - Error: api_errors.NewInternalError(fmt.Errorf("failed calling webhook \"webhook.serving.knative.dev\": Post https://webhook.knative-serving.svc:443/defaulting?timeout=10s: i/o timeout")), - Internal: true, - }, - { - Name: "not internal error", - Error: mockErrType{}, - Internal: false, - }, - } - - for _, tc := range cases { - err := tc.Error - internal := tc.Internal - t.Run(tc.Name, func(t *testing.T) { - t.Parallel() - assert.Equal(t, api_errors.IsInternalError(GetError(err)), internal) - }) - } -} - -func TestStatusError(t *testing.T) { - cases := []struct { - Name string - Error error - ErrorType func(error) bool - }{ - { - Name: "Timeout error", - Error: api_errors.NewTimeoutError("failed processing request: i/o timeout", 10), - ErrorType: api_errors.IsTimeout, - }, - { - Name: "Conflict error", - Error: api_errors.NewConflict(servingv1.Resource("service"), "tempService", fmt.Errorf("failure: i/o timeout")), - ErrorType: api_errors.IsConflict, - }, - { - Name: "i/o timeout", - Error: errors.New("Get https://api.example.com:27435/apis/foo/bar: dial tcp 192.168.1.1:27435: i/o timeout"), - ErrorType: func(err error) bool { - var kne *KNError - return errors.As(err, &kne) - }, - }, - } - for _, tc := range cases { - itc := tc - t.Run(tc.Name, func(t *testing.T) { - t.Parallel() - assert.Assert(t, itc.ErrorType(GetError(itc.Error))) - }) - } -} diff --git a/pkg/errors/knerror_test.go b/pkg/errors/knerror_test.go deleted file mode 100644 index 61e318b8b0..0000000000 --- a/pkg/errors/knerror_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package errors - -import ( - "testing" - - "gotest.tools/v3/assert" -) - -func TestNewKNError(t *testing.T) { - err := NewKNError("myerror") - assert.Error(t, err, "myerror") - - err = NewKNError("") - assert.Error(t, err, "") -} - -func TestKNError_Error(t *testing.T) { - err := NewKNError("myerror") - assert.Equal(t, err.Error(), "myerror") - - err = NewKNError("") - assert.Equal(t, err.Error(), "") -} diff --git a/pkg/eventing/v1/client.go b/pkg/eventing/v1/client.go index decc443e15..8e502996dc 100644 --- a/pkg/eventing/v1/client.go +++ b/pkg/eventing/v1/client.go @@ -24,16 +24,16 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/util/retry" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" v1 "knative.dev/eventing/pkg/apis/duck/v1" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" clientv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1" duckv1 "knative.dev/pkg/apis/duck/v1" - kn_errors "knative.dev/client/pkg/errors" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" + kn_errors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" ) type TriggerUpdateFunc func(origTrigger *eventingv1.Trigger) (*eventingv1.Trigger, error) diff --git a/pkg/eventing/v1/client_mock.go b/pkg/eventing/v1/client_mock.go index e8cea8559f..b95d2561bd 100644 --- a/pkg/eventing/v1/client_mock.go +++ b/pkg/eventing/v1/client_mock.go @@ -21,7 +21,7 @@ import ( eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" ) // MockKnEventingClient is a combine of test object and recorder diff --git a/pkg/eventing/v1/client_test.go b/pkg/eventing/v1/client_test.go index be4ba6ddd5..817b5df45d 100644 --- a/pkg/eventing/v1/client_test.go +++ b/pkg/eventing/v1/client_test.go @@ -29,7 +29,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" client_testing "k8s.io/client-go/testing" - "knative.dev/client/pkg/wait" + "knative.dev/client-pkg/pkg/wait" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1/fake" "knative.dev/pkg/apis" diff --git a/pkg/eventing/v1beta2/client.go b/pkg/eventing/v1beta2/client.go index c1f5eacf5e..b1b713c24c 100644 --- a/pkg/eventing/v1beta2/client.go +++ b/pkg/eventing/v1beta2/client.go @@ -19,8 +19,8 @@ import ( 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" + kn_errors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" diff --git a/pkg/eventing/v1beta2/client_mock.go b/pkg/eventing/v1beta2/client_mock.go index 6d53b91c88..b026f1efec 100644 --- a/pkg/eventing/v1beta2/client_mock.go +++ b/pkg/eventing/v1beta2/client_mock.go @@ -20,7 +20,7 @@ import ( eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" ) // MockKnEventingV1beta2Client is a combine of test object and recorder diff --git a/pkg/kn/commands/broker/broker_test.go b/pkg/kn/commands/broker/broker_test.go index aaae5aa44e..619b31e838 100644 --- a/pkg/kn/commands/broker/broker_test.go +++ b/pkg/kn/commands/broker/broker_test.go @@ -20,8 +20,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/clientcmd" - "knative.dev/client/pkg/dynamic" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/dynamic" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" v1 "knative.dev/eventing/pkg/apis/duck/v1" duckv1 "knative.dev/pkg/apis/duck/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" diff --git a/pkg/kn/commands/broker/create_test.go b/pkg/kn/commands/broker/create_test.go index dc55b03ef6..472b631d71 100644 --- a/pkg/kn/commands/broker/create_test.go +++ b/pkg/kn/commands/broker/create_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" v1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/client-pkg/pkg/util" clienteventingv1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" ) var ( diff --git a/pkg/kn/commands/broker/delete_test.go b/pkg/kn/commands/broker/delete_test.go index d5319f7e74..e32a86bfba 100644 --- a/pkg/kn/commands/broker/delete_test.go +++ b/pkg/kn/commands/broker/delete_test.go @@ -22,9 +22,9 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/mock" clienteventingv1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/util/mock" ) func TestBrokerDelete(t *testing.T) { diff --git a/pkg/kn/commands/broker/delivery_option_flags.go b/pkg/kn/commands/broker/delivery_option_flags.go index e9c21dea3f..ef309923bc 100644 --- a/pkg/kn/commands/broker/delivery_option_flags.go +++ b/pkg/kn/commands/broker/delivery_option_flags.go @@ -18,13 +18,13 @@ import ( "reflect" "github.com/spf13/cobra" - "knative.dev/client/pkg/dynamic" - "knative.dev/client/pkg/kn/commands/flags" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/dynamic" duckv1 "knative.dev/pkg/apis/duck/v1" ) type DeliveryOptionFlags struct { - SinkFlags flags.SinkFlags + SinkFlags sinkfl.Flag RetryCount int32 Timeout string BackoffPolicy string @@ -49,7 +49,7 @@ func (d *DeliveryOptionFlags) Add(cmd *cobra.Command) { } func (d *DeliveryOptionFlags) GetDlSink(cmd *cobra.Command, dynamicClient dynamic.KnDynamicClient, namespace string) (*duckv1.Destination, error) { - var empty = flags.SinkFlags{} + var empty = sinkfl.Flag{} var destination *duckv1.Destination var err error if !reflect.DeepEqual(d.SinkFlags, empty) { diff --git a/pkg/kn/commands/broker/describe.go b/pkg/kn/commands/broker/describe.go index 31b2d7273f..99050c7ef0 100644 --- a/pkg/kn/commands/broker/describe.go +++ b/pkg/kn/commands/broker/describe.go @@ -28,8 +28,8 @@ import ( v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" ) var describeExample = ` diff --git a/pkg/kn/commands/broker/describe_test.go b/pkg/kn/commands/broker/describe_test.go index b57389d06a..5b277446e9 100644 --- a/pkg/kn/commands/broker/describe_test.go +++ b/pkg/kn/commands/broker/describe_test.go @@ -30,8 +30,8 @@ import ( "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/client-pkg/pkg/util" clientv1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" ) func TestBrokerDescribe(t *testing.T) { diff --git a/pkg/kn/commands/broker/list.go b/pkg/kn/commands/broker/list.go index 438829be88..c2deb0c64c 100644 --- a/pkg/kn/commands/broker/list.go +++ b/pkg/kn/commands/broker/list.go @@ -26,9 +26,9 @@ import ( metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" - hprinters "knative.dev/client/pkg/printers" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" ) @@ -41,7 +41,7 @@ var listExample = ` // NewBrokerListCommand represents command to list all brokers func NewBrokerListCommand(p *commands.KnParams) *cobra.Command { - brokerListFlags := flags.NewListPrintFlags(ListHandlers) + brokerListFlags := listfl.NewPrintFlags(ListHandlers) cmd := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/broker/list_test.go b/pkg/kn/commands/broker/list_test.go index 5c7518539a..8a4b0699f0 100644 --- a/pkg/kn/commands/broker/list_test.go +++ b/pkg/kn/commands/broker/list_test.go @@ -25,8 +25,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" clientv1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" ) diff --git a/pkg/kn/commands/broker/update.go b/pkg/kn/commands/broker/update.go index d81ae25cdf..be7203e2c9 100644 --- a/pkg/kn/commands/broker/update.go +++ b/pkg/kn/commands/broker/update.go @@ -21,7 +21,7 @@ import ( "fmt" "github.com/spf13/cobra" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" v1 "knative.dev/client/pkg/eventing/v1" duckv1 "knative.dev/eventing/pkg/apis/duck/v1" diff --git a/pkg/kn/commands/broker/update_test.go b/pkg/kn/commands/broker/update_test.go index d7adc31b9b..48e1c982ce 100644 --- a/pkg/kn/commands/broker/update_test.go +++ b/pkg/kn/commands/broker/update_test.go @@ -20,8 +20,8 @@ import ( "testing" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" clienteventingv1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" ) func TestBrokerUpdateWithDlSink(t *testing.T) { diff --git a/pkg/kn/commands/channel/create.go b/pkg/kn/commands/channel/create.go index 0489588951..a3aeaa1e2c 100644 --- a/pkg/kn/commands/channel/create.go +++ b/pkg/kn/commands/channel/create.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" knflags "knative.dev/client/pkg/kn/flags" knmessagingv1 "knative.dev/client/pkg/messaging/v1" diff --git a/pkg/kn/commands/channel/create_test.go b/pkg/kn/commands/channel/create_test.go index 7579945354..f3d4fe3c57 100644 --- a/pkg/kn/commands/channel/create_test.go +++ b/pkg/kn/commands/channel/create_test.go @@ -20,8 +20,8 @@ import ( "gotest.tools/v3/assert" "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/client-pkg/pkg/util" v1beta1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" ) func TestCreateChannelErrorCase(t *testing.T) { diff --git a/pkg/kn/commands/channel/delete_test.go b/pkg/kn/commands/channel/delete_test.go index 71b06f8d5a..495d1a68f7 100644 --- a/pkg/kn/commands/channel/delete_test.go +++ b/pkg/kn/commands/channel/delete_test.go @@ -20,8 +20,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v1beta1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" ) func TestDeleteChannelErrorCase(t *testing.T) { diff --git a/pkg/kn/commands/channel/describe.go b/pkg/kn/commands/channel/describe.go index 38e03cdaba..02aae96d3c 100644 --- a/pkg/kn/commands/channel/describe.go +++ b/pkg/kn/commands/channel/describe.go @@ -24,9 +24,9 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" ) var describeExample = ` diff --git a/pkg/kn/commands/channel/describe_test.go b/pkg/kn/commands/channel/describe_test.go index 77135dd490..6147199c61 100644 --- a/pkg/kn/commands/channel/describe_test.go +++ b/pkg/kn/commands/channel/describe_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/client-pkg/pkg/util" clientv1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" ) diff --git a/pkg/kn/commands/channel/flags.go b/pkg/kn/commands/channel/flags.go index d5673ee601..a939ce8340 100644 --- a/pkg/kn/commands/channel/flags.go +++ b/pkg/kn/commands/channel/flags.go @@ -22,9 +22,9 @@ import ( metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" + "knative.dev/client-pkg/pkg/printers" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" - hprinters "knative.dev/client/pkg/printers" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" ) diff --git a/pkg/kn/commands/channel/list.go b/pkg/kn/commands/channel/list.go index ab81371791..26a13e6fce 100644 --- a/pkg/kn/commands/channel/list.go +++ b/pkg/kn/commands/channel/list.go @@ -17,18 +17,18 @@ package channel import ( "fmt" - "knative.dev/client/pkg/util" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" + "knative.dev/client-pkg/pkg/util" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" "github.com/spf13/cobra" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" ) // NewChannelListCommand is for listing channel objects func NewChannelListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(ListHandlers) + listFlags := listfl.NewPrintFlags(ListHandlers) listCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/channel/list_test.go b/pkg/kn/commands/channel/list_test.go index 4d8a96a859..f800695149 100644 --- a/pkg/kn/commands/channel/list_test.go +++ b/pkg/kn/commands/channel/list_test.go @@ -26,7 +26,7 @@ import ( clientv1 "knative.dev/client/pkg/messaging/v1" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestChannelListNoChannelsFound(t *testing.T) { diff --git a/pkg/kn/commands/channel/list_types.go b/pkg/kn/commands/channel/list_types.go index 944504224c..591af3dd3a 100644 --- a/pkg/kn/commands/channel/list_types.go +++ b/pkg/kn/commands/channel/list_types.go @@ -13,6 +13,7 @@ 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 channel import ( @@ -21,16 +22,16 @@ import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "knative.dev/client/pkg/dynamic" - knerrors "knative.dev/client/pkg/errors" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" + "knative.dev/client-pkg/pkg/dynamic" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" messagingv1 "knative.dev/client/pkg/messaging/v1" ) // NewChannelListTypesCommand defines and processes `kn channel list-types` func NewChannelListTypesCommand(p *commands.KnParams) *cobra.Command { - listTypesFlags := flags.NewListPrintFlags(ListTypesHandlers) + listTypesFlags := listfl.NewPrintFlags(ListTypesHandlers) listTypesCommand := &cobra.Command{ Use: "list-types", Short: "List channel types", diff --git a/pkg/kn/commands/channel/list_types_test.go b/pkg/kn/commands/channel/list_types_test.go index 49d4e055d4..00496d8d6e 100644 --- a/pkg/kn/commands/channel/list_types_test.go +++ b/pkg/kn/commands/channel/list_types_test.go @@ -27,11 +27,11 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - dynamicfakeClient "knative.dev/client/pkg/dynamic/fake" + dynamicfakeClient "knative.dev/client-pkg/pkg/dynamic/fake" - clientdynamic "knative.dev/client/pkg/dynamic" + clientdynamic "knative.dev/client-pkg/pkg/dynamic" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" "knative.dev/eventing/pkg/apis/messaging" ) diff --git a/pkg/kn/commands/completion/completion_test.go b/pkg/kn/commands/completion/completion_test.go index 495f75d991..13e81ea1fc 100644 --- a/pkg/kn/commands/completion/completion_test.go +++ b/pkg/kn/commands/completion/completion_test.go @@ -17,9 +17,9 @@ package completion import ( "testing" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" "github.com/spf13/cobra" "gotest.tools/v3/assert" diff --git a/pkg/kn/commands/container/add_test.go b/pkg/kn/commands/container/add_test.go index ed2cbd8dfa..08d95f2f01 100644 --- a/pkg/kn/commands/container/add_test.go +++ b/pkg/kn/commands/container/add_test.go @@ -18,7 +18,7 @@ import ( "os" "testing" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "gotest.tools/v3/assert" ) diff --git a/pkg/kn/commands/describe.go b/pkg/kn/commands/describe.go index 2fd7538054..89bfdeaf2c 100644 --- a/pkg/kn/commands/describe.go +++ b/pkg/kn/commands/describe.go @@ -24,7 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/duration" - "knative.dev/client/pkg/printers" + "knative.dev/client-pkg/pkg/printers" "knative.dev/pkg/apis" ) diff --git a/pkg/kn/commands/describe_test.go b/pkg/kn/commands/describe_test.go index 49a5470e74..face235c25 100644 --- a/pkg/kn/commands/describe_test.go +++ b/pkg/kn/commands/describe_test.go @@ -25,7 +25,7 @@ import ( "gotest.tools/v3/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "knative.dev/client/pkg/printers" + "knative.dev/client-pkg/pkg/printers" "knative.dev/pkg/apis" ) diff --git a/pkg/kn/commands/domain/create.go b/pkg/kn/commands/domain/create.go index 181775e76b..cce4c4a9dd 100644 --- a/pkg/kn/commands/domain/create.go +++ b/pkg/kn/commands/domain/create.go @@ -21,7 +21,7 @@ import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/util/validation" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" clientv1beta1 "knative.dev/client/pkg/serving/v1beta1" ) diff --git a/pkg/kn/commands/domain/create_test.go b/pkg/kn/commands/domain/create_test.go index c8338df4e7..d8386db70e 100644 --- a/pkg/kn/commands/domain/create_test.go +++ b/pkg/kn/commands/domain/create_test.go @@ -19,9 +19,9 @@ import ( "gotest.tools/v3/assert" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/serving/v1beta1" - "knative.dev/client/pkg/util" ) func TestDomainMappingCreate(t *testing.T) { diff --git a/pkg/kn/commands/domain/delete.go b/pkg/kn/commands/domain/delete.go index 6d0e65e5be..0d585ac5b0 100644 --- a/pkg/kn/commands/domain/delete.go +++ b/pkg/kn/commands/domain/delete.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" ) diff --git a/pkg/kn/commands/domain/delete_test.go b/pkg/kn/commands/domain/delete_test.go index 6b8b74ccb5..ed9e8bc877 100644 --- a/pkg/kn/commands/domain/delete_test.go +++ b/pkg/kn/commands/domain/delete_test.go @@ -20,9 +20,9 @@ import ( "gotest.tools/v3/assert" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/serving/v1beta1" - "knative.dev/client/pkg/util" ) func TestDomainMappingDelete(t *testing.T) { diff --git a/pkg/kn/commands/domain/describe.go b/pkg/kn/commands/domain/describe.go index 5ebc051e96..1d385558ef 100644 --- a/pkg/kn/commands/domain/describe.go +++ b/pkg/kn/commands/domain/describe.go @@ -23,8 +23,8 @@ import ( "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" "knative.dev/serving/pkg/apis/serving/v1beta1" ) diff --git a/pkg/kn/commands/domain/describe_test.go b/pkg/kn/commands/domain/describe_test.go index 6421f6bcb6..66b9d33cc7 100644 --- a/pkg/kn/commands/domain/describe_test.go +++ b/pkg/kn/commands/domain/describe_test.go @@ -24,8 +24,8 @@ import ( "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/serving/v1beta1" - "knative.dev/client/pkg/util" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1" diff --git a/pkg/kn/commands/domain/domain.go b/pkg/kn/commands/domain/domain.go index 280b590aa8..c06fa3589b 100644 --- a/pkg/kn/commands/domain/domain.go +++ b/pkg/kn/commands/domain/domain.go @@ -22,7 +22,7 @@ import ( "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - clientdynamic "knative.dev/client/pkg/dynamic" + clientdynamic "knative.dev/client-pkg/pkg/dynamic" "knative.dev/client/pkg/kn/commands" duckv1 "knative.dev/pkg/apis/duck/v1" ) diff --git a/pkg/kn/commands/domain/domain_test.go b/pkg/kn/commands/domain/domain_test.go index 9a246627fc..7422c7b413 100644 --- a/pkg/kn/commands/domain/domain_test.go +++ b/pkg/kn/commands/domain/domain_test.go @@ -26,8 +26,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/clientcmd" - kndynamic "knative.dev/client/pkg/dynamic" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + kndynamic "knative.dev/client-pkg/pkg/dynamic" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" "knative.dev/client/pkg/kn/commands" knflags "knative.dev/client/pkg/kn/flags" clientservingv1beta1 "knative.dev/client/pkg/serving/v1beta1" diff --git a/pkg/kn/commands/domain/human_readable_flags.go b/pkg/kn/commands/domain/human_readable_flags.go index 9cba66b4c6..8908fb437c 100644 --- a/pkg/kn/commands/domain/human_readable_flags.go +++ b/pkg/kn/commands/domain/human_readable_flags.go @@ -19,8 +19,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "knative.dev/serving/pkg/apis/serving/v1beta1" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - hprinters "knative.dev/client/pkg/printers" ) // DomainMappingListHandlers adds print handlers for route list command diff --git a/pkg/kn/commands/domain/list.go b/pkg/kn/commands/domain/list.go index e6dbb99f59..2e6349d434 100644 --- a/pkg/kn/commands/domain/list.go +++ b/pkg/kn/commands/domain/list.go @@ -18,14 +18,14 @@ import ( "fmt" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewDomainMappingListCommand represents 'kn revision list' command func NewDomainMappingListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(DomainMappingListHandlers) + listFlags := listfl.NewPrintFlags(DomainMappingListHandlers) cmd := &cobra.Command{ Use: "list", Short: "List domain mappings", diff --git a/pkg/kn/commands/domain/list_test.go b/pkg/kn/commands/domain/list_test.go index 8685c32f0a..fac7d26933 100644 --- a/pkg/kn/commands/domain/list_test.go +++ b/pkg/kn/commands/domain/list_test.go @@ -20,8 +20,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/serving/v1beta1" - "knative.dev/client/pkg/util" servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1" "knative.dev/serving/pkg/client/clientset/versioned/scheme" ) diff --git a/pkg/kn/commands/domain/update.go b/pkg/kn/commands/domain/update.go index 52b0e8ade7..05d12a0da3 100644 --- a/pkg/kn/commands/domain/update.go +++ b/pkg/kn/commands/domain/update.go @@ -18,12 +18,12 @@ import ( "errors" "fmt" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "knative.dev/serving/pkg/apis/serving/v1beta1" "github.com/spf13/cobra" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" ) diff --git a/pkg/kn/commands/domain/update_test.go b/pkg/kn/commands/domain/update_test.go index c027632d41..35edf51611 100644 --- a/pkg/kn/commands/domain/update_test.go +++ b/pkg/kn/commands/domain/update_test.go @@ -23,9 +23,9 @@ import ( "gotest.tools/v3/assert" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/serving/v1beta1" - "knative.dev/client/pkg/util" ) func TestDomainMappingUpdate(t *testing.T) { diff --git a/pkg/kn/commands/eventtype/create.go b/pkg/kn/commands/eventtype/create.go index 7c8d557a66..a41ae6f08d 100644 --- a/pkg/kn/commands/eventtype/create.go +++ b/pkg/kn/commands/eventtype/create.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" clienteventingv1beta2 "knative.dev/client/pkg/eventing/v1beta2" "knative.dev/client/pkg/kn/commands" knflags "knative.dev/client/pkg/kn/commands/flags" @@ -40,7 +41,7 @@ func NewEventtypeCreateCommand(p *commands.KnParams) *cobra.Command { var eventtypeFlags knflags.EventtypeFlags - referenceFlag := knflags.NewSinkFlag(referenceMappings) + referenceFlag := sinkfl.NewFlag(referenceMappings) cmd := &cobra.Command{ Use: "create", diff --git a/pkg/kn/commands/eventtype/create_test.go b/pkg/kn/commands/eventtype/create_test.go index ad41989d43..66febed0e7 100644 --- a/pkg/kn/commands/eventtype/create_test.go +++ b/pkg/kn/commands/eventtype/create_test.go @@ -20,11 +20,11 @@ import ( "fmt" "testing" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/eventing/v1beta2" - "knative.dev/client/pkg/util" "knative.dev/pkg/apis" ) diff --git a/pkg/kn/commands/eventtype/delete_test.go b/pkg/kn/commands/eventtype/delete_test.go index f96524c7b4..a7f6ebff2e 100644 --- a/pkg/kn/commands/eventtype/delete_test.go +++ b/pkg/kn/commands/eventtype/delete_test.go @@ -20,11 +20,11 @@ import ( "fmt" "testing" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/eventing/v1beta2" - "knative.dev/client/pkg/util" ) func TestEventtypeDelete(t *testing.T) { diff --git a/pkg/kn/commands/eventtype/describe.go b/pkg/kn/commands/eventtype/describe.go index 4e292933f1..83581b37de 100644 --- a/pkg/kn/commands/eventtype/describe.go +++ b/pkg/kn/commands/eventtype/describe.go @@ -26,8 +26,8 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "knative.dev/eventing/pkg/apis/eventing/v1beta2" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" ) var describeExample = ` diff --git a/pkg/kn/commands/eventtype/describe_test.go b/pkg/kn/commands/eventtype/describe_test.go index ba732aa3a2..a98ec2ea01 100644 --- a/pkg/kn/commands/eventtype/describe_test.go +++ b/pkg/kn/commands/eventtype/describe_test.go @@ -21,14 +21,14 @@ import ( "fmt" "testing" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/eventing/v1beta2" - "knative.dev/client/pkg/util" eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" diff --git a/pkg/kn/commands/eventtype/eventtype_test.go b/pkg/kn/commands/eventtype/eventtype_test.go index f4a44be857..9a936a84a2 100644 --- a/pkg/kn/commands/eventtype/eventtype_test.go +++ b/pkg/kn/commands/eventtype/eventtype_test.go @@ -19,7 +19,7 @@ package eventtype import ( "bytes" - kndynamic "knative.dev/client/pkg/dynamic" + kndynamic "knative.dev/client-pkg/pkg/dynamic" "k8s.io/client-go/tools/clientcmd" "knative.dev/client/pkg/eventing/v1beta2" diff --git a/pkg/kn/commands/eventtype/list.go b/pkg/kn/commands/eventtype/list.go index 53da78e53e..d8084a328c 100644 --- a/pkg/kn/commands/eventtype/list.go +++ b/pkg/kn/commands/eventtype/list.go @@ -20,13 +20,13 @@ import ( "fmt" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" - hprinters "knative.dev/client/pkg/printers" eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" ) @@ -39,7 +39,7 @@ var listExample = ` // NewEventtypeListCommand represents command to list all eventtypes func NewEventtypeListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(ListHandlers) + listFlags := listfl.NewPrintFlags(ListHandlers) cmd := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/eventtype/list_test.go b/pkg/kn/commands/eventtype/list_test.go index d76892686e..7071905d6c 100644 --- a/pkg/kn/commands/eventtype/list_test.go +++ b/pkg/kn/commands/eventtype/list_test.go @@ -21,11 +21,11 @@ import ( "strings" "testing" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/eventing/v1beta2" - "knative.dev/client/pkg/util" eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" ) diff --git a/pkg/kn/commands/flags/listprint.go b/pkg/kn/commands/flags/listprint.go index da73381c01..e8fdbfb374 100644 --- a/pkg/kn/commands/flags/listprint.go +++ b/pkg/kn/commands/flags/listprint.go @@ -21,9 +21,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/cli-runtime/pkg/genericclioptions" + hprinters "knative.dev/client-pkg/pkg/printers" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - hprinters "knative.dev/client/pkg/printers" - "knative.dev/client/pkg/util" ) // ListFlags composes common printer flag structs @@ -85,16 +85,6 @@ func (f *ListPrintFlags) AddFlags(cmd *cobra.Command) { f.HumanReadableFlags.AddFlags(cmd) } -// NewListFlags returns flags associated with humanreadable, -// template, and "name" printing, with default values set. -func NewListPrintFlags(printer func(h hprinters.PrintHandler)) *ListPrintFlags { - return &ListPrintFlags{ - GenericPrintFlags: genericclioptions.NewPrintFlags(""), - HumanReadableFlags: commands.NewHumanPrintFlags(), - PrinterHandler: printer, - } -} - // EnsureWithNamespace ensures that humanreadable flags return // a printer capable of printing with a "namespace" column. func (f *ListPrintFlags) EnsureWithNamespace() { diff --git a/pkg/kn/commands/flags/listprint_test.go b/pkg/kn/commands/flags/listprint_test.go deleted file mode 100644 index a5e8e0cd46..0000000000 --- a/pkg/kn/commands/flags/listprint_test.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package flags - -import ( - "bytes" - "testing" - "time" - - "github.com/spf13/cobra" - "gotest.tools/v3/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/duration" - - "k8s.io/cli-runtime/pkg/genericclioptions" - "knative.dev/client/pkg/printers" - hprinters "knative.dev/client/pkg/printers" - "knative.dev/client/pkg/util" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" -) - -var ( - validPrintFunc = func(obj *servingv1.Service, opts printers.PrintOptions) ([]metav1beta1.TableRow, error) { - tableRow := metav1beta1.TableRow{ - Object: runtime.RawExtension{Object: obj}, - } - tableRow.Cells = append(tableRow.Cells, obj.Name, duration.HumanDuration(time.Since(obj.CreationTimestamp.Time))) - if opts.AllNamespaces { - tableRow.Cells = append(tableRow.Cells, obj.Namespace) - } - return []metav1.TableRow{tableRow}, nil - } - columnDefs = []metav1beta1.TableColumnDefinition{ - {Name: "Namespace", Type: "string", Description: "Namespace of mock instance", Priority: 0}, - {Name: "Name", Type: "string", Description: "Name of the mock instance", Priority: 1}, - {Name: "Age", Type: "string", Description: "Age of the mock instance", Priority: 1}, - } - myksvc = &servingv1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "myksvc", Namespace: "default"}, - } -) - -func TestListPrintFlagsFormats(t *testing.T) { - flags := NewListPrintFlags(nil) - formats := flags.AllowedFormats() - expected := []string{"json", "yaml", "name", "go-template", "go-template-file", "template", "templatefile", "jsonpath", "jsonpath-as-json", "jsonpath-file", "no-headers"} - assert.DeepEqual(t, formats, expected) -} - -func TestListPrintFlags(t *testing.T) { - var cmd *cobra.Command - flags := NewListPrintFlags(func(h hprinters.PrintHandler) {}) - - cmd = &cobra.Command{} - flags.AddFlags(cmd) - - assert.Assert(t, flags != nil) - assert.Assert(t, cmd.Flags() != nil) - - allowMissingTemplateKeys, err := cmd.Flags().GetBool("allow-missing-template-keys") - assert.NilError(t, err) - assert.Assert(t, allowMissingTemplateKeys == true) - - _, err = flags.ToPrinter() - assert.NilError(t, err) -} - -func TestListPrintFlagsPrint(t *testing.T) { - var cmd *cobra.Command - flags := NewListPrintFlags(func(h hprinters.PrintHandler) { - h.TableHandler(columnDefs, validPrintFunc) - }) - - cmd = &cobra.Command{} - var out bytes.Buffer - cmd.SetOut(&out) - flags.AddFlags(cmd) - - pr, err := flags.ToPrinter() - assert.NilError(t, err) - assert.Assert(t, pr != nil) - - err = flags.Print(nil, cmd.OutOrStdout()) - assert.NilError(t, err) - flags.GenericPrintFlags = genericclioptions.NewPrintFlags("mockOperation") - flags.GenericPrintFlags.OutputFlagSpecified = func() bool { - return true - } - err = flags.Print(myksvc, cmd.OutOrStdout()) - assert.NilError(t, err) - assert.Assert(t, util.ContainsAll(out.String(), "myksvc")) -} - -func TestEnsureNamespaces(t *testing.T) { - var cmd *cobra.Command - flags := NewListPrintFlags(func(h hprinters.PrintHandler) { - h.TableHandler(columnDefs, validPrintFunc) - }) - - cmd = &cobra.Command{} - var out bytes.Buffer - cmd.SetOut(&out) - flags.AddFlags(cmd) - err := flags.Print(myksvc, cmd.OutOrStderr()) - assert.NilError(t, err) - assert.Assert(t, util.ContainsAll(out.String(), "myksvc")) - assert.Assert(t, util.ContainsNone(out.String(), "default")) - flags.EnsureWithNamespace() - err = flags.Print(myksvc, cmd.OutOrStderr()) - assert.Assert(t, util.ContainsAll(out.String(), "default")) - assert.NilError(t, err) -} diff --git a/pkg/kn/commands/flags/sink_test.go b/pkg/kn/commands/flags/sink_test.go deleted file mode 100644 index 7e2800ca12..0000000000 --- a/pkg/kn/commands/flags/sink_test.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package flags - -import ( - "context" - "testing" - - "github.com/spf13/cobra" - "gotest.tools/v3/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" - messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" - "knative.dev/eventing/pkg/apis/sources/v1beta2" - "knative.dev/pkg/apis" - duckv1 "knative.dev/pkg/apis/duck/v1" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" - - dynamicfake "knative.dev/client/pkg/dynamic/fake" -) - -type resolveCase struct { - sink string - destination *duckv1.Destination - errContents string -} - -type sinkFlagAddTestCases struct { - flagName string - expectedFlagName string - expectedShortName string -} - -func TestSinkFlagAdd(t *testing.T) { - cases := []*sinkFlagAddTestCases{ - { - "", - "sink", - "s", - }, - { - "subscriber", - "subscriber", - "", - }, - } - for _, tc := range cases { - c := &cobra.Command{Use: "sinktest"} - sinkFlags := SinkFlags{} - if tc.flagName == "" { - sinkFlags.Add(c) - assert.Equal(t, tc.expectedFlagName, c.Flag("sink").Name) - assert.Equal(t, tc.expectedShortName, c.Flag("sink").Shorthand) - } else { - sinkFlags.AddWithFlagName(c, tc.flagName, "") - assert.Equal(t, tc.expectedFlagName, c.Flag(tc.flagName).Name) - assert.Equal(t, tc.expectedShortName, c.Flag(tc.flagName).Shorthand) - } - } -} - -func TestResolve(t *testing.T) { - targetExampleCom, err := apis.ParseURL("http://target.example.com") - assert.NilError(t, err) - - mysvc := &servingv1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "default"}, - } - defaultBroker := &eventingv1.Broker{ - TypeMeta: metav1.TypeMeta{Kind: "Broker", APIVersion: "eventing.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "default"}, - } - pipeChannel := &messagingv1.Channel{ - TypeMeta: metav1.TypeMeta{Kind: "Channel", APIVersion: "messaging.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "pipe", Namespace: "default"}, - } - pingSource := &v1beta2.PingSource{ - TypeMeta: metav1.TypeMeta{Kind: "PingSource", APIVersion: "sources.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}, - } - cases := []resolveCase{ - {"ksvc:mysvc", &duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Service", - APIVersion: "serving.knative.dev/v1", - Namespace: "default", - Name: "mysvc"}}, ""}, - {"mysvc", &duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Service", - APIVersion: "serving.knative.dev/v1", - Namespace: "default", - Name: "mysvc"}}, ""}, - {"ksvc:absent", nil, "\"absent\" not found"}, - {"broker:default", &duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Broker", - APIVersion: "eventing.knative.dev/v1", - Namespace: "default", - Name: "default"}}, ""}, - {"channel:pipe", - &duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Channel", - APIVersion: "messaging.knative.dev/v1", - Namespace: "default", - Name: "pipe", - }, - }, - ""}, - - {"sources.knative.dev/v1/pingsource:foo", &duckv1.Destination{Ref: &duckv1.KReference{ - APIVersion: "sources.knative.dev/v1", - Kind: "PingSource", - Namespace: "default", - Name: "foo", - }}, ""}, - {"sources.knative.dev/v1/pingsources:foo", &duckv1.Destination{Ref: &duckv1.KReference{ - APIVersion: "sources.knative.dev/v1", - Kind: "PingSource", - Namespace: "default", - Name: "foo", - }}, ""}, - {"sources.knative.dev/v1/Pingsource:foo", &duckv1.Destination{Ref: &duckv1.KReference{ - APIVersion: "sources.knative.dev/v1", - Kind: "PingSource", - Namespace: "default", - Name: "foo", - }}, ""}, - {"sources.knative.dev/v1/PingSources:foo", &duckv1.Destination{Ref: &duckv1.KReference{ - APIVersion: "sources.knative.dev/v1", - Kind: "PingSource", - Namespace: "default", - Name: "foo", - }}, ""}, - {"http://target.example.com", &duckv1.Destination{ - URI: targetExampleCom, - }, ""}, - {"k8ssvc:foo", nil, "k8ssvcs \"foo\" not found"}, - {"svc:foo", nil, "please use prefix 'ksvc' for knative service"}, - {"service:foo", nil, "please use prefix 'ksvc' for knative service"}, - {"absent:foo", nil, "absents \"foo\" not found"}, - } - dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default", mysvc, defaultBroker, pipeChannel, pingSource) - - for _, c := range cases { - i := &SinkFlags{Sink: c.sink} - result, err := i.ResolveSink(context.Background(), dynamicClient, "default") - if c.destination != nil { - assert.DeepEqual(t, result, c.destination) - assert.NilError(t, err) - } else { - assert.ErrorContains(t, err, c.errContents) - } - } -} - -func TestResolveWithNamespace(t *testing.T) { - mysvc := &servingv1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "mysvc", Namespace: "my-namespace"}, - } - defaultBroker := &eventingv1.Broker{ - TypeMeta: metav1.TypeMeta{Kind: "Broker", APIVersion: "eventing.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "my-namespace"}, - } - pipeChannel := &messagingv1.Channel{ - TypeMeta: metav1.TypeMeta{Kind: "Channel", APIVersion: "messaging.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "pipe", Namespace: "my-namespace"}, - } - - cases := []resolveCase{ - {"ksvc:mysvc:my-namespace", &duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Service", - APIVersion: "serving.knative.dev/v1", - Namespace: "my-namespace", - Name: "mysvc"}}, ""}, - {"broker:default:my-namespace", &duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Broker", - APIVersion: "eventing.knative.dev/v1", - Namespace: "my-namespace", - Name: "default"}}, ""}, - {"channel:pipe:my-namespace", &duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Channel", - APIVersion: "messaging.knative.dev/v1", - Namespace: "my-namespace", - Name: "pipe"}}, ""}, - } - dynamicClient := dynamicfake.CreateFakeKnDynamicClient("my-namespace", mysvc, defaultBroker, pipeChannel) - for _, c := range cases { - i := &SinkFlags{Sink: c.sink} - result, err := i.ResolveSink(context.Background(), dynamicClient, "default") - if c.destination != nil { - assert.DeepEqual(t, result, c.destination) - assert.Equal(t, c.destination.Ref.Namespace, "my-namespace") - assert.NilError(t, err) - } else { - assert.ErrorContains(t, err, c.errContents) - } - } -} - -func TestSinkToString(t *testing.T) { - sink := duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Service", - APIVersion: "serving.knative.dev/v1", - Namespace: "my-namespace", - Name: "mysvc"}} - expected := "ksvc:mysvc" - assert.Equal(t, expected, SinkToString(sink)) - sink = duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Broker", - APIVersion: "eventing.knative.dev/v1", - Namespace: "my-namespace", - Name: "default"}} - expected = "broker:default" - assert.Equal(t, expected, SinkToString(sink)) - sink = duckv1.Destination{ - Ref: &duckv1.KReference{Kind: "Service", - APIVersion: "v1", - Namespace: "my-namespace", - Name: "mysvc"}} - expected = "service:mysvc" - assert.Equal(t, expected, SinkToString(sink)) - - uri := "http://target.example.com" - targetExampleCom, err := apis.ParseURL(uri) - assert.NilError(t, err) - sink = duckv1.Destination{ - URI: targetExampleCom, - } - assert.Equal(t, uri, SinkToString(sink)) - assert.Equal(t, "", SinkToString(duckv1.Destination{})) -} diff --git a/pkg/kn/commands/human_readable_flags.go b/pkg/kn/commands/human_readable_flags.go index 716c119706..faa477e2d6 100644 --- a/pkg/kn/commands/human_readable_flags.go +++ b/pkg/kn/commands/human_readable_flags.go @@ -22,7 +22,7 @@ import ( "github.com/spf13/pflag" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/duration" - hprinters "knative.dev/client/pkg/printers" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" ) diff --git a/pkg/kn/commands/human_readable_flags_test.go b/pkg/kn/commands/human_readable_flags_test.go index ca606b3b6a..d910e55716 100644 --- a/pkg/kn/commands/human_readable_flags_test.go +++ b/pkg/kn/commands/human_readable_flags_test.go @@ -29,8 +29,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/duration" - "knative.dev/client/pkg/printers" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/printers" + "knative.dev/client-pkg/pkg/util" ) var ( diff --git a/pkg/kn/commands/namespaced_test.go b/pkg/kn/commands/namespaced_test.go index 3110c08508..d88dd1b450 100644 --- a/pkg/kn/commands/namespaced_test.go +++ b/pkg/kn/commands/namespaced_test.go @@ -19,7 +19,7 @@ import ( "path/filepath" "testing" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" "k8s.io/client-go/tools/clientcmd" diff --git a/pkg/kn/commands/plugin/list_test.go b/pkg/kn/commands/plugin/list_test.go index 9d6fdba5b6..42f933a994 100644 --- a/pkg/kn/commands/plugin/list_test.go +++ b/pkg/kn/commands/plugin/list_test.go @@ -22,9 +22,9 @@ import ( "strings" "testing" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/config" - "knative.dev/client/pkg/util" "github.com/spf13/cobra" "gotest.tools/v3/assert" diff --git a/pkg/kn/commands/plugin/plugin_test.go b/pkg/kn/commands/plugin/plugin_test.go index 2a23d7a241..78d5b57ab7 100644 --- a/pkg/kn/commands/plugin/plugin_test.go +++ b/pkg/kn/commands/plugin/plugin_test.go @@ -19,8 +19,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" ) func TestNewPluginCommand(t *testing.T) { diff --git a/pkg/kn/commands/revision/delete_mock_test.go b/pkg/kn/commands/revision/delete_mock_test.go index c70753a89d..c2a42d76e8 100644 --- a/pkg/kn/commands/revision/delete_mock_test.go +++ b/pkg/kn/commands/revision/delete_mock_test.go @@ -21,9 +21,9 @@ import ( "testing" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/mock" clientservingv1 "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/util/mock" "knative.dev/serving/pkg/apis/serving" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/kn/commands/revision/delete_test.go b/pkg/kn/commands/revision/delete_test.go index d6ab73c5e4..74411891f4 100644 --- a/pkg/kn/commands/revision/delete_test.go +++ b/pkg/kn/commands/revision/delete_test.go @@ -24,9 +24,9 @@ import ( "k8s.io/apimachinery/pkg/watch" clienttesting "k8s.io/client-go/testing" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/kn/commands/revision/describe.go b/pkg/kn/commands/revision/describe.go index 8c8acab0d3..2a5375a11f 100644 --- a/pkg/kn/commands/revision/describe.go +++ b/pkg/kn/commands/revision/describe.go @@ -28,8 +28,8 @@ import ( "knative.dev/serving/pkg/apis/serving" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" clientserving "knative.dev/client/pkg/serving" ) diff --git a/pkg/kn/commands/revision/describe_test.go b/pkg/kn/commands/revision/describe_test.go index bb09ff9649..900b31119d 100644 --- a/pkg/kn/commands/revision/describe_test.go +++ b/pkg/kn/commands/revision/describe_test.go @@ -34,8 +34,8 @@ import ( servingv1 "knative.dev/serving/pkg/apis/serving/v1" "sigs.k8s.io/yaml" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" ) const ( diff --git a/pkg/kn/commands/revision/human_readable_flags.go b/pkg/kn/commands/revision/human_readable_flags.go index 081279b9c4..b2f1deb936 100644 --- a/pkg/kn/commands/revision/human_readable_flags.go +++ b/pkg/kn/commands/revision/human_readable_flags.go @@ -20,8 +20,8 @@ import ( "knative.dev/serving/pkg/apis/serving" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - hprinters "knative.dev/client/pkg/printers" ) const ( diff --git a/pkg/kn/commands/revision/list.go b/pkg/kn/commands/revision/list.go index 2f818b73f4..5aeef8d7d4 100644 --- a/pkg/kn/commands/revision/list.go +++ b/pkg/kn/commands/revision/list.go @@ -21,13 +21,13 @@ import ( "strconv" "strings" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/serving/pkg/apis/serving" "github.com/spf13/cobra" servingv1 "knative.dev/serving/pkg/apis/serving/v1" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" clientservingv1 "knative.dev/client/pkg/serving/v1" ) @@ -36,7 +36,7 @@ var serviceNameFilter string // NewRevisionListCommand represents 'kn revision list' command func NewRevisionListCommand(p *commands.KnParams) *cobra.Command { - revisionListFlags := flags.NewListPrintFlags(RevisionListHandlers) + revisionListFlags := listfl.NewPrintFlags(RevisionListHandlers) revisionListCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/revision/list_test.go b/pkg/kn/commands/revision/list_test.go index 647baec9f5..533a580803 100644 --- a/pkg/kn/commands/revision/list_test.go +++ b/pkg/kn/commands/revision/list_test.go @@ -25,8 +25,8 @@ import ( "knative.dev/serving/pkg/apis/serving" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" ) var revisionListHeader = []string{"NAME", "SERVICE", "TRAFFIC", "TAGS", "GENERATION", "AGE", "CONDITIONS", "READY", "REASON"} diff --git a/pkg/kn/commands/revision/revision_test.go b/pkg/kn/commands/revision/revision_test.go index 3bf77b6bc1..c3201dcba5 100644 --- a/pkg/kn/commands/revision/revision_test.go +++ b/pkg/kn/commands/revision/revision_test.go @@ -25,9 +25,9 @@ import ( knflags "knative.dev/client/pkg/kn/flags" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" clientservingv1 "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" ) // Helper methods diff --git a/pkg/kn/commands/route/describe.go b/pkg/kn/commands/route/describe.go index 3064350cd2..fe9ab6f1ce 100644 --- a/pkg/kn/commands/route/describe.go +++ b/pkg/kn/commands/route/describe.go @@ -23,8 +23,8 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" ) // NewRouteDescribeCommand represents 'kn route describe' command diff --git a/pkg/kn/commands/route/describe_test.go b/pkg/kn/commands/route/describe_test.go index c26e9fbaac..087934871c 100644 --- a/pkg/kn/commands/route/describe_test.go +++ b/pkg/kn/commands/route/describe_test.go @@ -27,8 +27,8 @@ import ( servingv1 "knative.dev/serving/pkg/apis/serving/v1" "sigs.k8s.io/yaml" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" "knative.dev/pkg/ptr" ) diff --git a/pkg/kn/commands/route/human_readable_flags.go b/pkg/kn/commands/route/human_readable_flags.go index f366f9580d..55b27c42fb 100644 --- a/pkg/kn/commands/route/human_readable_flags.go +++ b/pkg/kn/commands/route/human_readable_flags.go @@ -19,8 +19,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - hprinters "knative.dev/client/pkg/printers" ) // RouteListHandlers adds print handlers for route list command diff --git a/pkg/kn/commands/route/list.go b/pkg/kn/commands/route/list.go index 2e40896341..a3bbc3e1fb 100644 --- a/pkg/kn/commands/route/list.go +++ b/pkg/kn/commands/route/list.go @@ -18,18 +18,17 @@ import ( "errors" "fmt" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/kn/commands" clientservingv1 "knative.dev/client/pkg/serving/v1" "github.com/spf13/cobra" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - - "knative.dev/client/pkg/kn/commands/flags" ) // NewrouteListCommand represents 'kn route list' command func NewRouteListCommand(p *commands.KnParams) *cobra.Command { - routeListFlags := flags.NewListPrintFlags(RouteListHandlers) + routeListFlags := listfl.NewPrintFlags(RouteListHandlers) routeListCommand := &cobra.Command{ Use: "list NAME", Short: "List routes", diff --git a/pkg/kn/commands/route/list_test.go b/pkg/kn/commands/route/list_test.go index de87b69563..039080df48 100644 --- a/pkg/kn/commands/route/list_test.go +++ b/pkg/kn/commands/route/list_test.go @@ -25,8 +25,8 @@ import ( "knative.dev/pkg/ptr" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" ) func fakeRouteList(args []string, response *servingv1.RouteList) (action client_testing.Action, output []string, err error) { diff --git a/pkg/kn/commands/secret/create.go b/pkg/kn/commands/secret/create.go index 7bd2abb852..c9bf99d2fc 100644 --- a/pkg/kn/commands/secret/create.go +++ b/pkg/kn/commands/secret/create.go @@ -22,7 +22,7 @@ import ( "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" ) diff --git a/pkg/kn/commands/secret/create_test.go b/pkg/kn/commands/secret/create_test.go index d7924f3dfc..ee62167cff 100644 --- a/pkg/kn/commands/secret/create_test.go +++ b/pkg/kn/commands/secret/create_test.go @@ -19,7 +19,7 @@ import ( "gotest.tools/v3/assert" "k8s.io/client-go/kubernetes/fake" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestSecretCreate(t *testing.T) { diff --git a/pkg/kn/commands/secret/list.go b/pkg/kn/commands/secret/list.go index 66e8fde37e..d2c41851e0 100644 --- a/pkg/kn/commands/secret/list.go +++ b/pkg/kn/commands/secret/list.go @@ -22,14 +22,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" - "knative.dev/client/pkg/kn/commands/flags" - hprinters "knative.dev/client/pkg/printers" - + listfl "knative.dev/client-pkg/pkg/commands/flags/list" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" ) func NewSecretListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(SecretListHandlers) + listFlags := listfl.NewPrintFlags(SecretListHandlers) cmd := &cobra.Command{ Use: "list", Short: "List secrets", diff --git a/pkg/kn/commands/secret/list_test.go b/pkg/kn/commands/secret/list_test.go index d65a83f3f6..c5829259d8 100644 --- a/pkg/kn/commands/secret/list_test.go +++ b/pkg/kn/commands/secret/list_test.go @@ -21,7 +21,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestSecretList(t *testing.T) { diff --git a/pkg/kn/commands/service/apply_mock_test.go b/pkg/kn/commands/service/apply_mock_test.go index e6042d067c..4d6488cec1 100644 --- a/pkg/kn/commands/service/apply_mock_test.go +++ b/pkg/kn/commands/service/apply_mock_test.go @@ -26,11 +26,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util/mock" + "knative.dev/client-pkg/pkg/wait" knclient "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util/mock" - "knative.dev/client/pkg/wait" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestServiceApplyCreateMock(t *testing.T) { diff --git a/pkg/kn/commands/service/configuration_edit_flags.go b/pkg/kn/commands/service/configuration_edit_flags.go index d4d7a45d6c..037ce45f4c 100644 --- a/pkg/kn/commands/service/configuration_edit_flags.go +++ b/pkg/kn/commands/service/configuration_edit_flags.go @@ -24,10 +24,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/serving/pkg/apis/config" + "knative.dev/client-pkg/pkg/util" knconfig "knative.dev/client/pkg/kn/config" knflags "knative.dev/client/pkg/kn/flags" servinglib "knative.dev/client/pkg/serving" - "knative.dev/client/pkg/util" network "knative.dev/networking/pkg/apis/networking" "knative.dev/serving/pkg/apis/autoscaling" "knative.dev/serving/pkg/apis/serving" diff --git a/pkg/kn/commands/service/configuration_edit_flags_test.go b/pkg/kn/commands/service/configuration_edit_flags_test.go index 4955fcc942..c13faae735 100644 --- a/pkg/kn/commands/service/configuration_edit_flags_test.go +++ b/pkg/kn/commands/service/configuration_edit_flags_test.go @@ -22,9 +22,9 @@ import ( "github.com/spf13/viper" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/config" - "knative.dev/client/pkg/util" "knative.dev/serving/pkg/apis/autoscaling" ) diff --git a/pkg/kn/commands/service/create.go b/pkg/kn/commands/service/create.go index 24bf476ff9..7b7eb330bf 100644 --- a/pkg/kn/commands/service/create.go +++ b/pkg/kn/commands/service/create.go @@ -22,7 +22,7 @@ import ( "os" "time" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands/flags" "knative.dev/client/pkg/kn/traffic" diff --git a/pkg/kn/commands/service/create_mock_test.go b/pkg/kn/commands/service/create_mock_test.go index 67a83a6f23..1ebad989b2 100644 --- a/pkg/kn/commands/service/create_mock_test.go +++ b/pkg/kn/commands/service/create_mock_test.go @@ -28,12 +28,12 @@ import ( servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util/mock" + "knative.dev/client-pkg/pkg/wait" servinglib "knative.dev/client/pkg/serving" knclient "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util/mock" - "knative.dev/client/pkg/wait" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "knative.dev/pkg/ptr" ) diff --git a/pkg/kn/commands/service/create_test.go b/pkg/kn/commands/service/create_test.go index 97bd28123f..908c8d1ce6 100644 --- a/pkg/kn/commands/service/create_test.go +++ b/pkg/kn/commands/service/create_test.go @@ -30,9 +30,9 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" network "knative.dev/networking/pkg/apis/networking" corev1 "k8s.io/api/core/v1" diff --git a/pkg/kn/commands/service/delete_mock_test.go b/pkg/kn/commands/service/delete_mock_test.go index 177b80dfd1..0f820b796b 100644 --- a/pkg/kn/commands/service/delete_mock_test.go +++ b/pkg/kn/commands/service/delete_mock_test.go @@ -20,9 +20,9 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/mock" clientservingv1 "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/util/mock" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/kn/commands/service/delete_test.go b/pkg/kn/commands/service/delete_test.go index 7bf6d77ca3..dfb7f8f69b 100644 --- a/pkg/kn/commands/service/delete_test.go +++ b/pkg/kn/commands/service/delete_test.go @@ -25,9 +25,9 @@ import ( client_testing "k8s.io/client-go/testing" clienttesting "k8s.io/client-go/testing" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" ) func fakeServiceDelete(args []string) (action client_testing.Action, name string, output string, err error) { diff --git a/pkg/kn/commands/service/describe.go b/pkg/kn/commands/service/describe.go index dc438ef415..74244348ef 100644 --- a/pkg/kn/commands/service/describe.go +++ b/pkg/kn/commands/service/describe.go @@ -27,9 +27,9 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "knative.dev/serving/pkg/apis/serving" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands/revision" "knative.dev/client/pkg/kn/plugin" - "knative.dev/client/pkg/printers" clientservingv1 "knative.dev/client/pkg/serving/v1" "github.com/spf13/cobra" diff --git a/pkg/kn/commands/service/describe_test.go b/pkg/kn/commands/service/describe_test.go index f61f88a80a..f2597079bb 100644 --- a/pkg/kn/commands/service/describe_test.go +++ b/pkg/kn/commands/service/describe_test.go @@ -33,9 +33,9 @@ import ( api_serving "knative.dev/serving/pkg/apis/serving" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" client_serving "knative.dev/client/pkg/serving" knclient "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" "knative.dev/pkg/ptr" ) diff --git a/pkg/kn/commands/service/export_test.go b/pkg/kn/commands/service/export_test.go index 7b2b2ee83f..10e0983a6c 100644 --- a/pkg/kn/commands/service/export_test.go +++ b/pkg/kn/commands/service/export_test.go @@ -24,10 +24,10 @@ import ( "gotest.tools/v3/assert" v1 "k8s.io/api/core/v1" - libtest "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/mock" + libtest "knative.dev/client-pkg/pkg/util/test" clientv1alpha1 "knative.dev/client/pkg/apis/client/v1alpha1" knclient "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util/mock" "knative.dev/pkg/ptr" apiserving "knative.dev/serving/pkg/apis/serving" servingv1 "knative.dev/serving/pkg/apis/serving/v1" diff --git a/pkg/kn/commands/service/human_readable_flags.go b/pkg/kn/commands/service/human_readable_flags.go index a4e2a8fb79..716bbc798a 100644 --- a/pkg/kn/commands/service/human_readable_flags.go +++ b/pkg/kn/commands/service/human_readable_flags.go @@ -19,8 +19,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - hprinters "knative.dev/client/pkg/printers" ) // ServiceListHandlers adds print handlers for service list command diff --git a/pkg/kn/commands/service/import_test.go b/pkg/kn/commands/service/import_test.go index 04cc0a6c8c..8a770d2ec4 100644 --- a/pkg/kn/commands/service/import_test.go +++ b/pkg/kn/commands/service/import_test.go @@ -23,10 +23,10 @@ import ( "gotest.tools/v3/assert" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/mock" + "knative.dev/client-pkg/pkg/wait" knclient "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/util/mock" - "knative.dev/client/pkg/wait" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/kn/commands/service/list.go b/pkg/kn/commands/service/list.go index 1212a0db53..88cb46e3ab 100644 --- a/pkg/kn/commands/service/list.go +++ b/pkg/kn/commands/service/list.go @@ -20,16 +20,16 @@ import ( "sort" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" servingv1 "knative.dev/serving/pkg/apis/serving/v1" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" clientservingv1 "knative.dev/client/pkg/serving/v1" ) // NewServiceListCommand represents 'kn service list' command func NewServiceListCommand(p *commands.KnParams) *cobra.Command { - serviceListFlags := flags.NewListPrintFlags(ServiceListHandlers) + serviceListFlags := listfl.NewPrintFlags(ServiceListHandlers) serviceListCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/service/list_mock_test.go b/pkg/kn/commands/service/list_mock_test.go index e89a973812..9373527757 100644 --- a/pkg/kn/commands/service/list_mock_test.go +++ b/pkg/kn/commands/service/list_mock_test.go @@ -21,9 +21,9 @@ import ( "gotest.tools/v3/assert" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/mock" clientservingv1 "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/util/mock" ) func TestServiceListAllNamespaceMock(t *testing.T) { diff --git a/pkg/kn/commands/service/list_test.go b/pkg/kn/commands/service/list_test.go index c74539ec04..cc72945dda 100644 --- a/pkg/kn/commands/service/list_test.go +++ b/pkg/kn/commands/service/list_test.go @@ -26,8 +26,8 @@ import ( "knative.dev/pkg/apis" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" ) func fakeServiceList(args []string, response *servingv1.ServiceList) (action clienttesting.Action, output []string, err error) { diff --git a/pkg/kn/commands/service/service.go b/pkg/kn/commands/service/service.go index 6b1afcdf38..c576e17f72 100644 --- a/pkg/kn/commands/service/service.go +++ b/pkg/kn/commands/service/service.go @@ -20,9 +20,9 @@ import ( "io" "time" + "knative.dev/client-pkg/pkg/wait" "knative.dev/client/pkg/kn/commands" clientservingv1 "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/wait" "github.com/spf13/cobra" ) diff --git a/pkg/kn/commands/service/service_update_mock_test.go b/pkg/kn/commands/service/service_update_mock_test.go index 94c57aad85..0e722e399d 100644 --- a/pkg/kn/commands/service/service_update_mock_test.go +++ b/pkg/kn/commands/service/service_update_mock_test.go @@ -25,9 +25,9 @@ import ( servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" clientserving "knative.dev/client/pkg/serving" clientservingv1 "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" "knative.dev/pkg/ptr" ) diff --git a/pkg/kn/commands/service/update.go b/pkg/kn/commands/service/update.go index 5beefaf8d5..25afd32557 100644 --- a/pkg/kn/commands/service/update.go +++ b/pkg/kn/commands/service/update.go @@ -20,7 +20,7 @@ import ( "time" "github.com/spf13/cobra" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "knative.dev/client/pkg/kn/commands/flags" "knative.dev/client/pkg/kn/traffic" diff --git a/pkg/kn/commands/service/update_test.go b/pkg/kn/commands/service/update_test.go index 4a695fd693..4365457f34 100644 --- a/pkg/kn/commands/service/update_test.go +++ b/pkg/kn/commands/service/update_test.go @@ -28,10 +28,10 @@ import ( "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" "knative.dev/client/pkg/kn/commands" servinglib "knative.dev/client/pkg/serving" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" network "knative.dev/networking/pkg/apis/networking" corev1 "k8s.io/api/core/v1" diff --git a/pkg/kn/commands/service/wait_test.go b/pkg/kn/commands/service/wait_test.go index af340e4e07..5562963d66 100644 --- a/pkg/kn/commands/service/wait_test.go +++ b/pkg/kn/commands/service/wait_test.go @@ -20,9 +20,9 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" servingv1 "knative.dev/serving/pkg/apis/serving/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/kn/commands/source/apiserver/apiserver_test.go b/pkg/kn/commands/source/apiserver/apiserver_test.go index b3586997ab..6a27b042d7 100644 --- a/pkg/kn/commands/source/apiserver/apiserver_test.go +++ b/pkg/kn/commands/source/apiserver/apiserver_test.go @@ -21,7 +21,7 @@ import ( v1 "knative.dev/eventing/pkg/apis/sources/v1" duckv1 "knative.dev/pkg/apis/duck/v1" - kndynamic "knative.dev/client/pkg/dynamic" + kndynamic "knative.dev/client-pkg/pkg/dynamic" clientv1 "knative.dev/client/pkg/sources/v1" "knative.dev/client/pkg/kn/commands" diff --git a/pkg/kn/commands/source/apiserver/create.go b/pkg/kn/commands/source/apiserver/create.go index 3412866f30..4f4d09d896 100644 --- a/pkg/kn/commands/source/apiserver/create.go +++ b/pkg/kn/commands/source/apiserver/create.go @@ -19,17 +19,17 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) // NewAPIServerCreateCommand for creating source func NewAPIServerCreateCommand(p *commands.KnParams) *cobra.Command { var updateFlags APIServerSourceUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "create NAME --resource RESOURCE --sink SINK", diff --git a/pkg/kn/commands/source/apiserver/create_test.go b/pkg/kn/commands/source/apiserver/create_test.go index 70b3c818ad..e92a81082d 100644 --- a/pkg/kn/commands/source/apiserver/create_test.go +++ b/pkg/kn/commands/source/apiserver/create_test.go @@ -21,9 +21,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestCreateApiServerSource(t *testing.T) { diff --git a/pkg/kn/commands/source/apiserver/delete_test.go b/pkg/kn/commands/source/apiserver/delete_test.go index f8efa39b75..4358b16ba4 100644 --- a/pkg/kn/commands/source/apiserver/delete_test.go +++ b/pkg/kn/commands/source/apiserver/delete_test.go @@ -20,8 +20,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestApiServerSourceDelete(t *testing.T) { diff --git a/pkg/kn/commands/source/apiserver/describe.go b/pkg/kn/commands/source/apiserver/describe.go index ad692bc14e..2562c287bf 100644 --- a/pkg/kn/commands/source/apiserver/describe.go +++ b/pkg/kn/commands/source/apiserver/describe.go @@ -22,9 +22,9 @@ import ( "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/lib/printing" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" v1 "knative.dev/eventing/pkg/apis/sources/v1" ) diff --git a/pkg/kn/commands/source/apiserver/describe_test.go b/pkg/kn/commands/source/apiserver/describe_test.go index 31bbb8d384..8c9882c578 100644 --- a/pkg/kn/commands/source/apiserver/describe_test.go +++ b/pkg/kn/commands/source/apiserver/describe_test.go @@ -20,8 +20,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" ) diff --git a/pkg/kn/commands/source/apiserver/flags.go b/pkg/kn/commands/source/apiserver/flags.go index f891d36ba7..d2f6d953f6 100644 --- a/pkg/kn/commands/source/apiserver/flags.go +++ b/pkg/kn/commands/source/apiserver/flags.go @@ -25,13 +25,13 @@ import ( "k8s.io/apimachinery/pkg/runtime" sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" - hprinters "knative.dev/client/pkg/printers" - "knative.dev/client/pkg/util" + hprinters "knative.dev/client-pkg/pkg/printers" + "knative.dev/client-pkg/pkg/util" ) const ( @@ -206,7 +206,7 @@ func printSource(source *sourcesv1.ApiServerSource, options hprinters.PrintOptio // Not moving to SinkToString() as it references v1beta1.Destination // This source is going to be moved/removed soon to sourcesv1, so no need to move // it now - sink := flags.SinkToString(source.Spec.Sink) + sink := sinkfl.SinkToString(source.Spec.Sink) if options.AllNamespaces { row.Cells = append(row.Cells, source.Namespace) diff --git a/pkg/kn/commands/source/apiserver/list.go b/pkg/kn/commands/source/apiserver/list.go index edf701e7d8..998923228c 100644 --- a/pkg/kn/commands/source/apiserver/list.go +++ b/pkg/kn/commands/source/apiserver/list.go @@ -18,14 +18,14 @@ import ( "fmt" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewAPIServerListCommand is for listing ApiServer source COs func NewAPIServerListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(APIServerSourceListHandlers) + listFlags := listfl.NewPrintFlags(APIServerSourceListHandlers) listCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/source/apiserver/list_test.go b/pkg/kn/commands/source/apiserver/list_test.go index 4077c79350..9664d33d26 100644 --- a/pkg/kn/commands/source/apiserver/list_test.go +++ b/pkg/kn/commands/source/apiserver/list_test.go @@ -23,8 +23,8 @@ import ( v1 "knative.dev/eventing/pkg/apis/sources/v1" + "knative.dev/client-pkg/pkg/util" v12 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestListAPIServerSource(t *testing.T) { diff --git a/pkg/kn/commands/source/apiserver/update.go b/pkg/kn/commands/source/apiserver/update.go index f369a8aafd..1682c49094 100644 --- a/pkg/kn/commands/source/apiserver/update.go +++ b/pkg/kn/commands/source/apiserver/update.go @@ -19,17 +19,17 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) // NewAPIServerUpdateCommand for managing source update func NewAPIServerUpdateCommand(p *commands.KnParams) *cobra.Command { var updateFlags APIServerSourceUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "update NAME", diff --git a/pkg/kn/commands/source/apiserver/update_test.go b/pkg/kn/commands/source/apiserver/update_test.go index 594e07525e..40bbb40834 100644 --- a/pkg/kn/commands/source/apiserver/update_test.go +++ b/pkg/kn/commands/source/apiserver/update_test.go @@ -24,9 +24,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestApiServerSourceUpdate(t *testing.T) { diff --git a/pkg/kn/commands/source/binding/binding_test.go b/pkg/kn/commands/source/binding/binding_test.go index d68105ba7b..4e96c9dab6 100644 --- a/pkg/kn/commands/source/binding/binding_test.go +++ b/pkg/kn/commands/source/binding/binding_test.go @@ -22,7 +22,7 @@ import ( sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1" duckv1 "knative.dev/pkg/apis/duck/v1" - kndynamic "knative.dev/client/pkg/dynamic" + kndynamic "knative.dev/client-pkg/pkg/dynamic" "knative.dev/client/pkg/kn/commands" clientv1 "knative.dev/client/pkg/sources/v1" ) diff --git a/pkg/kn/commands/source/binding/create.go b/pkg/kn/commands/source/binding/create.go index 13f868a033..46f87fe90f 100644 --- a/pkg/kn/commands/source/binding/create.go +++ b/pkg/kn/commands/source/binding/create.go @@ -19,17 +19,17 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" v1alpha12 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) // NewBindingCreateCommand is for creating sink bindings func NewBindingCreateCommand(p *commands.KnParams) *cobra.Command { var bindingFlags bindingUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "create NAME --subject SUBJECT --sink SINK", diff --git a/pkg/kn/commands/source/binding/create_test.go b/pkg/kn/commands/source/binding/create_test.go index e11a6c6cba..bb75b97353 100644 --- a/pkg/kn/commands/source/binding/create_test.go +++ b/pkg/kn/commands/source/binding/create_test.go @@ -19,10 +19,10 @@ import ( "gotest.tools/v3/assert" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestSimpleCreateBinding(t *testing.T) { diff --git a/pkg/kn/commands/source/binding/delete_test.go b/pkg/kn/commands/source/binding/delete_test.go index 33bba3484c..b3e89300ef 100644 --- a/pkg/kn/commands/source/binding/delete_test.go +++ b/pkg/kn/commands/source/binding/delete_test.go @@ -20,8 +20,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestSimpleDelete(t *testing.T) { diff --git a/pkg/kn/commands/source/binding/describe.go b/pkg/kn/commands/source/binding/describe.go index 152e2c5687..8299351ce5 100644 --- a/pkg/kn/commands/source/binding/describe.go +++ b/pkg/kn/commands/source/binding/describe.go @@ -24,9 +24,9 @@ import ( v1 "knative.dev/eventing/pkg/apis/sources/v1" "knative.dev/pkg/tracker" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/lib/printing" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" ) var describeExample = ` diff --git a/pkg/kn/commands/source/binding/describe_test.go b/pkg/kn/commands/source/binding/describe_test.go index 90f7025bdd..67199f5bda 100644 --- a/pkg/kn/commands/source/binding/describe_test.go +++ b/pkg/kn/commands/source/binding/describe_test.go @@ -26,8 +26,8 @@ import ( duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/pkg/tracker" + "knative.dev/client-pkg/pkg/util" clientv1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) var ( diff --git a/pkg/kn/commands/source/binding/flags.go b/pkg/kn/commands/source/binding/flags.go index f8a2ab42cd..369df847a1 100644 --- a/pkg/kn/commands/source/binding/flags.go +++ b/pkg/kn/commands/source/binding/flags.go @@ -18,10 +18,10 @@ import ( "github.com/spf13/cobra" metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" - hprinters "knative.dev/client/pkg/printers" v1 "knative.dev/eventing/pkg/apis/sources/v1" ) @@ -68,7 +68,7 @@ func printSinkBinding(binding *v1.SinkBinding, options hprinters.PrintOptions) ( name := binding.Name subject := subjectToString(binding.Spec.Subject) - sink := flags.SinkToString(binding.Spec.Sink) + sink := sinkfl.SinkToString(binding.Spec.Sink) age := commands.TranslateTimestampSince(binding.CreationTimestamp) conditions := commands.ConditionsValue(binding.Status.Conditions) ready := commands.ReadyCondition(binding.Status.Conditions) diff --git a/pkg/kn/commands/source/binding/list.go b/pkg/kn/commands/source/binding/list.go index cf8bb0234e..5c374ddb40 100644 --- a/pkg/kn/commands/source/binding/list.go +++ b/pkg/kn/commands/source/binding/list.go @@ -18,13 +18,13 @@ import ( "fmt" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewBindingListCommand is for listing sink bindings func NewBindingListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(BindingListHandlers) + listFlags := listfl.NewPrintFlags(BindingListHandlers) cmd := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/source/binding/list_test.go b/pkg/kn/commands/source/binding/list_test.go index f5ee82c9fb..c89bbf81f9 100644 --- a/pkg/kn/commands/source/binding/list_test.go +++ b/pkg/kn/commands/source/binding/list_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" v1 "knative.dev/eventing/pkg/apis/sources/v1" + "knative.dev/client-pkg/pkg/util" clientv1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestListBindingSimple(t *testing.T) { diff --git a/pkg/kn/commands/source/binding/update.go b/pkg/kn/commands/source/binding/update.go index 3886e3f3d5..ba85e5313d 100644 --- a/pkg/kn/commands/source/binding/update.go +++ b/pkg/kn/commands/source/binding/update.go @@ -19,17 +19,17 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" v1alpha12 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) // NewBindingUpdateCommand prepares the command for a sink binding update func NewBindingUpdateCommand(p *commands.KnParams) *cobra.Command { var bindingFlags bindingUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "update NAME", diff --git a/pkg/kn/commands/source/binding/update_test.go b/pkg/kn/commands/source/binding/update_test.go index 8edaf25b63..a86c125dda 100644 --- a/pkg/kn/commands/source/binding/update_test.go +++ b/pkg/kn/commands/source/binding/update_test.go @@ -23,9 +23,9 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" clientsourcesv1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestSimpleBindingUpdate(t *testing.T) { diff --git a/pkg/kn/commands/source/container/container_test.go b/pkg/kn/commands/source/container/container_test.go index 10dadf3259..960cf02aaa 100644 --- a/pkg/kn/commands/source/container/container_test.go +++ b/pkg/kn/commands/source/container/container_test.go @@ -25,7 +25,7 @@ import ( v1 "knative.dev/eventing/pkg/apis/sources/v1" duckv1 "knative.dev/pkg/apis/duck/v1" - kndynamic "knative.dev/client/pkg/dynamic" + kndynamic "knative.dev/client-pkg/pkg/dynamic" clientv1 "knative.dev/client/pkg/sources/v1" "knative.dev/client/pkg/kn/commands" diff --git a/pkg/kn/commands/source/container/create.go b/pkg/kn/commands/source/container/create.go index d7f817519a..e9bd995a39 100644 --- a/pkg/kn/commands/source/container/create.go +++ b/pkg/kn/commands/source/container/create.go @@ -22,7 +22,7 @@ import ( "os" "github.com/spf13/cobra" - "knative.dev/client/pkg/kn/commands/flags" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" knflags "knative.dev/client/pkg/kn/flags" corev1 "k8s.io/api/core/v1" @@ -33,7 +33,7 @@ import ( // NewContainerCreateCommand for creating source func NewContainerCreateCommand(p *commands.KnParams) *cobra.Command { var podFlags knflags.PodSpecFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "create NAME --image IMAGE --sink SINK", diff --git a/pkg/kn/commands/source/container/create_test.go b/pkg/kn/commands/source/container/create_test.go index 0a30bd07fb..d64853532f 100644 --- a/pkg/kn/commands/source/container/create_test.go +++ b/pkg/kn/commands/source/container/create_test.go @@ -23,9 +23,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestCreateContainerSource(t *testing.T) { diff --git a/pkg/kn/commands/source/container/delete_test.go b/pkg/kn/commands/source/container/delete_test.go index d724524361..0dc3777241 100644 --- a/pkg/kn/commands/source/container/delete_test.go +++ b/pkg/kn/commands/source/container/delete_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestContainerSourceDelete(t *testing.T) { diff --git a/pkg/kn/commands/source/container/describe.go b/pkg/kn/commands/source/container/describe.go index 7e5b1efe8b..d9572d829b 100644 --- a/pkg/kn/commands/source/container/describe.go +++ b/pkg/kn/commands/source/container/describe.go @@ -22,9 +22,9 @@ import ( "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/lib/printing" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" v1 "knative.dev/eventing/pkg/apis/sources/v1" ) diff --git a/pkg/kn/commands/source/container/describe_test.go b/pkg/kn/commands/source/container/describe_test.go index 9f32e40cef..b5305fe038 100644 --- a/pkg/kn/commands/source/container/describe_test.go +++ b/pkg/kn/commands/source/container/describe_test.go @@ -21,8 +21,8 @@ import ( "testing" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" ) func TestDescribeError(t *testing.T) { diff --git a/pkg/kn/commands/source/container/human_readable_flags.go b/pkg/kn/commands/source/container/human_readable_flags.go index 1454f9657f..c81b53c382 100644 --- a/pkg/kn/commands/source/container/human_readable_flags.go +++ b/pkg/kn/commands/source/container/human_readable_flags.go @@ -21,14 +21,13 @@ import ( "strings" "k8s.io/apimachinery/pkg/runtime" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" v1 "knative.dev/eventing/pkg/apis/sources/v1" - "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" - metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" + "knative.dev/client/pkg/kn/commands" - hprinters "knative.dev/client/pkg/printers" + hprinters "knative.dev/client-pkg/pkg/printers" ) // ContainerSourceListHandlers handles printing human readable table for `kn source apiserver list` command's output @@ -63,7 +62,7 @@ func printSource(source *v1.ContainerSource, options hprinters.PrintOptions) ([] // Not moving to SinkToString() as it references v1beta1.Destination // This source is going to be moved/removed soon to v1, so no need to move // it now - sink := flags.SinkToString(source.Spec.Sink) + sink := sinkfl.SinkToString(source.Spec.Sink) if options.AllNamespaces { row.Cells = append(row.Cells, source.Namespace) diff --git a/pkg/kn/commands/source/container/list.go b/pkg/kn/commands/source/container/list.go index a28a1d52dd..dbf974b519 100644 --- a/pkg/kn/commands/source/container/list.go +++ b/pkg/kn/commands/source/container/list.go @@ -20,14 +20,14 @@ import ( "fmt" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewContainerListCommand is for listing Container sources func NewContainerListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(ContainerSourceListHandlers) + listFlags := listfl.NewPrintFlags(ContainerSourceListHandlers) listCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/source/container/list_test.go b/pkg/kn/commands/source/container/list_test.go index 718a279d2f..658db57c2a 100644 --- a/pkg/kn/commands/source/container/list_test.go +++ b/pkg/kn/commands/source/container/list_test.go @@ -22,8 +22,8 @@ import ( "knative.dev/eventing/pkg/client/clientset/versioned/scheme" "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v12 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" v1 "knative.dev/eventing/pkg/apis/sources/v1" ) diff --git a/pkg/kn/commands/source/container/update.go b/pkg/kn/commands/source/container/update.go index e0e1816cd5..17dc94bc3a 100644 --- a/pkg/kn/commands/source/container/update.go +++ b/pkg/kn/commands/source/container/update.go @@ -22,8 +22,8 @@ import ( "os" "github.com/spf13/cobra" - "knative.dev/client/pkg/config" - "knative.dev/client/pkg/kn/commands/flags" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/config" knflags "knative.dev/client/pkg/kn/flags" "knative.dev/client/pkg/kn/commands" @@ -34,7 +34,7 @@ import ( // NewContainerUpdateCommand for managing source update func NewContainerUpdateCommand(p *commands.KnParams) *cobra.Command { var podFlags knflags.PodSpecFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "update NAME --image IMAGE", diff --git a/pkg/kn/commands/source/container/update_test.go b/pkg/kn/commands/source/container/update_test.go index a2bbd5f0b8..111925d74a 100644 --- a/pkg/kn/commands/source/container/update_test.go +++ b/pkg/kn/commands/source/container/update_test.go @@ -22,9 +22,9 @@ import ( "gotest.tools/v3/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/client/pkg/sources/v1" - "knative.dev/client/pkg/util" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/kn/commands/source/duck/multisourcelist.go b/pkg/kn/commands/source/duck/multisourcelist.go index 28d3346233..f70b677911 100644 --- a/pkg/kn/commands/source/duck/multisourcelist.go +++ b/pkg/kn/commands/source/duck/multisourcelist.go @@ -19,6 +19,7 @@ import ( "fmt" "strings" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,11 +27,10 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1" - duck "knative.dev/pkg/apis/duck" + "knative.dev/pkg/apis/duck" duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/client/pkg/kn/commands" - knflags "knative.dev/client/pkg/kn/commands/flags" ) // Source struct holds common properties between different eventing sources @@ -157,17 +157,17 @@ func findSink(source *unstructured.Unstructured) string { case "ApiServerSource": var apiSource sourcesv1.ApiServerSource if err := duck.FromUnstructured(source, &apiSource); err == nil { - return knflags.SinkToString(apiSource.Spec.Sink) + return sinkfl.SinkToString(apiSource.Spec.Sink) } case "SinkBinding": var binding sourcesv1.SinkBinding if err := duck.FromUnstructured(source, &binding); err == nil { - return knflags.SinkToString(binding.Spec.Sink) + return sinkfl.SinkToString(binding.Spec.Sink) } case "PingSource": var pingSource sourcesv1beta2.PingSource if err := duck.FromUnstructured(source, &pingSource); err == nil { - return knflags.SinkToString(pingSource.Spec.Sink) + return sinkfl.SinkToString(pingSource.Spec.Sink) } default: sink, err := sinkFromUnstructured(source) @@ -177,7 +177,7 @@ func findSink(source *unstructured.Unstructured) string { if sink == nil { return "" } - return knflags.SinkToString(*sink) + return sinkfl.SinkToString(*sink) } return "" } diff --git a/pkg/kn/commands/source/duck/multisourcelist_test.go b/pkg/kn/commands/source/duck/multisourcelist_test.go index dad6c43fc4..91f6ed2e7c 100644 --- a/pkg/kn/commands/source/duck/multisourcelist_test.go +++ b/pkg/kn/commands/source/duck/multisourcelist_test.go @@ -21,7 +21,7 @@ import ( "gotest.tools/v3/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - //"knative.dev/client/pkg/util" + //"knative.dev/client-pkg/pkg/util" ) func TestToSource(t *testing.T) { diff --git a/pkg/kn/commands/source/human_readable_flags.go b/pkg/kn/commands/source/human_readable_flags.go index c86045cff6..511ee5510c 100644 --- a/pkg/kn/commands/source/human_readable_flags.go +++ b/pkg/kn/commands/source/human_readable_flags.go @@ -22,8 +22,8 @@ import ( metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" + "knative.dev/client-pkg/pkg/printers" clientduck "knative.dev/client/pkg/kn/commands/source/duck" - "knative.dev/client/pkg/printers" ) var sourceTypeDescription = map[string]string{ diff --git a/pkg/kn/commands/source/list.go b/pkg/kn/commands/source/list.go index 82f2519075..b4f484eb70 100644 --- a/pkg/kn/commands/source/list.go +++ b/pkg/kn/commands/source/list.go @@ -17,13 +17,14 @@ package source import ( "fmt" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/sources" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "knative.dev/client/pkg/dynamic" - knerrors "knative.dev/client/pkg/errors" + "knative.dev/client-pkg/pkg/dynamic" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands/flags" "knative.dev/client/pkg/kn/commands/source/duck" @@ -48,7 +49,7 @@ var listExample = ` // NewListCommand defines and processes `kn source list` func NewListCommand(p *commands.KnParams) *cobra.Command { filterFlags := &flags.SourceTypeFilters{} - listFlags := flags.NewListPrintFlags(ListHandlers) + listFlags := listfl.NewPrintFlags(ListHandlers) listCommand := &cobra.Command{ Use: "list", Short: "List event sources", diff --git a/pkg/kn/commands/source/list_test.go b/pkg/kn/commands/source/list_test.go index 9a568f6afb..82dbfc484c 100644 --- a/pkg/kn/commands/source/list_test.go +++ b/pkg/kn/commands/source/list_test.go @@ -19,15 +19,15 @@ import ( "strings" "testing" - "knative.dev/client/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/dynamic/fake" "gotest.tools/v3/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" ) const ( diff --git a/pkg/kn/commands/source/list_types.go b/pkg/kn/commands/source/list_types.go index f0fbb1108b..be765c4589 100644 --- a/pkg/kn/commands/source/list_types.go +++ b/pkg/kn/commands/source/list_types.go @@ -17,21 +17,21 @@ package source import ( "context" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/sources" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "knative.dev/client/pkg/dynamic" - knerrors "knative.dev/client/pkg/errors" + "knative.dev/client-pkg/pkg/dynamic" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewListTypesCommand defines and processes `kn source list-types` func NewListTypesCommand(p *commands.KnParams) *cobra.Command { - listTypesFlags := flags.NewListPrintFlags(ListTypesHandlers) + listTypesFlags := listfl.NewPrintFlags(ListTypesHandlers) listTypesCommand := &cobra.Command{ Use: "list-types", Short: "List event source types", diff --git a/pkg/kn/commands/source/ping/create.go b/pkg/kn/commands/source/ping/create.go index e566936a31..87e5914ec6 100644 --- a/pkg/kn/commands/source/ping/create.go +++ b/pkg/kn/commands/source/ping/create.go @@ -19,17 +19,17 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" clientsourcesv1beta2 "knative.dev/client/pkg/sources/v1beta2" - "knative.dev/client/pkg/util" ) // NewPingCreateCommand is for creating Ping source COs func NewPingCreateCommand(p *commands.KnParams) *cobra.Command { var updateFlags pingUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "create NAME --sink SINK", diff --git a/pkg/kn/commands/source/ping/create_test.go b/pkg/kn/commands/source/ping/create_test.go index 00add675c5..22bc3a62ac 100644 --- a/pkg/kn/commands/source/ping/create_test.go +++ b/pkg/kn/commands/source/ping/create_test.go @@ -21,10 +21,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" clientsourcesv1beta2 "knative.dev/client/pkg/sources/v1beta2" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestSimpleCreatePingSource(t *testing.T) { diff --git a/pkg/kn/commands/source/ping/delete_test.go b/pkg/kn/commands/source/ping/delete_test.go index 927dd65963..76782ad3b9 100644 --- a/pkg/kn/commands/source/ping/delete_test.go +++ b/pkg/kn/commands/source/ping/delete_test.go @@ -21,7 +21,7 @@ import ( "gotest.tools/v3/assert" clientsourcesv1beta2 "knative.dev/client/pkg/sources/v1beta2" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestSimpleDelete(t *testing.T) { diff --git a/pkg/kn/commands/source/ping/describe.go b/pkg/kn/commands/source/ping/describe.go index b6fc2c119e..7b4888db79 100644 --- a/pkg/kn/commands/source/ping/describe.go +++ b/pkg/kn/commands/source/ping/describe.go @@ -21,9 +21,9 @@ import ( "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/lib/printing" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" clientsourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" ) diff --git a/pkg/kn/commands/source/ping/describe_test.go b/pkg/kn/commands/source/ping/describe_test.go index de3653dc26..1226a1286a 100644 --- a/pkg/kn/commands/source/ping/describe_test.go +++ b/pkg/kn/commands/source/ping/describe_test.go @@ -23,8 +23,8 @@ import ( sourcesv1beta "knative.dev/eventing/pkg/apis/sources/v1beta2" duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/client-pkg/pkg/util" clientv1beta2 "knative.dev/client/pkg/sources/v1beta2" - "knative.dev/client/pkg/util" "knative.dev/pkg/apis" ) diff --git a/pkg/kn/commands/source/ping/flags.go b/pkg/kn/commands/source/ping/flags.go index 65cd916d0d..306cb15a29 100644 --- a/pkg/kn/commands/source/ping/flags.go +++ b/pkg/kn/commands/source/ping/flags.go @@ -23,8 +23,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - hprinters "knative.dev/client/pkg/printers" sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" ) diff --git a/pkg/kn/commands/source/ping/list.go b/pkg/kn/commands/source/ping/list.go index 9e2118af13..7c03028af8 100644 --- a/pkg/kn/commands/source/ping/list.go +++ b/pkg/kn/commands/source/ping/list.go @@ -18,14 +18,14 @@ import ( "fmt" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewPingListCommand is for listing Ping source COs func NewPingListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(PingSourceListHandlers) + listFlags := listfl.NewPrintFlags(PingSourceListHandlers) listCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/source/ping/list_test.go b/pkg/kn/commands/source/ping/list_test.go index a09ce091ad..ba8462db13 100644 --- a/pkg/kn/commands/source/ping/list_test.go +++ b/pkg/kn/commands/source/ping/list_test.go @@ -23,8 +23,8 @@ import ( sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" + "knative.dev/client-pkg/pkg/util" clientv1beta2 "knative.dev/client/pkg/sources/v1beta2" - "knative.dev/client/pkg/util" ) func TestListPingSource(t *testing.T) { diff --git a/pkg/kn/commands/source/ping/ping_test.go b/pkg/kn/commands/source/ping/ping_test.go index ee3af4666e..3f1b9686ee 100644 --- a/pkg/kn/commands/source/ping/ping_test.go +++ b/pkg/kn/commands/source/ping/ping_test.go @@ -24,7 +24,7 @@ import ( sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" duckv1 "knative.dev/pkg/apis/duck/v1" - kndynamic "knative.dev/client/pkg/dynamic" + kndynamic "knative.dev/client-pkg/pkg/dynamic" "knative.dev/client/pkg/kn/commands" clientv1beta2 "knative.dev/client/pkg/sources/v1beta2" ) diff --git a/pkg/kn/commands/source/ping/update.go b/pkg/kn/commands/source/ping/update.go index 1eda2f25c7..370de33c55 100644 --- a/pkg/kn/commands/source/ping/update.go +++ b/pkg/kn/commands/source/ping/update.go @@ -18,22 +18,22 @@ import ( "errors" "fmt" - "knative.dev/client/pkg/config" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/config" "github.com/spf13/cobra" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" sourcesv1beta2 "knative.dev/client/pkg/sources/v1beta2" eventingsourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // NewPingUpdateCommand prepares the command for a PingSource update func NewPingUpdateCommand(p *commands.KnParams) *cobra.Command { var updateFlags pingUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "update NAME", diff --git a/pkg/kn/commands/source/ping/update_test.go b/pkg/kn/commands/source/ping/update_test.go index 4b87e53099..72f4375fc2 100644 --- a/pkg/kn/commands/source/ping/update_test.go +++ b/pkg/kn/commands/source/ping/update_test.go @@ -22,9 +22,9 @@ import ( "gotest.tools/v3/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" sourcesv1beta2 "knative.dev/client/pkg/sources/v1beta2" - "knative.dev/client/pkg/util" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/kn/commands/subscription/create.go b/pkg/kn/commands/subscription/create.go index f2f9019ab2..a7b852a4b0 100644 --- a/pkg/kn/commands/subscription/create.go +++ b/pkg/kn/commands/subscription/create.go @@ -21,10 +21,10 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" knflags "knative.dev/client/pkg/kn/flags" knmessagingv1 "knative.dev/client/pkg/messaging/v1" ) @@ -33,7 +33,7 @@ import ( func NewSubscriptionCreateCommand(p *commands.KnParams) *cobra.Command { var ( crefFlag knflags.ChannelRef - subscriberFlag, replyFlag, dlsFlag flags.SinkFlags + subscriberFlag, replyFlag, dlsFlag sinkfl.Flag ) cmd := &cobra.Command{ diff --git a/pkg/kn/commands/subscription/create_test.go b/pkg/kn/commands/subscription/create_test.go index dad6d720ec..79d2bf7f77 100644 --- a/pkg/kn/commands/subscription/create_test.go +++ b/pkg/kn/commands/subscription/create_test.go @@ -21,9 +21,9 @@ import ( "gotest.tools/v3/assert" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" clientmessagingv1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" ) func TestCreateSubscriptionErrorCase(t *testing.T) { diff --git a/pkg/kn/commands/subscription/delete_test.go b/pkg/kn/commands/subscription/delete_test.go index e99805dae9..a6ca098203 100644 --- a/pkg/kn/commands/subscription/delete_test.go +++ b/pkg/kn/commands/subscription/delete_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" v1beta1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" ) func TestDeleteSubscriptionErrorCase(t *testing.T) { diff --git a/pkg/kn/commands/subscription/describe.go b/pkg/kn/commands/subscription/describe.go index aced44a85c..e88242be7f 100644 --- a/pkg/kn/commands/subscription/describe.go +++ b/pkg/kn/commands/subscription/describe.go @@ -25,10 +25,10 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/lib/printing" - knerrors "knative.dev/client/pkg/errors" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" ) // NewSubscriptionDescribeCommand returns a new command for describe a subscription object diff --git a/pkg/kn/commands/subscription/describe_test.go b/pkg/kn/commands/subscription/describe_test.go index da9eb5db24..092ee93bba 100644 --- a/pkg/kn/commands/subscription/describe_test.go +++ b/pkg/kn/commands/subscription/describe_test.go @@ -23,8 +23,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" clientv1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" ) diff --git a/pkg/kn/commands/subscription/flags.go b/pkg/kn/commands/subscription/flags.go index a139bac2a3..2798ea2f70 100644 --- a/pkg/kn/commands/subscription/flags.go +++ b/pkg/kn/commands/subscription/flags.go @@ -21,10 +21,10 @@ import ( metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" - hprinters "knative.dev/client/pkg/printers" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" ) @@ -57,17 +57,17 @@ func printSubscription(subscription *messagingv1.Subscription, options hprinters var subscriber, reply, dls string if subscription.Spec.Subscriber != nil { - subscriber = flags.SinkToString(*subscription.Spec.Subscriber) + subscriber = sinkfl.SinkToString(*subscription.Spec.Subscriber) } else { subscriber = "" } if subscription.Spec.Reply != nil { - reply = flags.SinkToString(*subscription.Spec.Reply) + reply = sinkfl.SinkToString(*subscription.Spec.Reply) } else { reply = "" } if subscription.Spec.Delivery != nil && subscription.Spec.Delivery.DeadLetterSink != nil { - dls = flags.SinkToString(*subscription.Spec.Delivery.DeadLetterSink) + dls = sinkfl.SinkToString(*subscription.Spec.Delivery.DeadLetterSink) } else { dls = "" } diff --git a/pkg/kn/commands/subscription/list.go b/pkg/kn/commands/subscription/list.go index d77da3741d..c88f240acb 100644 --- a/pkg/kn/commands/subscription/list.go +++ b/pkg/kn/commands/subscription/list.go @@ -19,19 +19,19 @@ package subscription import ( "fmt" - "knative.dev/client/pkg/util" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" + "knative.dev/client-pkg/pkg/util" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" "github.com/spf13/cobra" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewSubscriptionListCommand is for listing subscription objects func NewSubscriptionListCommand(p *commands.KnParams) *cobra.Command { - listFlags := flags.NewListPrintFlags(ListHandlers) + listFlags := listfl.NewPrintFlags(ListHandlers) listCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/subscription/list_test.go b/pkg/kn/commands/subscription/list_test.go index 28f29c2e7d..c2dd5430dc 100644 --- a/pkg/kn/commands/subscription/list_test.go +++ b/pkg/kn/commands/subscription/list_test.go @@ -25,8 +25,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" clientv1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" ) diff --git a/pkg/kn/commands/subscription/subscription_test.go b/pkg/kn/commands/subscription/subscription_test.go index 8a19d066bc..c1b4766b85 100644 --- a/pkg/kn/commands/subscription/subscription_test.go +++ b/pkg/kn/commands/subscription/subscription_test.go @@ -26,7 +26,7 @@ import ( duckv1 "knative.dev/pkg/apis/duck/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - kndynamic "knative.dev/client/pkg/dynamic" + kndynamic "knative.dev/client-pkg/pkg/dynamic" "knative.dev/client/pkg/kn/commands" clientv1 "knative.dev/client/pkg/messaging/v1" ) diff --git a/pkg/kn/commands/subscription/update.go b/pkg/kn/commands/subscription/update.go index 851755cc07..7f0dd09879 100644 --- a/pkg/kn/commands/subscription/update.go +++ b/pkg/kn/commands/subscription/update.go @@ -20,20 +20,20 @@ import ( "errors" "fmt" - "knative.dev/client/pkg/config" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/config" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" "github.com/spf13/cobra" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" knmessagingv1 "knative.dev/client/pkg/messaging/v1" ) // NewSubscriptionUpdateCommand to update event subscriptions func NewSubscriptionUpdateCommand(p *commands.KnParams) *cobra.Command { - var subscriberFlag, replyFlag, dlsFlag flags.SinkFlags + var subscriberFlag, replyFlag, dlsFlag sinkfl.Flag cmd := &cobra.Command{ Use: "update NAME", Short: "Update an event subscription", diff --git a/pkg/kn/commands/subscription/update_test.go b/pkg/kn/commands/subscription/update_test.go index 41f21d57d9..01ee42c698 100644 --- a/pkg/kn/commands/subscription/update_test.go +++ b/pkg/kn/commands/subscription/update_test.go @@ -21,9 +21,9 @@ import ( "gotest.tools/v3/assert" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" v1beta1 "knative.dev/client/pkg/messaging/v1" - "knative.dev/client/pkg/util" ) func TestUpdateSubscriptionErrorCase(t *testing.T) { diff --git a/pkg/kn/commands/testing_helper.go b/pkg/kn/commands/testing_helper.go index 391d8ab9c7..a8b1ac94d7 100644 --- a/pkg/kn/commands/testing_helper.go +++ b/pkg/kn/commands/testing_helper.go @@ -17,7 +17,7 @@ package commands import ( "bytes" - "knative.dev/client/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/dynamic/fake" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/runtime" @@ -30,7 +30,7 @@ import ( sourcesv1fake "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1/fake" - clientdynamic "knative.dev/client/pkg/dynamic" + clientdynamic "knative.dev/client-pkg/pkg/dynamic" ) const FakeNamespace = "current" diff --git a/pkg/kn/commands/testing_helper_test.go b/pkg/kn/commands/testing_helper_test.go index 0685010abb..f78ae9673d 100644 --- a/pkg/kn/commands/testing_helper_test.go +++ b/pkg/kn/commands/testing_helper_test.go @@ -21,7 +21,7 @@ import ( "github.com/spf13/cobra" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" ) func TestCreateTestKnCommand(t *testing.T) { diff --git a/pkg/kn/commands/trigger/create.go b/pkg/kn/commands/trigger/create.go index 181c750551..f22cd789b1 100644 --- a/pkg/kn/commands/trigger/create.go +++ b/pkg/kn/commands/trigger/create.go @@ -19,18 +19,18 @@ import ( "fmt" "github.com/spf13/cobra" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" duckv1 "knative.dev/pkg/apis/duck/v1" clientv1beta1 "knative.dev/client/pkg/eventing/v1" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewTriggerCreateCommand to create trigger create command func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command { var triggerUpdateFlags TriggerUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "create NAME --sink SINK", diff --git a/pkg/kn/commands/trigger/create_test.go b/pkg/kn/commands/trigger/create_test.go index fafb3f4d56..9e486633bc 100644 --- a/pkg/kn/commands/trigger/create_test.go +++ b/pkg/kn/commands/trigger/create_test.go @@ -22,9 +22,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" clienteventingv1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" ) var ( diff --git a/pkg/kn/commands/trigger/delete_test.go b/pkg/kn/commands/trigger/delete_test.go index b2f21797f0..55233a8783 100644 --- a/pkg/kn/commands/trigger/delete_test.go +++ b/pkg/kn/commands/trigger/delete_test.go @@ -20,8 +20,8 @@ import ( "gotest.tools/v3/assert" + "knative.dev/client-pkg/pkg/util" eventingclientv1beta1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" ) func TestTriggerDelete(t *testing.T) { diff --git a/pkg/kn/commands/trigger/describe.go b/pkg/kn/commands/trigger/describe.go index 278c67499f..f57e854d9b 100644 --- a/pkg/kn/commands/trigger/describe.go +++ b/pkg/kn/commands/trigger/describe.go @@ -19,9 +19,9 @@ import ( "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" + "knative.dev/client-pkg/pkg/printers" "knative.dev/client/lib/printing" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/printers" v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1" ) diff --git a/pkg/kn/commands/trigger/describe_test.go b/pkg/kn/commands/trigger/describe_test.go index 4d5188965e..554a5c0d1c 100644 --- a/pkg/kn/commands/trigger/describe_test.go +++ b/pkg/kn/commands/trigger/describe_test.go @@ -20,7 +20,7 @@ import ( "errors" "testing" - "knative.dev/client/pkg/printers" + "knative.dev/client-pkg/pkg/printers" "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" @@ -30,8 +30,8 @@ import ( "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/client-pkg/pkg/util" clientv1beta1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" ) func TestSimpleDescribe(t *testing.T) { diff --git a/pkg/kn/commands/trigger/list.go b/pkg/kn/commands/trigger/list.go index 7c952a2bab..5fd119939d 100644 --- a/pkg/kn/commands/trigger/list.go +++ b/pkg/kn/commands/trigger/list.go @@ -18,14 +18,14 @@ import ( "fmt" "github.com/spf13/cobra" + listfl "knative.dev/client-pkg/pkg/commands/flags/list" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" ) // NewTriggerListCommand represents 'kn trigger list' command func NewTriggerListCommand(p *commands.KnParams) *cobra.Command { - triggerListFlags := flags.NewListPrintFlags(TriggerListHandlers) + triggerListFlags := listfl.NewPrintFlags(TriggerListHandlers) triggerListCommand := &cobra.Command{ Use: "list", diff --git a/pkg/kn/commands/trigger/list_flags.go b/pkg/kn/commands/trigger/list_flags.go index a9dde8c379..e97e7981ff 100644 --- a/pkg/kn/commands/trigger/list_flags.go +++ b/pkg/kn/commands/trigger/list_flags.go @@ -19,9 +19,9 @@ import ( metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + hprinters "knative.dev/client-pkg/pkg/printers" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" - hprinters "knative.dev/client/pkg/printers" v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1" ) @@ -45,7 +45,7 @@ func TriggerListHandlers(h hprinters.PrintHandler) { func printTrigger(trigger *v1beta1.Trigger, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) { name := trigger.Name broker := trigger.Spec.Broker - sink := flags.SinkToString(trigger.Spec.Subscriber) + sink := sinkfl.SinkToString(trigger.Spec.Subscriber) age := commands.TranslateTimestampSince(trigger.CreationTimestamp) conditions := commands.ConditionsValue(trigger.Status.Conditions) ready := commands.ReadyCondition(trigger.Status.Conditions) diff --git a/pkg/kn/commands/trigger/list_test.go b/pkg/kn/commands/trigger/list_test.go index ca729d8290..d0442b1987 100644 --- a/pkg/kn/commands/trigger/list_test.go +++ b/pkg/kn/commands/trigger/list_test.go @@ -26,9 +26,9 @@ import ( eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/client-pkg/pkg/util" clienteventingv1 "knative.dev/client/pkg/eventing/v1" clientservingv1 "knative.dev/client/pkg/serving/v1" - "knative.dev/client/pkg/util" ) func TestTriggerList(t *testing.T) { diff --git a/pkg/kn/commands/trigger/trigger_test.go b/pkg/kn/commands/trigger/trigger_test.go index 8665f2dc58..33562aa61a 100644 --- a/pkg/kn/commands/trigger/trigger_test.go +++ b/pkg/kn/commands/trigger/trigger_test.go @@ -22,7 +22,7 @@ import ( "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" - clientdynamic "knative.dev/client/pkg/dynamic" + clientdynamic "knative.dev/client-pkg/pkg/dynamic" eventclientv1beta1 "knative.dev/client/pkg/eventing/v1" "knative.dev/client/pkg/kn/commands" ) diff --git a/pkg/kn/commands/trigger/update.go b/pkg/kn/commands/trigger/update.go index d0ab10610f..273033aa95 100644 --- a/pkg/kn/commands/trigger/update.go +++ b/pkg/kn/commands/trigger/update.go @@ -18,22 +18,22 @@ import ( "errors" "fmt" - "knative.dev/client/pkg/config" + sinkfl "knative.dev/client-pkg/pkg/commands/flags/sink" + "knative.dev/client-pkg/pkg/config" clientv1beta1 "knative.dev/client/pkg/eventing/v1" duckv1 "knative.dev/pkg/apis/duck/v1" "github.com/spf13/cobra" v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/kn/commands/flags" - "knative.dev/client/pkg/util" ) // NewTriggerUpdateCommand prepares the command for a tigger update func NewTriggerUpdateCommand(p *commands.KnParams) *cobra.Command { var triggerUpdateFlags TriggerUpdateFlags - var sinkFlags flags.SinkFlags + var sinkFlags sinkfl.Flag cmd := &cobra.Command{ Use: "update NAME", diff --git a/pkg/kn/commands/trigger/update_flags.go b/pkg/kn/commands/trigger/update_flags.go index fd3aacf90e..2059a2b104 100644 --- a/pkg/kn/commands/trigger/update_flags.go +++ b/pkg/kn/commands/trigger/update_flags.go @@ -19,7 +19,7 @@ import ( "github.com/spf13/cobra" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // TriggerUpdateFlags are flags for create and update a trigger diff --git a/pkg/kn/commands/trigger/update_test.go b/pkg/kn/commands/trigger/update_test.go index b9fb700eec..3baaf4728f 100644 --- a/pkg/kn/commands/trigger/update_test.go +++ b/pkg/kn/commands/trigger/update_test.go @@ -23,9 +23,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - dynamicfake "knative.dev/client/pkg/dynamic/fake" + dynamicfake "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/util" clienteventingv1 "knative.dev/client/pkg/eventing/v1" - "knative.dev/client/pkg/util" ) func TestTriggerUpdate(t *testing.T) { diff --git a/pkg/kn/commands/types.go b/pkg/kn/commands/types.go index 67621e0c18..0a59b359d8 100644 --- a/pkg/kn/commands/types.go +++ b/pkg/kn/commands/types.go @@ -33,10 +33,10 @@ import ( servingv1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" servingv1beta1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" - clientdynamic "knative.dev/client/pkg/dynamic" - knerrors "knative.dev/client/pkg/errors" + clientdynamic "knative.dev/client-pkg/pkg/dynamic" + knerrors "knative.dev/client-pkg/pkg/errors" clienteventingv1 "knative.dev/client/pkg/eventing/v1" clienteventingv1beta2 "knative.dev/client/pkg/eventing/v1beta2" clientmessagingv1 "knative.dev/client/pkg/messaging/v1" diff --git a/pkg/kn/commands/types_test.go b/pkg/kn/commands/types_test.go index 0ae5f166c6..e76aedf42c 100644 --- a/pkg/kn/commands/types_test.go +++ b/pkg/kn/commands/types_test.go @@ -21,12 +21,12 @@ import ( "strings" "testing" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" "gotest.tools/v3/assert" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) type configTestCase struct { diff --git a/pkg/kn/commands/version/version_test.go b/pkg/kn/commands/version/version_test.go index 8902fd9919..718a3f047f 100644 --- a/pkg/kn/commands/version/version_test.go +++ b/pkg/kn/commands/version/version_test.go @@ -25,8 +25,8 @@ import ( "gotest.tools/v3/assert" "sigs.k8s.io/yaml" + "knative.dev/client-pkg/pkg/util" "knative.dev/client/pkg/kn/commands" - "knative.dev/client/pkg/util" ) var versionOutputTemplate = `Version: {{.Version}} diff --git a/pkg/kn/flags/podspec.go b/pkg/kn/flags/podspec.go index 502cec14d5..9f49f8dba7 100644 --- a/pkg/kn/flags/podspec.go +++ b/pkg/kn/flags/podspec.go @@ -20,7 +20,7 @@ import ( "strings" corev1 "k8s.io/api/core/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "github.com/spf13/pflag" ) diff --git a/pkg/kn/flags/podspec_helper.go b/pkg/kn/flags/podspec_helper.go index 862b7b7b89..d1d9f1b4b8 100644 --- a/pkg/kn/flags/podspec_helper.go +++ b/pkg/kn/flags/podspec_helper.go @@ -30,7 +30,7 @@ import ( corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // VolumeSourceType is a type standing for enumeration of ConfigMap and Secret diff --git a/pkg/kn/flags/podspec_helper_test.go b/pkg/kn/flags/podspec_helper_test.go index b9bac561f3..6be309efe8 100644 --- a/pkg/kn/flags/podspec_helper_test.go +++ b/pkg/kn/flags/podspec_helper_test.go @@ -27,11 +27,11 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/api/resource" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" "gotest.tools/v3/assert" corev1 "k8s.io/api/core/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "knative.dev/pkg/ptr" ) diff --git a/pkg/kn/flags/podspec_test.go b/pkg/kn/flags/podspec_test.go index aaec95b799..3b8df147af 100644 --- a/pkg/kn/flags/podspec_test.go +++ b/pkg/kn/flags/podspec_test.go @@ -24,12 +24,12 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" "github.com/spf13/cobra" "gotest.tools/v3/assert" corev1 "k8s.io/api/core/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "knative.dev/pkg/ptr" ) diff --git a/pkg/kn/flags/resources.go b/pkg/kn/flags/resources.go index b703604648..945d89d0d9 100644 --- a/pkg/kn/flags/resources.go +++ b/pkg/kn/flags/resources.go @@ -18,7 +18,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // ResourceOptions to hold the container resource requirements values diff --git a/pkg/kn/plugin/verify_test.go b/pkg/kn/plugin/verify_test.go index 921a5fd9fa..1da9c96358 100644 --- a/pkg/kn/plugin/verify_test.go +++ b/pkg/kn/plugin/verify_test.go @@ -24,7 +24,7 @@ import ( "strconv" "testing" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "gotest.tools/v3/assert" ) diff --git a/pkg/kn/root/root_test.go b/pkg/kn/root/root_test.go index 52cc4f3a83..a20b490296 100644 --- a/pkg/kn/root/root_test.go +++ b/pkg/kn/root/root_test.go @@ -23,7 +23,7 @@ import ( "github.com/spf13/cobra" "gotest.tools/v3/assert" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestNewRootCommand(t *testing.T) { diff --git a/pkg/messaging/v1/channels_client.go b/pkg/messaging/v1/channels_client.go index 2f996155dc..5a4beb5a28 100644 --- a/pkg/messaging/v1/channels_client.go +++ b/pkg/messaging/v1/channels_client.go @@ -17,7 +17,7 @@ package v1 import ( "context" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" @@ -26,7 +26,7 @@ import ( messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" clientmessagingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" ) // KnChannelsClient for interacting with Channels diff --git a/pkg/messaging/v1/channels_client_mock.go b/pkg/messaging/v1/channels_client_mock.go index bc4cab109c..bb7120e2a4 100644 --- a/pkg/messaging/v1/channels_client_mock.go +++ b/pkg/messaging/v1/channels_client_mock.go @@ -20,7 +20,7 @@ import ( messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" ) type MockKnChannelsClient struct { diff --git a/pkg/messaging/v1/client.go b/pkg/messaging/v1/client.go index a3bf1064e2..eeadc12e52 100644 --- a/pkg/messaging/v1/client.go +++ b/pkg/messaging/v1/client.go @@ -21,7 +21,7 @@ import ( "knative.dev/eventing/pkg/client/clientset/versioned/scheme" clientv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // KnMessagingClient to Eventing Messaging. All methods are relative to diff --git a/pkg/messaging/v1/subscriptions_client.go b/pkg/messaging/v1/subscriptions_client.go index c52d902bdb..61c4dc5bfc 100644 --- a/pkg/messaging/v1/subscriptions_client.go +++ b/pkg/messaging/v1/subscriptions_client.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "k8s.io/client-go/util/retry" @@ -30,7 +30,7 @@ import ( clientmessagingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" duckv1 "knative.dev/pkg/apis/duck/v1" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" ) type SubscriptionUpdateFunc func(origSub *messagingv1.Subscription) (*messagingv1.Subscription, error) diff --git a/pkg/messaging/v1/subscriptions_client_mock.go b/pkg/messaging/v1/subscriptions_client_mock.go index 11091a03c2..1f84ad8c9f 100644 --- a/pkg/messaging/v1/subscriptions_client_mock.go +++ b/pkg/messaging/v1/subscriptions_client_mock.go @@ -22,7 +22,7 @@ import ( messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" ) type MockKnSubscriptionsClient struct { diff --git a/pkg/printers/interface_test.go b/pkg/printers/interface_test.go deleted file mode 100644 index d7105c60a2..0000000000 --- a/pkg/printers/interface_test.go +++ /dev/null @@ -1,31 +0,0 @@ -// 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 printers - -import ( - "fmt" - "io" - "testing" - - "gotest.tools/v3/assert" - "k8s.io/apimachinery/pkg/runtime" -) - -func TestResourcePrintObj(t *testing.T) { - mockFunc := ResourcePrinterFunc(func(runtime.Object, io.Writer) error { - return fmt.Errorf(mockErrorString) - }) - assert.Error(t, mockFunc.PrintObj(nil, nil), mockErrorString) -} diff --git a/pkg/printers/prefixwriter_test.go b/pkg/printers/prefixwriter_test.go deleted file mode 100644 index c1e2f03916..0000000000 --- a/pkg/printers/prefixwriter_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package printers - -import ( - "bytes" - "testing" - - "gotest.tools/v3/assert" -) - -func TestWriteColsLn(t *testing.T) { - buf := &bytes.Buffer{} - w := NewBarePrefixWriter(buf) - sub := w.WriteColsLn("a", "bbbb", "c", "ddd") - sub.WriteColsLn("B", "C", "D", "E") - expected := "a\tbbbb\tc\tddd\n\tB\tC\tD\tE\n" - actual := buf.String() - assert.Equal(t, actual, expected) -} - -func TestWriteAttribute(t *testing.T) { - buf := &bytes.Buffer{} - w := NewBarePrefixWriter(buf) - sub := w.WriteAttribute("Thing", "Stuff") - sub.WriteColsLn("B", "C", "D", "E") - expected := "Thing:\tStuff\n B\tC\tD\tE\n" - actual := buf.String() - assert.Equal(t, actual, expected) -} - -func TestWriteNested(t *testing.T) { - buf := &bytes.Buffer{} - w := NewBarePrefixWriter(buf) - sub := w.WriteColsLn("*", "Header") - subsub := sub.WriteAttribute("Thing", "stuff") - subsub.WriteAttribute("Subthing", "substuff") - expected := "*\tHeader\n\tThing:\tstuff\n\t Subthing:\tsubstuff\n" - actual := buf.String() - assert.Equal(t, actual, expected) -} diff --git a/pkg/printers/tablegenerator_test.go b/pkg/printers/tablegenerator_test.go deleted file mode 100644 index fca8aaf89d..0000000000 --- a/pkg/printers/tablegenerator_test.go +++ /dev/null @@ -1,120 +0,0 @@ -// 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 printers - -import ( - "fmt" - "reflect" - "testing" - "time" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/duration" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" - - "gotest.tools/v3/assert" - metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" -) - -const ( - mockErrorString = "This function returns an error" -) - -var ( - invalidPrintTypeFunc = true - invalidPrintFuncIncorrectInCount = func() ([]metav1beta1.TableRow, error) { return nil, nil } - invalidPrintFuncIncorrectInType = func(*servingv1.Service, bool) ([]metav1beta1.TableRow, error) { return nil, nil } - validPrintFunc = func(obj *servingv1.Service, opts PrintOptions) ([]metav1beta1.TableRow, error) { - tableRow := metav1beta1.TableRow{ - Object: runtime.RawExtension{Object: obj}, - } - tableRow.Cells = append(tableRow.Cells, obj.Namespace, obj.Name, duration.HumanDuration(time.Since(obj.CreationTimestamp.Time))) - return []metav1.TableRow{tableRow}, nil - } - validPrintFuncErrOutput = func(obj *servingv1.Service, opts PrintOptions) ([]metav1beta1.TableRow, error) { - return nil, fmt.Errorf(mockErrorString) - } - columnDefs = []metav1beta1.TableColumnDefinition{ - {Name: "Namespace", Type: "string", Description: "Namespace of mock instance", Priority: 0}, - {Name: "Name", Type: "string", Description: "Name of the mock instance", Priority: 1}, - {Name: "Age", Type: "string", Description: "Age of the mock instance", Priority: 1}, - } -) - -// Do we need this function? -func TestValidateRowPrintHandlerFunc(t *testing.T) { - assert.Error(t, ValidateRowPrintHandlerFunc(reflect.ValueOf(invalidPrintTypeFunc)), fmt.Sprintf("invalid print handler. %#v is not a function", reflect.ValueOf(invalidPrintTypeFunc))) - assert.Error(t, ValidateRowPrintHandlerFunc(reflect.ValueOf(invalidPrintFuncIncorrectInCount)), fmt.Sprintf("invalid print handler."+ - "Must accept 2 parameters and return 2 value.")) - assert.Error(t, ValidateRowPrintHandlerFunc(reflect.ValueOf(invalidPrintFuncIncorrectInType)), fmt.Sprintf("invalid print handler. The expected signature is: "+ - "func handler(obj %v, options PrintOptions) ([]metav1beta1.TableRow, error)", reflect.TypeOf(&servingv1.Service{}))) - assert.NilError(t, ValidateRowPrintHandlerFunc(reflect.ValueOf(validPrintFunc))) -} - -func TestTableHandler(t *testing.T) { - h := NewTableGenerator() - assert.ErrorContains(t, h.TableHandler(columnDefs, invalidPrintTypeFunc), "invalid print handler") - assert.ErrorContains(t, h.TableHandler(columnDefs, invalidPrintFuncIncorrectInCount), "invalid print handler") - assert.ErrorContains(t, h.TableHandler(columnDefs, invalidPrintFuncIncorrectInType), "invalid print handler") - assert.NilError(t, h.TableHandler(columnDefs, validPrintFunc)) - assert.ErrorContains(t, h.TableHandler(columnDefs, validPrintFunc), "registered duplicate printer") -} - -func TestGenerateTable(t *testing.T) { - h := NewTableGenerator() - myksvc := &servingv1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "myksvc", Namespace: "default"}, - } - _, err := h.GenerateTable(myksvc, h.options) - assert.ErrorContains(t, err, "no table handler registered for this type") - err = h.TableHandler(columnDefs, validPrintFunc) - assert.NilError(t, err) - table, err := h.GenerateTable(myksvc, h.options) - assert.NilError(t, err) - expected := metav1beta1.TableRow{ - Object: runtime.RawExtension{Object: myksvc}, - } - expected.Cells = append(expected.Cells, myksvc.Namespace, myksvc.Name, duration.HumanDuration(time.Since(myksvc.CreationTimestamp.Time))) - assert.DeepEqual(t, table.Rows[0], expected) - - myksvcList := &servingv1.ServiceList{ - TypeMeta: metav1.TypeMeta{}, - ListMeta: metav1.ListMeta{}, - Items: []servingv1.Service{*myksvc}, - } - - printServiceList := func(objList *servingv1.ServiceList, opts PrintOptions) ([]metav1beta1.TableRow, error) { - rows := make([]metav1beta1.TableRow, 0, len(objList.Items)) - for _, obj := range objList.Items { - row, err := validPrintFunc(&obj, h.options) - assert.NilError(t, err) - rows = append(rows, row...) - } - return rows, nil - } - err = h.TableHandler(columnDefs, printServiceList) - assert.NilError(t, err) - table, err = h.GenerateTable(myksvcList, h.options) - assert.NilError(t, err) - assert.DeepEqual(t, table.Rows[0], expected) - - // Create new human readable printer - h = NewTableGenerator() - assert.NilError(t, h.TableHandler(columnDefs, validPrintFuncErrOutput)) - _, err = h.GenerateTable(myksvc, h.options) - assert.Error(t, err, mockErrorString) -} diff --git a/pkg/printers/tableprinter_test.go b/pkg/printers/tableprinter_test.go deleted file mode 100644 index 5f4d31a78f..0000000000 --- a/pkg/printers/tableprinter_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// 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 printers - -import ( - "bytes" - "os" - "testing" - - "gotest.tools/v3/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "knative.dev/client/pkg/util" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" -) - -func TestPrintObj(t *testing.T) { - h := NewTablePrinter(PrintOptions{}) - assert.Assert(t, h != nil) - assert.NilError(t, h.PrintObj(nil, nil)) - - myksvc := &servingv1.Service{ - TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1"}, - ObjectMeta: metav1.ObjectMeta{Name: "myksvc", Namespace: "default"}, - } - assert.ErrorContains(t, h.PrintObj(myksvc, os.Stdout), "unknown type") - h.TableHandler(columnDefs, validPrintFunc) - var out bytes.Buffer - assert.NilError(t, h.PrintObj(myksvc, &out)) - assert.Assert(t, util.ContainsAll(out.String(), "myksvc")) - h = NewTablePrinter(PrintOptions{}) - h.TableHandler(columnDefs, validPrintFuncErrOutput) - assert.Error(t, h.PrintObj(myksvc, os.Stdout), mockErrorString) -} diff --git a/pkg/serving/config_changes_test.go b/pkg/serving/config_changes_test.go index 1aa21e8302..740ab07029 100644 --- a/pkg/serving/config_changes_test.go +++ b/pkg/serving/config_changes_test.go @@ -24,7 +24,7 @@ import ( "knative.dev/pkg/ptr" "knative.dev/serving/pkg/apis/autoscaling" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/serving/v1/apply.go b/pkg/serving/v1/apply.go index 11808b426a..40588d69f4 100644 --- a/pkg/serving/v1/apply.go +++ b/pkg/serving/v1/apply.go @@ -15,7 +15,7 @@ import ( "k8s.io/apimachinery/pkg/util/jsonmergepatch" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // Copyright © 2020 The Knative Authors diff --git a/pkg/serving/v1/apply_test.go b/pkg/serving/v1/apply_test.go index c1526f0945..3e6009bff3 100644 --- a/pkg/serving/v1/apply_test.go +++ b/pkg/serving/v1/apply_test.go @@ -30,7 +30,7 @@ import ( servingv1 "knative.dev/serving/pkg/apis/serving/v1" "sigs.k8s.io/yaml" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func TestApplyServiceWithNoImage(t *testing.T) { diff --git a/pkg/serving/v1/client.go b/pkg/serving/v1/client.go index f5c6e964a9..5a3aa4e953 100644 --- a/pkg/serving/v1/client.go +++ b/pkg/serving/v1/client.go @@ -20,7 +20,7 @@ import ( "fmt" "time" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "k8s.io/client-go/util/retry" @@ -29,9 +29,9 @@ import ( "knative.dev/pkg/apis" "knative.dev/serving/pkg/client/clientset/versioned/scheme" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" "knative.dev/client/pkg/serving" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -41,7 +41,7 @@ import ( servingv1 "knative.dev/serving/pkg/apis/serving/v1" clientv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" - clienterrors "knative.dev/client/pkg/errors" + clienterrors "knative.dev/client-pkg/pkg/errors" ) // Func signature for an updating function which returns the updated service object diff --git a/pkg/serving/v1/client_mock.go b/pkg/serving/v1/client_mock.go index ad2a1fb1b4..f446b8d713 100644 --- a/pkg/serving/v1/client_mock.go +++ b/pkg/serving/v1/client_mock.go @@ -24,8 +24,8 @@ import ( "k8s.io/apimachinery/pkg/labels" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - "knative.dev/client/pkg/util/mock" - "knative.dev/client/pkg/wait" + "knative.dev/client-pkg/pkg/util/mock" + "knative.dev/client-pkg/pkg/wait" ) type MockKnServingClient struct { diff --git a/pkg/serving/v1/client_mock_test.go b/pkg/serving/v1/client_mock_test.go index 2945daae85..34c0400020 100644 --- a/pkg/serving/v1/client_mock_test.go +++ b/pkg/serving/v1/client_mock_test.go @@ -22,8 +22,8 @@ import ( "knative.dev/serving/pkg/apis/serving" servingv1 "knative.dev/serving/pkg/apis/serving/v1" - "knative.dev/client/pkg/util/mock" - "knative.dev/client/pkg/wait" + "knative.dev/client-pkg/pkg/util/mock" + "knative.dev/client-pkg/pkg/wait" ) func TestMockKnClient(t *testing.T) { diff --git a/pkg/serving/v1/client_test.go b/pkg/serving/v1/client_test.go index 480b9dfd2f..ca1a5020e7 100644 --- a/pkg/serving/v1/client_test.go +++ b/pkg/serving/v1/client_test.go @@ -42,8 +42,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" clienttesting "k8s.io/client-go/testing" - "knative.dev/client/pkg/util" - "knative.dev/client/pkg/wait" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" ) var testNamespace = "test-ns" diff --git a/pkg/serving/v1/gitops.go b/pkg/serving/v1/gitops.go index d3b3d05798..7dcc9ad1ea 100644 --- a/pkg/serving/v1/gitops.go +++ b/pkg/serving/v1/gitops.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/cli-runtime/pkg/genericclioptions" - "knative.dev/client/pkg/wait" + "knative.dev/client-pkg/pkg/wait" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/serving/v1/gitops_test.go b/pkg/serving/v1/gitops_test.go index 8095dccceb..4632fcc3a8 100644 --- a/pkg/serving/v1/gitops_test.go +++ b/pkg/serving/v1/gitops_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" servingtest "knative.dev/serving/pkg/testing/v1" - libtest "knative.dev/client/lib/test" + libtest "knative.dev/client-pkg/pkg/util/test" "knative.dev/pkg/ptr" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/pkg/serving/v1beta1/client.go b/pkg/serving/v1beta1/client.go index aa4301c50b..81fe12ff11 100644 --- a/pkg/serving/v1beta1/client.go +++ b/pkg/serving/v1beta1/client.go @@ -18,7 +18,7 @@ import ( "context" "fmt" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "k8s.io/client-go/util/retry" @@ -26,8 +26,8 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - knerrors "knative.dev/client/pkg/errors" - "knative.dev/client/pkg/util" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1" "knative.dev/serving/pkg/client/clientset/versioned/scheme" clientv1beta1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1" diff --git a/pkg/serving/v1beta1/client_mock.go b/pkg/serving/v1beta1/client_mock.go index ea18cee093..470b956c1a 100644 --- a/pkg/serving/v1beta1/client_mock.go +++ b/pkg/serving/v1beta1/client_mock.go @@ -18,7 +18,7 @@ import ( "context" "testing" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1" ) diff --git a/pkg/serving/v1beta1/client_test.go b/pkg/serving/v1beta1/client_test.go index 8fb03bf5a0..cc40d4042d 100644 --- a/pkg/serving/v1beta1/client_test.go +++ b/pkg/serving/v1beta1/client_test.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" clienttesting "k8s.io/client-go/testing" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" duckv1 "knative.dev/pkg/apis/duck/v1" servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1" "knative.dev/serving/pkg/client/clientset/versioned/scheme" diff --git a/pkg/sources/v1/apiserver_client.go b/pkg/sources/v1/apiserver_client.go index 09a59d0855..f84d3bcff4 100644 --- a/pkg/sources/v1/apiserver_client.go +++ b/pkg/sources/v1/apiserver_client.go @@ -20,8 +20,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - knerrors "knative.dev/client/pkg/errors" - "knative.dev/client/pkg/util" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/eventing/pkg/apis/sources/v1" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" diff --git a/pkg/sources/v1/apiserver_client_mock.go b/pkg/sources/v1/apiserver_client_mock.go index be1cee50b5..9fffb66bad 100644 --- a/pkg/sources/v1/apiserver_client_mock.go +++ b/pkg/sources/v1/apiserver_client_mock.go @@ -20,7 +20,7 @@ import ( v1 "knative.dev/eventing/pkg/apis/sources/v1" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" ) // MockKnAPIServerSourceClient for mocking the client diff --git a/pkg/sources/v1/binding_client.go b/pkg/sources/v1/binding_client.go index 0a23cd1b3f..fd197dfe96 100644 --- a/pkg/sources/v1/binding_client.go +++ b/pkg/sources/v1/binding_client.go @@ -28,8 +28,8 @@ import ( duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/pkg/tracker" - knerrors "knative.dev/client/pkg/errors" - "knative.dev/client/pkg/util" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" ) // KnSinkBindingClient to Eventing Sources. All methods are relative to the diff --git a/pkg/sources/v1/binding_client_mock.go b/pkg/sources/v1/binding_client_mock.go index c3f0d33a5d..ab79482364 100644 --- a/pkg/sources/v1/binding_client_mock.go +++ b/pkg/sources/v1/binding_client_mock.go @@ -20,7 +20,7 @@ import ( v1 "knative.dev/eventing/pkg/apis/sources/v1" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" ) // MockKnSinkBindingClient is a combine of test object and recorder diff --git a/pkg/sources/v1/container_client.go b/pkg/sources/v1/container_client.go index 7e9e408154..7aaef5118f 100644 --- a/pkg/sources/v1/container_client.go +++ b/pkg/sources/v1/container_client.go @@ -20,15 +20,15 @@ import ( "context" "fmt" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "k8s.io/client-go/util/retry" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - knerrors "knative.dev/client/pkg/errors" - "knative.dev/client/pkg/util" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" v1 "knative.dev/eventing/pkg/apis/sources/v1" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" clientv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1" diff --git a/pkg/sources/v1/container_client_mock.go b/pkg/sources/v1/container_client_mock.go index 19a34ae104..59416e61d2 100644 --- a/pkg/sources/v1/container_client_mock.go +++ b/pkg/sources/v1/container_client_mock.go @@ -20,7 +20,7 @@ import ( "context" "testing" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" v1 "knative.dev/eventing/pkg/apis/sources/v1" ) diff --git a/pkg/sources/v1beta2/ping_client.go b/pkg/sources/v1beta2/ping_client.go index 8ae3843906..2d0e1e94ba 100644 --- a/pkg/sources/v1beta2/ping_client.go +++ b/pkg/sources/v1beta2/ping_client.go @@ -18,15 +18,15 @@ import ( "context" "fmt" - "knative.dev/client/pkg/config" + "knative.dev/client-pkg/pkg/config" "k8s.io/client-go/util/retry" "k8s.io/apimachinery/pkg/runtime" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" - knerrors "knative.dev/client/pkg/errors" + knerrors "knative.dev/client-pkg/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" diff --git a/pkg/sources/v1beta2/ping_client_mock.go b/pkg/sources/v1beta2/ping_client_mock.go index 44b2c97870..42623f0369 100644 --- a/pkg/sources/v1beta2/ping_client_mock.go +++ b/pkg/sources/v1beta2/ping_client_mock.go @@ -18,7 +18,7 @@ import ( "context" "testing" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" ) diff --git a/pkg/templates/command_groups_test.go b/pkg/templates/command_groups_test.go index 0b7fcae66f..7e11c9d6d7 100644 --- a/pkg/templates/command_groups_test.go +++ b/pkg/templates/command_groups_test.go @@ -22,8 +22,8 @@ import ( "github.com/spf13/cobra" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) var groups = CommandGroups{ diff --git a/pkg/templates/template_engine_test.go b/pkg/templates/template_engine_test.go index 4d5b4722c8..d8b250a7f6 100644 --- a/pkg/templates/template_engine_test.go +++ b/pkg/templates/template_engine_test.go @@ -23,8 +23,8 @@ import ( "github.com/spf13/cobra" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) type testData struct { diff --git a/pkg/util/compare_test.go b/pkg/util/compare_test.go deleted file mode 100644 index 261cf83765..0000000000 --- a/pkg/util/compare_test.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "fmt" - "reflect" - "strings" - "testing" - - "gotest.tools/v3/assert" - "gotest.tools/v3/assert/cmp" -) - -type containsAllTestCase struct { - target string - substrings []string - success bool - missing []string -} - -type containsNoneTestCase struct { - target string - substrings []string - success bool - contains []string -} - -func TestContainsAll(t *testing.T) { - for i, tc := range []containsAllTestCase{ - { - target: "NAME SERVICE AGE CONDITIONS READY REASON", - substrings: []string{"REASON", "AGE"}, - success: true, - }, - { - "No resources found.", - []string{"NAME", "AGE"}, - false, - []string{"NAME", "AGE"}, - }, - { - "NAME SERVICE AGE CONDITIONS READY REASON", - []string{"NAME", "URL", "DOMAIN", "READY"}, - false, - []string{"URL", "DOMAIN"}, - }, - { - target: "Sword!", - substrings: []string{}, - success: true, - }, - } { - result := ContainsAll(tc.target, tc.substrings...)() - if result.Success() != tc.success { - t.Errorf("%d: Expecting %s to contain %s", i, tc.target, tc.substrings) - } - if !tc.success { - message := fmt.Sprintf("\nActual output: %s\nMissing strings: %s", tc.target, strings.Join(tc.missing[:], ", ")) - if !reflect.DeepEqual(result, cmp.ResultFailure(message)) { - t.Errorf("%d: Incorrect error message returned\nGot: %v\nExpecting: %s", i, result, message) - } - } - } -} - -func TestContainsIgnoreCase(t *testing.T) { - for i, tc := range []containsAllTestCase{ - { - target: "NAME SERVICE AGE CONDITIONS READY REASON", - substrings: []string{"reason", "age"}, - success: true, - }, - { - "No resources found.", - []string{"NAME", "AGE"}, - false, - []string{"name", "age"}, - }, - { - "NAME SERVICE AGE CONDITIONS READY REASON", - []string{"name", "url", "domain", "ready"}, - false, - []string{"url", "domain"}, - }, - } { - result := ContainsAllIgnoreCase(tc.target, tc.substrings...)() - if result.Success() != tc.success { - t.Errorf("%d: Expecting %s to contain %s", i, tc.target, tc.substrings) - } - if !tc.success { - message := fmt.Sprintf("\nActual output (lower-cased): %s\nMissing strings (lower-cased): %s", strings.ToLower(tc.target), strings.ToLower(strings.Join(tc.missing[:], ", "))) - if !reflect.DeepEqual(result, cmp.ResultFailure(message)) { - t.Errorf("%d: Incorrect error message returned\n. Got: %v\nExpecting: %s", i, result, message) - } - } - } -} - -func TestContainsNone(t *testing.T) { - for i, tc := range []containsNoneTestCase{ - { - target: "NAME SERVICE AGE CONDITIONS", - substrings: []string{"REASON", "READY", "foo", "bar"}, - success: true, - }, - { - "NAME SERVICE AGE CONDITIONS READY REASON", - []string{"foo", "bar", "NAME", "AGE"}, - false, - []string{"NAME", "AGE"}, - }, - { - "No resources found", - []string{"NAME", "URL", "DOMAIN", "READY", "resources"}, - false, - []string{"resources"}, - }, - { - target: "Sword!", - substrings: []string{}, - success: true, - }, - } { - comparison := ContainsNone(tc.target, tc.substrings...) - result := comparison() - if result.Success() != tc.success { - t.Errorf("%d: Expecting %s to contain %s", i, tc.target, tc.substrings) - } - if !tc.success { - message := fmt.Sprintf("\nActual output: %s\nContains strings: %s", tc.target, strings.Join(tc.contains[:], ", ")) - if !reflect.DeepEqual(result, cmp.ResultFailure(message)) { - t.Errorf("%d: Incorrect error message returned\nExpecting: %s", i, message) - } - } - } -} - -func TestSliceContainsIgnoreCase(t *testing.T) { - assert.Equal(t, - SliceContainsIgnoreCase([]string{"FOO", "bar"}, "foo"), - true) - assert.Equal(t, - SliceContainsIgnoreCase([]string{"BAR", "bar"}, "foo"), - false) -} diff --git a/pkg/util/corev1_helper_test.go b/pkg/util/corev1_helper_test.go deleted file mode 100644 index 52e4bfbd32..0000000000 --- a/pkg/util/corev1_helper_test.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2020 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 util - -import ( - "testing" - - "gotest.tools/v3/assert" -) - -func TestGenerateVolumeName(t *testing.T) { - actual := []string{ - "Ab12~`!@#$%^&*()-=_+[]{}|/\\<>,./?:;\"'xZ", - "/Ab12~`!@#$%^&*()-=_+[]{}|/\\<>,./?:;\"'xZ/", - "", - "/", - "/path.mypath/", - "/.path.mypath", - } - - expected := []string{ - "ab12---------------------------------xz", - "ab12---------------------------------xz-", - "k-", - "k-", - "path-mypath-", - "k--path-mypath", - } - - for i := range actual { - actualName := GenerateVolumeName(actual[i]) - expectedName := appendCheckSum(expected[i], actual[i]) - assert.Equal(t, actualName, expectedName) - } - - // 63 char limit case, no need to append the checksum in expected string - expName_63 := "k---ab12---------------------------------xz-ab12--------------n" - assert.Equal(t, len(expName_63), 63) - assert.Equal(t, GenerateVolumeName("/./Ab12~`!@#$%^&*()-=_+[]{}|/\\<>,./?:;\"'xZ/Ab12~`!@#$%^&*()-=_+[]{}|/\\<>,./?:;\"'xZ/"), expName_63) -} diff --git a/pkg/util/logging_http_transport_test.go b/pkg/util/logging_http_transport_test.go deleted file mode 100644 index 915024715c..0000000000 --- a/pkg/util/logging_http_transport_test.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "bytes" - "errors" - "fmt" - "io" - "net/http" - "net/http/httputil" - "strings" - "testing" - - "gotest.tools/v3/assert" -) - -type fakeTransport struct { - requestDump string -} - -func (d *fakeTransport) RoundTrip(r *http.Request) (*http.Response, error) { - dump, err := httputil.DumpRequest(r, true) - if err != nil { - return nil, fmt.Errorf("dumping request: %w", err) - } - d.requestDump = string(dump) - return &http.Response{ - Status: "200 OK", - StatusCode: 200, - Proto: "HTTP/1.0", - Body: io.NopCloser(strings.NewReader("")), - }, nil -} - -type errorTransport struct{} - -func (d *errorTransport) RoundTrip(r *http.Request) (*http.Response, error) { - return nil, errors.New("This is an error") -} - -func TestWritesRequestResponse(t *testing.T) { - out := &bytes.Buffer{} - dt := &fakeTransport{} - transport := NewLoggingTransportWithStream(dt, out) - - body := "{this: is, the: body, of: [the, request]}" - req, _ := http.NewRequest("POST", "http://example.com", strings.NewReader(body)) - nonRedacted := "this string will be logged" - redacted := "this string will be redacted" - req.Header.Add("non-redacted", nonRedacted) - req.Header.Add(sensitiveRequestHeaders.List()[0], redacted) - - _, e := transport.RoundTrip(req) - assert.NilError(t, e) - s := out.String() - assert.Assert(t, strings.Contains(s, "REQUEST")) - assert.Assert(t, strings.Contains(s, "RESPONSE")) - assert.Assert(t, strings.Contains(s, body)) - assert.Assert(t, strings.Contains(s, nonRedacted)) - assert.Assert(t, !strings.Contains(s, redacted)) - - assert.Assert(t, strings.Contains(dt.requestDump, body)) - assert.Assert(t, strings.Contains(dt.requestDump, nonRedacted)) - assert.Assert(t, strings.Contains(dt.requestDump, redacted)) -} - -func TestElideAuthorizationHeader(t *testing.T) { - out := &bytes.Buffer{} - transport := NewLoggingTransportWithStream(&fakeTransport{}, out) - req, _ := http.NewRequest("GET", "http://example.com", nil) - req.Header.Set("X-Normal-Header", "la la normal text") - req.Header.Set("Authorization", "Bearer: SECRET") - _, e := transport.RoundTrip(req) - assert.NilError(t, e) - s := out.String() - assert.Assert(t, strings.Contains(s, "REQUEST")) - assert.Assert(t, strings.Contains(s, "Authorization")) - assert.Assert(t, strings.Contains(s, "********")) - assert.Assert(t, strings.Contains(s, "la la normal text")) - assert.Assert(t, !strings.Contains(s, "SECRET")) - assert.Assert(t, strings.Contains(s, "RESPONSE")) -} - -func TestWritesRequestError(t *testing.T) { - out := &bytes.Buffer{} - transport := NewLoggingTransportWithStream(&errorTransport{}, out) - req, _ := http.NewRequest("GET", "http://example.com", nil) - transport.RoundTrip(req) - s := out.String() - assert.Assert(t, strings.Contains(s, "REQUEST")) - assert.Assert(t, strings.Contains(s, "ERROR")) -} diff --git a/pkg/util/orderedmap_test.go b/pkg/util/orderedmap_test.go deleted file mode 100644 index 0475406dcf..0000000000 --- a/pkg/util/orderedmap_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "testing" - - "gotest.tools/v3/assert" -) - -func TestOrderedMapCreate(t *testing.T) { - initial := [][]string{{"1", "v1"}, {"2", "v2"}, {"3", "v3"}} - o := NewOrderedMapWithKVStrings(initial) - it := o.Iterator() - - assert.Equal(t, o.Len(), len(initial)) - i := 0 - - for k, v, ok := it.NextString(); ok; k, v, ok = it.NextString() { - assert.Equal(t, k, initial[i][0]) - assert.Equal(t, v, initial[i][1]) - i++ - } -} - -func TestOrderedMapSet(t *testing.T) { - initial := [][]string{{"1", "v1"}, {"2", "v2"}, {"3", "v3"}} - o := NewOrderedMapWithKVStrings(initial) - o.Set("4", "v4") - o.Set("2", "v2-1") - - expected := [][]string{{"1", "v1"}, {"2", "v2-1"}, {"3", "v3"}, {"4", "v4"}} - assert.Equal(t, o.Len(), len(expected)) - - i := 0 - it := o.Iterator() - - for k, v, ok := it.NextString(); ok; k, v, ok = it.NextString() { - assert.Equal(t, k, expected[i][0]) - assert.Equal(t, v, expected[i][1]) - i++ - } -} - -func TestOrderedMapGet(t *testing.T) { - initial := [][]string{{"1", "v1"}, {"2", "v2"}, {"3", "v3"}} - o := NewOrderedMapWithKVStrings(initial) - o.Set("4", "v4") - o.Set("2", "v2-1") - - expected := [][]string{{"1", "v1"}, {"2", "v2-1"}, {"3", "v3"}, {"4", "v4"}} - assert.Equal(t, o.Len(), len(expected)) - - for i := 0; i < len(expected); i++ { - assert.Equal(t, o.GetStringWithDefault(expected[i][0], ""), expected[i][1]) - } -} - -func TestOrderedMapDelete(t *testing.T) { - initial := [][]string{{"1", "v1"}, {"2", "v2"}, {"3", "v3"}} - o := NewOrderedMapWithKVStrings(initial) - o.Set("4", "v4") - o.Set("2", "v2-1") - o.Delete("3") - o.Delete("1") - - expected := [][]string{{"2", "v2-1"}, {"4", "v4"}} - assert.Equal(t, o.Len(), len(expected)) - - i := 0 - it := o.Iterator() - - for k, v, ok := it.NextString(); ok; k, v, ok = it.NextString() { - assert.Equal(t, k, expected[i][0]) - assert.Equal(t, v, expected[i][1]) - i++ - } -} diff --git a/pkg/util/parsing_helper_test.go b/pkg/util/parsing_helper_test.go deleted file mode 100644 index 60532ca852..0000000000 --- a/pkg/util/parsing_helper_test.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "fmt" - "os" - "testing" - - "gotest.tools/v3/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "knative.dev/pkg/tracker" -) - -func TestMapFromArray(t *testing.T) { - testMapFromArray(t, []string{"good=value"}, "=", map[string]string{"good": "value"}) - testMapFromArray(t, []string{"multi=value", "other=value"}, "=", map[string]string{"multi": "value", "other": "value"}) - testMapFromArray(t, []string{"only,split,once", "just,once,"}, ",", map[string]string{"only": "split,once", "just": "once,"}) - testMapFromArray(t, []string{"empty="}, "=", map[string]string{"empty": ""}) -} - -func testMapFromArray(t *testing.T, input []string, delimiter string, expected map[string]string) { - actual, err := MapFromArray(input, delimiter) - assert.NilError(t, err) - assert.DeepEqual(t, expected, actual) -} - -func TestKeyValuePairListAndRemovalListFromArray(t *testing.T) { - testKeyValuePairListAndRemovalListFromArray(t, []string{"add=value"}, "=", [][]string{{"add", "value"}}, []string{}) - testKeyValuePairListAndRemovalListFromArray(t, []string{"add=value", "remove-"}, "=", [][]string{{"add", "value"}}, []string{"remove"}) -} - -func testKeyValuePairListAndRemovalListFromArray(t *testing.T, input []string, delimiter string, expectedKVList [][]string, expectedList []string) { - actualKVList, actualList, err := OrderedMapAndRemovalListFromArray(input, delimiter) - assert.NilError(t, err) - assert.DeepEqual(t, NewOrderedMapWithKVStrings(expectedKVList), actualKVList) - assert.DeepEqual(t, expectedList, actualList) -} - -func TestMapFromArrayNoDelimiter(t *testing.T) { - input := []string{"badvalue"} - _, err := MapFromArray(input, "+") - assert.ErrorContains(t, err, "Argument requires") - assert.ErrorContains(t, err, "+") -} - -func TestMapFromArrayNoDelimiterAllowingSingles(t *testing.T) { - input := []string{"okvalue"} - actual, err := MapFromArrayAllowingSingles(input, "+") - expected := map[string]string{"okvalue": ""} - assert.NilError(t, err) - assert.DeepEqual(t, expected, actual) -} - -func TestMapFromArrayEmptyValueEmptyDelimiter(t *testing.T) { - input := []string{""} - _, err := MapFromArray(input, "") - assert.ErrorContains(t, err, "Argument requires") -} - -func TestMapFromArrayEmptyValueEmptyDelimiterAllowingSingles(t *testing.T) { - input := []string{""} - _, err := MapFromArrayAllowingSingles(input, "") - assert.ErrorContains(t, err, "Argument requires") -} - -func TestMapFromArrayMapRepeat(t *testing.T) { - input := []string{"a1=b1", "a1=b2"} - _, err := MapFromArrayAllowingSingles(input, "=") - assert.ErrorContains(t, err, "duplicate") -} - -func TestMapFromArrayMapKeyEmpty(t *testing.T) { - input := []string{"=a1"} - _, err := MapFromArrayAllowingSingles(input, "=") - assert.ErrorContains(t, err, "empty") -} - -func TestParseMinusSuffix(t *testing.T) { - inputMap := map[string]string{"a1": "b1", "a2-": ""} - expectedMap := map[string]string{"a1": "b1"} - expectedStringToRemove := []string{"a2"} - stringToRemove := ParseMinusSuffix(inputMap) - assert.DeepEqual(t, expectedMap, inputMap) - assert.DeepEqual(t, expectedStringToRemove, stringToRemove) -} - -func TestStringMap(t *testing.T) { - inputMap := StringMap{"a1": "b1", "a2": "b2"} - mergedMap := map[string]string{"a1": "b1-new", "a3": "b3"} - removedKeys := []string{"a2", "a4"} - - inputMap.Merge(mergedMap).Remove(removedKeys) - expectedMap := StringMap{"a1": "b1-new", "a3": "b3"} - assert.DeepEqual(t, expectedMap, inputMap) -} - -func TestAddedAndRemovalListFromArray(t *testing.T) { - addList, removeList := AddedAndRemovalListsFromArray([]string{"addvalue1", "remove1-", "addvalue2", "remove2-"}) - assert.DeepEqual(t, []string{"addvalue1", "addvalue2"}, addList) - assert.DeepEqual(t, []string{"remove1", "remove2"}, removeList) - - addList, removeList = AddedAndRemovalListsFromArray([]string{"remove1-"}) - assert.DeepEqual(t, []string{}, addList) - assert.DeepEqual(t, []string{"remove1"}, removeList) - - addList, removeList = AddedAndRemovalListsFromArray([]string{"addvalue1"}) - assert.DeepEqual(t, []string{"addvalue1"}, addList) - assert.DeepEqual(t, []string{}, removeList) -} - -func TestToTrackerReference(t *testing.T) { - testToTrackerReference(t, - "Broker:eventing.knative.dev/v1:default", "demo", - &tracker.Reference{ - APIVersion: "eventing.knative.dev/v1", - Kind: "Broker", - Namespace: "demo", - Name: "default", - Selector: nil, - }, nil) - testToTrackerReference(t, - "Broker:eventing.knative.dev/v1:default", "", - &tracker.Reference{ - APIVersion: "eventing.knative.dev/v1", - Kind: "Broker", - Namespace: "", - Name: "default", - Selector: nil, - }, nil) - testToTrackerReference(t, - "Job:batch/v1:app=heartbeat-cron,priority=high", "demo", - &tracker.Reference{ - APIVersion: "batch/v1", - Kind: "Job", - Namespace: "demo", - Name: "", - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "app": "heartbeat-cron", - "priority": "high", - }, - }, - }, nil) - testToTrackerReference(t, "", "demo", nil, - funcRef(func(t *testing.T, err error) { - assert.ErrorContains(t, err, "not in format kind:api/version:nameOrSelector") - })) - testToTrackerReference(t, "Job:batch/v1:app=acme,cmea", "demo", nil, - funcRef(func(t *testing.T, err error) { - assert.ErrorContains(t, err, "expected format: key1=value,key2=value") - })) - testToTrackerReference(t, "Job:batch/v1/next:acme", "demo", nil, - funcRef(func(t *testing.T, err error) { - assert.ErrorContains(t, err, "unexpected GroupVersion string") - })) -} - -func testToTrackerReference(t *testing.T, input, namespace string, expected *tracker.Reference, errMatch *func(*testing.T, error)) { - t.Helper() - t.Run(fmt.Sprintf("%s:%s", input, namespace), func(t *testing.T) { - ref, err := ToTrackerReference(input, namespace) - if err != nil { - if errMatch != nil { - m := *errMatch - m(t, err) - } else { - assert.NilError(t, err, "unexpected error") - } - } - assert.DeepEqual(t, expected, ref) - }) -} - -func funcRef(ref func(t *testing.T, err error)) *func(*testing.T, error) { - return &ref -} - -func TestGetEnvsFromFile(t *testing.T) { - file, err := os.CreateTemp("", "test-1") - assert.NilError(t, err) - file.WriteString(` -name=service-1 - -target=hello-world - -`) - defer os.Remove(file.Name()) - - envs, err := GetEnvsFromFile(file.Name(), "=") - assert.NilError(t, err) - assert.DeepEqual(t, envs, []string{"name=service-1", "target=hello-world"}) -} - -func TestGetEnvsFromFileErrorNotFound(t *testing.T) { - envs, err := GetEnvsFromFile("/tmp/somerandom/path/bla/bla", "=") - assert.ErrorContains(t, err, "no such file or directory") - assert.DeepEqual(t, envs, []string{}) -} diff --git a/pkg/util/schema_handling_test.go b/pkg/util/schema_handling_test.go deleted file mode 100644 index 861a43900a..0000000000 --- a/pkg/util/schema_handling_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "testing" - - "k8s.io/apimachinery/pkg/runtime/schema" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" - "knative.dev/serving/pkg/client/clientset/versioned/scheme" -) - -func TestGVKUpdate(t *testing.T) { - service := servingv1.Service{} - err := UpdateGroupVersionKindWithScheme(&service, servingv1.SchemeGroupVersion, scheme.Scheme) - if err != nil { - t.Fatalf("cannot update GVK to a service %v", err) - } - if service.Kind != "Service" { - t.Fatalf("wrong kind '%s'", service.Kind) - } - if service.APIVersion != servingv1.SchemeGroupVersion.Group+"/"+servingv1.SchemeGroupVersion.Version { - t.Fatalf("wrong version '%s'", service.APIVersion) - } -} - -func TestGVKUpdateNegative(t *testing.T) { - service := servingv1.Service{} - err := UpdateGroupVersionKindWithScheme(&service, schema.GroupVersion{Group: "bla", Version: "blub"}, scheme.Scheme) - if err == nil { - t.Fatal("expect an error for an unregistered group version") - } -} diff --git a/pkg/util/unstructured_test.go b/pkg/util/unstructured_test.go deleted file mode 100644 index 0b9af60fda..0000000000 --- a/pkg/util/unstructured_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "testing" - - "gotest.tools/v3/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" -) - -func TestToUnstructuredList(t *testing.T) { - serviceList := servingv1.ServiceList{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "List", - }, - Items: []servingv1.Service{createService("s1"), createService("s2")}, - } - expectedList := &unstructured.UnstructuredList{ - Object: map[string]interface{}{ - "apiVersion": "v1", - "kind": "List", - }, - } - expectedList.Items = []unstructured.Unstructured{createUnstructured("s1"), createUnstructured("s2")} - unstructuredList, err := ToUnstructuredList(&serviceList) - assert.NilError(t, err) - assert.DeepEqual(t, unstructuredList, expectedList) - - service1 := createService("s3") - expectedList = &unstructured.UnstructuredList{} - expectedList.Items = []unstructured.Unstructured{createUnstructured("s3")} - unstructuredList, err = ToUnstructuredList(&service1) - assert.NilError(t, err) - assert.DeepEqual(t, unstructuredList, expectedList) -} - -func createService(name string) servingv1.Service { - service := servingv1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - APIVersion: "serving.knative.dev/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: "default", - }, - } - return service -} - -func createUnstructured(name string) unstructured.Unstructured { - return unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "serving.knative.dev/v1", - "kind": "Service", - "metadata": map[string]interface{}{ - "namespace": "default", - "name": name, - "creationTimestamp": nil, - }, - "spec": map[string]interface{}{ - "template": map[string]interface{}{ - "metadata": map[string]interface{}{"creationTimestamp": nil}, - "spec": map[string]interface{}{"containers": nil}, - }, - }, - "status": map[string]interface{}{}, - }, - } -} diff --git a/pkg/wait/poll_watcher_test.go b/pkg/wait/poll_watcher_test.go deleted file mode 100644 index 707c8d1fbe..0000000000 --- a/pkg/wait/poll_watcher_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package wait - -import ( - "context" - "fmt" - "sync" - "testing" - "time" - - "gotest.tools/v3/assert" - api_errors "k8s.io/apimachinery/pkg/api/errors" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" - - servingv1 "knative.dev/serving/pkg/apis/serving/v1" -) - -type fakePollInterval struct { - c chan time.Time -} - -func (f *fakePollInterval) PollChan() <-chan time.Time { - return f.c -} - -func (f *fakePollInterval) Stop() {} - -func newFakePollInterval(n int) PollInterval { - c := make(chan time.Time, n) - t := time.Now() - for i := 0; i < n; i++ { - c <- t.Add(time.Duration(i) * time.Second) - } - return &fakePollInterval{c} -} - -func newWatcherForTest(pollResults []runtime.Object) watch.Interface { - i := 0 - poll := func() (runtime.Object, error) { - defer func() { i++ }() - if pollResults[i] == nil { - // 404 - return nil, api_errors.NewNotFound(schema.GroupResource{Group: "thing", Resource: "stuff"}, "eggs") - } - return pollResults[i], nil - } - ret := &pollingWatcher{nil, "", "", "", time.Minute, make(chan bool), make(chan watch.Event), &sync.WaitGroup{}, - newFakePollInterval(len(pollResults)), poll} - ret.start() - return ret -} - -var a, aa, b, bb, c, cc, z, zz runtime.Object - -func init() { - a = &servingv1.Service{ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "a", UID: "one"}} - aa = a.DeepCopyObject() - b = &servingv1.Service{ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "b", UID: "one"}} - bb = b.DeepCopyObject() - c = &servingv1.Service{ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "c", UID: "one"}} - cc = c.DeepCopyObject() - z = &servingv1.Service{ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "z", UID: "two"}} - zz = z.DeepCopyObject() -} - -type testCase struct { - pollResults []runtime.Object - watchResults []watch.Event -} - -func TestNewWatcherWithVersion(t *testing.T) { - w, err := NewWatcherWithVersion(context.Background(), watchF(func(context.Context, metav1.ListOptions) (watch.Interface, error) { - return NewFakeWatch([]watch.Event{}), nil - }), nil, "mockNamespace", "resourceName", "mockName", "v1", 5*time.Second) - w.Stop() - assert.NilError(t, err) - w, err = NewWatcherWithVersion(context.Background(), watchF(func(context.Context, metav1.ListOptions) (watch.Interface, error) { - return NewFakeWatch([]watch.Event{}), fmt.Errorf("mockErrMsg") - }), nil, "mockNamespace", "resourceName", "mockName", "v1", 5*time.Second) - w.Stop() - assert.NilError(t, err) -} - -func TestPollWatcher(t *testing.T) { - cases := []testCase{ - // Doesn't exist for a while, then does for a while. - {[]runtime.Object{nil, nil, a, aa, nil}, []watch.Event{{Type: watch.Added, Object: a}, {Type: watch.Deleted, Object: a}}}, - // Changes. - {[]runtime.Object{a, b}, []watch.Event{{Type: watch.Added, Object: a}, {Type: watch.Modified, Object: b}}}, - // Changes but stays the same a couple times too. - {[]runtime.Object{a, aa, b, bb, c, cc, nil}, - []watch.Event{{Type: watch.Added, Object: a}, {Type: watch.Modified, Object: b}, {Type: watch.Modified, Object: c}, {Type: watch.Deleted, Object: c}}}, - // Deleted and recreated between polls. - {[]runtime.Object{a, z}, []watch.Event{{Type: watch.Added, Object: a}, {Type: watch.Deleted, Object: a}, {Type: watch.Added, Object: z}}}, - } - for _, c := range cases { - w := newWatcherForTest(c.pollResults) - for _, expected := range c.watchResults { - actual := <-w.ResultChan() - assert.Equal(t, actual.Type, expected.Type) - if actual.Type == watch.Added || actual.Type == watch.Modified || actual.Type == watch.Deleted { - fmt.Printf("expected, %v, actual %v\n", expected, actual) - assert.Equal(t, actual.Object.(metav1.Object).GetResourceVersion(), expected.Object.(metav1.Object).GetResourceVersion()) - assert.Equal(t, actual.Object.(metav1.Object).GetUID(), expected.Object.(metav1.Object).GetUID()) - } - } - w.Stop() - } -} diff --git a/pkg/wait/wait_for_ready_test.go b/pkg/wait/wait_for_ready_test.go deleted file mode 100644 index a6cdc40aed..0000000000 --- a/pkg/wait/wait_for_ready_test.go +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package wait - -import ( - "bytes" - "context" - "errors" - "fmt" - "testing" - "time" - - "gotest.tools/v3/assert" - "gotest.tools/v3/assert/cmp" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/watch" - "knative.dev/client/pkg/util" - "knative.dev/pkg/apis" - duckv1 "knative.dev/pkg/apis/duck/v1" - servingv1 "knative.dev/serving/pkg/apis/serving/v1" -) - -type waitForReadyTestCase struct { - testcase string - events []watch.Event - timeout time.Duration - errorText string - messagesExpected []string -} - -func TestWaitCancellation(t *testing.T) { - fakeWatchApi := NewFakeWatch([]watch.Event{}) - fakeWatchApi.Start() - wfe := NewWaitForEvent("foobar", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return fakeWatchApi, nil - }, - func(e *watch.Event) bool { - return false - }) - - timeout := time.Second * 5 - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go func() { - time.Sleep(time.Millisecond * 500) - cancel() - }() - err, _ := wfe.Wait(ctx, "foobar", "", Options{Timeout: &timeout}, NoopMessageCallback()) - assert.Assert(t, errors.Is(err, context.Canceled)) - - ctx, cancel = context.WithCancel(context.Background()) - defer cancel() - go func() { - time.Sleep(time.Millisecond * 500) - cancel() - }() - wfr := NewWaitForReady( - "blub", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return fakeWatchApi, nil - }, - func(obj runtime.Object) (apis.Conditions, error) { - return apis.Conditions(obj.(*servingv1.Service).Status.Conditions), nil - }) - window := 2 * time.Second - err, _ = wfr.Wait(ctx, "foobar", "", Options{Timeout: nil, ErrorWindow: &window}, NoopMessageCallback()) - assert.Assert(t, errors.Is(err, context.Canceled)) -} - -func TestAddWaitForReady(t *testing.T) { - - for _, tc := range prepareTestCases(t, "test-service") { - tc := tc - t.Run(tc.testcase, func(t *testing.T) { - - fakeWatchApi := NewFakeWatch(tc.events) - waitForReady := NewWaitForReady( - "blub", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return fakeWatchApi, nil - }, - conditionsFor) - fakeWatchApi.Start() - msgs := make([]string, 0) - err, _ := waitForReady.Wait(context.Background(), "foobar", "", Options{Timeout: &tc.timeout}, func(_ time.Duration, msg string) { - msgs = append(msgs, msg) - }) - close(fakeWatchApi.eventChan) - - if tc.errorText == "" && err != nil { - t.Errorf("Error received %v", err) - return - } - if tc.errorText != "" { - if err == nil { - t.Error("No error but expected one") - } else { - assert.ErrorContains(t, err, tc.errorText) - } - } - - // check messages - assert.Assert(t, cmp.DeepEqual(tc.messagesExpected, msgs), "Messages expected to be equal") - - if fakeWatchApi.StopCalled != 1 { - t.Errorf("Exactly one 'stop' should be called, but got %d", fakeWatchApi.StopCalled) - } - - }) - } -} - -func TestAddWaitForReadyWithChannelClose(t *testing.T) { - for _, tc := range prepareTestCases(t, "test-service") { - tc := tc - t.Run(tc.testcase, func(t *testing.T) { - - fakeWatchApi := NewFakeWatch(tc.events) - counter := 0 - waitForReady := NewWaitForReady( - "blub", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - if counter == 0 { - close(fakeWatchApi.eventChan) - counter++ - return fakeWatchApi, nil - } - fakeWatchApi.eventChan = make(chan watch.Event) - fakeWatchApi.Start() - return fakeWatchApi, nil - }, - conditionsFor) - msgs := make([]string, 0) - - err, _ := waitForReady.Wait(context.Background(), "foobar", "", Options{Timeout: &tc.timeout}, func(_ time.Duration, msg string) { - msgs = append(msgs, msg) - }) - close(fakeWatchApi.eventChan) - - if tc.errorText == "" && err != nil { - t.Errorf("Error received %v", err) - return - } - if tc.errorText != "" { - if err == nil { - t.Error("No error but expected one") - } else { - assert.ErrorContains(t, err, tc.errorText) - } - } - - // check messages - assert.Assert(t, cmp.DeepEqual(tc.messagesExpected, msgs), "Messages expected to be equal") - - if fakeWatchApi.StopCalled != 2 { - t.Errorf("Exactly one 'stop' should be called, but got %d", fakeWatchApi.StopCalled) - } - - }) - } -} - -func TestWaitTimeout(t *testing.T) { - fakeWatchApi := NewFakeWatch([]watch.Event{}) - timeout := time.Second * 3 - wfe := NewWaitForEvent("foobar", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return fakeWatchApi, nil - }, - func(e *watch.Event) bool { - return false - }) - - err, _ := wfe.Wait(context.Background(), "foobar", "", Options{Timeout: &timeout}, NoopMessageCallback()) - assert.ErrorContains(t, err, "not ready") - assert.Assert(t, fakeWatchApi.StopCalled == 1) - - fakeWatchApi = NewFakeWatch([]watch.Event{}) - wfr := NewWaitForReady( - "blub", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return fakeWatchApi, nil - }, - conditionsFor) - err, _ = wfr.Wait(context.Background(), "foobar", "", Options{Timeout: &timeout}, NoopMessageCallback()) - assert.ErrorContains(t, err, "not ready") - assert.Assert(t, fakeWatchApi.StopCalled == 1) -} - -func TestWaitWatchError(t *testing.T) { - timeout := time.Second * 3 - wfe := NewWaitForEvent("foobar", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return nil, fmt.Errorf("error creating watcher") - }, - func(e *watch.Event) bool { - return false - }) - - err, _ := wfe.Wait(context.Background(), "foobar", "", Options{Timeout: &timeout}, NoopMessageCallback()) - assert.ErrorContains(t, err, "error creating watcher") - - wfr := NewWaitForReady( - "blub", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return nil, fmt.Errorf("error creating watcher") - }, - func(obj runtime.Object) (apis.Conditions, error) { - return apis.Conditions(obj.(*servingv1.Service).Status.Conditions), nil - }) - err, _ = wfr.Wait(context.Background(), "foobar", "", Options{Timeout: &timeout}, NoopMessageCallback()) - assert.ErrorContains(t, err, "error creating watcher") -} - -func TestAddWaitForDelete(t *testing.T) { - for _, tc := range prepareDeleteTestCases("test-service") { - tc := tc - t.Run(tc.testcase, func(t *testing.T) { - - fakeWatchAPI := NewFakeWatch(tc.events) - - waitForEvent := NewWaitForEvent( - "blub", - func(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { - return fakeWatchAPI, nil - }, - func(evt *watch.Event) bool { return evt.Type == watch.Deleted }) - fakeWatchAPI.Start() - - err, _ := waitForEvent.Wait(context.Background(), "foobar", "", Options{Timeout: &tc.timeout}, NoopMessageCallback()) - close(fakeWatchAPI.eventChan) - - if tc.errorText == "" && err != nil { - t.Errorf("Error received %v", err) - return - } - if tc.errorText != "" { - if err == nil { - t.Error("No error but expected one") - } else { - assert.ErrorContains(t, err, tc.errorText) - } - } - - if fakeWatchAPI.StopCalled != 1 { - t.Errorf("Exactly one 'stop' should be called, but got %d", fakeWatchAPI.StopCalled) - } - - }) - } -} - -func TestSimpleMessageCallback(t *testing.T) { - var out bytes.Buffer - callback := SimpleMessageCallback(&out) - callback(5*time.Second, "hello") - assert.Assert(t, util.ContainsAll(out.String(), "hello")) - callback(5*time.Second, "hello") - assert.Assert(t, util.ContainsAll(out.String(), "...")) -} - -// Test cases which consists of a series of events to send and the expected behaviour. -func prepareTestCases(tb testing.TB, name string) []waitForReadyTestCase { - return []waitForReadyTestCase{ - errorTest(name), - tc("peNormal", peNormal, name, 5*time.Second, ""), - tc("peUnstructured", peUnstructured(tb), name, 5*time.Second, - ""), - tc("peWrongGeneration", peWrongGeneration, name, 5*time.Second, - "timeout"), - tc("peMissingGeneration", peMissingGeneration(tb), name, 5*time.Second, - "no field 'generation' in metadata"), - tc("peTimeout", peTimeout, name, 5*time.Second, "timeout"), - tc("peReadyFalseWithinErrorWindow", peReadyFalseWithinErrorWindow, - name, 5*time.Second, ""), - } -} - -func prepareDeleteTestCases(name string) []waitForReadyTestCase { - return []waitForReadyTestCase{ - tc("deNormal", deNormal, name, time.Second, ""), - tc("peTimeout", peTimeout, name, 10*time.Second, "timeout"), - } -} - -func errorTest(name string) waitForReadyTestCase { - events := []watch.Event{ - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", "msg1")}, - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionFalse, corev1.ConditionTrue, "FakeError", "Test Error")}, - } - - return waitForReadyTestCase{ - testcase: "errorTest", - events: events, - timeout: 5 * time.Second, - errorText: "FakeError", - messagesExpected: []string{"msg1", "Test Error"}, - } -} - -func tc(testcase string, f func(name string) (evts []watch.Event, nrMessages int), name string, timeout time.Duration, errorTxt string) waitForReadyTestCase { - events, nrMsgs := f(name) - return waitForReadyTestCase{ - testcase, - events, - timeout, - errorTxt, - pMessages(nrMsgs), - } -} - -func pMessages(max int) []string { - return []string{ - "msg1", "msg2", "msg3", "msg4", "msg5", "msg6", - }[:max] -} - -// ============================================================================= - -func peNormal(name string) ([]watch.Event, int) { - messages := pMessages(2) - return []watch.Event{ - {Type: watch.Added, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", messages[0], 1, 2)}, - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", messages[0], 2, 2)}, - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionTrue, "", messages[1], 2, 2)}, - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "", "", 2, 2)}, - }, len(messages) -} - -func peUnstructured(tb testing.TB) func(name string) ([]watch.Event, int) { - return func(name string) ([]watch.Event, int) { - events, msgLen := peNormal(name) - for i, event := range events { - unC, err := runtime.DefaultUnstructuredConverter.ToUnstructured(event.Object) - if err != nil { - tb.Fatal(err) - } - if event.Type == watch.Added { - delete(unC, "status") - } - un := unstructured.Unstructured{Object: unC} - events[i] = watch.Event{ - Type: event.Type, - Object: &un, - } - } - return events, msgLen - } -} - -func peTimeout(name string) ([]watch.Event, int) { - messages := pMessages(1) - return []watch.Event{ - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", messages[0])}, - }, len(messages) -} - -func peWrongGeneration(name string) ([]watch.Event, int) { - messages := pMessages(1) - return []watch.Event{ - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", messages[0])}, - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "", "", 1, 2)}, - }, len(messages) -} - -func peMissingGeneration(tb testing.TB) func(name string) ([]watch.Event, int) { - return func(name string) ([]watch.Event, int) { - svc := CreateTestServiceWithConditions(name, - corev1.ConditionUnknown, corev1.ConditionUnknown, - "", "") - unC, err := runtime.DefaultUnstructuredConverter.ToUnstructured(svc) - if err != nil { - tb.Fatal(err) - } - metadata, ok := unC["metadata"].(map[string]interface{}) - assert.Check(tb, ok) - delete(metadata, "generation") - un := unstructured.Unstructured{Object: unC} - return []watch.Event{ - {Type: watch.Modified, Object: &un}, - }, 0 - } -} - -func peReadyFalseWithinErrorWindow(name string) ([]watch.Event, int) { - messages := pMessages(1) - return []watch.Event{ - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionFalse, corev1.ConditionFalse, "Route not ready", messages[0])}, - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "Route ready", "")}, - }, len(messages) -} - -func deNormal(name string) ([]watch.Event, int) { - messages := pMessages(2) - return []watch.Event{ - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", messages[0])}, - {Type: watch.Modified, Object: CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionTrue, "", messages[1])}, - {Type: watch.Deleted, Object: CreateTestServiceWithConditions(name, corev1.ConditionTrue, corev1.ConditionTrue, "", "")}, - }, len(messages) -} - -func conditionsFor(obj runtime.Object) (apis.Conditions, error) { - if un, ok := obj.(*unstructured.Unstructured); ok { - kresource := duckv1.KResource{} - err := runtime.DefaultUnstructuredConverter. - FromUnstructured(un.UnstructuredContent(), &kresource) - if err != nil { - return nil, err - } - return kresource.GetStatus().GetConditions(), nil - } - return apis.Conditions(obj.(duckv1.KRShaped).GetStatus().Conditions), nil -} diff --git a/test/e2e/basic_workflow_test.go b/test/e2e/basic_workflow_test.go index 199b285624..87a1b5a5c1 100644 --- a/test/e2e/basic_workflow_test.go +++ b/test/e2e/basic_workflow_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestBasicWorkflow(t *testing.T) { diff --git a/test/e2e/broker_test.go b/test/e2e/broker_test.go index 461dfad848..85b4ed0dbf 100644 --- a/test/e2e/broker_test.go +++ b/test/e2e/broker_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestBroker(t *testing.T) { diff --git a/test/e2e/channels_test.go b/test/e2e/channels_test.go index b3ad947b1f..bc002da9cf 100644 --- a/test/e2e/channels_test.go +++ b/test/e2e/channels_test.go @@ -21,8 +21,8 @@ import ( "testing" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) const ( diff --git a/test/e2e/domain_mapping_test.go b/test/e2e/domain_mapping_test.go index e6f9f0ef87..73e5cfa1cd 100644 --- a/test/e2e/domain_mapping_test.go +++ b/test/e2e/domain_mapping_test.go @@ -32,11 +32,11 @@ import ( "testing" "time" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" ) func TestDomain(t *testing.T) { diff --git a/test/e2e/eventtype_test.go b/test/e2e/eventtype_test.go index 9172391067..cc8c079322 100644 --- a/test/e2e/eventtype_test.go +++ b/test/e2e/eventtype_test.go @@ -21,8 +21,8 @@ import ( "testing" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) const ( diff --git a/test/e2e/extra_containers_test.go b/test/e2e/extra_containers_test.go index 4d09ddfad8..464f92e9e4 100644 --- a/test/e2e/extra_containers_test.go +++ b/test/e2e/extra_containers_test.go @@ -26,12 +26,12 @@ import ( "strings" "testing" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" pkgtest "knative.dev/pkg/test" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" ) func TestMultiContainers(t *testing.T) { diff --git a/test/e2e/ping_test.go b/test/e2e/ping_test.go index 80fa0b4202..bf168a8ec1 100644 --- a/test/e2e/ping_test.go +++ b/test/e2e/ping_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestSourcePing(t *testing.T) { diff --git a/test/e2e/plugins_test.go b/test/e2e/plugins_test.go index f4404d75e6..9048b3f0de 100644 --- a/test/e2e/plugins_test.go +++ b/test/e2e/plugins_test.go @@ -26,8 +26,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) const ( diff --git a/test/e2e/revision_test.go b/test/e2e/revision_test.go index fd9fb9a340..3c06b5c087 100644 --- a/test/e2e/revision_test.go +++ b/test/e2e/revision_test.go @@ -22,7 +22,7 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" ) func TestRevision(t *testing.T) { diff --git a/test/e2e/route_test.go b/test/e2e/route_test.go index 8880f9582b..bcc3b5167e 100644 --- a/test/e2e/route_test.go +++ b/test/e2e/route_test.go @@ -24,8 +24,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestRoute(t *testing.T) { diff --git a/test/e2e/service_apply_test.go b/test/e2e/service_apply_test.go index 64c9ca4e36..077764b028 100644 --- a/test/e2e/service_apply_test.go +++ b/test/e2e/service_apply_test.go @@ -24,8 +24,8 @@ import ( pkgtest "knative.dev/pkg/test" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestServiceApply(t *testing.T) { diff --git a/test/e2e/service_export_test.go b/test/e2e/service_export_test.go index f787329f0d..ec3527d794 100644 --- a/test/e2e/service_export_test.go +++ b/test/e2e/service_export_test.go @@ -26,7 +26,7 @@ import ( "sigs.k8s.io/yaml" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" corev1 "k8s.io/api/core/v1" clientv1alpha1 "knative.dev/client/pkg/apis/client/v1alpha1" diff --git a/test/e2e/service_file_test.go b/test/e2e/service_file_test.go index 266c84b29c..0115dd6558 100644 --- a/test/e2e/service_file_test.go +++ b/test/e2e/service_file_test.go @@ -26,8 +26,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" pkgtest "knative.dev/pkg/test" ) diff --git a/test/e2e/service_import_test.go b/test/e2e/service_import_test.go index 9bbf343c0a..7db9015b88 100644 --- a/test/e2e/service_import_test.go +++ b/test/e2e/service_import_test.go @@ -23,8 +23,8 @@ import ( "testing" "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestServiceImport(t *testing.T) { diff --git a/test/e2e/service_options_test.go b/test/e2e/service_options_test.go index ce1962c499..1052fc1ce1 100644 --- a/test/e2e/service_options_test.go +++ b/test/e2e/service_options_test.go @@ -30,8 +30,8 @@ import ( "gotest.tools/v3/assert" corev1 "k8s.io/api/core/v1" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" pkgtest "knative.dev/pkg/test" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ) diff --git a/test/e2e/service_test.go b/test/e2e/service_test.go index 62e3c402c0..0d17712b87 100644 --- a/test/e2e/service_test.go +++ b/test/e2e/service_test.go @@ -26,8 +26,8 @@ import ( "gotest.tools/v3/assert" v1 "k8s.io/api/core/v1" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" network "knative.dev/networking/pkg/apis/networking" pkgtest "knative.dev/pkg/test" "knative.dev/serving/pkg/apis/serving" diff --git a/test/e2e/sink_test.go b/test/e2e/sink_test.go index 118a7f8196..4c9cedc35b 100644 --- a/test/e2e/sink_test.go +++ b/test/e2e/sink_test.go @@ -22,7 +22,7 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" ) func TestSink(t *testing.T) { diff --git a/test/e2e/sinkprefix_test.go b/test/e2e/sinkprefix_test.go index bfaa55feac..63c9edfd08 100644 --- a/test/e2e/sinkprefix_test.go +++ b/test/e2e/sinkprefix_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) const ( diff --git a/test/e2e/source_apiserver_test.go b/test/e2e/source_apiserver_test.go index d7db394163..ed513076f9 100644 --- a/test/e2e/source_apiserver_test.go +++ b/test/e2e/source_apiserver_test.go @@ -24,8 +24,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) const ( diff --git a/test/e2e/source_binding_test.go b/test/e2e/source_binding_test.go index c41894607c..4e6339a44a 100644 --- a/test/e2e/source_binding_test.go +++ b/test/e2e/source_binding_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestSourceBinding(t *testing.T) { diff --git a/test/e2e/source_container_test.go b/test/e2e/source_container_test.go index 973d417472..6064236ef3 100644 --- a/test/e2e/source_container_test.go +++ b/test/e2e/source_container_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" pkgtest "knative.dev/pkg/test" ) diff --git a/test/e2e/source_list_crd_test.go b/test/e2e/source_list_crd_test.go index 988a815827..9151c0ad6f 100644 --- a/test/e2e/source_list_crd_test.go +++ b/test/e2e/source_list_crd_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) // This test requires cluster admin permissions due to working with CustomResourceDefinitions. diff --git a/test/e2e/source_list_test.go b/test/e2e/source_list_test.go index d5660cc595..ebb9c27a44 100644 --- a/test/e2e/source_list_test.go +++ b/test/e2e/source_list_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestSourceListTypes(t *testing.T) { diff --git a/test/e2e/subscription_test.go b/test/e2e/subscription_test.go index 3242563145..26116ec70c 100644 --- a/test/e2e/subscription_test.go +++ b/test/e2e/subscription_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestSubscriptions(t *testing.T) { diff --git a/test/e2e/tekton_test.go b/test/e2e/tekton_test.go index 4d375e956d..695ea68c1c 100644 --- a/test/e2e/tekton_test.go +++ b/test/e2e/tekton_test.go @@ -27,8 +27,8 @@ import ( "gotest.tools/v3/assert" "k8s.io/apimachinery/pkg/util/wait" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) const ( diff --git a/test/e2e/traffic_split_test.go b/test/e2e/traffic_split_test.go index 46d0204fcd..13522cff30 100644 --- a/test/e2e/traffic_split_test.go +++ b/test/e2e/traffic_split_test.go @@ -25,7 +25,7 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" + "knative.dev/client-pkg/pkg/util/test" ) var targetsSeparator = "|" diff --git a/test/e2e/trigger_test.go b/test/e2e/trigger_test.go index df037117ea..a1d8968d84 100644 --- a/test/e2e/trigger_test.go +++ b/test/e2e/trigger_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestBrokerTrigger(t *testing.T) { diff --git a/test/e2e/version_test.go b/test/e2e/version_test.go index cd83696569..8edb612268 100644 --- a/test/e2e/version_test.go +++ b/test/e2e/version_test.go @@ -22,8 +22,8 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/lib/test" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/util/test" ) func TestVersion(t *testing.T) { diff --git a/vendor/knative.dev/client-pkg/pkg/apis/client/register.go b/vendor/knative.dev/client-pkg/pkg/apis/client/register.go new file mode 100644 index 0000000000..cf294021e3 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/apis/client/register.go @@ -0,0 +1,22 @@ +/* +Copyright 2020 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 client + +// GroupName is the group name used in this package +const ( + GroupName = "client-pkg.knative.dev" +) diff --git a/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/doc.go b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/doc.go new file mode 100644 index 0000000000..ae2317276f --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 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. +*/ + +// +k8s:deepcopy-gen=package +// +groupName=client-pkg.knative.dev + +// Package v1alpha1 is the v1alpha1 version of the API. +package v1alpha1 // import "knative.dev/client-pkg/pkg/apis/client/v1alpha1" diff --git a/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/export_types.go b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/export_types.go new file mode 100644 index 0000000000..c669d31b7d --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/export_types.go @@ -0,0 +1,50 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + servingv1 "knative.dev/serving/pkg/apis/serving/v1" +) + +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Export is a specification for a Export resource +type Export struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ExportSpec `json:"spec"` +} + +// ExportSpec is the spec for a Export resource +type ExportSpec struct { + Service servingv1.Service `json:"service"` + Revisions []servingv1.Revision `json:"revisions"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ExportList is a list of Export resources +type ExportList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Export `json:"items"` +} diff --git a/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/register.go b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/register.go new file mode 100644 index 0000000000..19ff9232a0 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/register.go @@ -0,0 +1,55 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "knative.dev/client-pkg/pkg/apis/client" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: client.GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder initializes a scheme builder + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Export{}, + &ExportList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/zz_generated.deepcopy.go b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..8a78cde819 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/apis/client/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,111 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2020 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 deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" + v1 "knative.dev/serving/pkg/apis/serving/v1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Export) DeepCopyInto(out *Export) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Export. +func (in *Export) DeepCopy() *Export { + if in == nil { + return nil + } + out := new(Export) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Export) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExportList) DeepCopyInto(out *ExportList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Export, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportList. +func (in *ExportList) DeepCopy() *ExportList { + if in == nil { + return nil + } + out := new(ExportList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExportList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExportSpec) DeepCopyInto(out *ExportSpec) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + if in.Revisions != nil { + in, out := &in.Revisions, &out.Revisions + *out = make([]v1.Revision, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportSpec. +func (in *ExportSpec) DeepCopy() *ExportSpec { + if in == nil { + return nil + } + out := new(ExportSpec) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/knative.dev/client-pkg/pkg/commands/completion_helper.go b/vendor/knative.dev/client-pkg/pkg/commands/completion_helper.go new file mode 100644 index 0000000000..398ff24202 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/completion_helper.go @@ -0,0 +1,458 @@ +// 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 commands + +import ( + "strings" + + "github.com/spf13/cobra" +) + +type completionConfig struct { + params *KnParams + command *cobra.Command + args []string + toComplete string +} + +var ( + resourceToFuncMap = map[string]func(config *completionConfig) []string{ + "apiserver": completeApiserverSource, + "binding": completeBindingSource, + "broker": completeBroker, + "channel": completeChannel, + "container": completeContainerSource, + "domain": completeDomain, + "ping": completePingSource, + "revision": completeRevision, + "route": completeRoute, + "service": completeService, + "subscription": completeSubscription, + "trigger": completeTrigger, + "eventtype": completeEventtype, + } +) + +// ResourceNameCompletionFunc will return a function that will autocomplete the name of +// the resource based on the subcommand +func ResourceNameCompletionFunc(p *KnParams) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + + var use string + if cmd.Parent() != nil { + use = cmd.Parent().Name() + } + config := completionConfig{ + p, + cmd, + args, + toComplete, + } + return config.getCompletion(use), cobra.ShellCompDirectiveNoFileComp + } +} + +func (config *completionConfig) getCompletion(parent string) []string { + completionFunc := resourceToFuncMap[parent] + if completionFunc == nil { + return []string{} + } + return completionFunc(config) +} + +func getTargetFlagValue(cmd *cobra.Command) string { + flag := cmd.Flag("target") + if flag == nil { + return "" + } + return flag.Value.String() +} + +func completeGitOps(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.NewGitopsServingClient(namespace, getTargetFlagValue(config.command)) + if err != nil { + return + } + serviceList, err := client.ListServices(config.command.Context()) + if err != nil { + return + } + for _, sug := range serviceList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeService(config *completionConfig) (suggestions []string) { + if getTargetFlagValue(config.command) != "" { + return completeGitOps(config) + } + + 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.NewServingClient(namespace) + if err != nil { + return + } + serviceList, err := client.ListServices(config.command.Context()) + if err != nil { + return + } + for _, sug := range serviceList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeBroker(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.NewEventingClient(namespace) + if err != nil { + return + } + brokerList, err := client.ListBrokers(config.command.Context()) + if err != nil { + return + } + for _, sug := range brokerList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeRevision(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.NewServingClient(namespace) + if err != nil { + return + } + revisionList, err := client.ListRevisions(config.command.Context()) + if err != nil { + return + } + for _, sug := range revisionList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeRoute(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.NewServingClient(namespace) + if err != nil { + return + } + routeList, err := client.ListRoutes(config.command.Context()) + if err != nil { + return + } + for _, sug := range routeList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeDomain(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.NewServingV1beta1Client(namespace) + if err != nil { + return + } + domainMappingList, err := client.ListDomainMappings(config.command.Context()) + if err != nil { + return + } + for _, sug := range domainMappingList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeTrigger(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.NewEventingClient(namespace) + if err != nil { + return + } + triggerList, err := client.ListTriggers(config.command.Context()) + if err != nil { + return + } + for _, sug := range triggerList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeContainerSource(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.NewSourcesClient(namespace) + if err != nil { + return + } + containerSourceList, err := client.ContainerSourcesClient().ListContainerSources(config.command.Context()) + if err != nil { + return + } + for _, sug := range containerSourceList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeApiserverSource(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.NewSourcesClient(namespace) + if err != nil { + return + } + apiServerSourceList, err := client.APIServerSourcesClient().ListAPIServerSource(config.command.Context()) + if err != nil { + return + } + for _, sug := range apiServerSourceList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeBindingSource(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.NewSourcesClient(namespace) + if err != nil { + return + } + bindingList, err := client.SinkBindingClient().ListSinkBindings(config.command.Context()) + if err != nil { + return + } + for _, sug := range bindingList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completePingSource(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.NewSourcesV1beta2Client(namespace) + if err != nil { + return + } + pingSourcesClient := client.PingSourcesClient() + + pingSourceList, err := pingSourcesClient.ListPingSource(config.command.Context()) + if err != nil { + return + } + for _, sug := range pingSourceList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeChannel(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.NewMessagingClient(namespace) + if err != nil { + return + } + + channelList, err := client.ChannelsClient().ListChannel(config.command.Context()) + if err != nil { + return + } + for _, sug := range channelList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + return +} + +func completeSubscription(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.NewMessagingClient(namespace) + if err != nil { + return + } + + subscriptionList, err := client.SubscriptionsClient().ListSubscription(config.command.Context()) + if err != nil { + return + } + for _, sug := range subscriptionList.Items { + if !strings.HasPrefix(sug.Name, config.toComplete) { + continue + } + suggestions = append(suggestions, sug.Name) + } + 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.NewEventingV1beta2Client(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/vendor/knative.dev/client-pkg/pkg/commands/describe.go b/vendor/knative.dev/client-pkg/pkg/commands/describe.go new file mode 100644 index 0000000000..89bfdeaf2c --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/describe.go @@ -0,0 +1,222 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package commands + +import ( + "fmt" + "sort" + "strconv" + "strings" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/duration" + "knative.dev/client-pkg/pkg/printers" + "knative.dev/pkg/apis" +) + +// Max length When to truncate long strings (when not "all" mode switched on) +const TruncateAt = 100 + +func WriteMetadata(dw printers.PrefixWriter, m *metav1.ObjectMeta, printDetails bool) { + dw.WriteAttribute("Name", m.Name) + dw.WriteAttribute("Namespace", m.Namespace) + WriteMapDesc(dw, m.Labels, "Labels", printDetails) + WriteMapDesc(dw, m.Annotations, "Annotations", printDetails) + dw.WriteAttribute("Age", Age(m.CreationTimestamp.Time)) +} + +var boringDomains = map[string]bool{ + "serving.knative.dev": true, + "client.knative.dev": true, + "kubectl.kubernetes.io": true, +} + +func keyIsBoring(k string) bool { + parts := strings.Split(k, "/") + return len(parts) > 1 && boringDomains[parts[0]] +} + +// Write a map either compact in a single line (possibly truncated) or, if printDetails is set, +// over multiple line, one line per key-value pair. The output is sorted by keys. +func WriteMapDesc(dw printers.PrefixWriter, m map[string]string, label string, details bool) { + if len(m) == 0 { + return + } + + var keys []string + for k := range m { + if details || !keyIsBoring(k) { + keys = append(keys, k) + } + } + if len(keys) == 0 { + return + } + sort.Strings(keys) + + if details { + for i, key := range keys { + l := "" + if i == 0 { + l = printers.Label(label) + } + dw.WriteColsLn(l, key+"="+m[key]) + } + return + } + + dw.WriteColsLn(printers.Label(label), joinAndTruncate(keys, m, TruncateAt-len(label)-2)) +} + +func Age(t time.Time) string { + if t.IsZero() { + return "" + } + return duration.ShortHumanDuration(time.Since(t)) +} + +func formatConditionType(condition apis.Condition) string { + return string(condition.Type) +} + +// Status in ASCII format +func formatStatus(c apis.Condition) string { + switch c.Status { + case corev1.ConditionTrue: + return "++" + case corev1.ConditionFalse: + switch c.Severity { + case apis.ConditionSeverityError: + return "!!" + case apis.ConditionSeverityWarning: + return " W" + case apis.ConditionSeverityInfo: + return " I" + default: + return " !" + } + default: + return "??" + } +} + +// Used for conditions table to do own formatting for the table, +// as the tabbed writer doesn't work nicely with colors +func getMaxTypeLen(conditions []apis.Condition) int { + max := 0 + for _, condition := range conditions { + if len(condition.Type) > max { + max = len(condition.Type) + } + } + return max +} + +// Sort conditions: Ready first, followed by error, then Warning, then Info +func sortConditions(conditions []apis.Condition) []apis.Condition { + // Don't change the orig slice + ret := make([]apis.Condition, len(conditions)) + copy(ret, conditions) + sort.SliceStable(ret, func(i, j int) bool { + ic := &ret[i] + jc := &ret[j] + // Ready first + if ic.Type == apis.ConditionReady { + return jc.Type != apis.ConditionReady + } + if jc.Type == apis.ConditionReady { + return false + } + // Among conditions of the same Severity, sort by Type + if ic.Severity == jc.Severity { + return ic.Type < jc.Type + } + // Error < Warning < Info + switch ic.Severity { + case apis.ConditionSeverityError: + return true + case apis.ConditionSeverityWarning: + return jc.Severity == apis.ConditionSeverityInfo + case apis.ConditionSeverityInfo: + return false + default: + return false + } + }) + return ret +} + +// Print out a table with conditions. +func WriteConditions(dw printers.PrefixWriter, conditions []apis.Condition, printMessage bool) { + section := dw.WriteAttribute("Conditions", "") + conditions = sortConditions(conditions) + maxLen := getMaxTypeLen(conditions) + formatHeader := "%-2s %-" + strconv.Itoa(maxLen) + "s %6s %-s\n" + formatRow := "%-2s %-" + strconv.Itoa(maxLen) + "s %6s %-s\n" + section.Writef(formatHeader, "OK", "TYPE", "AGE", "REASON") + for _, condition := range conditions { + ok := formatStatus(condition) + reason := condition.Reason + if printMessage && reason != "" { + reason = fmt.Sprintf("%s (%s)", reason, condition.Message) + } + section.Writef(formatRow, ok, formatConditionType(condition), Age(condition.LastTransitionTime.Inner.Time), reason) + } +} + +// Writer a slice compact (printDetails == false) in one line, or over multiple line +// with key-value line-by-line (printDetails == true) +func WriteSliceDesc(dw printers.PrefixWriter, s []string, label string, printDetails bool) { + + if len(s) == 0 { + return + } + + if printDetails { + for i, value := range s { + if i == 0 { + dw.WriteColsLn(printers.Label(label), value) + } else { + dw.WriteColsLn("", value) + } + } + return + } + + joined := strings.Join(s, ", ") + if len(joined) > TruncateAt { + joined = joined[:TruncateAt-4] + " ..." + } + dw.WriteAttribute(label, joined) +} + +// Join to key=value pair, comma separated, and truncate if longer than a limit +func joinAndTruncate(sortedKeys []string, m map[string]string, width int) string { + ret := "" + for _, key := range sortedKeys { + ret += fmt.Sprintf("%s=%s, ", key, m[key]) + if len(ret) > width { + break + } + } + // cut of two latest chars + ret = strings.TrimRight(ret, ", ") + if len(ret) <= width { + return ret + } + return ret[:width-4] + " ..." +} diff --git a/vendor/knative.dev/client-pkg/pkg/commands/flags/list/print.go b/vendor/knative.dev/client-pkg/pkg/commands/flags/list/print.go new file mode 100644 index 0000000000..6f59b26a1c --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/flags/list/print.go @@ -0,0 +1,103 @@ +/* + Copyright 2024 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 list + +import ( + "io" + + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/cli-runtime/pkg/genericclioptions" + "knative.dev/client-pkg/pkg/commands" + + hprinters "knative.dev/client-pkg/pkg/printers" + "knative.dev/client-pkg/pkg/util" +) + +// PrintFlags composes common printer flag structs used in the list command. +type PrintFlags struct { + GenericPrintFlags *genericclioptions.PrintFlags + HumanReadableFlags *commands.HumanPrintFlags + PrinterHandler func(h hprinters.PrintHandler) +} + +// AllowedFormats is the list of formats in which data can be displayed +func (f *PrintFlags) AllowedFormats() []string { + formats := f.GenericPrintFlags.AllowedFormats() + formats = append(formats, f.HumanReadableFlags.AllowedFormats()...) + return formats +} + +// ToPrinter attempts to find a composed set of ListTypesFlags suitable for +// returning a printer based on current flag values. +func (f *PrintFlags) ToPrinter() (hprinters.ResourcePrinter, error) { + // if there are flags specified for generic printing + if f.GenericPrintFlags.OutputFlagSpecified() { + p, err := f.GenericPrintFlags.ToPrinter() + if err != nil { + return nil, err + } + return p, nil + } + + p, err := f.HumanReadableFlags.ToPrinter(f.PrinterHandler) + if err != nil { + return nil, err + } + return p, nil +} + +// Print is to print an Object to a Writer +func (f *PrintFlags) Print(obj runtime.Object, w io.Writer) error { + printer, err := f.ToPrinter() + if err != nil { + return err + } + + if f.GenericPrintFlags.OutputFlagSpecified() { + unstructuredList, err := util.ToUnstructuredList(obj) + if err != nil { + return err + } + return printer.PrintObj(unstructuredList, w) + } + + return printer.PrintObj(obj, w) +} + +// AddFlags receives a *cobra.Command reference and binds +// flags related to humanreadable and template printing. +func (f *PrintFlags) AddFlags(cmd *cobra.Command) { + f.GenericPrintFlags.AddFlags(cmd) + f.HumanReadableFlags.AddFlags(cmd) +} + +// NewPrintFlags returns flags associated with humanreadable, template, and +// "name" printing, with default values set. +func NewPrintFlags(printer func(h hprinters.PrintHandler)) *PrintFlags { + return &PrintFlags{ + GenericPrintFlags: genericclioptions.NewPrintFlags(""), + HumanReadableFlags: commands.NewHumanPrintFlags(), + PrinterHandler: printer, + } +} + +// EnsureWithNamespace ensures that humanreadable flags return +// a printer capable of printing with a "namespace" column. +func (f *PrintFlags) EnsureWithNamespace() { + f.HumanReadableFlags.EnsureWithNamespace() +} diff --git a/pkg/kn/commands/flags/sink.go b/vendor/knative.dev/client-pkg/pkg/commands/flags/sink/flag.go similarity index 81% rename from pkg/kn/commands/flags/sink.go rename to vendor/knative.dev/client-pkg/pkg/commands/flags/sink/flag.go index 5bcd4254a8..ba03e58664 100644 --- a/pkg/kn/commands/flags/sink.go +++ b/vendor/knative.dev/client-pkg/pkg/commands/flags/sink/flag.go @@ -1,18 +1,20 @@ -// Copyright © 2019 The Knative Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package flags +/* + Copyright 2024 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 sink import ( "context" @@ -22,28 +24,29 @@ import ( "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/client-pkg/pkg/config" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" - clientdynamic "knative.dev/client/pkg/dynamic" - "knative.dev/client/pkg/kn/config" + clientdynamic "knative.dev/client-pkg/pkg/dynamic" ) -type SinkFlags struct { +// Flag holds the sink flag and its mappings +type Flag struct { Sink string SinkMappings map[string]schema.GroupVersionResource } -// NewSinkFlag is a constructor function to create SinkFlags from provided map -func NewSinkFlag(mapping map[string]schema.GroupVersionResource) *SinkFlags { - return &SinkFlags{ +// NewFlag is a constructor function to create Flag from provided map +func NewFlag(mapping map[string]schema.GroupVersionResource) *Flag { + return &Flag{ SinkMappings: mapping, } } // AddWithFlagName configures Sink flag with given flag name and a short flag name // pass empty short flag name if you don't want to set one -func (i *SinkFlags) AddWithFlagName(cmd *cobra.Command, fname, short string) { +func (i *Flag) AddWithFlagName(cmd *cobra.Command, fname, short string) { flag := "--" + fname if short == "" { cmd.Flags().StringVar(&i.Sink, fname, "", "") @@ -74,7 +77,7 @@ func (i *SinkFlags) AddWithFlagName(cmd *cobra.Command, fname, short string) { } // Add configures Sink flag with name 'Sink' amd short name 's' -func (i *SinkFlags) Add(cmd *cobra.Command) { +func (i *Flag) Add(cmd *cobra.Command) { i.AddWithFlagName(cmd, "sink", "s") } @@ -100,7 +103,7 @@ var defaultSinkMappings = map[string]schema.GroupVersionResource{ // ResolveSink returns the Destination referred to by the flags in the acceptor. // It validates that any object the user is referring to exists. -func (i *SinkFlags) ResolveSink(ctx context.Context, knclient clientdynamic.KnDynamicClient, namespace string) (*duckv1.Destination, error) { +func (i *Flag) ResolveSink(ctx context.Context, knclient clientdynamic.KnDynamicClient, namespace string) (*duckv1.Destination, error) { client := knclient.RawClient() if i.Sink == "" { return nil, nil diff --git a/vendor/knative.dev/client-pkg/pkg/commands/human_readable_flags.go b/vendor/knative.dev/client-pkg/pkg/commands/human_readable_flags.go new file mode 100644 index 0000000000..faa477e2d6 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/human_readable_flags.go @@ -0,0 +1,121 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package commands + +import ( + "fmt" + "time" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/duration" + hprinters "knative.dev/client-pkg/pkg/printers" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +// HumanPrintFlags provides default flags necessary for printing. +// Given the following flag values, a printer can be requested that knows +// how to handle printing based on these values. +type HumanPrintFlags struct { + WithNamespace bool + NoHeaders bool + //TODO: Add more flags as required +} + +// AllowedFormats returns more customized formating options +func (f *HumanPrintFlags) AllowedFormats() []string { + // TODO: Add more formats eg: wide + return []string{"no-headers"} +} + +// ToPrinter receives returns a printer capable of +// handling human-readable output. +func (f *HumanPrintFlags) ToPrinter(getHandlerFunc func(h hprinters.PrintHandler)) (hprinters.ResourcePrinter, error) { + p := hprinters.NewTablePrinter(hprinters.PrintOptions{AllNamespaces: f.WithNamespace, NoHeaders: f.NoHeaders}) + getHandlerFunc(p) + return p, nil +} + +// AddFlags receives a *cobra.Command reference and binds +// flags related to human-readable printing to it +func (f *HumanPrintFlags) AddFlags(c *cobra.Command) { + c.Flags().BoolVar(&f.NoHeaders, "no-headers", false, "When using the default output format, don't print headers (default: print headers).") + //TODO: Add more flags as required +} + +// NewHumanPrintFlags returns flags associated with +// human-readable printing, with default values set. +func NewHumanPrintFlags() *HumanPrintFlags { + return &HumanPrintFlags{} +} + +// EnsureWithNamespace sets the "WithNamespace" humanreadable option to true. +func (f *HumanPrintFlags) EnsureWithNamespace() { + f.WithNamespace = true +} + +// conditionsValue returns the True conditions count among total conditions +func ConditionsValue(conditions duckv1.Conditions) string { + var ok int + for _, condition := range conditions { + if condition.Status == "True" { + ok++ + } + } + return fmt.Sprintf("%d OK / %d", ok, len(conditions)) +} + +// readyCondition returns status of resource's Ready type condition +func ReadyCondition(conditions duckv1.Conditions) string { + for _, condition := range conditions { + if condition.Type == apis.ConditionReady { + return string(condition.Status) + } + } + return "" +} + +// NonReadyConditionReason returns formatted string of +// reason and message for non ready conditions +func NonReadyConditionReason(conditions duckv1.Conditions) string { + for _, condition := range conditions { + if condition.Type == apis.ConditionReady { + if string(condition.Status) == "True" { + return "" + } + if condition.Message != "" { + return fmt.Sprintf("%s : %s", condition.Reason, condition.Message) + } + return condition.Reason + } + } + return "" +} + +// translateTimestampSince returns the elapsed time since timestamp in +// human-readable approximation. +func TranslateTimestampSince(timestamp metav1.Time) string { + if timestamp.IsZero() { + return "" + } + return duration.HumanDuration(time.Since(timestamp.Time)) +} + +// AddGitOpsFlags adds flags to enable gitops mode +func AddGitOpsFlags(flags *pflag.FlagSet) { + flags.String("target", "", "Work on local directory instead of a remote cluster (experimental)") +} diff --git a/vendor/knative.dev/client-pkg/pkg/commands/namespaced.go b/vendor/knative.dev/client-pkg/pkg/commands/namespaced.go new file mode 100644 index 0000000000..3b7b90128a --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/namespaced.go @@ -0,0 +1,92 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "k8s.io/client-go/tools/clientcmd" +) + +// AddNamespaceFlags adds the namespace-related flags: +// * --namespace +// * --all-namespaces +func AddNamespaceFlags(flags *pflag.FlagSet, allowAll bool) { + flags.StringP( + "namespace", + "n", + "", + "Specify the namespace to operate in.", + ) + + if allowAll { + flags.BoolP( + "all-namespaces", + "A", + false, + "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.", + ) + } +} + +// GetNamespace returns namespace from command specified by flag +func (params *KnParams) GetNamespace(cmd *cobra.Command) (string, error) { + namespaceFlag := cmd.Flag("namespace") + if namespaceFlag == nil { + return "", fmt.Errorf("command %s doesn't have --namespace flag", cmd.Name()) + } + namespace := namespaceFlag.Value.String() + // check value of all-namespaces only if its defined + if cmd.Flags().Lookup("all-namespaces") != nil { + all, err := cmd.Flags().GetBool("all-namespaces") + if err != nil { + return "", err + } else if all { // if all-namespaces=True + // namespace = "" <-- all-namespaces representation + return "", nil + } + } + // if all-namespaces=False or namespace not given, use default namespace + if namespace == "" { + var err error + namespace, err = params.CurrentNamespace() + if err != nil { + if !clientcmd.IsEmptyConfig(err) { + return "", err + } + // If no current namespace is set use "default" + namespace = "default" + } + } + return namespace, nil +} + +// CurrentNamespace returns the current namespace which is either provided as option or picked up from kubeconfig +func (params *KnParams) CurrentNamespace() (string, error) { + var err error + if params.fixedCurrentNamespace != "" { + return params.fixedCurrentNamespace, nil + } + if params.ClientConfig == nil { + params.ClientConfig, err = params.GetClientConfig() + if err != nil { + return "", err + } + } + name, _, err := params.ClientConfig.Namespace() + return name, err +} diff --git a/vendor/knative.dev/client-pkg/pkg/commands/testing_helper.go b/vendor/knative.dev/client-pkg/pkg/commands/testing_helper.go new file mode 100644 index 0000000000..8582febda8 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/testing_helper.go @@ -0,0 +1,98 @@ +// Copyright © 2018 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 commands + +import ( + "bytes" + + "knative.dev/client-pkg/pkg/dynamic/fake" + "knative.dev/client-pkg/pkg/flags" + + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/runtime" + clienttesting "k8s.io/client-go/testing" + servingv1fake "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1/fake" + + clientservingv1 "knative.dev/client-pkg/pkg/serving/v1" + v1 "knative.dev/client-pkg/pkg/sources/v1" + + sourcesv1fake "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1/fake" + + clientdynamic "knative.dev/client-pkg/pkg/dynamic" +) + +const FakeNamespace = "current" + +// CreateTestKnCommand helper for creating test commands +func CreateTestKnCommand(cmd *cobra.Command, knParams *KnParams) (*cobra.Command, *servingv1fake.FakeServingV1, *bytes.Buffer) { + buf := new(bytes.Buffer) + fakeServing := &servingv1fake.FakeServingV1{Fake: &clienttesting.Fake{}} + knParams.Output = buf + knParams.NewServingClient = func(namespace string) (clientservingv1.KnServingClient, error) { + return clientservingv1.NewKnServingClient(fakeServing, FakeNamespace), nil + } + knParams.fixedCurrentNamespace = FakeNamespace + knCommand := NewTestCommand(cmd, knParams) + return knCommand, fakeServing, buf +} + +// CreateSourcesTestKnCommand helper for creating test commands +func CreateSourcesTestKnCommand(cmd *cobra.Command, knParams *KnParams) (*cobra.Command, *sourcesv1fake.FakeSourcesV1, *bytes.Buffer) { + buf := new(bytes.Buffer) + // create fake serving client because the sink of source depends on serving client + fakeServing := &servingv1fake.FakeServingV1{Fake: &clienttesting.Fake{}} + knParams.NewServingClient = func(namespace string) (clientservingv1.KnServingClient, error) { + return clientservingv1.NewKnServingClient(fakeServing, FakeNamespace), nil + } + // create fake sources client + fakeEventing := &sourcesv1fake.FakeSourcesV1{Fake: &clienttesting.Fake{}} + knParams.Output = buf + knParams.NewSourcesClient = func(namespace string) (v1.KnSourcesClient, error) { + return v1.NewKnSourcesClient(fakeEventing, FakeNamespace), nil + } + knParams.fixedCurrentNamespace = FakeNamespace + knCommand := NewTestCommand(cmd, knParams) + return knCommand, fakeEventing, buf +} + +// CreateDynamicTestKnCommand helper for creating test commands using dynamic client +func CreateDynamicTestKnCommand(cmd *cobra.Command, knParams *KnParams, objects ...runtime.Object) (*cobra.Command, *clientdynamic.KnDynamicClient, *bytes.Buffer) { + buf := new(bytes.Buffer) + fakeDynamic := fake.CreateFakeKnDynamicClient(FakeNamespace, objects...) + knParams.Output = buf + knParams.NewDynamicClient = func(namespace string) (clientdynamic.KnDynamicClient, error) { + return fakeDynamic, nil + } + + knParams.fixedCurrentNamespace = FakeNamespace + knCommand := NewTestCommand(cmd, knParams) + return knCommand, &fakeDynamic, buf + +} + +// NewTestCommand can be used by tes +func NewTestCommand(subCommand *cobra.Command, params *KnParams) *cobra.Command { + rootCmd := &cobra.Command{ + Use: "kn", + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return flags.ReconcileBoolFlags(cmd.Flags()) + }, + } + if params.Output != nil { + rootCmd.SetOut(params.Output) + } + rootCmd.AddCommand(subCommand) + return rootCmd +} diff --git a/vendor/knative.dev/client-pkg/pkg/commands/types.go b/vendor/knative.dev/client-pkg/pkg/commands/types.go new file mode 100644 index 0000000000..c792b8b61e --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/types.go @@ -0,0 +1,289 @@ +// Copyright © 2018 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 commands + +import ( + "fmt" + "io" + "os" + "path/filepath" + + "k8s.io/client-go/kubernetes" + + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + eventingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1" + eventingv1beta2 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta2" + 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" + servingv1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" + servingv1beta1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1" + + "knative.dev/client-pkg/pkg/util" + + clientdynamic "knative.dev/client-pkg/pkg/dynamic" + knerrors "knative.dev/client-pkg/pkg/errors" + clienteventingv1 "knative.dev/client-pkg/pkg/eventing/v1" + clienteventingv1beta2 "knative.dev/client-pkg/pkg/eventing/v1beta2" + clientmessagingv1 "knative.dev/client-pkg/pkg/messaging/v1" + clientservingv1 "knative.dev/client-pkg/pkg/serving/v1" + clientservingv1beta1 "knative.dev/client-pkg/pkg/serving/v1beta1" + clientsourcesv1 "knative.dev/client-pkg/pkg/sources/v1" + clientsourcesv1beta2 "knative.dev/client-pkg/pkg/sources/v1beta2" +) + +// KnParams for creating commands. Useful for inserting mocks for testing. +type KnParams struct { + Output io.Writer + KubeCfgPath string + KubeContext string + KubeCluster string + KubeAsUser string + KubeAsUID string + KubeAsGroup []string + ClientConfig clientcmd.ClientConfig + NewKubeClient func() (kubernetes.Interface, error) + NewServingClient func(namespace string) (clientservingv1.KnServingClient, error) + NewServingV1beta1Client func(namespace string) (clientservingv1beta1.KnServingClient, error) + NewGitopsServingClient func(namespace string, dir string) (clientservingv1.KnServingClient, error) + NewSourcesClient func(namespace string) (clientsourcesv1.KnSourcesClient, error) + NewSourcesV1beta2Client func(namespace string) (clientsourcesv1beta2.KnSourcesClient, error) + NewEventingClient func(namespace string) (clienteventingv1.KnEventingClient, error) + NewMessagingClient func(namespace string) (clientmessagingv1.KnMessagingClient, error) + NewDynamicClient func(namespace string) (clientdynamic.KnDynamicClient, error) + NewEventingV1beta2Client func(namespace string) (clienteventingv1beta2.KnEventingV1Beta2Client, error) + + // General global options + LogHTTP bool + + // Set this if you want to nail down the namespace + fixedCurrentNamespace string +} + +func (params *KnParams) Initialize() { + if params.NewKubeClient == nil { + params.NewKubeClient = params.newKubeClient + } + + if params.NewServingClient == nil { + params.NewServingClient = params.newServingClient + } + + if params.NewServingV1beta1Client == nil { + params.NewServingV1beta1Client = params.newServingClientV1beta1 + } + + if params.NewGitopsServingClient == nil { + params.NewGitopsServingClient = params.newGitopsServingClient + } + + if params.NewSourcesClient == nil { + params.NewSourcesClient = params.newSourcesClient + } + + if params.NewEventingClient == nil { + params.NewEventingClient = params.newEventingClient + } + + if params.NewMessagingClient == nil { + params.NewMessagingClient = params.newMessagingClient + } + + if params.NewDynamicClient == nil { + params.NewDynamicClient = params.newDynamicClient + } + + if params.NewSourcesV1beta2Client == nil { + params.NewSourcesV1beta2Client = params.newSourcesClientV1beta2 + } + + if params.NewEventingV1beta2Client == nil { + params.NewEventingV1beta2Client = params.newEventingV1Beta2Client + } +} + +func (params *KnParams) newKubeClient() (kubernetes.Interface, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return nil, err + } + + return client, nil +} + +func (params *KnParams) newServingClient(namespace string) (clientservingv1.KnServingClient, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, err := servingv1client.NewForConfig(restConfig) + if err != nil { + return nil, err + } + return clientservingv1.NewKnServingClient(client, namespace), nil +} + +func (params *KnParams) newServingClientV1beta1(namespace string) (clientservingv1beta1.KnServingClient, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, err := servingv1beta1client.NewForConfig(restConfig) + if err != nil { + return nil, err + } + return clientservingv1beta1.NewKnServingClient(client, namespace), nil +} + +func (params *KnParams) newGitopsServingClient(namespace string, dir string) (clientservingv1.KnServingClient, error) { + return clientservingv1.NewKnServingGitOpsClient(namespace, dir), nil +} + +func (params *KnParams) newSourcesClient(namespace string) (clientsourcesv1.KnSourcesClient, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, _ := sourcesv1client.NewForConfig(restConfig) + return clientsourcesv1.NewKnSourcesClient(client, namespace), nil +} + +func (params *KnParams) newSourcesClientV1beta2(namespace string) (clientsourcesv1beta2.KnSourcesClient, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, _ := sourcesv1beta2client.NewForConfig(restConfig) + return clientsourcesv1beta2.NewKnSourcesClient(client, namespace), nil +} + +func (params *KnParams) newEventingClient(namespace string) (clienteventingv1.KnEventingClient, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, _ := eventingv1.NewForConfig(restConfig) + return clienteventingv1.NewKnEventingClient(client, namespace), nil +} + +func (params *KnParams) newEventingV1Beta2Client(namespace string) (clienteventingv1beta2.KnEventingV1Beta2Client, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, _ := eventingv1beta2.NewForConfig(restConfig) + return clienteventingv1beta2.NewKnEventingV1Beta2Client(client, namespace), nil +} + +func (params *KnParams) newMessagingClient(namespace string) (clientmessagingv1.KnMessagingClient, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, _ := messagingv1.NewForConfig(restConfig) + return clientmessagingv1.NewKnMessagingClient(client, namespace), nil +} + +func (params *KnParams) newDynamicClient(namespace string) (clientdynamic.KnDynamicClient, error) { + restConfig, err := params.RestConfig() + if err != nil { + return nil, err + } + + client, _ := dynamic.NewForConfig(restConfig) + return clientdynamic.NewKnDynamicClient(client, namespace), nil +} + +// RestConfig returns REST config, which can be to use to create specific clientset +func (params *KnParams) RestConfig() (*rest.Config, error) { + var err error + + if params.ClientConfig == nil { + params.ClientConfig, err = params.GetClientConfig() + if err != nil { + return nil, knerrors.GetError(err) + } + } + + config, err := params.ClientConfig.ClientConfig() + if err != nil { + return nil, knerrors.GetError(err) + } + if params.LogHTTP { + config.Wrap(util.NewLoggingTransport) + } + // Override client-go's warning handler to give us nicely printed warnings. + config.WarningHandler = rest.NewWarningWriter(os.Stderr, rest.WarningWriterOptions{ + // only print a given warning the first time we receive it + Deduplicate: true, + }) + + return config, nil +} + +// GetClientConfig gets ClientConfig from KubeCfgPath +func (params *KnParams) GetClientConfig() (clientcmd.ClientConfig, error) { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + configOverrides := &clientcmd.ConfigOverrides{} + if params.KubeContext != "" { + configOverrides.CurrentContext = params.KubeContext + } + if params.KubeCluster != "" { + configOverrides.Context.Cluster = params.KubeCluster + } + if params.KubeAsUser != "" { + configOverrides.AuthInfo.Impersonate = params.KubeAsUser + } + if params.KubeAsUID != "" { + configOverrides.AuthInfo.ImpersonateUID = params.KubeAsUID + } + if len(params.KubeAsGroup) > 0 { + configOverrides.AuthInfo.ImpersonateGroups = params.KubeAsGroup + } + if len(params.KubeCfgPath) == 0 { + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides), nil + } + + _, err := os.Stat(params.KubeCfgPath) + if err == nil { + loadingRules.ExplicitPath = params.KubeCfgPath + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides), nil + } + + if !os.IsNotExist(err) { + return nil, err + } + + paths := filepath.SplitList(params.KubeCfgPath) + if len(paths) > 1 { + return nil, fmt.Errorf("can not find config file. '%s' looks like a path. "+ + "Please use the env var KUBECONFIG if you want to check for multiple configuration files", params.KubeCfgPath) + } + return nil, fmt.Errorf("config file '%s' can not be found", params.KubeCfgPath) +} diff --git a/vendor/knative.dev/client-pkg/pkg/commands/wait_flags.go b/vendor/knative.dev/client-pkg/pkg/commands/wait_flags.go new file mode 100644 index 0000000000..3ae3e4deb7 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/commands/wait_flags.go @@ -0,0 +1,59 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + + knflags "knative.dev/client-pkg/pkg/flags" +) + +// Default time out to use when waiting for reconciliation. It is deliberately very long as it is expected that +// the service doesn't stay in `Unknown` status very long and eventually ends up as `False` or `True` in a timely +// manner +const WaitDefaultTimeout = 600 + +// Flags for tuning wait behaviour +type WaitFlags struct { + // Timeout in seconds for how long to wait for a command to return + TimeoutInSeconds int + // If set then apply resources and wait for completion + Wait bool + // Duration in seconds for waiting between intermediate false ready conditions + ErrorWindowInSeconds int +} + +// Add flags which influence the wait/no-wait behaviour when creating, updating, waiting for +// resources. If the action is not `wait`, set `waitDefault` argument if the default behaviour is synchronous. +// Use `what` for describing what is waited for. +func (p *WaitFlags) AddConditionWaitFlags(command *cobra.Command, waitTimeoutDefault int, action, what, until string) { + if action != "wait" { + waitUsage := fmt.Sprintf("Wait for '%s %s' operation to be completed.", what, action) + waitDefault := true + // Special-case 'delete' command so it comes back to the user immediately + if action == "delete" { + waitDefault = false + } + + knflags.AddBothBoolFlagsUnhidden(command.Flags(), &p.Wait, "wait", "", waitDefault, waitUsage) + } + timeoutUsage := fmt.Sprintf("Seconds to wait before giving up on waiting for %s to be %s.", what, until) + command.Flags().IntVar(&p.TimeoutInSeconds, "wait-timeout", waitTimeoutDefault, timeoutUsage) + + windowUsage := fmt.Sprintf("Seconds to wait for %s to be %s after a false ready condition is returned", what, until) + command.Flags().IntVar(&p.ErrorWindowInSeconds, "wait-window", 2, windowUsage) +} diff --git a/vendor/knative.dev/client-pkg/pkg/config/config.go b/vendor/knative.dev/client-pkg/pkg/config/config.go new file mode 100644 index 0000000000..8f548bfe38 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/config/config.go @@ -0,0 +1,285 @@ +/* + Copyright 2024 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 config + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + + "github.com/mitchellh/go-homedir" + flag "github.com/spf13/pflag" + "github.com/spf13/viper" +) + +// bootstrapDefaults are the defaults values to use +type defaultConfig struct { + configFile string + pluginsDir string + lookupPluginsInPath bool +} + +// Initialize defaults +var bootstrapDefaults = initDefaults() + +const configContentDefaults = `# Taken from https://github.com/knative/client/blob/main/docs/README.md#options +# +#plugins: +# directory: ~/.config/kn/plugins +#eventing: +# sink-mappings: +# - prefix: svc +# group: core +# version: v1 +# resource: services +# channel-type-mappings: +# - alias: Kafka +# group: messaging.knative.dev +# version: v1alpha1 +# kind: KafkaChannel +` + +// config contains the variables for the Kn config +type config struct { + // configFile is the config file location + configFile string + + // sinkMappings is a list of sink mapping + sinkMappings []SinkMapping + + // channelTypeMappings is a list of channel type mapping + channelTypeMappings []ChannelTypeMapping +} + +// ConfigFile returns the config file which is either the default XDG conform +// config file location or the one set with --config +func (c *config) ConfigFile() string { + if c.configFile != "" { + return c.configFile + } + return bootstrapDefaults.configFile +} + +// PluginsDir returns the plugins' directory +func (c *config) PluginsDir() string { + if viper.IsSet(keyPluginsDirectory) { + return viper.GetString(keyPluginsDirectory) + } else if viper.IsSet(legacyKeyPluginsDirectory) { + // Remove that branch if legacy option is switched off + return viper.GetString(legacyKeyPluginsDirectory) + } else { + return bootstrapDefaults.pluginsDir + } +} + +// LookupPluginsInPath returns true if plugins should be also checked in the pat +func (c *config) LookupPluginsInPath() bool { + return bootstrapDefaults.lookupPluginsInPath +} + +func (c *config) SinkMappings() []SinkMapping { + return c.sinkMappings +} + +func (c *config) ChannelTypeMappings() []ChannelTypeMapping { + return c.channelTypeMappings +} + +// Config used for flag binding +var globalConfig = config{} + +// GlobalConfig is the global configuration available for every sub-command +var GlobalConfig Config = &globalConfig + +// BootstrapConfig reads in config file and bootstrap options if set. +func BootstrapConfig() error { + + // Create a new FlagSet for the bootstrap flags and parse those. This will + // initialize the config file to use (obtained via GlobalConfig.ConfigFile()) + bootstrapFlagSet := flag.NewFlagSet("kn", flag.ContinueOnError) + AddBootstrapFlags(bootstrapFlagSet) + bootstrapFlagSet.ParseErrorsWhitelist = flag.ParseErrorsWhitelist{UnknownFlags: true} // wokeignore:rule=whitelist // TODO(#1031) + bootstrapFlagSet.Usage = func() {} + err := bootstrapFlagSet.Parse(os.Args) + if err != nil && !errors.Is(err, flag.ErrHelp) { + return err + } + + // Bind flags so that options that have been provided have priority. + // Important: Always read options via GlobalConfig methods + err = viper.BindPFlag(keyPluginsDirectory, bootstrapFlagSet.Lookup(flagPluginsDir)) + if err != nil { + return err + } + + viper.SetConfigFile(GlobalConfig.ConfigFile()) + configFile := GlobalConfig.ConfigFile() + _, err = os.Lstat(configFile) + if err != nil { + if !os.IsNotExist(err) { + return fmt.Errorf("cannot stat configfile %s: %w", configFile, err) + } + if err := os.MkdirAll(filepath.Dir(viper.ConfigFileUsed()), 0775); err != nil { + // Can't create config directory, proceed silently without reading the config + return nil + } + if err := os.WriteFile(viper.ConfigFileUsed(), []byte(configContentDefaults), 0600); err != nil { + // Can't create config file, proceed silently without reading the config + return nil + } + } + + viper.AutomaticEnv() // read in environment variables that match + + // Defaults are taken from the parsed flags, which in turn have bootstrap defaults + // TODO: Re-enable when legacy handling for plugin config has been removed + // For now default handling is happening directly in the getter of GlobalConfig + // viper.SetDefault(keyPluginsDirectory, bootstrapDefaults.pluginsDir) + + // If a config file is found, read it in. + err = viper.ReadInConfig() + if err != nil { + return err + } + + // Deserialize sink mappings if configured + err = parseSinkMappings() + if err != nil { + return err + } + + // Deserialize channel type mappings if configured + err = parseChannelTypeMappings() + return err +} + +// Add bootstrap flags use in a separate bootstrap proceeds +func AddBootstrapFlags(flags *flag.FlagSet) { + flags.StringVar(&globalConfig.configFile, "config", "", fmt.Sprintf("kn configuration file (default: %s)", defaultConfigFileForUsageMessage())) + flags.String(flagPluginsDir, "", "Directory holding kn plugins") + + // Let's try that and mark the flags as hidden: (as those configuration is a permanent choice of operation) + flags.MarkHidden(flagPluginsDir) +} + +// =========================================================================================================== + +// Initialize defaults. This happens lazily go allow to change the +// home directory for e.g. tests +func initDefaults() *defaultConfig { + return &defaultConfig{ + configFile: defaultConfigLocation("config.yaml"), + pluginsDir: defaultConfigLocation("plugins"), + lookupPluginsInPath: true, + } +} + +func defaultConfigLocation(subpath string) string { + var base string + if runtime.GOOS == "windows" { + base = defaultConfigDirWindows() + } else { + base = defaultConfigDirUnix() + } + return filepath.Join(base, subpath) +} + +func defaultConfigDirUnix() string { + home, err := homedir.Dir() + if err != nil { + home = "~" + } + + // Check the deprecated path first and fallback to it, add warning to error message + if configHome := filepath.Join(home, ".kn"); dirExists(configHome) { + migrationPath := filepath.Join(home, ".config", "kn") + fmt.Fprintf(os.Stderr, "WARNING: deprecated kn config directory '%s' detected. Please move your configuration to '%s'\n", configHome, migrationPath) + return configHome + } + + // Respect XDG_CONFIG_HOME if set + if xdgHome := os.Getenv("XDG_CONFIG_HOME"); xdgHome != "" { + return filepath.Join(xdgHome, "kn") + } + // Fallback to XDG default for both Linux and macOS + // ~/.config/kn + return filepath.Join(home, ".config", "kn") +} + +func defaultConfigDirWindows() string { + home, err := homedir.Dir() + if err != nil { + // Check the deprecated path first and fallback to it, add warning to error message + if configHome := filepath.Join(home, ".kn"); dirExists(configHome) { + migrationPath := filepath.Join(os.Getenv("APPDATA"), "kn") + fmt.Fprintf(os.Stderr, "WARNING: deprecated kn config directory '%s' detected. Please move your configuration to '%s'\n", configHome, migrationPath) + return configHome + } + } + + return filepath.Join(os.Getenv("APPDATA"), "kn") +} + +func dirExists(path string) bool { + if _, err := os.Stat(path); !os.IsNotExist(err) { + return true + } + return false +} + +// parse sink mappings and store them in the global configuration +func parseSinkMappings() error { + // Parse sink configuration + key := "" + if viper.IsSet(keySinkMappings) { + key = keySinkMappings + } + if key == "" && viper.IsSet(legacyKeySinkMappings) { + key = legacyKeySinkMappings + } + + if key != "" { + err := viper.UnmarshalKey(key, &globalConfig.sinkMappings) + if err != nil { + return fmt.Errorf("error while parsing sink mappings in configuration file %s: %w", + viper.ConfigFileUsed(), err) + } + } + return nil +} + +// parse channel type mappings and store them in the global configuration +func parseChannelTypeMappings() error { + if viper.IsSet(keyChannelTypeMappings) { + err := viper.UnmarshalKey(keyChannelTypeMappings, &globalConfig.channelTypeMappings) + if err != nil { + return fmt.Errorf("error while parsing channel type mappings in configuration file %s: %w", + viper.ConfigFileUsed(), err) + } + } + return nil +} + +// Prepare the default config file for the usage message +func defaultConfigFileForUsageMessage() string { + if runtime.GOOS == "windows" { + return "%APPDATA%\\kn\\config.yaml" + } + return "~/.config/kn/config.yaml" +} diff --git a/pkg/config/defaults.go b/vendor/knative.dev/client-pkg/pkg/config/defaults.go similarity index 100% rename from pkg/config/defaults.go rename to vendor/knative.dev/client-pkg/pkg/config/defaults.go diff --git a/vendor/knative.dev/client-pkg/pkg/config/types.go b/vendor/knative.dev/client-pkg/pkg/config/types.go new file mode 100644 index 0000000000..2ef7dc8de7 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/config/types.go @@ -0,0 +1,88 @@ +// Copyright © 2020 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 config + +// Package for holding configuration types used in bootstrapping +// and for types in configuration files + +type Config interface { + + // ConfigFile returns the location of the configuration file + ConfigFile() string + + // PluginsDir returns the path to the directory containing plugins + PluginsDir() string + + // LookupPluginsInPath returns true if plugins should be also looked up + // in the execution path + LookupPluginsInPath() bool + + // SinkMappings returns additional mappings for sink prefixes to resources + SinkMappings() []SinkMapping + + // ChannelTypeMappings returns additional mappings for channel type aliases + ChannelTypeMappings() []ChannelTypeMapping +} + +// SinkMappings is the struct of sink prefix config in kn config +type SinkMapping struct { + + // Prefix is the mapping prefix (like "svc") + Prefix string + + // Resource is the name for the mapped resource (like "services", mind the plural) + Resource string + + // Group is the api group for the mapped resource (like "core") + Group string + + // Version is the api version for the mapped resource (like "v1") + Version string +} + +// ChannelTypeMapping is the struct of ChannelType alias config in kn config +type ChannelTypeMapping struct { + + // Alias is the mapping alias (like "kafka") + Alias string + + // Kind is the name for the mapped resource kind (like "KafkaChannel") + Kind string + + // Group is the API group for the mapped resource kind (like "messaging.knative.dev") + Group string + + // Version is the API version for the mapped resource kind (like "v1alpha1") + Version string +} + +// config Keys for looking up in viper +const ( + keyPluginsDirectory = "plugins.directory" + keySinkMappings = "eventing.sink-mappings" + keyChannelTypeMappings = "eventing.channel-type-mappings" +) + +// legacy config keys, deprecated +const ( + legacyKeyPluginsDirectory = "plugins-dir" + legacyKeySinkMappings = "sink" +) + +// Global (hidden) flags +// TODO: Remove me if decided that they are not needed +const ( + flagPluginsDir = "plugins-dir" +) diff --git a/pkg/dynamic/client.go b/vendor/knative.dev/client-pkg/pkg/dynamic/client.go similarity index 99% rename from pkg/dynamic/client.go rename to vendor/knative.dev/client-pkg/pkg/dynamic/client.go index e885dca840..950abf2ef7 100644 --- a/pkg/dynamic/client.go +++ b/vendor/knative.dev/client-pkg/pkg/dynamic/client.go @@ -25,7 +25,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "knative.dev/eventing/pkg/apis/messaging" ) diff --git a/pkg/dynamic/client_mock.go b/vendor/knative.dev/client-pkg/pkg/dynamic/client_mock.go similarity index 99% rename from pkg/dynamic/client_mock.go rename to vendor/knative.dev/client-pkg/pkg/dynamic/client_mock.go index ebeb19eab7..c856f1086c 100644 --- a/pkg/dynamic/client_mock.go +++ b/vendor/knative.dev/client-pkg/pkg/dynamic/client_mock.go @@ -22,7 +22,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "knative.dev/client/pkg/util/mock" + "knative.dev/client-pkg/pkg/util/mock" ) // MockKnDynamicClient is a combine of test object and recorder diff --git a/pkg/dynamic/fake/fake.go b/vendor/knative.dev/client-pkg/pkg/dynamic/fake/fake.go similarity index 97% rename from pkg/dynamic/fake/fake.go rename to vendor/knative.dev/client-pkg/pkg/dynamic/fake/fake.go index 954cc43ff0..205523257b 100644 --- a/pkg/dynamic/fake/fake.go +++ b/vendor/knative.dev/client-pkg/pkg/dynamic/fake/fake.go @@ -20,7 +20,7 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/runtime" - "knative.dev/client/pkg/dynamic" + "knative.dev/client-pkg/pkg/dynamic" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" diff --git a/pkg/dynamic/lib.go b/vendor/knative.dev/client-pkg/pkg/dynamic/lib.go similarity index 100% rename from pkg/dynamic/lib.go rename to vendor/knative.dev/client-pkg/pkg/dynamic/lib.go diff --git a/pkg/errors/errors.go b/vendor/knative.dev/client-pkg/pkg/errors/errors.go similarity index 100% rename from pkg/errors/errors.go rename to vendor/knative.dev/client-pkg/pkg/errors/errors.go diff --git a/pkg/errors/factory.go b/vendor/knative.dev/client-pkg/pkg/errors/factory.go similarity index 100% rename from pkg/errors/factory.go rename to vendor/knative.dev/client-pkg/pkg/errors/factory.go diff --git a/pkg/errors/knerror.go b/vendor/knative.dev/client-pkg/pkg/errors/knerror.go similarity index 100% rename from pkg/errors/knerror.go rename to vendor/knative.dev/client-pkg/pkg/errors/knerror.go diff --git a/pkg/errors/types.go b/vendor/knative.dev/client-pkg/pkg/errors/types.go similarity index 100% rename from pkg/errors/types.go rename to vendor/knative.dev/client-pkg/pkg/errors/types.go diff --git a/vendor/knative.dev/client-pkg/pkg/eventing/v1/client.go b/vendor/knative.dev/client-pkg/pkg/eventing/v1/client.go new file mode 100644 index 0000000000..8e502996dc --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/eventing/v1/client.go @@ -0,0 +1,524 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + "fmt" + "time" + + apis_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/util/retry" + "knative.dev/client-pkg/pkg/config" + v1 "knative.dev/eventing/pkg/apis/duck/v1" + eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + clientv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1" + duckv1 "knative.dev/pkg/apis/duck/v1" + + kn_errors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" +) + +type TriggerUpdateFunc func(origTrigger *eventingv1.Trigger) (*eventingv1.Trigger, error) +type BrokerUpdateFunc func(origBroker *eventingv1.Broker) (*eventingv1.Broker, error) + +// KnEventingClient to Eventing Sources. All methods are relative to the +// namespace specified during construction +type KnEventingClient interface { + // Namespace in which this client is operating for + Namespace() string + // CreateTrigger is used to create an instance of trigger + CreateTrigger(ctx context.Context, trigger *eventingv1.Trigger) error + // DeleteTrigger is used to delete an instance of trigger + DeleteTrigger(ctx context.Context, name string) error + // GetTrigger is used to get an instance of trigger + GetTrigger(ctx context.Context, name string) (*eventingv1.Trigger, error) + // ListTriggers returns list of trigger CRDs + ListTriggers(ctx context.Context) (*eventingv1.TriggerList, error) + // UpdateTrigger is used to update an instance of trigger + UpdateTrigger(ctx context.Context, trigger *eventingv1.Trigger) error + // UpdateTriggerWithRetry is used to update an instance of trigger + UpdateTriggerWithRetry(ctx context.Context, name string, updateFunc TriggerUpdateFunc, nrRetries int) error + // CreateBroker is used to create an instance of broker + CreateBroker(ctx context.Context, broker *eventingv1.Broker) error + // GetBroker is used to get an instance of broker + GetBroker(ctx context.Context, name string) (*eventingv1.Broker, error) + // DeleteBroker is used to delete an instance of broker + DeleteBroker(ctx context.Context, name string, timeout time.Duration) error + // ListBrokers returns list of broker CRDs + ListBrokers(ctx context.Context) (*eventingv1.BrokerList, error) + // UpdateBroker is used to update an instance of broker + UpdateBroker(ctx context.Context, broker *eventingv1.Broker) error + // UpdateBrokerWithRetry is used to update an instance of broker + UpdateBrokerWithRetry(ctx context.Context, name string, updateFunc BrokerUpdateFunc, nrRetries int) error +} + +// KnEventingClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type knEventingClient struct { + client clientv1.EventingV1Interface + namespace string +} + +// NewKnEventingClient is to invoke Eventing Sources Client API to create object +func NewKnEventingClient(client clientv1.EventingV1Interface, namespace string) KnEventingClient { + return &knEventingClient{ + client: client, + namespace: namespace, + } +} + +// CreateTrigger is used to create an instance of trigger +func (c *knEventingClient) CreateTrigger(ctx context.Context, trigger *eventingv1.Trigger) error { + _, err := c.client.Triggers(c.namespace).Create(ctx, trigger, meta_v1.CreateOptions{}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +// DeleteTrigger is used to delete an instance of trigger +func (c *knEventingClient) DeleteTrigger(ctx context.Context, name string) error { + err := c.client.Triggers(c.namespace).Delete(ctx, name, apis_v1.DeleteOptions{}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +// GetTrigger is used to get an instance of trigger +func (c *knEventingClient) GetTrigger(ctx context.Context, name string) (*eventingv1.Trigger, error) { + trigger, err := c.client.Triggers(c.namespace).Get(ctx, name, apis_v1.GetOptions{}) + if err != nil { + return nil, kn_errors.GetError(err) + } + err = updateEventingGVK(trigger) + if err != nil { + return nil, err + } + return trigger, nil +} + +func (c *knEventingClient) ListTriggers(ctx context.Context) (*eventingv1.TriggerList, error) { + triggerList, err := c.client.Triggers(c.namespace).List(ctx, apis_v1.ListOptions{}) + if err != nil { + return nil, kn_errors.GetError(err) + } + triggerListNew := triggerList.DeepCopy() + err = updateEventingGVK(triggerListNew) + if err != nil { + return nil, err + } + + triggerListNew.Items = make([]eventingv1.Trigger, len(triggerList.Items)) + for idx, trigger := range triggerList.Items { + triggerClone := trigger.DeepCopy() + err := updateEventingGVK(triggerClone) + if err != nil { + return nil, err + } + triggerListNew.Items[idx] = *triggerClone + } + return triggerListNew, nil +} + +// UpdateTrigger is used to update an instance of trigger +func (c *knEventingClient) UpdateTrigger(ctx context.Context, trigger *eventingv1.Trigger) error { + _, err := c.client.Triggers(c.namespace).Update(ctx, trigger, meta_v1.UpdateOptions{}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +func (c *knEventingClient) UpdateTriggerWithRetry(ctx context.Context, name string, updateFunc TriggerUpdateFunc, nrRetries int) error { + return updateTriggerWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +func updateTriggerWithRetry(ctx context.Context, c KnEventingClient, name string, updateFunc TriggerUpdateFunc, nrRetries int) error { + b := config.DefaultRetry + b.Steps = nrRetries + updateTriggerFunc := func() error { + return updateTrigger(ctx, c, name, updateFunc) + } + err := retry.RetryOnConflict(b, updateTriggerFunc) + return err +} + +func updateTrigger(ctx context.Context, c KnEventingClient, name string, updateFunc TriggerUpdateFunc) error { + trigger, err := c.GetTrigger(ctx, name) + if err != nil { + return err + } + if trigger.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't update trigger %s because it has been marked for deletion", name) + } + updatedTrigger, err := updateFunc(trigger.DeepCopy()) + if err != nil { + return err + } + + return c.UpdateTrigger(ctx, updatedTrigger) +} + +// Namespace returns the namespace this client is bound to +func (c *knEventingClient) Namespace() string { + return c.namespace +} + +// update with the eventingv1 group + version +func updateEventingGVK(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, eventingv1.SchemeGroupVersion, scheme.Scheme) +} + +// TriggerBuilder is for building the trigger +type TriggerBuilder struct { + trigger *eventingv1.Trigger +} + +// NewTriggerBuilder for building trigger object +func NewTriggerBuilder(name string) *TriggerBuilder { + return &TriggerBuilder{&eventingv1.Trigger{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: name, + }, + }} +} + +// WithGvk sets the GVK for the triggers (which otherwise remains empty +func (b *TriggerBuilder) WithGvk() *TriggerBuilder { + _ = updateEventingGVK(b.trigger) + return b +} + +// NewTriggerBuilderFromExisting for building the object from existing Trigger object +func NewTriggerBuilderFromExisting(trigger *eventingv1.Trigger) *TriggerBuilder { + return &TriggerBuilder{trigger: trigger.DeepCopy()} +} + +// Namespace for this trigger +func (b *TriggerBuilder) Namespace(ns string) *TriggerBuilder { + b.trigger.Namespace = ns + return b +} + +// Subscriber for the trigger to send to (it's a Sink actually) +func (b *TriggerBuilder) Subscriber(subscriber *duckv1.Destination) *TriggerBuilder { + b.trigger.Spec.Subscriber = *subscriber + return b +} + +// Broker to set the broker of trigger object +func (b *TriggerBuilder) Broker(broker string) *TriggerBuilder { + b.trigger.Spec.Broker = broker + + return b +} + +// InjectBroker to add annotation to setup default broker +func (b *TriggerBuilder) InjectBroker(inject bool) *TriggerBuilder { + if inject { + meta_v1.SetMetaDataAnnotation(&b.trigger.ObjectMeta, eventingv1.InjectionAnnotation, "enabled") + } else { + if meta_v1.HasAnnotation(b.trigger.ObjectMeta, eventingv1.InjectionAnnotation) { + delete(b.trigger.ObjectMeta.Annotations, eventingv1.InjectionAnnotation) + } + } + return b +} + +func (b *TriggerBuilder) Filters(filters map[string]string) *TriggerBuilder { + if len(filters) == 0 { + b.trigger.Spec.Filter = &eventingv1.TriggerFilter{} + return b + } + filter := b.trigger.Spec.Filter + if filter == nil { + filter = &eventingv1.TriggerFilter{} + b.trigger.Spec.Filter = filter + } + filter.Attributes = eventingv1.TriggerFilterAttributes{} + for k, v := range filters { + filter.Attributes[k] = v + } + return b +} + +// Build to return an instance of trigger object +func (b *TriggerBuilder) Build() *eventingv1.Trigger { + return b.trigger +} + +// CreateBroker is used to create an instance of broker +func (c *knEventingClient) CreateBroker(ctx context.Context, broker *eventingv1.Broker) error { + _, err := c.client.Brokers(c.namespace).Create(ctx, broker, meta_v1.CreateOptions{}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +// GetBroker is used to get an instance of broker +func (c *knEventingClient) GetBroker(ctx context.Context, name string) (*eventingv1.Broker, error) { + broker, err := c.client.Brokers(c.namespace).Get(ctx, name, apis_v1.GetOptions{}) + if err != nil { + return nil, kn_errors.GetError(err) + } + err = updateEventingGVK(broker) + if err != nil { + return nil, err + } + return broker, nil +} + +// WatchBroker is used to create watcher object +func (c *knEventingClient) WatchBroker(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { + return wait.NewWatcherWithVersion(ctx, c.client.Brokers(c.namespace).Watch, c.client.RESTClient(), c.namespace, "brokers", name, initialVersion, timeout) +} + +// DeleteBroker is used to delete an instance of broker and wait for completion until given timeout +// For `timeout == 0` delete is performed async without any wait +func (c *knEventingClient) DeleteBroker(ctx context.Context, name string, timeout time.Duration) error { + broker, err := c.GetBroker(ctx, name) + if err != nil { + return err + } + if broker.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't delete broker '%s' because it has been already marked for deletion", name) + } + if timeout == 0 { + return c.deleteBroker(ctx, name, apis_v1.DeletePropagationBackground) + } + waitC := make(chan error) + go func() { + waitForEvent := wait.NewWaitForEvent("broker", c.WatchBroker, func(evt *watch.Event) bool { return evt.Type == watch.Deleted }) + err, _ := waitForEvent.Wait(ctx, name, broker.ResourceVersion, wait.Options{Timeout: &timeout}, wait.NoopMessageCallback()) + waitC <- err + }() + err = c.deleteBroker(ctx, name, apis_v1.DeletePropagationForeground) + if err != nil { + return err + } + return <-waitC +} + +// deleteBroker is used to delete an instance of broker +func (c *knEventingClient) deleteBroker(ctx context.Context, name string, propagationPolicy apis_v1.DeletionPropagation) error { + err := c.client.Brokers(c.namespace).Delete(ctx, name, apis_v1.DeleteOptions{PropagationPolicy: &propagationPolicy}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +// ListBrokers is used to retrieve the list of broker instances +func (c *knEventingClient) ListBrokers(ctx context.Context) (*eventingv1.BrokerList, error) { + brokerList, err := c.client.Brokers(c.namespace).List(ctx, apis_v1.ListOptions{}) + if err != nil { + return nil, kn_errors.GetError(err) + } + brokerListNew := brokerList.DeepCopy() + err = updateEventingGVK(brokerListNew) + if err != nil { + return nil, err + } + + brokerListNew.Items = make([]eventingv1.Broker, len(brokerList.Items)) + for idx, trigger := range brokerList.Items { + triggerClone := trigger.DeepCopy() + err := updateEventingGVK(triggerClone) + if err != nil { + return nil, err + } + brokerListNew.Items[idx] = *triggerClone + } + return brokerListNew, nil +} + +// UpdateBroker is used to update an instance of broker +func (c *knEventingClient) UpdateBroker(ctx context.Context, broker *eventingv1.Broker) error { + _, err := c.client.Brokers(c.namespace).Update(ctx, broker, meta_v1.UpdateOptions{}) + if err != nil { + return kn_errors.GetError(err) + } + return nil +} + +func (c *knEventingClient) UpdateBrokerWithRetry(ctx context.Context, name string, updateFunc BrokerUpdateFunc, nrRetries int) error { + return updateBrokerWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +func updateBrokerWithRetry(ctx context.Context, c KnEventingClient, name string, updateFunc BrokerUpdateFunc, nrRetries int) error { + b := config.DefaultRetry + b.Steps = nrRetries + updateBrokerFunc := func() error { + return updateBroker(ctx, c, name, updateFunc) + } + err := retry.RetryOnConflict(b, updateBrokerFunc) + return err +} + +func updateBroker(ctx context.Context, c KnEventingClient, name string, updateFunc BrokerUpdateFunc) error { + broker, err := c.GetBroker(ctx, name) + if err != nil { + return err + } + if broker.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't update broker %s because it has been marked for deletion", name) + } + updatedBroker, err := updateFunc(broker.DeepCopy()) + if err != nil { + return err + } + + return c.UpdateBroker(ctx, updatedBroker) +} + +// BrokerBuilder is for building the broker +type BrokerBuilder struct { + broker *eventingv1.Broker +} + +// NewBrokerBuilder for building broker object +func NewBrokerBuilder(name string) *BrokerBuilder { + return &BrokerBuilder{broker: &eventingv1.Broker{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: name, + }, + }} +} + +// NewBrokerBuilderFromExisting returns broker builder from original broker +func NewBrokerBuilderFromExisting(broker *eventingv1.Broker) *BrokerBuilder { + return &BrokerBuilder{ + broker: broker, + } +} + +// WithGvk add the GVK coordinates for read tests +func (b *BrokerBuilder) WithGvk() *BrokerBuilder { + _ = updateEventingGVK(b.broker) + return b +} + +// Namespace for broker builder +func (b *BrokerBuilder) Namespace(ns string) *BrokerBuilder { + b.broker.Namespace = ns + return b +} + +// Class for broker builder +func (b *BrokerBuilder) Class(class string) *BrokerBuilder { + if class == "" { + return b + } + if len(b.broker.Annotations) == 0 { + b.broker.Annotations = make(map[string]string) + } + b.broker.Annotations[eventingv1.BrokerClassAnnotationKey] = class + return b +} + +// DlSink for the broker builder +func (b *BrokerBuilder) DlSink(dlSink *duckv1.Destination) *BrokerBuilder { + empty := duckv1.Destination{} + if dlSink == nil || *dlSink == empty { + return b + } + if b.broker.Spec.Delivery == nil { + b.broker.Spec.Delivery = &v1.DeliverySpec{} + } + b.broker.Spec.Delivery.DeadLetterSink = dlSink + return b +} + +// Retry for the broker builder +func (b *BrokerBuilder) Retry(retry *int32) *BrokerBuilder { + if retry == nil || *retry == 0 { + return b + } + if b.broker.Spec.Delivery == nil { + b.broker.Spec.Delivery = &v1.DeliverySpec{} + } + b.broker.Spec.Delivery.Retry = retry + return b +} + +// Timeout for the broker builder +func (b *BrokerBuilder) Timeout(timeout *string) *BrokerBuilder { + if timeout == nil || *timeout == "" { + return b + } + if b.broker.Spec.Delivery == nil { + b.broker.Spec.Delivery = &v1.DeliverySpec{} + } + b.broker.Spec.Delivery.Timeout = timeout + return b +} + +// BackoffPolicy for the broker builder +func (b *BrokerBuilder) BackoffPolicy(policyType *v1.BackoffPolicyType) *BrokerBuilder { + if policyType == nil || *policyType == "" { + return b + } + if b.broker.Spec.Delivery == nil { + b.broker.Spec.Delivery = &v1.DeliverySpec{} + } + b.broker.Spec.Delivery.BackoffPolicy = policyType + return b +} + +// BackoffDelay for the broker builder +func (b *BrokerBuilder) BackoffDelay(backoffDelay *string) *BrokerBuilder { + if backoffDelay == nil || *backoffDelay == "" { + return b + } + if b.broker.Spec.Delivery == nil { + b.broker.Spec.Delivery = &v1.DeliverySpec{} + } + b.broker.Spec.Delivery.BackoffDelay = backoffDelay + return b +} + +// RetryAfterMax for the broker builder +func (b *BrokerBuilder) RetryAfterMax(max *string) *BrokerBuilder { + if max == nil || *max == "" { + return b + } + if b.broker.Spec.Delivery == nil { + b.broker.Spec.Delivery = &v1.DeliverySpec{} + } + b.broker.Spec.Delivery.RetryAfterMax = max + return b + +} + +// Config for the broker builder +func (b *BrokerBuilder) Config(config *duckv1.KReference) *BrokerBuilder { + b.broker.Spec.Config = config + return b + +} + +// Build to return an instance of broker object +func (b *BrokerBuilder) Build() *eventingv1.Broker { + return b.broker +} diff --git a/vendor/knative.dev/client-pkg/pkg/eventing/v1/client_mock.go b/vendor/knative.dev/client-pkg/pkg/eventing/v1/client_mock.go new file mode 100644 index 0000000000..b95d2561bd --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/eventing/v1/client_mock.go @@ -0,0 +1,183 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + "testing" + "time" + + eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" + + "knative.dev/client-pkg/pkg/util/mock" +) + +// MockKnEventingClient is a combine of test object and recorder +type MockKnEventingClient struct { + t *testing.T + recorder *EventingRecorder +} + +// NewMockKnEventingClient returns a new mock instance which you need to record for +func NewMockKnEventingClient(t *testing.T, ns ...string) *MockKnEventingClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnEventingClient{ + t: t, + recorder: &EventingRecorder{mock.NewRecorder(t, namespace)}, + } +} + +// Ensure that the interface is implemented +var _ KnEventingClient = &MockKnEventingClient{} + +// EventingRecorder is recorder for eventing objects +type EventingRecorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnEventingClient) Recorder() *EventingRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnEventingClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// CreateTrigger records a call for CreatePingSource with the expected error +func (sr *EventingRecorder) CreateTrigger(trigger interface{}, err error) { + sr.r.Add("CreateTrigger", []interface{}{trigger}, []interface{}{err}) +} + +// CreateTrigger performs a previously recorded action +func (c *MockKnEventingClient) CreateTrigger(ctx context.Context, trigger *eventingv1.Trigger) error { + call := c.recorder.r.VerifyCall("CreateTrigger", trigger) + return mock.ErrorOrNil(call.Result[0]) +} + +// GetTrigger records a call for GetTrigger with the expected object or error. Either trigger or err should be nil +func (sr *EventingRecorder) GetTrigger(name interface{}, trigger *eventingv1.Trigger, err error) { + sr.r.Add("GetTrigger", []interface{}{name}, []interface{}{trigger, err}) +} + +// GetTrigger performs a previously recorded action +func (c *MockKnEventingClient) GetTrigger(ctx context.Context, name string) (*eventingv1.Trigger, error) { + call := c.recorder.r.VerifyCall("GetTrigger", name) + return call.Result[0].(*eventingv1.Trigger), mock.ErrorOrNil(call.Result[1]) +} + +// DeleteTrigger records a call for DeleteTrigger with the expected error (nil if none) +func (sr *EventingRecorder) DeleteTrigger(name interface{}, err error) { + sr.r.Add("DeleteTrigger", []interface{}{name}, []interface{}{err}) +} + +// DeleteTrigger performs a previously recorded action, failing if non has been registered +func (c *MockKnEventingClient) DeleteTrigger(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeleteTrigger", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListTriggers records a call for ListTriggers with the expected result and error (nil if none) +func (sr *EventingRecorder) ListTriggers(triggerList *eventingv1.TriggerList, err error) { + sr.r.Add("ListTriggers", nil, []interface{}{triggerList, err}) +} + +// ListTriggers performs a previously recorded action +func (c *MockKnEventingClient) ListTriggers(context.Context) (*eventingv1.TriggerList, error) { + call := c.recorder.r.VerifyCall("ListTriggers") + return call.Result[0].(*eventingv1.TriggerList), mock.ErrorOrNil(call.Result[1]) +} + +// UpdateTrigger records a call for UpdateTrigger with the expected result and error (nil if none) +func (sr *EventingRecorder) UpdateTrigger(trigger interface{}, err error) { + sr.r.Add("UpdateTrigger", []interface{}{trigger}, []interface{}{err}) +} + +// UpdateTrigger performs a previously recorded action +func (c *MockKnEventingClient) UpdateTrigger(ctx context.Context, trigger *eventingv1.Trigger) error { + call := c.recorder.r.VerifyCall("UpdateTrigger") + return mock.ErrorOrNil(call.Result[0]) +} + +func (c *MockKnEventingClient) UpdateTriggerWithRetry(ctx context.Context, name string, updateFunc TriggerUpdateFunc, nrRetries int) error { + return updateTriggerWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +// CreateBroker records a call for CreateBroker with the expected error +func (sr *EventingRecorder) CreateBroker(broker interface{}, err error) { + sr.r.Add("CreateBroker", []interface{}{broker}, []interface{}{err}) +} + +// CreateBroker performs a previously recorded action +func (c *MockKnEventingClient) CreateBroker(ctx context.Context, broker *eventingv1.Broker) error { + call := c.recorder.r.VerifyCall("CreateBroker", broker) + return mock.ErrorOrNil(call.Result[0]) +} + +// GetBroker records a call for GetBroker with the expected object or error. Either trigger or err should be nil +func (sr *EventingRecorder) GetBroker(name interface{}, broker *eventingv1.Broker, err error) { + sr.r.Add("GetBroker", []interface{}{name}, []interface{}{broker, err}) +} + +// GetBroker performs a previously recorded action +func (c *MockKnEventingClient) GetBroker(ctx context.Context, name string) (*eventingv1.Broker, error) { + call := c.recorder.r.VerifyCall("GetBroker", name) + return call.Result[0].(*eventingv1.Broker), mock.ErrorOrNil(call.Result[1]) +} + +// DeleteBroker records a call for DeleteBroker with the expected error (nil if none) +func (sr *EventingRecorder) DeleteBroker(name, timeout interface{}, err error) { + sr.r.Add("DeleteBroker", []interface{}{name, timeout}, []interface{}{err}) +} + +// DeleteBroker performs a previously recorded action, failing if non has been registered +func (c *MockKnEventingClient) DeleteBroker(ctx context.Context, name string, timeout time.Duration) error { + call := c.recorder.r.VerifyCall("DeleteBroker", name, timeout) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListBrokers records a call for ListBrokers with the expected result and error (nil if none) +func (sr *EventingRecorder) ListBrokers(brokerList *eventingv1.BrokerList, err error) { + sr.r.Add("ListBrokers", nil, []interface{}{brokerList, err}) +} + +// ListBrokers performs a previously recorded action +func (c *MockKnEventingClient) ListBrokers(context.Context) (*eventingv1.BrokerList, error) { + call := c.recorder.r.VerifyCall("ListBrokers") + return call.Result[0].(*eventingv1.BrokerList), mock.ErrorOrNil(call.Result[1]) +} + +// UpdateBroker records a call for UpdateBroker with the expected result and error (nil if none) +func (sr *EventingRecorder) UpdateBroker(broker *eventingv1.Broker, err error) { + sr.r.Add("UpdateBroker", []interface{}{broker}, []interface{}{err}) +} + +func (c *MockKnEventingClient) UpdateBroker(ctx context.Context, broker *eventingv1.Broker) error { + call := c.recorder.r.VerifyCall("UpdateBroker") + return mock.ErrorOrNil(call.Result[0]) +} + +func (c *MockKnEventingClient) UpdateBrokerWithRetry(ctx context.Context, name string, updateFunc BrokerUpdateFunc, nrRetries int) error { + return updateBrokerWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +// Validate validates whether every recorded action has been called +func (sr *EventingRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/vendor/knative.dev/client-pkg/pkg/eventing/v1beta2/client.go b/vendor/knative.dev/client-pkg/pkg/eventing/v1beta2/client.go new file mode 100644 index 0000000000..b1b713c24c --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/eventing/v1beta2/client.go @@ -0,0 +1,177 @@ +// 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 v1beta2 + +import ( + "context" + + apis_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + kn_errors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" + eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" + eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta2" + "knative.dev/pkg/apis" + v1 "knative.dev/pkg/apis/duck/v1" +) + +// KnEventingV1Beta2Client to Eventing Sources. All methods are relative to the +// namespace specified during construction +type KnEventingV1Beta2Client interface { + // Namespace in which this client is operating for + Namespace() string + // ListEventtypes is used to list eventtypes + ListEventtypes(ctx context.Context) (*eventingv1beta2.EventTypeList, error) + // GetEventtype is used to describe an eventtype + GetEventtype(ctx context.Context, name string) (*eventingv1beta2.EventType, error) + // CreateEventtype is used to create an eventtype + CreateEventtype(ctx context.Context, eventtype *eventingv1beta2.EventType) error + // DeleteEventtype is used to delete an eventtype + DeleteEventtype(ctx context.Context, name string) error +} + +// KnEventingV1Beta2Client is a client for eventing v1beta2 resources +type knEventingV1Beta1Client struct { + client beta1.EventingV1beta2Interface + namespace string +} + +// NewKnEventingV1Beta2Client is to invoke Eventing Types Client API to create object +func NewKnEventingV1Beta2Client(client beta1.EventingV1beta2Interface, namespace string) KnEventingV1Beta2Client { + return &knEventingV1Beta1Client{ + client: client, + namespace: namespace, + } +} + +func updateEventingBeta1GVK(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, eventingv1beta2.SchemeGroupVersion, scheme.Scheme) +} + +func (c *knEventingV1Beta1Client) Namespace() string { + return c.namespace +} + +func (c *knEventingV1Beta1Client) ListEventtypes(ctx context.Context) (*eventingv1beta2.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([]eventingv1beta2.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) (*eventingv1beta2.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 *eventingv1beta2.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 *eventingv1beta2.EventType +} + +// NewEventtypeBuilder for building eventtype object +func NewEventtypeBuilder(name string) *EventtypeBuilder { + return &EventtypeBuilder{eventtype: &eventingv1beta2.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.Reference = &v1.KReference{ + APIVersion: eventingv1.SchemeGroupVersion.String(), + Kind: "Broker", + Name: broker, + } + return e +} + +// Reference for eventtype builder +func (e *EventtypeBuilder) Reference(ref *v1.KReference) *EventtypeBuilder { + e.eventtype.Spec.Reference = ref + return e +} + +// Build to return an instance of eventtype object +func (e *EventtypeBuilder) Build() *eventingv1beta2.EventType { + return e.eventtype +} diff --git a/vendor/knative.dev/client-pkg/pkg/eventing/v1beta2/client_mock.go b/vendor/knative.dev/client-pkg/pkg/eventing/v1beta2/client_mock.go new file mode 100644 index 0000000000..b026f1efec --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/eventing/v1beta2/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 v1beta2 + +import ( + "context" + "testing" + + eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" + + "knative.dev/client-pkg/pkg/util/mock" +) + +// MockKnEventingV1beta2Client is a combine of test object and recorder +type MockKnEventingV1beta2Client struct { + t *testing.T + recorder *EventingV1beta2Recorder +} + +// NewMockKnEventingV1beta2Client returns a new mock instance which you need to record for +func NewMockKnEventingV1beta2Client(t *testing.T, ns ...string) *MockKnEventingV1beta2Client { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnEventingV1beta2Client{ + t: t, + recorder: &EventingV1beta2Recorder{mock.NewRecorder(t, namespace)}, + } +} + +// Ensure that the interface is implemented +var _ KnEventingV1Beta2Client = &MockKnEventingV1beta2Client{} + +// EventingV1beta2Recorder is recorder for eventingv1beta2 objects +type EventingV1beta2Recorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnEventingV1beta2Client) Recorder() *EventingV1beta2Recorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnEventingV1beta2Client) Namespace() string { + return c.recorder.r.Namespace() +} + +// ListEventtypes records a call for ListEventtypes with the expected result and error (nil if none) +func (sr *EventingV1beta2Recorder) ListEventtypes(eventtypeList *eventingv1beta2.EventTypeList, err error) { + sr.r.Add("ListEventtypes", nil, []interface{}{eventtypeList, err}) +} + +func (c *MockKnEventingV1beta2Client) ListEventtypes(ctx context.Context) (*eventingv1beta2.EventTypeList, error) { + call := c.recorder.r.VerifyCall("ListEventtypes") + return call.Result[0].(*eventingv1beta2.EventTypeList), mock.ErrorOrNil(call.Result[1]) +} + +// GetEventtype records a call for GetEventtype with the expected result and error (nil if none) +func (sr *EventingV1beta2Recorder) GetEventtype(name string, eventtype *eventingv1beta2.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 *MockKnEventingV1beta2Client) GetEventtype(ctx context.Context, name string) (*eventingv1beta2.EventType, error) { + call := c.recorder.r.VerifyCall("GetEventtype", name) + return call.Result[0].(*eventingv1beta2.EventType), mock.ErrorOrNil(call.Result[1]) +} + +// CreateEventtype records a call for CreateEventtype with the expected error +func (sr *EventingV1beta2Recorder) CreateEventtype(eventtype interface{}, err error) { + sr.r.Add("CreateEventtype", []interface{}{eventtype}, []interface{}{err}) +} + +func (c *MockKnEventingV1beta2Client) CreateEventtype(ctx context.Context, eventtype *eventingv1beta2.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 *EventingV1beta2Recorder) DeleteEventtype(name interface{}, err error) { + sr.r.Add("DeleteEventtype", []interface{}{name}, []interface{}{err}) +} + +func (c *MockKnEventingV1beta2Client) 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 *EventingV1beta2Recorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/vendor/knative.dev/client-pkg/pkg/flags/bool.go b/vendor/knative.dev/client-pkg/pkg/flags/bool.go new file mode 100644 index 0000000000..feca0b2af6 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/flags/bool.go @@ -0,0 +1,126 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flags + +import ( + "fmt" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "github.com/spf13/pflag" +) + +var ( + negPrefix = "no-" +) + +// AddBothBoolFlagsUnhidden is just like AddBothBoolFlags but shows both flags. +func AddBothBoolFlagsUnhidden(f *pflag.FlagSet, p *bool, name, short string, value bool, usage string) { + + negativeName := negPrefix + name + + f.BoolVarP(p, name, short, value, usage) + f.Bool(negativeName, !value, InvertUsage(usage)) +} + +// AddBothBoolFlags adds the given flag in both `--foo` and `--no-foo` variants. +// If you do this, make sure you call ReconcileBoolFlags later to catch errors +// and set the relationship between the flag values. Only the flag that does the +// non-default behavior is visible; the other is hidden. +func AddBothBoolFlags(f *pflag.FlagSet, p *bool, name, short string, value bool, usage string) { + AddBothBoolFlagsUnhidden(f, p, name, short, value, usage) + negativeName := negPrefix + name + if value { + err := f.MarkHidden(name) + if err != nil { + panic(err) + } + } else { + err := f.MarkHidden(negativeName) + if err != nil { + panic(err) + } + } +} + +// ReconcileBoolFlags sets the value of the all the "--foo" flags based on +// "--no-foo" if provided, and returns an error if both were provided or an +// explicit value of false was provided to either (as that's confusing). +func ReconcileBoolFlags(f *pflag.FlagSet) error { + var err error + f.VisitAll(func(flag *pflag.Flag) { + // Return early from our comprehension + if err != nil { + return + } + + // Walk the "no-" versions of the flags. Make sure we didn't set + // both, and set the positive value to the opposite of the "no-" + // value if it exists. + if strings.HasPrefix(flag.Name, negPrefix) { + positiveName := flag.Name[len(negPrefix):] + positive := f.Lookup(positiveName) + // Non-paired flag, or wrong types + if positive == nil || positive.Value.Type() != "bool" || flag.Value.Type() != "bool" { + return + } + if flag.Changed { + if positive.Changed { + err = fmt.Errorf("only one of --%s and --%s may be specified", + flag.Name, positiveName) + return + } + err = checkExplicitFalse(flag, positiveName) + if err != nil { + return + } + err = positive.Value.Set("false") + } else { + err = checkExplicitFalse(positive, flag.Name) + } + } + + }) + return err +} + +// checkExplicitFalse returns an error if the flag was explicitly set to false. +func checkExplicitFalse(f *pflag.Flag, betterFlag string) error { + if !f.Changed { + return nil + } + val, err := strconv.ParseBool(f.Value.String()) + if err != nil { + return err + } + if !val { + return fmt.Errorf("use --%s instead of providing \"%s\" to --%s", + betterFlag, f.Value.String(), f.Name) + } + return nil +} + +// FirstCharToLower converts first char in given string to lowercase +func FirstCharToLower(s string) string { + r, n := utf8.DecodeRuneInString(s) + return string(unicode.ToLower(r)) + s[n:] +} + +// InvertUsage inverts the usage string with prefix "Do not" +func InvertUsage(usage string) string { + return "Do not " + FirstCharToLower(usage) +} diff --git a/vendor/knative.dev/client-pkg/pkg/flags/podspec_helper.go b/vendor/knative.dev/client-pkg/pkg/flags/podspec_helper.go new file mode 100644 index 0000000000..d1d9f1b4b8 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/flags/podspec_helper.go @@ -0,0 +1,1127 @@ +// Copyright © 2020 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flags + +import ( + "fmt" + "os" + "strconv" + "strings" + + "k8s.io/utils/pointer" + + "k8s.io/apimachinery/pkg/util/intstr" + + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/yaml" + + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/sets" + "knative.dev/client-pkg/pkg/util" +) + +// VolumeSourceType is a type standing for enumeration of ConfigMap and Secret +type VolumeSourceType int + +// Enumeration of volume source types: ConfigMap or Secret +const ( + ConfigMapVolumeSourceType VolumeSourceType = iota + SecretVolumeSourceType + EmptyDirVolumeSourceType + PVCVolumeSourceType + PortFormatErr = "the port specification '%s' is not valid. Please provide in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'." +) + +type MountInfo struct { + VolumeName string + SubPath string + MountOptions string +} + +func (vt VolumeSourceType) String() string { + names := [...]string{"config-map", "secret"} + if vt < ConfigMapVolumeSourceType || vt > SecretVolumeSourceType { + return "unknown" + } + return names[vt] +} + +func containerOfPodSpec(spec *corev1.PodSpec) *corev1.Container { + if len(spec.Containers) == 0 { + newContainer := corev1.Container{} + spec.Containers = append(spec.Containers, newContainer) + } + return &spec.Containers[0] +} + +// UpdateEnvVars gives the configuration all the env var values listed in the given map of +// vars. Does not touch any environment variables not mentioned, but it can add +// new env vars and change the values of existing ones. +func UpdateEnvVars(spec *corev1.PodSpec, allArgs []string, + envToUpdate *util.OrderedMap, envToRemove []string, + envValueFromToUpdate *util.OrderedMap, envValueFromToRemove []string, + envFileName string, envValueFileToUpdate *util.OrderedMap, envValueFileToRemove []string, +) error { + container := containerOfPodSpec(spec) + + allEnvsToUpdate := util.NewOrderedMap() + + envIterator := envToUpdate.Iterator() + envValueFromIterator := envValueFromToUpdate.Iterator() + envValueFileIterator := envValueFileToUpdate.Iterator() + + envKey, envValue, envExists := envIterator.NextString() + envValueFromKey, envValueFromValue, envValueFromExists := envValueFromIterator.NextString() + envValueFileKey, envValueFileValue, envValueFileExists := envValueFileIterator.NextString() + for _, arg := range allArgs { + // envs are stored as NAME=value + if envExists && isValidEnvArg(arg, envKey, envValue) { + allEnvsToUpdate.Set(envKey, corev1.EnvVar{ + Name: envKey, + Value: envValue, + }) + envKey, envValue, envExists = envIterator.NextString() + } else if envValueFromExists && isValidEnvValueFromArg(arg, envValueFromKey, envValueFromValue) { + // envs are stored as NAME=secret:sercretName:key or NAME=config-map:cmName:key + envVarSource, err := createEnvVarSource(envValueFromValue) + if err != nil { + return err + } + allEnvsToUpdate.Set(envValueFromKey, corev1.EnvVar{ + Name: envValueFromKey, + ValueFrom: envVarSource, + }) + envValueFromKey, envValueFromValue, envValueFromExists = envValueFromIterator.NextString() + } else if envValueFileExists && isValidEnvValueFileArg(arg, envFileName) { + for envValueFileExists { + allEnvsToUpdate.Set(envValueFileKey, corev1.EnvVar{ + Name: envValueFileKey, + Value: envValueFileValue, + }) + envValueFileKey, envValueFileValue, envValueFileExists = envValueFileIterator.NextString() + } + } + } + + updated := updateEnvVarsFromMap(container.Env, allEnvsToUpdate) + updated = removeEnvVars(updated, append(envToRemove, envValueFromToRemove...)) + + container.Env = updated + + return nil +} + +// isValidEnvArg checks that the input arg is a valid argument for specifying env value, +// ie. stored as NAME=value +func isValidEnvArg(arg, envKey, envValue string) bool { + return strings.HasPrefix(arg, envKey+"="+envValue) || strings.HasPrefix(arg, "-e="+envKey+"="+envValue) || strings.HasPrefix(arg, "--env="+envKey+"="+envValue) +} + +// isValidEnvValueFromArg checks that the input arg is a valid argument for specifying env from value, +// ie. stored as NAME=secret:sercretName:key or NAME=config-map:cmName:key +func isValidEnvValueFromArg(arg, envValueFromKey, envValueFromValue string) bool { + return strings.HasPrefix(arg, envValueFromKey+"="+envValueFromValue) || strings.HasPrefix(arg, "--env-value-from="+envValueFromKey+"="+envValueFromValue) +} + +// isValidEnvValueFileArg checks that the input arg is a valid argument for specifying env from value, +// ie. stored as NAME=secret:sercretName:key or NAME=config-map:cmName:key +func isValidEnvValueFileArg(arg, envFileName string) bool { + return strings.HasPrefix(arg, envFileName) || strings.HasPrefix(arg, "--env-file="+envFileName) +} + +// UpdateEnvFrom updates envFrom +func UpdateEnvFrom(spec *corev1.PodSpec, toUpdate []string, toRemove []string) error { + container := containerOfPodSpec(spec) + envFrom, err := updateEnvFrom(container.EnvFrom, toUpdate) + if err != nil { + return err + } + container.EnvFrom, err = removeEnvFrom(envFrom, toRemove) + return err +} + +// UpdateVolumeMountsAndVolumes updates the configuration for volume mounts and volumes. +func UpdateVolumeMountsAndVolumes(spec *corev1.PodSpec, + mountsToUpdate *util.OrderedMap, mountsToRemove []string, volumesToUpdate *util.OrderedMap, volumesToRemove []string) error { + container := containerOfPodSpec(spec) + + volumeSourceInfoByName, mountsToUpdate, err := reviseVolumeInfoAndMountsToUpdate(mountsToUpdate, volumesToUpdate) + if err != nil { + return err + } + + volumes, err := updateVolumesFromMap(spec.Volumes, volumeSourceInfoByName) + if err != nil { + return err + } + + volumeMounts, err := updateVolumeMountsFromMap(container.VolumeMounts, mountsToUpdate, volumes) + if err != nil { + return err + } + + volumesToRemove = reviseVolumesToRemove(container.VolumeMounts, volumesToRemove, mountsToRemove) + + container.VolumeMounts = removeVolumeMounts(volumeMounts, mountsToRemove) + spec.Volumes, err = removeVolumes(volumes, volumesToRemove, container.VolumeMounts) + + return err +} + +// UpdateImage a given image +func UpdateImage(spec *corev1.PodSpec, image string) error { + // When not setting the image to a digest, add the user image annotation. + container := containerOfPodSpec(spec) + container.Image = image + return nil +} + +// UpdateContainerCommand updates container with a given argument +func UpdateContainerCommand(spec *corev1.PodSpec, command []string) error { + container := containerOfPodSpec(spec) + container.Command = command + return nil +} + +// UpdateContainerArg updates container with a given argument +func UpdateContainerArg(spec *corev1.PodSpec, arg []string) error { + container := containerOfPodSpec(spec) + container.Args = arg + return nil +} + +// UpdateContainerPort updates container with a given name:port +func UpdateContainerPort(spec *corev1.PodSpec, port string) error { + container := containerOfPodSpec(spec) + + var containerPort int64 + var name string + var err error + + elements := strings.SplitN(port, ":", 2) + if len(elements) == 2 { + name = elements[0] + containerPort, err = strconv.ParseInt(elements[1], 10, 32) + if err != nil { + return fmt.Errorf(PortFormatErr, port) + } + } else { + name = "" + containerPort, err = strconv.ParseInt(elements[0], 10, 32) + if err != nil { + return fmt.Errorf(PortFormatErr, port) + } + } + + container.Ports = []corev1.ContainerPort{{ + ContainerPort: int32(containerPort), + Name: name, + }} + return nil +} + +// UpdateUser updates container with a given user id +func UpdateUser(spec *corev1.PodSpec, user int64) error { + container := containerOfPodSpec(spec) + container.SecurityContext = &corev1.SecurityContext{ + RunAsUser: &user, + } + return nil +} + +// UpdateResources updates container resources for given revision spec +func UpdateResources(spec *corev1.PodSpec, resources corev1.ResourceRequirements, requestsToRemove, limitsToRemove []string) error { + container := containerOfPodSpec(spec) + + if container.Resources.Requests == nil { + container.Resources.Requests = corev1.ResourceList{} + } + + for k, v := range resources.Requests { + container.Resources.Requests[k] = v + } + + for _, reqToRemove := range requestsToRemove { + delete(container.Resources.Requests, corev1.ResourceName(reqToRemove)) + } + + if container.Resources.Limits == nil { + container.Resources.Limits = corev1.ResourceList{} + } + + for k, v := range resources.Limits { + container.Resources.Limits[k] = v + } + + for _, limToRemove := range limitsToRemove { + delete(container.Resources.Limits, corev1.ResourceName(limToRemove)) + } + + return nil +} + +// UpdateServiceAccountName updates the service account name used for the corresponding knative service +func UpdateServiceAccountName(spec *corev1.PodSpec, serviceAccountName string) { + serviceAccountName = strings.TrimSpace(serviceAccountName) + spec.ServiceAccountName = serviceAccountName +} + +// UpdateImagePullSecrets updates the image pull secrets used for the corresponding knative service +func UpdateImagePullSecrets(spec *corev1.PodSpec, pullsecrets string) { + pullsecrets = strings.TrimSpace(pullsecrets) + if pullsecrets == "" { + spec.ImagePullSecrets = nil + } else { + spec.ImagePullSecrets = []corev1.LocalObjectReference{{ + Name: pullsecrets, + }} + } +} + +// UpdateContainers updates the containers array with additional ones provided from file or os.Stdin +func UpdateContainers(spec *corev1.PodSpec, containers []corev1.Container) { + var matched []string + if len(spec.Containers) == 1 { + spec.Containers = append(spec.Containers, containers...) + } else { + for i, container := range spec.Containers { + for j, toUpdate := range containers { + if container.Name == toUpdate.Name { + + spec.Containers[i] = containers[j] + + matched = append(matched, toUpdate.Name) + } + } + } + for _, container := range containers { + if !util.SliceContainsIgnoreCase(matched, container.Name) { + spec.Containers = append(spec.Containers, container) + } + } + } +} + +// UpdateLivenessProbe updates container liveness probe based on provided string +func UpdateLivenessProbe(spec *corev1.PodSpec, probeString string) error { + c := containerOfPodSpec(spec) + handler, err := resolveProbeHandler(probeString) + if err != nil { + return err + } + if c.LivenessProbe == nil { + c.LivenessProbe = &corev1.Probe{} + } + c.LivenessProbe.ProbeHandler = *handler + return nil +} + +// UpdateLivenessProbeOpts updates container liveness probe commons options based on provided string +func UpdateLivenessProbeOpts(spec *corev1.PodSpec, probeString string) error { + c := containerOfPodSpec(spec) + if c.LivenessProbe == nil { + c.LivenessProbe = &corev1.Probe{} + } + err := resolveProbeOptions(c.LivenessProbe, probeString) + if err != nil { + return err + } + return nil +} + +// UpdateReadinessProbe updates container readiness probe based on provided string +func UpdateReadinessProbe(spec *corev1.PodSpec, probeString string) error { + c := containerOfPodSpec(spec) + handler, err := resolveProbeHandler(probeString) + if err != nil { + return err + } + if c.ReadinessProbe == nil { + c.ReadinessProbe = &corev1.Probe{} + } + c.ReadinessProbe.ProbeHandler = *handler + return nil +} + +// UpdateReadinessProbeOpts updates container readiness probe commons options based on provided string +func UpdateReadinessProbeOpts(spec *corev1.PodSpec, probeString string) error { + c := containerOfPodSpec(spec) + if c.ReadinessProbe == nil { + c.ReadinessProbe = &corev1.Probe{} + } + err := resolveProbeOptions(c.ReadinessProbe, probeString) + if err != nil { + return err + } + return nil +} + +// UpdateImagePullPolicy updates the pull policy for the given revision template +func UpdateImagePullPolicy(spec *corev1.PodSpec, imagePullPolicy string) error { + container := containerOfPodSpec(spec) + + if !isValidPullPolicy(imagePullPolicy) { + return fmt.Errorf("invalid --pull-policy %s. Valid arguments (case insensitive): Always | Never | IfNotPresent", imagePullPolicy) + } + container.ImagePullPolicy = getPolicy(imagePullPolicy) + return nil +} + +// UpdateSecurityContext update the Security Context +func UpdateSecurityContext(spec *corev1.PodSpec, securityContext string) error { + container := containerOfPodSpec(spec) + switch strings.ToLower(securityContext) { + case "none": + // Blank any Security Context defined + container.SecurityContext = nil + case "strict": + // Add or update Security Context to default strict + container.SecurityContext = DefaultStrictSecCon() + //TODO(dsimansk): add parsing of SC options from the flag value + default: + return fmt.Errorf("invalid --security-context %s. Valid arguments: strict | none", securityContext) + } + return nil +} + +// DefaultStrictSecCon helper function to get default strict Security Context +func DefaultStrictSecCon() *corev1.SecurityContext { + return &corev1.SecurityContext{ + AllowPrivilegeEscalation: pointer.Bool(false), + RunAsNonRoot: pointer.Bool(true), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + } +} + +func getPolicy(policy string) v1.PullPolicy { + var ret v1.PullPolicy + switch strings.ToLower(policy) { + case "always": + ret = v1.PullAlways + case "ifnotpresent": + ret = v1.PullIfNotPresent + case "never": + ret = v1.PullNever + } + return ret +} + +func isValidPullPolicy(policy string) bool { + validPolicies := []string{string(v1.PullAlways), string(v1.PullNever), string(v1.PullIfNotPresent)} + return util.SliceContainsIgnoreCase(validPolicies, policy) +} + +// ======================================================================================= +func updateEnvVarsFromMap(env []corev1.EnvVar, toUpdate *util.OrderedMap) []corev1.EnvVar { + updated := sets.NewString() + + for i := range env { + object, present := toUpdate.Get(env[i].Name) + if present { + env[i] = object.(corev1.EnvVar) + updated.Insert(env[i].Name) + } + } + it := toUpdate.Iterator() + for name, envVar, ok := it.Next(); ok; name, envVar, ok = it.Next() { + if !updated.Has(name) { + env = append(env, envVar.(corev1.EnvVar)) + } + } + return env +} + +func removeEnvVars(env []corev1.EnvVar, toRemove []string) []corev1.EnvVar { + for _, name := range toRemove { + for i, envVar := range env { + if envVar.Name == name { + env = append(env[:i], env[i+1:]...) + break + } + } + } + return env +} + +func createEnvVarSource(spec string) (*corev1.EnvVarSource, error) { + slices := strings.SplitN(spec, ":", 3) + if len(slices) != 3 { + return nil, fmt.Errorf("argument requires a value in form \"resourceType:name:key\" where \"resourceType\" can be one of \"config-map\" (\"cm\") or \"secret\" (\"sc\"); got %q", spec) + } + + typeString := strings.TrimSpace(slices[0]) + sourceName := strings.TrimSpace(slices[1]) + sourceKey := strings.TrimSpace(slices[2]) + + var sourceType string + envVarSource := corev1.EnvVarSource{} + + switch typeString { + case "config-map", "cm": + sourceType = "ConfigMap" + envVarSource.ConfigMapKeyRef = &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: sourceName, + }, + Key: sourceKey} + case "secret", "sc": + sourceType = "Secret" + envVarSource.SecretKeyRef = &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: sourceName, + }, + Key: sourceKey} + default: + return nil, fmt.Errorf("unsupported env source type \"%q\"; supported source types are \"config-map\" (\"cm\") and \"secret\" (\"sc\")", slices[0]) + } + + if len(sourceName) == 0 { + return nil, fmt.Errorf("the name of %s cannot be an empty string", sourceType) + } + + if len(sourceKey) == 0 { + return nil, fmt.Errorf("the key referenced by resource %s \"%s\" cannot be an empty string", sourceType, sourceName) + } + + return &envVarSource, nil +} + +// ======================================================================================= +func updateEnvFrom(envFromSources []corev1.EnvFromSource, toUpdate []string) ([]corev1.EnvFromSource, error) { + existingNameSet := make(map[string]bool) + + for i := range envFromSources { + envSrc := &envFromSources[i] + if canonicalName, err := getCanonicalNameFromEnvFromSource(envSrc); err == nil { + existingNameSet[canonicalName] = true + } + } + + for _, s := range toUpdate { + info, err := newVolumeSourceInfoWithSpecString(s) + if err != nil { + return nil, err + } + + if _, ok := existingNameSet[info.getCanonicalName()]; !ok { + envFromSources = append(envFromSources, *info.createEnvFromSource()) + } + } + + return envFromSources, nil +} + +func removeEnvFrom(envFromSources []corev1.EnvFromSource, toRemove []string) ([]corev1.EnvFromSource, error) { + for _, name := range toRemove { + info, err := newVolumeSourceInfoWithSpecString(name) + if err != nil { + return nil, err + } + for i, envSrc := range envFromSources { + if (info.volumeSourceType == ConfigMapVolumeSourceType && envSrc.ConfigMapRef != nil && info.volumeSourceName == envSrc.ConfigMapRef.Name) || + (info.volumeSourceType == SecretVolumeSourceType && envSrc.SecretRef != nil && info.volumeSourceName == envSrc.SecretRef.Name) { + envFromSources = append(envFromSources[:i], envFromSources[i+1:]...) + break + } + } + } + + if len(envFromSources) == 0 { + envFromSources = nil + } + + return envFromSources, nil +} + +func updateVolume(volume *corev1.Volume, info *volumeSourceInfo) error { + switch info.volumeSourceType { + case ConfigMapVolumeSourceType: + volume.Secret = nil + volume.ConfigMap = &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: info.volumeSourceName}} + case SecretVolumeSourceType: + volume.ConfigMap = nil + volume.Secret = &corev1.SecretVolumeSource{SecretName: info.volumeSourceName} + case EmptyDirVolumeSourceType: + volume.EmptyDir = &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMedium(info.emptyDirMemoryType), SizeLimit: info.emptyDirSize} + case PVCVolumeSourceType: + volume.PersistentVolumeClaim = &corev1.PersistentVolumeClaimVolumeSource{ClaimName: info.volumeSourceName} + default: + return fmt.Errorf("Invalid VolumeSourceType") + } + return nil +} + +// updateVolumeMountsFromMap updates or adds volume mounts. If a given name of a volume is not existing, it returns an error +func updateVolumeMountsFromMap(volumeMounts []corev1.VolumeMount, toUpdate *util.OrderedMap, volumes []corev1.Volume) ([]corev1.VolumeMount, error) { + set := make(map[string]bool) + + var err error + for i := range volumeMounts { + volumeMount := &volumeMounts[i] + mountInfo, present := toUpdate.Get(volumeMount.MountPath) + + if present { + volumeMountInfo := mountInfo.(*MountInfo) + name := volumeMountInfo.VolumeName + if !existsVolumeNameInVolumes(name, volumes) { + return nil, fmt.Errorf("There is no volume matched with %q", name) + } + volumeMount.ReadOnly, err = isReadOnlyVolume(name, volumeMountInfo.MountOptions, volumes) + if err != nil { + return nil, err + } + volumeMount.Name = name + volumeMount.SubPath = volumeMountInfo.SubPath + set[volumeMount.MountPath] = true + } + } + + it := toUpdate.Iterator() + for mountPath, mountInfo, ok := it.Next(); ok; mountPath, mountInfo, ok = it.Next() { + volumeMountInfo := mountInfo.(*MountInfo) + name := volumeMountInfo.VolumeName + readOnly, err := isReadOnlyVolume(name, volumeMountInfo.MountOptions, volumes) + if err != nil { + return nil, err + } + if !set[mountPath] { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: name, + ReadOnly: readOnly, + MountPath: mountPath, + SubPath: volumeMountInfo.SubPath, + }) + } + } + + return volumeMounts, nil +} + +func removeVolumeMounts(volumeMounts []corev1.VolumeMount, toRemove []string) []corev1.VolumeMount { + for _, mountPath := range toRemove { + for i, volumeMount := range volumeMounts { + if volumeMount.MountPath == mountPath { + volumeMounts = append(volumeMounts[:i], volumeMounts[i+1:]...) + break + } + } + } + + if len(volumeMounts) == 0 { + return nil + } + + return volumeMounts +} + +// updateVolumesFromMap updates or adds volumes regardless whether the volume is used or not +func updateVolumesFromMap(volumes []corev1.Volume, toUpdate *util.OrderedMap) ([]corev1.Volume, error) { + set := make(map[string]bool) + + for i := range volumes { + volume := &volumes[i] + info, present := toUpdate.Get(volume.Name) + if present { + err := updateVolume(volume, info.(*volumeSourceInfo)) + if err != nil { + return nil, err + } + set[volume.Name] = true + } + } + + it := toUpdate.Iterator() + for name, info, ok := it.Next(); ok; name, info, ok = it.Next() { + if !set[name] { + volumes = append(volumes, corev1.Volume{Name: name}) + updateVolume(&volumes[len(volumes)-1], info.(*volumeSourceInfo)) + } + } + + return volumes, nil +} + +// removeVolumes removes volumes. If there is a volume mount referencing the volume, it causes an error +func removeVolumes(volumes []corev1.Volume, toRemove []string, volumeMounts []corev1.VolumeMount) ([]corev1.Volume, error) { + for _, name := range toRemove { + for i, volume := range volumes { + if volume.Name == name { + if existsVolumeNameInVolumeMounts(name, volumeMounts) { + return nil, fmt.Errorf("The volume %q cannot be removed because it is mounted", name) + } + volumes = append(volumes[:i], volumes[i+1:]...) + break + } + } + } + + if len(volumes) == 0 { + return nil, nil + } + + return volumes, nil +} + +// ======================================================================================= + +type volumeSourceInfo struct { + volumeSourceType VolumeSourceType + volumeSourceName string + emptyDirMemoryType string + emptyDirSize *resource.Quantity +} + +func newVolumeSourceInfoWithSpecString(spec string) (*volumeSourceInfo, error) { + slices := strings.SplitN(spec, ":", 3) + if len(slices) < 2 { + return nil, fmt.Errorf("argument requires a value that contains the : character; got %q, %q", spec, slices) + } + + if len(slices) == 2 { + var volumeSourceType VolumeSourceType + + typeString := strings.TrimSpace(slices[0]) + volumeSourceName := strings.TrimSpace(slices[1]) + + switch typeString { + case "config-map", "cm": + volumeSourceType = ConfigMapVolumeSourceType + case "secret", "sc": + volumeSourceType = SecretVolumeSourceType + case "emptyDir", "ed": + volumeSourceType = EmptyDirVolumeSourceType + case "persistentVolumeClaim", "pvc": + volumeSourceType = PVCVolumeSourceType + default: + return nil, fmt.Errorf("unsupported volume source type \"%q\"; supported volume source types are \"config-map\" and \"secret\"", slices[0]) + } + + if len(volumeSourceName) == 0 { + return nil, fmt.Errorf("the name of %s cannot be an empty string", volumeSourceType) + } + + return &volumeSourceInfo{ + volumeSourceType: volumeSourceType, + volumeSourceName: volumeSourceName, + }, nil + } else { + typeString := strings.TrimSpace(slices[0]) + switch typeString { + case "config-map", "cm", "secret", "sc", "persistentVolumeClaim", "pvc": + return nil, fmt.Errorf("incorrect mount details for type %q", typeString) + case "emptyDir", "ed": + volName := slices[1] + edType, edSize, err := getEmptyDirTypeAndSize(slices[2]) + if err != nil { + return nil, err + } + return &volumeSourceInfo{ + volumeSourceType: EmptyDirVolumeSourceType, + volumeSourceName: volName, + emptyDirMemoryType: edType, + emptyDirSize: edSize, + }, nil + default: + return nil, fmt.Errorf("unsupported volume type \"%q\"; supported volume types are \"config-map or cm\", \"secret or sc\", \"volume or vo\", and \"emptyDir or ed\"", slices[0]) + } + + } +} + +func (vol *volumeSourceInfo) getCanonicalName() string { + return fmt.Sprintf("%s:%s", vol.volumeSourceType, vol.volumeSourceName) +} + +func getCanonicalNameFromEnvFromSource(envSrc *corev1.EnvFromSource) (string, error) { + if envSrc.ConfigMapRef != nil { + return fmt.Sprintf("%s:%s", ConfigMapVolumeSourceType, envSrc.ConfigMapRef.Name), nil + } + if envSrc.SecretRef != nil { + return fmt.Sprintf("%s:%s", SecretVolumeSourceType, envSrc.SecretRef.Name), nil + } + + return "", fmt.Errorf("there is no ConfigMapRef or SecretRef in a EnvFromSource") +} + +func (vol *volumeSourceInfo) createEnvFromSource() *corev1.EnvFromSource { + switch vol.volumeSourceType { + case ConfigMapVolumeSourceType: + return &corev1.EnvFromSource{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: vol.volumeSourceName, + }}} + case SecretVolumeSourceType: + return &corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: vol.volumeSourceName, + }}} + } + + return nil +} + +// ======================================================================================= + +func isReadOnlyVolume(volumeName string, mountOptions string, volumes []corev1.Volume) (bool, error) { + if mountOptions != "" { + options, err := parseMountOptions(mountOptions) + if err != nil { + return false, err + } + if val, ok := options.Get("readonly"); ok && val != "" { + return strconv.ParseBool(val.(string)) + } + } + for _, volume := range volumes { + if volume.Name == volumeName { + return defaultReadOnly(volume), nil + } + } + return true, nil +} + +func parseMountOptions(options string) (*util.OrderedMap, error) { + mountOptions := util.NewOrderedMap() + slices := strings.Split(options, ",") + for _, slice := range slices { + pair := strings.SplitN(slice, "=", 2) + switch strings.ToLower(pair[0]) { + case "readonly": + mountOptions.Set("readonly", pair[1]) + default: + return nil, fmt.Errorf("unknown mount option %q", pair[0]) + } + } + return mountOptions, nil +} + +func defaultReadOnly(volume v1.Volume) bool { + if volume.EmptyDir != nil || volume.PersistentVolumeClaim != nil { + return false + } + return true +} + +func existsVolumeNameInVolumes(volumeName string, volumes []corev1.Volume) bool { + for _, volume := range volumes { + if volume.Name == volumeName { + return true + } + } + return false +} + +func existsVolumeNameInVolumeMounts(volumeName string, volumeMounts []corev1.VolumeMount) bool { + for _, volumeMount := range volumeMounts { + if volumeMount.Name == volumeName { + return true + } + } + return false +} + +// ======================================================================================= + +func getMountInfo(volume string) *MountInfo { + configSlices := strings.SplitN(volume, ":", 2) + var mountInfo MountInfo + if len(configSlices) == 2 { + readOnlySlices := strings.SplitN(configSlices[1], "=", 2) + switch strings.ToLower(readOnlySlices[0]) { + case "readonly": + + } + mountInfo.MountOptions = configSlices[1] + } + slices := strings.SplitN(configSlices[0], "/", 2) + if len(slices) == 1 || slices[1] == "" { + mountInfo.VolumeName = slices[0] + } else { + mountInfo.VolumeName = slices[0] + mountInfo.SubPath = slices[1] + } + return &mountInfo +} + +func reviseVolumeInfoAndMountsToUpdate(mountsToUpdate *util.OrderedMap, volumesToUpdate *util.OrderedMap) (*util.OrderedMap, *util.OrderedMap, error) { + volumeSourceInfoByName := util.NewOrderedMap() //make(map[string]*volumeSourceInfo) + mountsToUpdateRevised := util.NewOrderedMap() //make(map[string]string) + + it := mountsToUpdate.Iterator() + for path, value, ok := it.NextString(); ok; path, value, ok = it.NextString() { + // slices[0] -> config-map, cm, secret, sc, volume, or vo + // slices[1] -> secret, config-map, or volume name + slices := strings.SplitN(value, ":", 2) + if len(slices) == 1 { + mountInfo := getMountInfo(slices[0]) + mountsToUpdateRevised.Set(path, mountInfo) + } else { + switch volumeType := slices[0]; volumeType { + case "config-map", "cm": + generatedName := util.GenerateVolumeName(path) + mountInfo := getMountInfo(slices[1]) + volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{ + volumeSourceType: ConfigMapVolumeSourceType, + volumeSourceName: mountInfo.VolumeName, + }) + mountInfo.VolumeName = generatedName + mountsToUpdateRevised.Set(path, mountInfo) + case "secret", "sc": + generatedName := util.GenerateVolumeName(path) + mountInfo := getMountInfo(slices[1]) + volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{ + volumeSourceType: SecretVolumeSourceType, + volumeSourceName: mountInfo.VolumeName, + }) + mountInfo.VolumeName = generatedName + mountsToUpdateRevised.Set(path, mountInfo) + case "emptyDir", "ed": + generatedName := util.GenerateVolumeName(path) + mountInfo := getMountInfo(slices[1]) + volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{ + volumeSourceType: EmptyDirVolumeSourceType, + volumeSourceName: slices[1], + emptyDirMemoryType: "", + }) + mountInfo.VolumeName = generatedName + mountsToUpdateRevised.Set(path, mountInfo) + case "persistentVolumeClaim", "pvc": + generatedName := util.GenerateVolumeName(path) + mountInfo := getMountInfo(slices[1]) + volumeSourceInfoByName.Set(generatedName, &volumeSourceInfo{ + volumeSourceType: PVCVolumeSourceType, + volumeSourceName: mountInfo.VolumeName, + }) + mountInfo.VolumeName = generatedName + mountsToUpdateRevised.Set(path, mountInfo) + default: + return nil, nil, fmt.Errorf("unsupported volume type \"%q\"; supported volume types are \"config-map or cm\", \"secret or sc\", \"volume or vo\", and \"emptyDir or ed\"", slices[0]) + } + } + } + + it = volumesToUpdate.Iterator() + for name, value, ok := it.NextString(); ok; name, value, ok = it.NextString() { + info, err := newVolumeSourceInfoWithSpecString(value) + if err != nil { + return nil, nil, err + } + volumeSourceInfoByName.Set(name, info) + } + + return volumeSourceInfoByName, mountsToUpdateRevised, nil +} + +func getEmptyDirTypeAndSize(value string) (string, *resource.Quantity, error) { + slices := strings.SplitN(value, ",", 2) + formatErr := fmt.Errorf("incorrect format to specify emptyDir type") + repeatErrStr := "cannot repeat the key %q" + var dirType string + var size *resource.Quantity + switch len(slices) { + case 0: + return "", nil, nil + case 1: + typeSizeSlices := strings.SplitN(slices[0], "=", 2) + if len(typeSizeSlices) < 2 { + return "", nil, formatErr + } + switch strings.ToLower(typeSizeSlices[0]) { + case "type": + dirType = typeSizeSlices[1] + case "size": + quantity, err := resource.ParseQuantity(typeSizeSlices[1]) + if err != nil { + return "", nil, formatErr + } + size = &quantity + default: + return "", nil, formatErr + } + case 2: + for _, slice := range slices { + typeSizeSlices := strings.SplitN(slice, "=", 2) + if len(typeSizeSlices) < 2 { + return "", nil, formatErr + } + switch strings.ToLower(typeSizeSlices[0]) { + case "type": + if dirType != "" { + return "", nil, fmt.Errorf(repeatErrStr, "type") + } + dirType = typeSizeSlices[1] + case "size": + if size != nil { + return "", nil, fmt.Errorf(repeatErrStr, "size") + } + quantity, err := resource.ParseQuantity(typeSizeSlices[1]) + if err != nil { + return "", nil, formatErr + } + size = &quantity + default: + return "", nil, formatErr + } + } + } + return dirType, size, nil +} + +func reviseVolumesToRemove(volumeMounts []corev1.VolumeMount, volumesToRemove []string, mountsToRemove []string) []string { + for _, pathToRemove := range mountsToRemove { + for _, volumeMount := range volumeMounts { + if volumeMount.MountPath == pathToRemove && volumeMount.Name == util.GenerateVolumeName(pathToRemove) { + volumesToRemove = append(volumesToRemove, volumeMount.Name) + } + } + } + return volumesToRemove +} + +func decodeContainersFromFile(filename string) (*corev1.PodSpec, error) { + var f *os.File + var err error + if filename == "-" { + f = os.Stdin + } else { + f, err = os.Open(filename) + if err != nil { + return nil, err + } + } + podSpec := &corev1.PodSpec{} + decoder := yaml.NewYAMLOrJSONDecoder(f, 512) + if err = decoder.Decode(podSpec); err != nil { + return nil, err + } + return podSpec, nil +} + +// ======================================================================================= +// Probes + +// resolveProbe parses probes as a string +// It's split into two functions: +// - resolveProbeOptions() -> common probe opts +// - resolveProbeHandler() -> probe handler [HTTPGet, Exec, TCPSocket] +// Format: +// - [http,https]:host:port:path +// - exec:cmd,cmd,... +// - tcp:host:port +// Common opts (comma separated, case insensitive): +// - InitialDelaySeconds=,FailureThreshold=, +// SuccessThreshold=,PeriodSeconds==,TimeoutSeconds= + +// resolveProbeOptions parses probe commons options +func resolveProbeOptions(probe *corev1.Probe, probeString string) error { + options := strings.Split(probeString, ",") + mappedOptions, err := util.MapFromArray(options, "=") + if err != nil { + return err + } + for k, v := range mappedOptions { + // Trim & verify value is convertible to int + intValue, err := strconv.ParseInt(strings.TrimSpace(v), 0, 32) + if err != nil { + return fmt.Errorf("not a nummeric value for parameter '%s'", k) + } + // Lower case param name mapping + switch strings.TrimSpace(strings.ToLower(k)) { + case "initialdelayseconds": + probe.InitialDelaySeconds = int32(intValue) + case "timeoutseconds": + probe.TimeoutSeconds = int32(intValue) + case "periodseconds": + probe.PeriodSeconds = int32(intValue) + case "successthreshold": + probe.SuccessThreshold = int32(intValue) + case "failurethreshold": + probe.FailureThreshold = int32(intValue) + default: + return fmt.Errorf("not a valid probe parameter name '%s'", k) + } + } + return nil +} + +// resolveProbeHandler parses probe handler options +func resolveProbeHandler(probeString string) (*corev1.ProbeHandler, error) { + if len(probeString) == 0 { + return nil, fmt.Errorf("no probe parameters detected") + } + probeParts := strings.Split(probeString, ":") + if len(probeParts) > 4 { + return nil, fmt.Errorf("too many probe parameters provided, please check the format") + } + var probeHandler *corev1.ProbeHandler + switch probeParts[0] { + case "http", "https": + if len(probeParts) != 4 { + return nil, fmt.Errorf("unexpected probe format, please use 'http:host:port:path'") + } + handler := corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{}, + } + if probeParts[0] == "https" { + handler.HTTPGet.Scheme = v1.URISchemeHTTPS + } + handler.HTTPGet.Host = probeParts[1] + if probeParts[2] != "" { + // Cosmetic fix to have default 'port: 0' instead of empty string 'port: ""' + handler.HTTPGet.Port = intstr.Parse(probeParts[2]) + } + handler.HTTPGet.Path = probeParts[3] + + probeHandler = &handler + case "exec": + if len(probeParts) != 2 { + return nil, fmt.Errorf("unexpected probe format, please use 'exec:[,,...]'") + } + if len(probeParts[1]) == 0 { + return nil, fmt.Errorf("at least one command parameter is required for Exec probe") + } + handler := corev1.ProbeHandler{ + Exec: &corev1.ExecAction{}, + } + cmd := strings.Split(probeParts[1], ",") + handler.Exec.Command = cmd + + probeHandler = &handler + case "tcp": + if len(probeParts) != 3 { + return nil, fmt.Errorf("unexpected probe format, please use 'tcp:host:port") + } + handler := corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{}, + } + handler.TCPSocket.Host = probeParts[1] + handler.TCPSocket.Port = intstr.Parse(probeParts[2]) + + probeHandler = &handler + default: + return nil, fmt.Errorf("unsupported probe type '%s'; supported types: http, https, exec, tcp", probeParts[0]) + } + return probeHandler, nil +} + +// ======================================================================================= diff --git a/vendor/knative.dev/client-pkg/pkg/messaging/v1/channels_client.go b/vendor/knative.dev/client-pkg/pkg/messaging/v1/channels_client.go new file mode 100644 index 0000000000..5a4beb5a28 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/messaging/v1/channels_client.go @@ -0,0 +1,165 @@ +// Copyright © 2020 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 v1 + +import ( + "context" + + "knative.dev/client-pkg/pkg/util" + eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + clientmessagingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" + + knerrors "knative.dev/client-pkg/pkg/errors" +) + +// KnChannelsClient for interacting with Channels +type KnChannelsClient interface { + + // GetChannel returns a Channel by its name + GetChannel(ctx context.Context, name string) (*messagingv1.Channel, error) + + // CreteChannel creates a Channel with given spec + CreateChannel(ctx context.Context, channel *messagingv1.Channel) error + + // DeleteChannel deletes a Channel by its name + DeleteChannel(ctx context.Context, name string) error + + // ListChannel lists all Channels + ListChannel(ctx context.Context) (*messagingv1.ChannelList, error) + + // Namespace returns the namespace for this channel client + Namespace() string +} + +// channelsClient struct holds the client interface and namespace +type channelsClient struct { + client clientmessagingv1.ChannelInterface + namespace string +} + +// newKnChannelsClient returns kn channels client +func newKnChannelsClient(client clientmessagingv1.ChannelInterface, namespace string) KnChannelsClient { + return &channelsClient{ + client: client, + namespace: namespace, + } +} + +// Get the namespace for which this client is created +func (c *channelsClient) Namespace() string { + return c.namespace +} + +// GetChannel gets Channel by its name +func (c *channelsClient) GetChannel(ctx context.Context, name string) (*messagingv1.Channel, error) { + channel, err := c.client.Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + err = updateMessagingGVK(channel) + if err != nil { + return nil, err + } + return channel, nil +} + +// CreateChannel creates Channel with given spec +func (c *channelsClient) CreateChannel(ctx context.Context, channel *messagingv1.Channel) error { + _, err := c.client.Create(ctx, channel, metav1.CreateOptions{}) + return knerrors.GetError(err) +} + +// DeleteChannel deletes Channel by its name +func (c *channelsClient) DeleteChannel(ctx context.Context, name string) error { + return knerrors.GetError(c.client.Delete(ctx, name, metav1.DeleteOptions{})) +} + +// ListChannel lists channels in configured namespace +func (c *channelsClient) ListChannel(ctx context.Context) (*messagingv1.ChannelList, error) { + channelList, err := c.client.List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + + return updateChannelListGVK(channelList) +} + +func updateChannelListGVK(channelList *messagingv1.ChannelList) (*messagingv1.ChannelList, error) { + channelListNew := channelList.DeepCopy() + err := updateMessagingGVK(channelListNew) + if err != nil { + return nil, err + } + + channelListNew.Items = make([]messagingv1.Channel, len(channelList.Items)) + for idx, channel := range channelList.Items { + channelClone := channel.DeepCopy() + err := updateMessagingGVK(channelClone) + if err != nil { + return nil, err + } + channelListNew.Items[idx] = *channelClone + } + return channelListNew, nil +} + +// ChannelBuilder is for building the Channel object +type ChannelBuilder struct { + channel *messagingv1.Channel +} + +// NewChannelBuilder for building Channel object +func NewChannelBuilder(name, namespace string) *ChannelBuilder { + return &ChannelBuilder{channel: &messagingv1.Channel{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + }} +} + +// WithGvk sets the GVK on the channel +func (c *ChannelBuilder) WithGvk() *ChannelBuilder { + _ = util.UpdateGroupVersionKindWithScheme(c.channel, eventingv1.SchemeGroupVersion, scheme.Scheme) + return c +} + +// Type sets the type of the channel to create +func (c *ChannelBuilder) Type(gvk *schema.GroupVersionKind) *ChannelBuilder { + if gvk == nil { + return c + } + + c.channel.TypeMeta = metav1.TypeMeta{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, + } + + spec := &messagingv1.ChannelTemplateSpec{} + spec.Kind = gvk.Kind + spec.APIVersion = gvk.GroupVersion().String() + c.channel.Spec.ChannelTemplate = spec + return c +} + +// Build returns the Channel object from the builder +func (c *ChannelBuilder) Build() *messagingv1.Channel { + return c.channel +} diff --git a/vendor/knative.dev/client-pkg/pkg/messaging/v1/channels_client_mock.go b/vendor/knative.dev/client-pkg/pkg/messaging/v1/channels_client_mock.go new file mode 100644 index 0000000000..bb7120e2a4 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/messaging/v1/channels_client_mock.go @@ -0,0 +1,108 @@ +// Copyright © 2020 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 v1 + +import ( + "context" + "testing" + + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + + "knative.dev/client-pkg/pkg/util/mock" +) + +type MockKnChannelsClient struct { + t *testing.T + recorder *ChannelsRecorder +} + +// NewMockKnChannelsClient returns a new mock instance which you need to record for +func NewMockKnChannelsClient(t *testing.T, ns ...string) *MockKnChannelsClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnChannelsClient{ + t: t, + recorder: &ChannelsRecorder{mock.NewRecorder(t, namespace)}, + } +} + +// Ensure that the interface is implemented +var _ KnChannelsClient = &MockKnChannelsClient{} + +// recorder for service +type ChannelsRecorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnChannelsClient) Recorder() *ChannelsRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnChannelsClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// CreateChannel records a call for CreateChannel with the expected error +func (sr *ChannelsRecorder) CreateChannel(channels interface{}, err error) { + sr.r.Add("CreateChannel", []interface{}{channels}, []interface{}{err}) +} + +// CreateChannel performs a previously recorded action, failing if non has been registered +func (c *MockKnChannelsClient) CreateChannel(ctx context.Context, channels *messagingv1.Channel) error { + call := c.recorder.r.VerifyCall("CreateChannel", channels) + return mock.ErrorOrNil(call.Result[0]) +} + +// GetChannel records a call for GetChannel with the expected object or error. Either channels or err should be nil +func (sr *ChannelsRecorder) GetChannel(name interface{}, channels *messagingv1.Channel, err error) { + sr.r.Add("GetChannel", []interface{}{name}, []interface{}{channels, err}) +} + +// GetChannel performs a previously recorded action, failing if non has been registered +func (c *MockKnChannelsClient) GetChannel(ctx context.Context, name string) (*messagingv1.Channel, error) { + call := c.recorder.r.VerifyCall("GetChannel", name) + return call.Result[0].(*messagingv1.Channel), mock.ErrorOrNil(call.Result[1]) +} + +// DeleteChannel records a call for DeleteChannel with the expected error (nil if none) +func (sr *ChannelsRecorder) DeleteChannel(name interface{}, err error) { + sr.r.Add("DeleteChannel", []interface{}{name}, []interface{}{err}) +} + +// DeleteChannel performs a previously recorded action, failing if non has been registered +func (c *MockKnChannelsClient) DeleteChannel(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeleteChannel", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListChannel records a call for ListChannel with the expected error (nil if none) +func (sr *ChannelsRecorder) ListChannel(channelsList *messagingv1.ChannelList, err error) { + sr.r.Add("ListChannel", []interface{}{}, []interface{}{channelsList, err}) +} + +// ListChannel performs a previously recorded action, failing if non has been registered +func (c *MockKnChannelsClient) ListChannel(context.Context) (*messagingv1.ChannelList, error) { + call := c.recorder.r.VerifyCall("ListChannel") + return call.Result[0].(*messagingv1.ChannelList), mock.ErrorOrNil(call.Result[1]) +} + +// Validates validates whether every recorded action has been called +func (sr *ChannelsRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/vendor/knative.dev/client-pkg/pkg/messaging/v1/client.go b/vendor/knative.dev/client-pkg/pkg/messaging/v1/client.go new file mode 100644 index 0000000000..eeadc12e52 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/messaging/v1/client.go @@ -0,0 +1,71 @@ +// Copyright © 2020 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 v1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + clientv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" + + "knative.dev/client-pkg/pkg/util" +) + +// KnMessagingClient to Eventing Messaging. All methods are relative to +// the namespace specified during construction +type KnMessagingClient interface { + // Get the Channels client + ChannelsClient() KnChannelsClient + + // Get the Subscriptions client + SubscriptionsClient() KnSubscriptionsClient +} + +// messagingClient holds Messaging client interface and namespace +type messagingClient struct { + client clientv1beta1.MessagingV1Interface + namespace string +} + +// NewKnMessagingClient for managing all eventing messaging types +func NewKnMessagingClient(client clientv1beta1.MessagingV1Interface, namespace string) KnMessagingClient { + return &messagingClient{ + client: client, + namespace: namespace, + } +} + +// ChannelsClient for working with Channels +func (c *messagingClient) ChannelsClient() KnChannelsClient { + return newKnChannelsClient(c.client.Channels(c.namespace), c.namespace) +} + +// SubscriptionsClient for working with Subscriptions +func (c *messagingClient) SubscriptionsClient() KnSubscriptionsClient { + return newKnSubscriptionsClient(c.client.Subscriptions(c.namespace), c.namespace) +} + +// update GVK of object +func updateMessagingGVK(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, messagingv1.SchemeGroupVersion, scheme.Scheme) +} + +// BuiltInChannelGVKs returns the GVKs for built in channel +func BuiltInChannelGVKs() []schema.GroupVersionKind { + return []schema.GroupVersionKind{ + messagingv1.SchemeGroupVersion.WithKind("InMemoryChannel"), + } +} diff --git a/vendor/knative.dev/client-pkg/pkg/messaging/v1/subscriptions_client.go b/vendor/knative.dev/client-pkg/pkg/messaging/v1/subscriptions_client.go new file mode 100644 index 0000000000..61c4dc5bfc --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/messaging/v1/subscriptions_client.go @@ -0,0 +1,235 @@ +/* +Copyright 2020 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 v1 + +import ( + "context" + "fmt" + + "knative.dev/client-pkg/pkg/config" + + "k8s.io/client-go/util/retry" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1" + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + clientmessagingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" + duckv1 "knative.dev/pkg/apis/duck/v1" + + knerrors "knative.dev/client-pkg/pkg/errors" +) + +type SubscriptionUpdateFunc func(origSub *messagingv1.Subscription) (*messagingv1.Subscription, error) + +// KnSubscriptionsClient for interacting with Subscriptions +type KnSubscriptionsClient interface { + + // GetSubscription returns a Subscription by its name + GetSubscription(ctx context.Context, name string) (*messagingv1.Subscription, error) + + // CreateSubscription creates a Subscription with given spec + CreateSubscription(ctx context.Context, subscription *messagingv1.Subscription) error + + // UpdateSubscription updates a Subscription with given spec + UpdateSubscription(ctx context.Context, subscription *messagingv1.Subscription) error + + // UpdateSubscriptionWithRetry updates a Subscription and retries on conflict error + UpdateSubscriptionWithRetry(ctx context.Context, name string, updateFunc SubscriptionUpdateFunc, nrRetries int) error + + // DeleteSubscription deletes a Subscription by its name + DeleteSubscription(ctx context.Context, name string) error + + // ListSubscription lists all Subscriptions + ListSubscription(ctx context.Context) (*messagingv1.SubscriptionList, error) + + // Namespace returns the namespace for this subscription client + Namespace() string +} + +// subscriptionsClient struct holds the client interface and namespace +type subscriptionsClient struct { + client clientmessagingv1.SubscriptionInterface + namespace string +} + +// newKnSubscriptionsClient returns kn subscriptions client +func newKnSubscriptionsClient(client clientmessagingv1.SubscriptionInterface, namespace string) KnSubscriptionsClient { + return &subscriptionsClient{ + client: client, + namespace: namespace, + } +} + +// Get the namespace for which this client is created +func (c *subscriptionsClient) Namespace() string { + return c.namespace +} + +// GetSubscription gets Subscription by its name +func (c *subscriptionsClient) GetSubscription(ctx context.Context, name string) (*messagingv1.Subscription, error) { + subscription, err := c.client.Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + err = updateMessagingGVK(subscription) + if err != nil { + return nil, err + } + return subscription, nil +} + +// CreateSubscription creates Subscription with given spec +func (c *subscriptionsClient) CreateSubscription(ctx context.Context, subscription *messagingv1.Subscription) error { + _, err := c.client.Create(ctx, subscription, metav1.CreateOptions{}) + return knerrors.GetError(err) +} + +// UpdateSubscription creates Subscription with given spec +func (c *subscriptionsClient) UpdateSubscription(ctx context.Context, subscription *messagingv1.Subscription) error { + _, err := c.client.Update(ctx, subscription, metav1.UpdateOptions{}) + return knerrors.GetError(err) +} + +func (c *subscriptionsClient) UpdateSubscriptionWithRetry(ctx context.Context, name string, updateFunc SubscriptionUpdateFunc, nrRetries int) error { + return updateSubscriptionWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +func updateSubscriptionWithRetry(ctx context.Context, c KnSubscriptionsClient, name string, updateFunc SubscriptionUpdateFunc, nrRetries int) error { + b := config.DefaultRetry + b.Steps = nrRetries + err := retry.RetryOnConflict(b, func() error { + return updateSubscription(ctx, c, name, updateFunc) + }) + return err +} + +func updateSubscription(ctx context.Context, c KnSubscriptionsClient, name string, updateFunc SubscriptionUpdateFunc) error { + sub, err := c.GetSubscription(ctx, name) + if err != nil { + return err + } + if sub.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't update subscription %s because it has been marked for deletion", name) + } + updatedSub, err := updateFunc(sub.DeepCopy()) + if err != nil { + return err + } + + return c.UpdateSubscription(ctx, updatedSub) +} + +// DeleteSubscription deletes Subscription by its name +func (c *subscriptionsClient) DeleteSubscription(ctx context.Context, name string) error { + return knerrors.GetError(c.client.Delete(ctx, name, metav1.DeleteOptions{})) +} + +// ListSubscription lists subscriptions in configured namespace +func (c *subscriptionsClient) ListSubscription(ctx context.Context) (*messagingv1.SubscriptionList, error) { + subscriptionList, err := c.client.List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + + return updateSubscriptionListGVK(subscriptionList) +} + +func updateSubscriptionListGVK(subscriptionList *messagingv1.SubscriptionList) (*messagingv1.SubscriptionList, error) { + subscriptionListNew := subscriptionList.DeepCopy() + err := updateMessagingGVK(subscriptionListNew) + if err != nil { + return nil, err + } + + subscriptionListNew.Items = make([]messagingv1.Subscription, len(subscriptionList.Items)) + for idx, subscription := range subscriptionList.Items { + subscriptionClone := subscription.DeepCopy() + err := updateMessagingGVK(subscriptionClone) + if err != nil { + return nil, err + } + subscriptionListNew.Items[idx] = *subscriptionClone + } + return subscriptionListNew, nil +} + +// SubscriptionBuilder is for building the Subscription object +type SubscriptionBuilder struct { + subscription *messagingv1.Subscription +} + +// NewSubscriptionBuilder for building Subscription object +func NewSubscriptionBuilder(name string) *SubscriptionBuilder { + return &SubscriptionBuilder{subscription: &messagingv1.Subscription{ + TypeMeta: metav1.TypeMeta{ + APIVersion: messagingv1.SchemeGroupVersion.String(), + Kind: "Subscription", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }} +} + +// NewSubscriptionBuilderFromExisting for building Subscription object from existing Subscription object +func NewSubscriptionBuilderFromExisting(subs *messagingv1.Subscription) *SubscriptionBuilder { + return &SubscriptionBuilder{subscription: subs.DeepCopy()} +} + +// Channel sets the channel reference for this subscription +func (s *SubscriptionBuilder) Channel(channel *duckv1.KReference) *SubscriptionBuilder { + if channel == nil { + return s + } + + s.subscription.Spec.Channel = *channel + return s +} + +func (s *SubscriptionBuilder) Subscriber(subs *duckv1.Destination) *SubscriptionBuilder { + if subs == nil { + return s + } + + s.subscription.Spec.Subscriber = subs + return s +} + +func (s *SubscriptionBuilder) Reply(reply *duckv1.Destination) *SubscriptionBuilder { + if reply == nil { + return s + } + + s.subscription.Spec.Reply = reply + return s +} + +func (s *SubscriptionBuilder) DeadLetterSink(dls *duckv1.Destination) *SubscriptionBuilder { + if dls == nil { + return s + } + + ds := &eventingduckv1.DeliverySpec{} + ds.DeadLetterSink = dls + s.subscription.Spec.Delivery = ds + return s +} + +// Build returns the Subscription object from the builder +func (s *SubscriptionBuilder) Build() *messagingv1.Subscription { + return s.subscription +} diff --git a/vendor/knative.dev/client-pkg/pkg/messaging/v1/subscriptions_client_mock.go b/vendor/knative.dev/client-pkg/pkg/messaging/v1/subscriptions_client_mock.go new file mode 100644 index 0000000000..1f84ad8c9f --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/messaging/v1/subscriptions_client_mock.go @@ -0,0 +1,127 @@ +/* +Copyright 2020 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 v1 + +import ( + "context" + "testing" + + messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" + + "knative.dev/client-pkg/pkg/util/mock" +) + +type MockKnSubscriptionsClient struct { + t *testing.T + recorder *SubscriptionsRecorder + namespace string +} + +// NewMockKnSubscriptionsClient returns a new mock instance which you need to record for +func NewMockKnSubscriptionsClient(t *testing.T, ns ...string) *MockKnSubscriptionsClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnSubscriptionsClient{ + t: t, + recorder: &SubscriptionsRecorder{mock.NewRecorder(t, namespace)}, + namespace: namespace, + } +} + +// Ensure that the interface is implemented +var _ KnSubscriptionsClient = &MockKnSubscriptionsClient{} + +// recorder for service +type SubscriptionsRecorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnSubscriptionsClient) Recorder() *SubscriptionsRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnSubscriptionsClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// CreateSubscription records a call for CreateSubscription with the expected error +func (sr *SubscriptionsRecorder) CreateSubscription(subscription interface{}, err error) { + sr.r.Add("CreateSubscription", []interface{}{subscription}, []interface{}{err}) +} + +// CreateSubscription performs a previously recorded action, failing if non has been registered +func (c *MockKnSubscriptionsClient) CreateSubscription(ctx context.Context, subscription *messagingv1.Subscription) error { + call := c.recorder.r.VerifyCall("CreateSubscription", subscription) + return mock.ErrorOrNil(call.Result[0]) +} + +// GetSubscription records a call for GetSubscription with the expected object or error. Either subscriptions or err should be nil +func (sr *SubscriptionsRecorder) GetSubscription(name interface{}, subscription *messagingv1.Subscription, err error) { + sr.r.Add("GetSubscription", []interface{}{name}, []interface{}{subscription, err}) +} + +// GetSubscription performs a previously recorded action, failing if non has been registered +func (c *MockKnSubscriptionsClient) GetSubscription(ctx context.Context, name string) (*messagingv1.Subscription, error) { + call := c.recorder.r.VerifyCall("GetSubscription", name) + return call.Result[0].(*messagingv1.Subscription), mock.ErrorOrNil(call.Result[1]) +} + +// DeleteSubscription records a call for DeleteSubscription with the expected error (nil if none) +func (sr *SubscriptionsRecorder) DeleteSubscription(name interface{}, err error) { + sr.r.Add("DeleteSubscription", []interface{}{name}, []interface{}{err}) +} + +// DeleteSubscription performs a previously recorded action, failing if non has been registered +func (c *MockKnSubscriptionsClient) DeleteSubscription(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeleteSubscription", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListSubscription records a call for ListSubscription with the expected error (nil if none) +func (sr *SubscriptionsRecorder) ListSubscription(subscriptionsList *messagingv1.SubscriptionList, err error) { + sr.r.Add("ListSubscription", []interface{}{}, []interface{}{subscriptionsList, err}) +} + +// ListSubscription performs a previously recorded action, failing if non has been registered +func (c *MockKnSubscriptionsClient) ListSubscription(context.Context) (*messagingv1.SubscriptionList, error) { + call := c.recorder.r.VerifyCall("ListSubscription") + return call.Result[0].(*messagingv1.SubscriptionList), mock.ErrorOrNil(call.Result[1]) +} + +// UpdateSubscription records a call for CreateSubscription with the expected error +func (sr *SubscriptionsRecorder) UpdateSubscription(subscription interface{}, err error) { + sr.r.Add("UpdateSubscription", []interface{}{subscription}, []interface{}{err}) +} + +// UpdateSubscription performs a previously recorded action, failing if non has been registered +func (c *MockKnSubscriptionsClient) UpdateSubscription(ctx context.Context, subscription *messagingv1.Subscription) error { + call := c.recorder.r.VerifyCall("UpdateSubscription", subscription) + return mock.ErrorOrNil(call.Result[0]) +} + +func (c *MockKnSubscriptionsClient) UpdateSubscriptionWithRetry(ctx context.Context, name string, updateFunc SubscriptionUpdateFunc, nrRetries int) error { + return updateSubscriptionWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +// Validates validates whether every recorded action has been called +func (sr *SubscriptionsRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/pkg/printers/interface.go b/vendor/knative.dev/client-pkg/pkg/printers/interface.go similarity index 100% rename from pkg/printers/interface.go rename to vendor/knative.dev/client-pkg/pkg/printers/interface.go diff --git a/pkg/printers/prefixwriter.go b/vendor/knative.dev/client-pkg/pkg/printers/prefixwriter.go similarity index 100% rename from pkg/printers/prefixwriter.go rename to vendor/knative.dev/client-pkg/pkg/printers/prefixwriter.go diff --git a/pkg/printers/tablegenerator.go b/vendor/knative.dev/client-pkg/pkg/printers/tablegenerator.go similarity index 100% rename from pkg/printers/tablegenerator.go rename to vendor/knative.dev/client-pkg/pkg/printers/tablegenerator.go diff --git a/pkg/printers/tableprinter.go b/vendor/knative.dev/client-pkg/pkg/printers/tableprinter.go similarity index 100% rename from pkg/printers/tableprinter.go rename to vendor/knative.dev/client-pkg/pkg/printers/tableprinter.go diff --git a/pkg/printers/tabwriter.go b/vendor/knative.dev/client-pkg/pkg/printers/tabwriter.go similarity index 100% rename from pkg/printers/tabwriter.go rename to vendor/knative.dev/client-pkg/pkg/printers/tabwriter.go diff --git a/vendor/knative.dev/client-pkg/pkg/serving/config_changes.go b/vendor/knative.dev/client-pkg/pkg/serving/config_changes.go new file mode 100644 index 0000000000..f16d478f8d --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/config_changes.go @@ -0,0 +1,240 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package serving + +import ( + "context" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "knative.dev/client-pkg/pkg/flags" + "knative.dev/pkg/ptr" + "knative.dev/serving/pkg/apis/autoscaling" + servingconfig "knative.dev/serving/pkg/apis/config" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" +) + +// VolumeSourceType is a type standing for enumeration of ConfigMap and Secret +type VolumeSourceType int + +// Enumeration of volume source types: ConfigMap or Secret +const ( + ConfigMapVolumeSourceType VolumeSourceType = iota + SecretVolumeSourceType + PortFormatErr = "the port specification '%s' is not valid. Please provide in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'." +) + +var ( + UserImageAnnotationKey = "client.knative.dev/user-image" + UpdateTimestampAnnotationKey = "client.knative.dev/updateTimestamp" + APITooOldError = errors.New("the service is using too old of an API format for the operation") +) + +func (vt VolumeSourceType) String() string { + names := [...]string{"config-map", "secret"} + if vt < ConfigMapVolumeSourceType || vt > SecretVolumeSourceType { + return "unknown" + } + return names[vt] +} + +// UpdateMinScale updates min scale annotation +func UpdateMinScale(template *servingv1.RevisionTemplateSpec, min int) error { + return UpdateRevisionTemplateAnnotation(template, autoscaling.MinScaleAnnotationKey, strconv.Itoa(min)) +} + +// UpdateMaxScale updates max scale annotation +func UpdateMaxScale(template *servingv1.RevisionTemplateSpec, max int) error { + return UpdateRevisionTemplateAnnotation(template, autoscaling.MaxScaleAnnotationKey, strconv.Itoa(max)) +} + +// UpdateScaleWindow updates the autoscale window annotation +func UpdateScaleWindow(template *servingv1.RevisionTemplateSpec, window string) error { + _, err := time.ParseDuration(window) + if err != nil { + return fmt.Errorf("invalid duration for 'scale-window': %w", err) + } + return UpdateRevisionTemplateAnnotation(template, autoscaling.WindowAnnotationKey, window) +} + +// UpdateScaleTarget updates container concurrency annotation +func UpdateScaleTarget(template *servingv1.RevisionTemplateSpec, target int) error { + return UpdateRevisionTemplateAnnotation(template, autoscaling.TargetAnnotationKey, strconv.Itoa(target)) +} + +// UpdateScaleActivation updates the scale activation annotation +func UpdateScaleActivation(template *servingv1.RevisionTemplateSpec, activation int) error { + return UpdateRevisionTemplateAnnotation(template, autoscaling.ActivationScaleKey, strconv.Itoa(activation)) +} + +// UpdateScaleUtilization updates container target utilization percentage annotation +func UpdateScaleUtilization(template *servingv1.RevisionTemplateSpec, target int) error { + return UpdateRevisionTemplateAnnotation(template, autoscaling.TargetUtilizationPercentageKey, strconv.Itoa(target)) +} + +// UpdateConcurrencyLimit updates container concurrency limit +func UpdateConcurrencyLimit(template *servingv1.RevisionTemplateSpec, limit int64) error { + if limit < 0 { + return fmt.Errorf("invalid concurrency-limit %d (must not be less than 0)", limit) + } + template.Spec.ContainerConcurrency = ptr.Int64(limit) + return nil +} + +// UnsetUserImageAnnotation removes the user image annotation +func UnsetUserImageAnnotation(template *servingv1.RevisionTemplateSpec) { + delete(template.Annotations, UserImageAnnotationKey) +} + +// UpdateUserImageAnnotation sets the user image annotation if the image isn't by-digest already. +func UpdateUserImageAnnotation(template *servingv1.RevisionTemplateSpec) { + // If the current image isn't by-digest, set the user-image annotation to it + // so we remember what it was. + currentContainer := ContainerOfRevisionSpec(&template.Spec) + if currentContainer == nil { + // No container set in the template, so + return + } + image := currentContainer.Image + if strings.Contains(image, "@") { + // Ensure that the non-digestified image is used + storedImage, ok := template.Annotations[UserImageAnnotationKey] + if ok { + image = storedImage + } + } + ensureAnnotations(template) + template.Annotations[UserImageAnnotationKey] = image +} + +// UpdateTimestampAnnotation update the annotation for the last update with the current timestamp +func UpdateTimestampAnnotation(template *servingv1.RevisionTemplateSpec) { + ensureAnnotations(template) + + template.Annotations[UpdateTimestampAnnotationKey] = time.Now().UTC().Format(time.RFC3339) +} + +func ensureAnnotations(template *servingv1.RevisionTemplateSpec) { + if template.Annotations == nil { + template.Annotations = make(map[string]string) + } +} + +// PinImageToDigest sets the image on the template to the image digest of the base revision. +func PinImageToDigest(currentRevisionTemplate *servingv1.RevisionTemplateSpec, baseRevision *servingv1.Revision) error { + // If there is no base revision then there is nothing to pin to. It's not an error so let's return + // silently + if baseRevision == nil { + return nil + } + + err := VerifyThatContainersMatchInCurrentAndBaseRevision(currentRevisionTemplate, baseRevision) + if err != nil { + return fmt.Errorf("can not pin image to digest: %w", err) + } + + containerStatus := ContainerStatus(baseRevision) + if containerStatus != nil && containerStatus.ImageDigest != "" { + return flags.UpdateImage(¤tRevisionTemplate.Spec.PodSpec, containerStatus.ImageDigest) + } + return nil +} + +// VerifyThatContainersMatchInCurrentAndBaseRevision checks if the image in the current revision matches +// matches the one in a given base revision +func VerifyThatContainersMatchInCurrentAndBaseRevision(template *servingv1.RevisionTemplateSpec, baseRevision *servingv1.Revision) error { + currentContainer := ContainerOfRevisionSpec(&template.Spec) + if currentContainer == nil { + return fmt.Errorf("no container given in current revision %s", template.Name) + } + + baseContainer := ContainerOfRevisionSpec(&baseRevision.Spec) + if baseContainer == nil { + return fmt.Errorf("no container found in base revision %s", baseRevision.Name) + } + + if currentContainer.Image != baseContainer.Image { + return fmt.Errorf("current revision %s contains unexpected image (%s) that does not fit to the base revision's %s image (%s)", template.Name, currentContainer.Image, baseRevision.Name, baseContainer.Image) + } + return nil +} + +// UpdateLabels updates the labels by adding items from `add` then removing any items from `remove` +func UpdateLabels(labelsMap map[string]string, add map[string]string, remove []string) map[string]string { + if labelsMap == nil { + labelsMap = map[string]string{} + } + + for key, value := range add { + labelsMap[key] = value + } + for _, key := range remove { + delete(labelsMap, key) + } + + return labelsMap +} + +// UpdateServiceAnnotations updates annotations for the given Service Metadata. +func UpdateServiceAnnotations(service *servingv1.Service, toUpdate map[string]string, toRemove []string) error { + if service.Annotations == nil && len(toUpdate) > 0 { + service.Annotations = make(map[string]string) + } + return updateAnnotations(service.Annotations, toUpdate, toRemove) +} + +// UpdateRevisionTemplateAnnotations updates annotations for the given Revision Template. +// Also validates the autoscaling annotation values +func UpdateRevisionTemplateAnnotations(template *servingv1.RevisionTemplateSpec, toUpdate map[string]string, toRemove []string) error { + ctx := context.TODO() + autoscalerConfig := servingconfig.FromContextOrDefaults(ctx).Autoscaler + autoscalerConfig.AllowZeroInitialScale = true + if err := autoscaling.ValidateAnnotations(ctx, autoscalerConfig, toUpdate); err != nil { + return err + } + if template.Annotations == nil { + template.Annotations = make(map[string]string) + } + return updateAnnotations(template.Annotations, toUpdate, toRemove) +} + +// UpdateRevisionTemplateAnnotation updates an annotation for the given Revision Template. +// Also validates the autoscaling annotation values +func UpdateRevisionTemplateAnnotation(template *servingv1.RevisionTemplateSpec, annotation string, value string) error { + return UpdateRevisionTemplateAnnotations(template, map[string]string{annotation: value}, []string{}) +} + +// UpdateScaleMetric updates the metric annotation for the given Revision Template +func UpdateScaleMetric(template *servingv1.RevisionTemplateSpec, metric string) { + if template.Annotations == nil { + template.Annotations = make(map[string]string) + } + template.Annotations[autoscaling.MetricAnnotationKey] = metric +} + +// ======================================================================================= + +func updateAnnotations(annotations map[string]string, toUpdate map[string]string, toRemove []string) error { + for key, value := range toUpdate { + annotations[key] = value + } + for _, key := range toRemove { + delete(annotations, key) + } + return nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/revision_template.go b/vendor/knative.dev/client-pkg/pkg/serving/revision_template.go new file mode 100644 index 0000000000..efb6907aa9 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/revision_template.go @@ -0,0 +1,130 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package serving + +import ( + "strconv" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/serving/pkg/apis/autoscaling" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" +) + +type Scaling struct { + Min *int + Max *int +} + +// ContainerOfRevisionSpec returns the 'main' container of a revision specification and +// use GetServingContainerIndex to identify the container. +// Nil is returned if no such container could be found +func ContainerOfRevisionSpec(revisionSpec *servingv1.RevisionSpec) *corev1.Container { + idx := ContainerIndexOfRevisionSpec(revisionSpec) + if idx == -1 { + return nil + } + return &revisionSpec.Containers[0] +} + +// ContainerIndexOfRevisionSpec returns the index of the "main" container if +// multiple containers are present. The main container is either the single +// container when there is only ony container in the list or the first container +// which has a ports declaration (validation guarantees that there is only one +// such container) +// If no container could be found (list is empty or no container has a port declaration) +// then -1 is returned +// This method's logic is taken from RevisionSpec.GetContainer() +func ContainerIndexOfRevisionSpec(revisionSpec *servingv1.RevisionSpec) int { + switch { + case len(revisionSpec.Containers) == 1: + return 0 + case len(revisionSpec.Containers) > 1: + for i := range revisionSpec.Containers { + if len(revisionSpec.Containers[i].Ports) != 0 { + return i + } + } + } + return -1 +} + +// ContainerStatus returns the status of the main container or nil of no +// such status could be found +func ContainerStatus(r *servingv1.Revision) *servingv1.ContainerStatus { + idx := ContainerIndexOfRevisionSpec(&r.Spec) + if idx < 0 || idx >= len(r.Status.ContainerStatuses) { + return nil + } + return &r.Status.ContainerStatuses[idx] +} + +func ScalingInfo(m *metav1.ObjectMeta) (*Scaling, error) { + ret := &Scaling{} + var err error + ret.Min, err = annotationAsInt(m, autoscaling.MinScaleAnnotationKey) + if err != nil { + return nil, err + } + ret.Max, err = annotationAsInt(m, autoscaling.MaxScaleAnnotationKey) + if err != nil { + return nil, err + } + return ret, nil +} + +func UserImage(m *metav1.ObjectMeta) string { + return m.Annotations[UserImageAnnotationKey] +} + +func ConcurrencyTarget(m *metav1.ObjectMeta) *int { + ret, _ := annotationAsInt(m, autoscaling.TargetAnnotationKey) + return ret +} + +func ConcurrencyTargetUtilization(m *metav1.ObjectMeta) *int { + ret, _ := annotationAsInt(m, autoscaling.TargetUtilizationPercentageKey) + return ret +} + +func AutoscaleWindow(m *metav1.ObjectMeta) string { + return m.Annotations[autoscaling.WindowAnnotationKey] +} + +func Port(revisionSpec *servingv1.RevisionSpec) *int32 { + c := ContainerOfRevisionSpec(revisionSpec) + if c == nil { + return nil + } + if len(c.Ports) > 0 { + p := c.Ports[0].ContainerPort + return &p + } + return nil +} + +// ======================================================================================= + +func annotationAsInt(m *metav1.ObjectMeta, annotationKey string) (*int, error) { + annos := m.Annotations + if val, ok := annos[annotationKey]; ok { + valInt, err := strconv.Atoi(val) + if err != nil { + return nil, err + } + return &valInt, nil + } + return nil, nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/service.go b/vendor/knative.dev/client-pkg/pkg/serving/service.go new file mode 100644 index 0000000000..6e37a15807 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/service.go @@ -0,0 +1,74 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package serving + +import ( + "bytes" + "math/rand" + "strings" + "text/template" + "time" + + servingv1 "knative.dev/serving/pkg/apis/serving/v1" +) + +var revisionNameRand = rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec // Weak crypto is fine here, we use it for generating unique keys. + +var charChoices = []string{ + "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", + "y", "z", +} + +type revisionTemplContext struct { + Service string + Generation int64 +} + +func (c *revisionTemplContext) Random(l int) string { + chars := make([]string, 0, l) + for i := 0; i < l; i++ { + //nolint:gosec // Weak crypto is fine here, we use it for generating unique keys. + chars = append(chars, charChoices[revisionNameRand.Int()%len(charChoices)]) + } + return strings.Join(chars, "") +} + +// GenerateRevisionName returns an automatically-generated name suitable for the +// next revision of the given service. +func GenerateRevisionName(nameTempl string, service *servingv1.Service) (string, error) { + templ, err := template.New("revisionName").Parse(nameTempl) + if err != nil { + return "", err + } + context := &revisionTemplContext{ + Service: service.Name, + Generation: service.Generation + 1, + } + buf := new(bytes.Buffer) + err = templ.Execute(buf, context) + if err != nil { + return "", err + } + res := buf.String() + // Empty is ok. + if res == "" { + return res, nil + } + prefix := service.Name + "-" + if !strings.HasPrefix(res, prefix) { + res = prefix + res + } + return res, nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/v1/apply.go b/vendor/knative.dev/client-pkg/pkg/serving/v1/apply.go new file mode 100644 index 0000000000..40588d69f4 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/v1/apply.go @@ -0,0 +1,268 @@ +package v1 + +import ( + "context" + "strings" + "time" + + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/jsonmergepatch" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" + + "knative.dev/client-pkg/pkg/util" +) + +// Copyright © 2020 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. + +// Helper methods supporting Apply() + +// patch performs a 3-way merge and returns whether the original service has been changed +// This method uses a simple JSON 3-way merge which has some severe limitations, like that arrays +// can't be merged. Ideally a strategicpatch merge should be used, which allows a more fine grained +// way for performing the merge (but this is not supported for custom resources) +// See issue https://github.com/knative/client/issues/1073 for more details how this method should be +// improved for a better merge strategy. +func (cl *knServingClient) patch(ctx context.Context, modifiedService *servingv1.Service, currentService *servingv1.Service, uOriginalService []byte) (bool, error) { + uModifiedService, err := getModifiedConfiguration(modifiedService, true) + if err != nil { + return false, err + } + hasChanged, err := cl.patchSimple(ctx, currentService, uModifiedService, uOriginalService) + for i := 1; i <= 5 && apierrors.IsConflict(err); i++ { + if i > 1 { + time.Sleep(1 * time.Second) + } + currentService, err = cl.GetService(ctx, currentService.Name) + if err != nil { + return false, err + } + hasChanged, err = cl.patchSimple(ctx, currentService, uModifiedService, uOriginalService) + } + return hasChanged, err +} + +func (cl *knServingClient) patchSimple(ctx context.Context, currentService *servingv1.Service, uModifiedService []byte, uOriginalService []byte) (bool, error) { + // Serialize the current configuration of the object from the server. + uCurrentService, err := encodeService(currentService) + if err != nil { + return false, err + } + + patch, err := jsonmergepatch.CreateThreeWayJSONMergePatch(uOriginalService, uModifiedService, uCurrentService) + if err != nil { + return false, err + } + + if string(patch) == "{}" { + return false, nil + } + + // Check if the generation has been counted up, only then the backend detected a change + savedService, err := cl.patchService(ctx, currentService.Name, types.MergePatchType, patch) + if err != nil { + return false, err + } + return savedService.Generation != savedService.Status.ObservedGeneration, nil +} + +// patchService patches the given service +func (cl *knServingClient) patchService(ctx context.Context, name string, patchType types.PatchType, patch []byte) (*servingv1.Service, error) { + service, err := cl.client.Services(cl.namespace).Patch(ctx, name, patchType, patch, metav1.PatchOptions{}) + if err != nil { + return nil, err + } + err = updateServingGvk(service) + + return service, err +} + +func getOriginalConfiguration(service *servingv1.Service) []byte { + annots := service.Annotations + if annots == nil { + return nil + } + original, ok := annots[v1.LastAppliedConfigAnnotation] + if !ok { + return nil + } + return []byte(original) +} + +func getModifiedConfiguration(service *servingv1.Service, annotate bool) ([]byte, error) { + + // First serialize the object without the annotation to prevent recursion, + // then add that serialization to it as the annotation and serialize it again. + var uModifiedService []byte + + // Otherwise, use the server side version of the object. + // Get the current annotations from the object. + annots := service.Annotations + if annots == nil { + annots = map[string]string{} + } + + original := annots[v1.LastAppliedConfigAnnotation] + delete(annots, v1.LastAppliedConfigAnnotation) + service.Annotations = annots + + uModifiedService, err := encodeService(service) + if err != nil { + return nil, err + } + + if annotate { + annots[v1.LastAppliedConfigAnnotation] = strings.TrimRight(string(uModifiedService), "\n") + + service.Annotations = annots + uModifiedService, err = encodeService(service) + if err != nil { + return nil, err + } + } + + // Restore the object to its original condition. + annots[v1.LastAppliedConfigAnnotation] = original + service.Annotations = annots + return uModifiedService, nil +} + +func updateLastAppliedAnnotation(service *servingv1.Service) error { + annots := service.Annotations + if annots == nil { + annots = map[string]string{} + } + lastApplied, err := encodeService(service) + if err != nil { + return err + } + + // Cleanup any trailing newlines + annots[v1.LastAppliedConfigAnnotation] = strings.TrimRight(string(lastApplied), "\n") + + service.Annotations = annots + return nil +} + +func encodeService(service *servingv1.Service) ([]byte, error) { + scheme := runtime.NewScheme() + err := servingv1.AddToScheme(scheme) + if err != nil { + return nil, err + } + factory := serializer.NewCodecFactory(scheme) + encoder := factory.EncoderForVersion(unstructured.UnstructuredJSONScheme, servingv1.SchemeGroupVersion) + err = util.UpdateGroupVersionKindWithScheme(service, servingv1.SchemeGroupVersion, scheme) + if err != nil { + return nil, err + } + + serviceUnstructured, err := util.ToUnstructured(service) + if err != nil { + return nil, err + } + + // Remove/adapt service so that it can be used in the apply-annotation + cleanupServiceUnstructured(serviceUnstructured) + + return runtime.Encode(encoder, serviceUnstructured) +} + +func cleanupServiceUnstructured(uService *unstructured.Unstructured) { + clearCreationTimestamps(uService.Object) + removeStatus(uService.Object) + removeContainerNameAndResourcesIfNotSet(uService.Object) + +} + +func removeContainerNameAndResourcesIfNotSet(uService map[string]interface{}) { + uContainer := extractUserContainer(uService) + if uContainer == nil { + return + } + name, ok := uContainer["name"] + if ok && name != "" { + delete(uContainer, "name") + } + + resources := uContainer["resources"] + if resources == nil { + return + } + resourcesMap := resources.(map[string]interface{}) + if len(resourcesMap) == 0 { + delete(uContainer, "resources") + } +} + +func extractUserContainer(uService map[string]interface{}) map[string]interface{} { + tSpec := extractTemplateSpec(uService) + if tSpec == nil { + return nil + } + containers := tSpec["containers"] + if len(containers.([]interface{})) == 0 { + return nil + } + return containers.([]interface{})[0].(map[string]interface{}) +} + +func removeStatus(uService map[string]interface{}) { + delete(uService, "status") +} + +func clearCreationTimestamps(uService map[string]interface{}) { + meta := uService["metadata"] + if meta != nil { + delete(meta.(map[string]interface{}), "creationTimestamp") + } + template := extractTemplate(uService) + if template != nil { + meta = template["metadata"] + if meta != nil { + delete(meta.(map[string]interface{}), "creationTimestamp") + } + } +} + +func extractTemplateSpec(uService map[string]interface{}) map[string]interface{} { + templ := extractTemplate(uService) + if templ == nil { + return nil + } + templSpec := templ["spec"] + if templSpec == nil { + return nil + } + + return templSpec.(map[string]interface{}) +} + +func extractTemplate(uService map[string]interface{}) map[string]interface{} { + spec := uService["spec"] + if spec == nil { + return nil + } + templ := spec.(map[string]interface{})["template"] + if templ == nil { + return nil + } + return templ.(map[string]interface{}) +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/v1/client.go b/vendor/knative.dev/client-pkg/pkg/serving/v1/client.go new file mode 100644 index 0000000000..9c83ab5959 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/v1/client.go @@ -0,0 +1,581 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + "errors" + "fmt" + "time" + + "knative.dev/client-pkg/pkg/config" + + "k8s.io/client-go/util/retry" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/fields" + "knative.dev/pkg/apis" + "knative.dev/serving/pkg/client/clientset/versioned/scheme" + + "knative.dev/client-pkg/pkg/serving" + "knative.dev/client-pkg/pkg/util" + "knative.dev/client-pkg/pkg/wait" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + apiserving "knative.dev/serving/pkg/apis/serving" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" + clientv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" + + clienterrors "knative.dev/client-pkg/pkg/errors" +) + +// Func signature for an updating function which returns the updated service object +// or an error +type ServiceUpdateFunc func(origService *servingv1.Service) (*servingv1.Service, error) + +type WaitConfig struct { + Timeout time.Duration + ErrorWindow time.Duration +} + +// Kn interface to serving. All methods are relative to the +// namespace specified during construction +type KnServingClient interface { + + // Namespace in which this client is operating for + Namespace() string + + // Get a service by its unique name + GetService(ctx context.Context, name string) (*servingv1.Service, error) + + // List services + ListServices(ctx context.Context, opts ...ListConfig) (*servingv1.ServiceList, error) + + // Create a new service + CreateService(ctx context.Context, service *servingv1.Service) error + + // UpdateService updates the given service. For a more robust variant with automatic + // conflict resolution see UpdateServiceWithRetry + UpdateService(ctx context.Context, service *servingv1.Service) (bool, error) + + // UpdateServiceWithRetry updates service and retries if there is a version conflict. + // The updateFunc receives a deep copy of the existing service and can add update it in + // place. Return if the service creates a new generation or not + UpdateServiceWithRetry(ctx context.Context, name string, updateFunc ServiceUpdateFunc, nrRetries int) (bool, error) + + // Apply a service's definition to the cluster. The full service declaration needs to be provided, + // which is different to UpdateService which can also do a partial update. If the given + // service does not already exists (identified by name) then the service is create. + // If the service exists, then a three-way merge will be performed between the original + // configuration given (from the last "apply" operation), the new configuration as given ] + // here and the current configuration as found on the cluster. + // The returned bool indicates whether the service has been changed or whether this operation + // was a no-op + // An error can indicate a general error or a conflict that occurred during the three way merge. + ApplyService(ctx context.Context, service *servingv1.Service) (bool, error) + + // Delete a service by name + DeleteService(ctx context.Context, name string, timeout time.Duration) error + + // Wait for a service to become ready, but not longer than provided timeout. + // Return error and how long has been waited + WaitForService(ctx context.Context, name string, wconfig WaitConfig, msgCallback wait.MessageCallback) (error, time.Duration) + + // Get a configuration by name + GetConfiguration(ctx context.Context, name string) (*servingv1.Configuration, error) + + // Get a revision by name + GetRevision(ctx context.Context, name string) (*servingv1.Revision, error) + + // Get the "base" revision for a Service; the one that corresponds to the + // current template. + GetBaseRevision(ctx context.Context, service *servingv1.Service) (*servingv1.Revision, error) + + // Create revision + CreateRevision(ctx context.Context, revision *servingv1.Revision) error + + // Update revision + UpdateRevision(ctx context.Context, revision *servingv1.Revision) error + + // List revisions + ListRevisions(ctx context.Context, opts ...ListConfig) (*servingv1.RevisionList, error) + + // Delete a revision + DeleteRevision(ctx context.Context, name string, timeout time.Duration) error + + // Get a route by its unique name + GetRoute(ctx context.Context, name string) (*servingv1.Route, error) + + // List routes + ListRoutes(ctx context.Context, opts ...ListConfig) (*servingv1.RouteList, error) +} + +type listConfigCollector struct { + // Labels to filter on + Labels labels.Set + + // Labels to filter on + Fields fields.Set +} + +// Config function for builder pattern +type ListConfig func(config *listConfigCollector) + +type ListConfigs []ListConfig + +// add selectors to a list options +func (opts ListConfigs) toListOptions() v1.ListOptions { + listConfig := listConfigCollector{labels.Set{}, fields.Set{}} + for _, f := range opts { + f(&listConfig) + } + options := v1.ListOptions{} + if len(listConfig.Fields) > 0 { + options.FieldSelector = listConfig.Fields.String() + } + if len(listConfig.Labels) > 0 { + options.LabelSelector = listConfig.Labels.String() + } + return options +} + +// Filter list on the provided name +func WithName(name string) ListConfig { + return func(lo *listConfigCollector) { + lo.Fields["metadata.name"] = name + } +} + +// Filter on the service name +func WithService(service string) ListConfig { + return func(lo *listConfigCollector) { + lo.Labels[apiserving.ServiceLabelKey] = service + } +} + +// WithLabel filters on the provided label +func WithLabel(labelKey, labelValue string) ListConfig { + return func(lo *listConfigCollector) { + lo.Labels[labelKey] = labelValue + } +} + +type knServingClient struct { + client clientv1.ServingV1Interface + namespace string +} + +// Create a new client facade for the provided namespace +func NewKnServingClient(client clientv1.ServingV1Interface, namespace string) KnServingClient { + return &knServingClient{ + client: client, + namespace: namespace, + } +} + +// Return the client's namespace +func (cl *knServingClient) Namespace() string { + return cl.namespace +} + +// Get a service by its unique name +func (cl *knServingClient) GetService(ctx context.Context, name string) (*servingv1.Service, error) { + service, err := cl.client.Services(cl.namespace).Get(ctx, name, v1.GetOptions{}) + if err != nil { + return nil, clienterrors.GetError(err) + } + err = updateServingGvk(service) + if err != nil { + return nil, err + } + return service, nil +} + +func (cl *knServingClient) WatchServiceWithVersion(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { + return wait.NewWatcherWithVersion(ctx, cl.client.Services(cl.namespace).Watch, cl.client.RESTClient(), cl.namespace, "services", name, initialVersion, timeout) +} + +func (cl *knServingClient) WatchRevisionWithVersion(ctx context.Context, name string, initialVersion string, timeout time.Duration) (watch.Interface, error) { + return wait.NewWatcherWithVersion(ctx, cl.client.Revisions(cl.namespace).Watch, cl.client.RESTClient(), cl.namespace, "revision", name, initialVersion, timeout) +} + +// List services +func (cl *knServingClient) ListServices(ctx context.Context, config ...ListConfig) (*servingv1.ServiceList, error) { + serviceList, err := cl.client.Services(cl.namespace).List(ctx, ListConfigs(config).toListOptions()) + if err != nil { + return nil, clienterrors.GetError(err) + } + serviceListNew := serviceList.DeepCopy() + err = updateServingGvk(serviceListNew) + if err != nil { + return nil, err + } + + serviceListNew.Items = make([]servingv1.Service, len(serviceList.Items)) + for idx, service := range serviceList.Items { + serviceClone := service.DeepCopy() + err := updateServingGvk(serviceClone) + if err != nil { + return nil, err + } + serviceListNew.Items[idx] = *serviceClone + } + return serviceListNew, nil +} + +// Create a new service +func (cl *knServingClient) CreateService(ctx context.Context, service *servingv1.Service) error { + _, err := cl.client.Services(cl.namespace).Create(ctx, service, v1.CreateOptions{}) + if err != nil { + return clienterrors.GetError(err) + } + return updateServingGvk(service) +} + +// Update the given service +func (cl *knServingClient) UpdateService(ctx context.Context, service *servingv1.Service) (bool, error) { + updated, err := cl.client.Services(cl.namespace).Update(ctx, service, v1.UpdateOptions{}) + if err != nil { + return false, err + } + changed := service.ObjectMeta.Generation != updated.ObjectMeta.Generation + return changed, updateServingGvk(service) +} + +// Update the given service with a retry in case of a conflict +func (cl *knServingClient) UpdateServiceWithRetry(ctx context.Context, name string, updateFunc ServiceUpdateFunc, nrRetries int) (bool, error) { + return updateServiceWithRetry(ctx, cl, name, updateFunc, nrRetries) +} + +// Extracted to be usable with the Mocking client +func updateServiceWithRetry(ctx context.Context, cl KnServingClient, name string, updateFunc ServiceUpdateFunc, nrRetries int) (bool, error) { + var changed bool + var err error + b := config.DefaultRetry + b.Steps = nrRetries + err = retry.RetryOnConflict(b, func() error { + service, err := cl.GetService(ctx, name) + if err != nil { + return err + } + if service.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't update service %s because it has been marked for deletion", name) + } + updatedService, err := updateFunc(service.DeepCopy()) + if err != nil { + return err + } + + changed, err = cl.UpdateService(ctx, updatedService) + return err + }) + return changed, err +} + +// ApplyService applies a service definition that contains the service's targer state +func (cl *knServingClient) ApplyService(ctx context.Context, modifiedService *servingv1.Service) (bool, error) { + currentService, err := cl.GetService(ctx, modifiedService.Name) + if err != nil && !apierrors.IsNotFound(err) { + return false, err + } + + containers := modifiedService.Spec.Template.Spec.Containers + if len(containers) == 0 || containers[0].Image == "" && currentService != nil { + return false, errors.New("'service apply' requires the image name to run provided with the --image option") + } + + // No current service --> create a new service + if currentService == nil { + err := updateLastAppliedAnnotation(modifiedService) + if err != nil { + return false, err + } + return true, cl.CreateService(ctx, modifiedService) + } + + // Merge with existing service + uOriginalService := getOriginalConfiguration(currentService) + return cl.patch(ctx, modifiedService, currentService, uOriginalService) +} + +// Delete a service by name +// Param `timeout` represents a duration to wait for a delete op to finish. +// For `timeout == 0` delete is performed async without any wait. +func (cl *knServingClient) DeleteService(ctx context.Context, serviceName string, timeout time.Duration) error { + service, err := cl.GetService(ctx, serviceName) + if err != nil { + return err + } + if service.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't delete service '%s' because it has been already marked for deletion", serviceName) + } + if timeout == 0 { + return cl.deleteService(ctx, serviceName, v1.DeletePropagationBackground) + } + + waitC := make(chan error) + go func() { + waitForEvent := wait.NewWaitForEvent("service", cl.WatchServiceWithVersion, func(evt *watch.Event) bool { return evt.Type == watch.Deleted }) + err, _ := waitForEvent.Wait(ctx, serviceName, service.ResourceVersion, wait.Options{Timeout: &timeout}, wait.NoopMessageCallback()) + waitC <- err + }() + err = cl.deleteService(ctx, serviceName, v1.DeletePropagationForeground) + if err != nil { + return err + } + + return <-waitC +} + +func (cl *knServingClient) deleteService(ctx context.Context, serviceName string, propagationPolicy v1.DeletionPropagation) error { + err := cl.client.Services(cl.namespace).Delete( + ctx, + serviceName, + v1.DeleteOptions{PropagationPolicy: &propagationPolicy}, + ) + if err != nil { + return clienterrors.GetError(err) + } + + return nil +} + +// Wait for a service to become ready, but not longer than provided timeout +func (cl *knServingClient) WaitForService(ctx context.Context, name string, wconfig WaitConfig, msgCallback wait.MessageCallback) (error, time.Duration) { + waitForReady := wait.NewWaitForReady("service", cl.WatchServiceWithVersion, serviceConditionExtractor) + + service, err := cl.GetService(ctx, name) + if err != nil { + if apierrors.IsNotFound(err) { + return waitForReady.Wait(ctx, name, "", wait.Options{Timeout: &wconfig.Timeout, ErrorWindow: &wconfig.ErrorWindow}, msgCallback) + } + return err, 0 + } + return waitForReady.Wait(ctx, name, service.ResourceVersion, wait.Options{Timeout: &wconfig.Timeout, ErrorWindow: &wconfig.ErrorWindow}, msgCallback) +} + +// Get the configuration for a service +func (cl *knServingClient) GetConfiguration(ctx context.Context, name string) (*servingv1.Configuration, error) { + configuration, err := cl.client.Configurations(cl.namespace).Get(ctx, name, v1.GetOptions{}) + if err != nil { + return nil, err + } + err = updateServingGvk(configuration) + if err != nil { + return nil, err + } + return configuration, nil +} + +// Get a revision by name +func (cl *knServingClient) GetRevision(ctx context.Context, name string) (*servingv1.Revision, error) { + revision, err := cl.client.Revisions(cl.namespace).Get(ctx, name, v1.GetOptions{}) + if err != nil { + return nil, clienterrors.GetError(err) + } + err = updateServingGvk(revision) + if err != nil { + return nil, err + } + return revision, nil +} + +type NoBaseRevisionError struct { + msg string +} + +func (e NoBaseRevisionError) Error() string { + return e.msg +} + +var noBaseRevisionError = &NoBaseRevisionError{"base revision not found"} + +// Get a "base" revision. This is the revision corresponding to the template of +// a Service. It may not be findable with our heuristics, in which case this +// method returns Errors()["no-base-revision"]. If it simply doesn't exist (like +// it wasn't yet created or was deleted), return the usual not found error. +func (cl *knServingClient) GetBaseRevision(ctx context.Context, service *servingv1.Service) (*servingv1.Revision, error) { + return getBaseRevision(ctx, cl, service) +} + +func getBaseRevision(ctx context.Context, cl KnServingClient, service *servingv1.Service) (*servingv1.Revision, error) { + template := service.Spec.Template + // First, try to get it by name. If the template has a particular name, the + // base revision is the one created with that name. + if template.Name != "" { + return cl.GetRevision(ctx, template.Name) + } + // Next, let's try the LatestCreatedRevision, and see if that matches the + // template, at least in terms of the image (which is what we care about here). + if service.Status.LatestCreatedRevisionName != "" { + latestCreated, err := cl.GetRevision(ctx, service.Status.LatestCreatedRevisionName) + if err != nil { + return nil, err + } + + err = serving.VerifyThatContainersMatchInCurrentAndBaseRevision(&template, latestCreated) + if err != nil { + return nil, err + } + // There is still some chance the latestCreatedRevision is out of date, + // but we can't check the whole thing for equality because of + // server-side defaulting. Since what we probably want it for is to + // check the image digest anyway, keep it as good enough. + return latestCreated, nil + } + return nil, noBaseRevisionError +} + +// Create a revision +func (cl *knServingClient) CreateRevision(ctx context.Context, revision *servingv1.Revision) error { + rev, err := cl.client.Revisions(cl.namespace).Create(ctx, revision, v1.CreateOptions{}) + if err != nil { + return clienterrors.GetError(err) + } + return updateServingGvk(rev) +} + +// Update the given service +func (cl *knServingClient) UpdateRevision(ctx context.Context, revision *servingv1.Revision) error { + _, err := cl.client.Revisions(cl.namespace).Update(ctx, revision, v1.UpdateOptions{}) + if err != nil { + return err + } + return updateServingGvk(revision) +} + +// Delete a revision by name +func (cl *knServingClient) DeleteRevision(ctx context.Context, name string, timeout time.Duration) error { + revision, err := cl.client.Revisions(cl.namespace).Get(ctx, name, v1.GetOptions{}) + if err != nil { + return clienterrors.GetError(err) + } + if revision.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't delete revision '%s' because it has been already marked for deletion", name) + } + if timeout == 0 { + return cl.deleteRevision(ctx, name) + } + waitC := make(chan error) + go func() { + waitForEvent := wait.NewWaitForEvent("revision", cl.WatchRevisionWithVersion, func(evt *watch.Event) bool { return evt.Type == watch.Deleted }) + err, _ := waitForEvent.Wait(ctx, name, revision.ResourceVersion, wait.Options{Timeout: &timeout}, wait.NoopMessageCallback()) + waitC <- err + }() + err = cl.deleteRevision(ctx, name) + if err != nil { + return clienterrors.GetError(err) + } + + return <-waitC +} + +func (cl *knServingClient) deleteRevision(ctx context.Context, name string) error { + err := cl.client.Revisions(cl.namespace).Delete(ctx, name, v1.DeleteOptions{}) + if err != nil { + return clienterrors.GetError(err) + } + + return nil +} + +// List revisions +func (cl *knServingClient) ListRevisions(ctx context.Context, config ...ListConfig) (*servingv1.RevisionList, error) { + revisionList, err := cl.client.Revisions(cl.namespace).List(ctx, ListConfigs(config).toListOptions()) + if err != nil { + return nil, clienterrors.GetError(err) + } + return updateServingGvkForRevisionList(revisionList) +} + +// Get a route by its unique name +func (cl *knServingClient) GetRoute(ctx context.Context, name string) (*servingv1.Route, error) { + route, err := cl.client.Routes(cl.namespace).Get(ctx, name, v1.GetOptions{}) + if err != nil { + return nil, err + } + err = updateServingGvk(route) + if err != nil { + return nil, err + } + return route, nil +} + +// List routes +func (cl *knServingClient) ListRoutes(ctx context.Context, config ...ListConfig) (*servingv1.RouteList, error) { + routeList, err := cl.client.Routes(cl.namespace).List(ctx, ListConfigs(config).toListOptions()) + if err != nil { + return nil, err + } + return updateServingGvkForRouteList(routeList) +} + +// update all the list + all items contained in the list with +// the proper GroupVersionKind specific to Knative serving +func updateServingGvkForRevisionList(revisionList *servingv1.RevisionList) (*servingv1.RevisionList, error) { + revisionListNew := revisionList.DeepCopy() + err := updateServingGvk(revisionListNew) + if err != nil { + return nil, err + } + + revisionListNew.Items = make([]servingv1.Revision, len(revisionList.Items)) + for idx := range revisionList.Items { + revision := revisionList.Items[idx].DeepCopy() + err := updateServingGvk(revision) + if err != nil { + return nil, err + } + revisionListNew.Items[idx] = *revision + } + return revisionListNew, nil +} + +// update all the list + all items contained in the list with +// the proper GroupVersionKind specific to Knative serving +func updateServingGvkForRouteList(routeList *servingv1.RouteList) (*servingv1.RouteList, error) { + routeListNew := routeList.DeepCopy() + err := updateServingGvk(routeListNew) + if err != nil { + return nil, err + } + + routeListNew.Items = make([]servingv1.Route, len(routeList.Items)) + for idx := range routeList.Items { + revision := routeList.Items[idx].DeepCopy() + err := updateServingGvk(revision) + if err != nil { + return nil, err + } + routeListNew.Items[idx] = *revision + } + return routeListNew, nil +} + +// update with the servingv1 group + version +func updateServingGvk(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, servingv1.SchemeGroupVersion, scheme.Scheme) +} + +func serviceConditionExtractor(obj runtime.Object) (apis.Conditions, error) { + service, ok := obj.(*servingv1.Service) + if !ok { + return nil, fmt.Errorf("%v is not a service", obj) + } + return apis.Conditions(service.Status.Conditions), nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/v1/client_mock.go b/vendor/knative.dev/client-pkg/pkg/serving/v1/client_mock.go new file mode 100644 index 0000000000..f446b8d713 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/v1/client_mock.go @@ -0,0 +1,282 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + "testing" + "time" + + "gotest.tools/v3/assert" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" + + "knative.dev/client-pkg/pkg/util/mock" + "knative.dev/client-pkg/pkg/wait" +) + +type MockKnServingClient struct { + t *testing.T + recorder *ServingRecorder +} + +// NewMockKnServiceClient returns a new mock instance which you need to record for +func NewMockKnServiceClient(t *testing.T, ns ...string) *MockKnServingClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnServingClient{ + t: t, + recorder: &ServingRecorder{mock.NewRecorder(t, namespace)}, + } +} + +// recorder for service +type ServingRecorder struct { + r *mock.Recorder +} + +// Get the record to start for the recorder +func (c *MockKnServingClient) Recorder() *ServingRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnServingClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// Get Service +func (sr *ServingRecorder) GetService(name interface{}, service *servingv1.Service, err error) { + sr.r.Add("GetService", []interface{}{name}, []interface{}{service, err}) +} + +func (c *MockKnServingClient) GetService(ctx context.Context, name string) (*servingv1.Service, error) { + call := c.recorder.r.VerifyCall("GetService", name) + return call.Result[0].(*servingv1.Service), mock.ErrorOrNil(call.Result[1]) +} + +// List services +func (sr *ServingRecorder) ListServices(opts interface{}, serviceList *servingv1.ServiceList, err error) { + sr.r.Add("ListServices", []interface{}{opts}, []interface{}{serviceList, err}) +} + +func (c *MockKnServingClient) ListServices(ctx context.Context, opts ...ListConfig) (*servingv1.ServiceList, error) { + call := c.recorder.r.VerifyCall("ListServices", opts) + return call.Result[0].(*servingv1.ServiceList), mock.ErrorOrNil(call.Result[1]) +} + +// Create a new service +func (sr *ServingRecorder) CreateService(service interface{}, err error) { + sr.r.Add("CreateService", []interface{}{service}, []interface{}{err}) +} + +func (c *MockKnServingClient) CreateService(ctx context.Context, service *servingv1.Service) error { + call := c.recorder.r.VerifyCall("CreateService", service) + return mock.ErrorOrNil(call.Result[0]) +} + +// Update the given service +func (sr *ServingRecorder) UpdateService(service interface{}, hasChanged bool, err error) { + sr.r.Add("UpdateService", []interface{}{service}, []interface{}{hasChanged, err}) +} + +func (c *MockKnServingClient) UpdateService(ctx context.Context, service *servingv1.Service) (bool, error) { + call := c.recorder.r.VerifyCall("UpdateService", service) + return call.Result[0].(bool), mock.ErrorOrNil(call.Result[1]) +} + +// Delegate to shared retry method +func (c *MockKnServingClient) UpdateServiceWithRetry(ctx context.Context, name string, updateFunc ServiceUpdateFunc, maxRetry int) (bool, error) { + return updateServiceWithRetry(ctx, c, name, updateFunc, maxRetry) +} + +// Update the given service +func (sr *ServingRecorder) ApplyService(service interface{}, hasChanged bool, err error) { + sr.r.Add("ApplyService", []interface{}{service}, []interface{}{hasChanged, err}) +} + +func (c *MockKnServingClient) ApplyService(ctx context.Context, service *servingv1.Service) (bool, error) { + call := c.recorder.r.VerifyCall("ApplyService", service) + return call.Result[0].(bool), mock.ErrorOrNil(call.Result[1]) +} + +// Delete a service by name +func (sr *ServingRecorder) DeleteService(name, timeout interface{}, err error) { + sr.r.Add("DeleteService", []interface{}{name, timeout}, []interface{}{err}) +} + +func (c *MockKnServingClient) DeleteService(ctx context.Context, name string, timeout time.Duration) error { + call := c.recorder.r.VerifyCall("DeleteService", name, timeout) + return mock.ErrorOrNil(call.Result[0]) +} + +// Wait for a service to become ready, but not longer than provided timeout +func (sr *ServingRecorder) WaitForService(name interface{}, wconfig interface{}, callback interface{}, err error, duration time.Duration) { + sr.r.Add("WaitForService", []interface{}{name, wconfig, callback}, []interface{}{err, duration}) +} + +func (c *MockKnServingClient) WaitForService(ctx context.Context, name string, wconfig WaitConfig, msgCallback wait.MessageCallback) (error, time.Duration) { + call := c.recorder.r.VerifyCall("WaitForService", name, wconfig, msgCallback) + return mock.ErrorOrNil(call.Result[0]), call.Result[1].(time.Duration) +} + +// Get a revision by name +func (sr *ServingRecorder) GetRevision(name interface{}, revision *servingv1.Revision, err error) { + sr.r.Add("GetRevision", []interface{}{name}, []interface{}{revision, err}) +} + +func (c *MockKnServingClient) GetRevision(ctx context.Context, name string) (*servingv1.Revision, error) { + call := c.recorder.r.VerifyCall("GetRevision", name) + return call.Result[0].(*servingv1.Revision), mock.ErrorOrNil(call.Result[1]) +} + +// List revisions +func (sr *ServingRecorder) ListRevisions(opts interface{}, revisionList *servingv1.RevisionList, err error) { + sr.r.Add("ListRevisions", []interface{}{opts}, []interface{}{revisionList, err}) +} + +func (c *MockKnServingClient) ListRevisions(ctx context.Context, opts ...ListConfig) (*servingv1.RevisionList, error) { + call := c.recorder.r.VerifyCall("ListRevisions", opts) + return call.Result[0].(*servingv1.RevisionList), mock.ErrorOrNil(call.Result[1]) +} + +// Delete a revision +func (sr *ServingRecorder) DeleteRevision(name, timeout interface{}, err error) { + sr.r.Add("DeleteRevision", []interface{}{name, timeout}, []interface{}{err}) +} + +func (c *MockKnServingClient) DeleteRevision(ctx context.Context, name string, timeout time.Duration) error { + call := c.recorder.r.VerifyCall("DeleteRevision", name, timeout) + return mock.ErrorOrNil(call.Result[0]) +} + +// Wait for a revision to become ready, but not longer than provided timeout +func (sr *ServingRecorder) WaitForRevision(name interface{}, timeout interface{}, callback interface{}, err error, duration time.Duration) { + sr.r.Add("WaitForRevision", []interface{}{name, timeout, callback}, []interface{}{err, duration}) +} + +func (c *MockKnServingClient) WaitForRevision(ctx context.Context, name string, timeout time.Duration, msgCallback wait.MessageCallback) (error, time.Duration) { + call := c.recorder.r.VerifyCall("WaitForRevision", name, timeout, msgCallback) + return mock.ErrorOrNil(call.Result[0]), call.Result[1].(time.Duration) +} + +// Get a route by its unique name +func (sr *ServingRecorder) GetRoute(name interface{}, route *servingv1.Route, err error) { + sr.r.Add("GetRoute", []interface{}{name}, []interface{}{route, err}) +} + +func (c *MockKnServingClient) GetRoute(ctx context.Context, name string) (*servingv1.Route, error) { + call := c.recorder.r.VerifyCall("GetRoute", name) + return call.Result[0].(*servingv1.Route), mock.ErrorOrNil(call.Result[1]) + +} + +// List routes +func (sr *ServingRecorder) ListRoutes(opts interface{}, routeList *servingv1.RouteList, err error) { + sr.r.Add("ListRoutes", []interface{}{opts}, []interface{}{routeList, err}) +} + +func (c *MockKnServingClient) ListRoutes(ctx context.Context, opts ...ListConfig) (*servingv1.RouteList, error) { + call := c.recorder.r.VerifyCall("ListRoutes", opts) + return call.Result[0].(*servingv1.RouteList), mock.ErrorOrNil(call.Result[1]) +} + +// GetConfiguration records a call to GetConfiguration with possible return values +func (sr *ServingRecorder) GetConfiguration(name string, config *servingv1.Configuration, err error) { + sr.r.Add("GetConfiguration", []interface{}{name}, []interface{}{config, err}) + +} + +// GetBaseRevision returns the base revision +func (c *MockKnServingClient) GetBaseRevision(ctx context.Context, service *servingv1.Service) (*servingv1.Revision, error) { + return getBaseRevision(ctx, c, service) +} + +// GetConfiguration returns a configuration looked up by name +func (c *MockKnServingClient) GetConfiguration(ctx context.Context, name string) (*servingv1.Configuration, error) { + call := c.recorder.r.VerifyCall("GetConfiguration", name) + return call.Result[0].(*servingv1.Configuration), mock.ErrorOrNil(call.Result[1]) +} + +// CreateRevision records a call CreateRevision +func (sr *ServingRecorder) CreateRevision(revision interface{}, err error) { + sr.r.Add("CreateRevision", []interface{}{revision}, []interface{}{err}) +} + +// CreateRevision creates a new revision +func (c *MockKnServingClient) CreateRevision(ctx context.Context, revision *servingv1.Revision) error { + call := c.recorder.r.VerifyCall("CreateRevision", revision) + return mock.ErrorOrNil(call.Result[0]) +} + +// UpdateRevision records a call UpdateRevision +func (sr *ServingRecorder) UpdateRevision(revision interface{}, err error) { + sr.r.Add("UpdateRevision", []interface{}{revision}, []interface{}{err}) +} + +// UpdateRevision updates given revision +func (c *MockKnServingClient) UpdateRevision(ctx context.Context, revision *servingv1.Revision) error { + call := c.recorder.r.VerifyCall("UpdateRevision", revision) + return mock.ErrorOrNil(call.Result[0]) +} + +// Check that every recorded method has been called +func (sr *ServingRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} + +// HasLabelSelector returns a comparable which can be used for asserting that list methods are called +// with the appropriate label selector +func HasLabelSelector(keyAndValues ...string) func(t *testing.T, a interface{}) { + return func(t *testing.T, a interface{}) { + lc := a.([]ListConfig) + listConfigCollector := listConfigCollector{ + Labels: make(labels.Set), + Fields: make(fields.Set), + } + lc[0](&listConfigCollector) + for i := 0; i < len(keyAndValues); i += 2 { + assert.Equal(t, listConfigCollector.Labels[keyAndValues[i]], keyAndValues[i+1]) + } + } +} + +// HasFieldSelector returns a comparable which can be used for asserting that list methods are called +// with the appropriate field selectors +func HasFieldSelector(keyAndValues ...string) func(t *testing.T, a interface{}) { + return func(t *testing.T, a interface{}) { + lc := a.([]ListConfig) + listConfigCollector := listConfigCollector{ + Labels: make(labels.Set), + Fields: make(fields.Set), + } + lc[0](&listConfigCollector) + for i := 0; i < len(keyAndValues); i += 2 { + assert.Equal(t, listConfigCollector.Fields[keyAndValues[i]], keyAndValues[i+1]) + } + } +} + +// HasSelector returns a comparable which can be used for asserting that list methods are called +// with the appropriate label and field selectors +func HasSelector(labelKeysAndValues []string, fieldKeysAndValue []string) func(t *testing.T, a interface{}) { + return func(t *testing.T, a interface{}) { + HasLabelSelector(labelKeysAndValues...)(t, a) + HasFieldSelector(fieldKeysAndValue...)(t, a) + } +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/v1/gitops.go b/vendor/knative.dev/client-pkg/pkg/serving/v1/gitops.go new file mode 100644 index 0000000000..7dcc9ad1ea --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/v1/gitops.go @@ -0,0 +1,220 @@ +// Copyright 2020 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 v1 + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + "time" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/cli-runtime/pkg/genericclioptions" + + "knative.dev/client-pkg/pkg/wait" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" +) + +const ( + ksvcKind = "ksvc" +) + +// knServingGitOpsClient - kn service client +// to work on a local repo instead of a remote cluster +type knServingGitOpsClient struct { + dir string + namespace string + fileMode bool + fileFormat string + KnServingClient +} + +// NewKnServingGitOpsClient returns an instance of the +// kn service gitops client +func NewKnServingGitOpsClient(namespace, dir string) KnServingClient { + mode, format := getFileModeAndType(dir) + return &knServingGitOpsClient{ + dir: dir, + namespace: namespace, + fileMode: mode, + fileFormat: format, + } +} + +func (cl *knServingGitOpsClient) getKsvcFilePath(name string) string { + if cl.fileMode { + return cl.dir + } + return filepath.Join(cl.dir, cl.namespace, ksvcKind, name+".yaml") +} + +func getFileModeAndType(dir string) (bool, string) { + switch { + case strings.HasSuffix(dir, ".yaml"): + return true, "yaml" + case strings.HasSuffix(dir, ".yml"): + return true, "yaml" + case strings.HasSuffix(dir, ".json"): + return true, "json" + } + return false, "yaml" +} + +// Namespace returns the namespace +func (cl *knServingGitOpsClient) Namespace() string { + return cl.namespace +} + +// GetService returns the knative service for the name +func (cl *knServingGitOpsClient) GetService(ctx context.Context, name string) (*servingv1.Service, error) { + return readServiceFromFile(cl.getKsvcFilePath(name), name) +} + +// ListServices lists the services in the path provided +func (cl *knServingGitOpsClient) ListServices(ctx context.Context, opts ...ListConfig) (*servingv1.ServiceList, error) { + svcs, err := cl.listServicesFromDirectory() + if err != nil { + return nil, err + } + typeMeta := metav1.TypeMeta{ + APIVersion: "v1", + Kind: "List", + } + serviceList := &servingv1.ServiceList{ + TypeMeta: typeMeta, + Items: svcs, + } + return serviceList, nil +} + +func (cl *knServingGitOpsClient) listServicesFromDirectory() ([]servingv1.Service, error) { + if cl.fileMode { + svc, err := readServiceFromFile(cl.dir, "") + if err != nil { + return nil, err + } + return []servingv1.Service{*svc}, nil + } + var services []servingv1.Service + root := cl.dir + if cl.namespace != "" { + root = filepath.Join(cl.dir, cl.namespace) + } + if _, err := os.Stat(root); err != nil { + return nil, err + } + if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + switch { + // skip if dir is not ksvc + case info.IsDir(): + return nil + + // skip non yaml files + case !strings.HasSuffix(info.Name(), ".yaml"): + return nil + + // skip non ksvc dir + case !strings.Contains(path, ksvcKind): + return filepath.SkipDir + + default: + svc, err := readServiceFromFile(path, "") + if err != nil { + return err + } + services = append(services, *svc) + return nil + } + }); err != nil { + return nil, err + } + return services, nil +} + +// CreateService saves the knative service spec in +// yaml format in the local path provided +func (cl *knServingGitOpsClient) CreateService(ctx context.Context, service *servingv1.Service) error { + updateServingGvk(service) + if cl.fileMode { + return writeFile(service, cl.dir, cl.fileFormat) + } + //check if dir exist + if _, err := os.Stat(cl.dir); os.IsNotExist(err) { + return fmt.Errorf("directory '%s' not present, please create the directory and try again", cl.dir) + } + return writeFile(service, cl.getKsvcFilePath(service.ObjectMeta.Name), cl.fileFormat) +} + +func writeFile(obj runtime.Object, fp, format string) error { + if _, err := os.Stat(fp); os.IsNotExist(err) { + os.MkdirAll(filepath.Dir(fp), 0755) + } + w, err := os.Create(fp) + if err != nil { + return err + } + yamlPrinter, err := genericclioptions.NewJSONYamlPrintFlags().ToPrinter(format) + if err != nil { + return err + } + return yamlPrinter.PrintObj(obj, w) +} + +// UpdateService updates the service in +// the local directory +func (cl *knServingGitOpsClient) UpdateService(ctx context.Context, service *servingv1.Service) (bool, error) { + // check if file exist + if _, err := cl.GetService(ctx, service.ObjectMeta.Name); err != nil { + return false, err + } + // replace file + return true, cl.CreateService(ctx, service) +} + +// UpdateServiceWithRetry updates the service in the local directory +func (cl *knServingGitOpsClient) UpdateServiceWithRetry(ctx context.Context, name string, updateFunc ServiceUpdateFunc, nrRetries int) (bool, error) { + return updateServiceWithRetry(ctx, cl, name, updateFunc, nrRetries) +} + +// DeleteService removes the file from the local file system +func (cl *knServingGitOpsClient) DeleteService(ctx context.Context, serviceName string, timeout time.Duration) error { + return os.Remove(cl.getKsvcFilePath(serviceName)) +} + +// WaitForService always returns success for this client +func (cl *knServingGitOpsClient) WaitForService(ctx context.Context, name string, wconfig WaitConfig, msgCallback wait.MessageCallback) (error, time.Duration) { + return nil, 1 * time.Second +} + +func readServiceFromFile(fileKey, name string) (*servingv1.Service, error) { + var svc servingv1.Service + file, err := os.Open(fileKey) + if err != nil { + if os.IsNotExist(err) { + return nil, apierrors.NewNotFound(servingv1.Resource("services"), name) + } + return nil, err + } + decoder := yaml.NewYAMLOrJSONDecoder(file, 512) + if err := decoder.Decode(&svc); err != nil { + return nil, err + } + return &svc, nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/v1beta1/client.go b/vendor/knative.dev/client-pkg/pkg/serving/v1beta1/client.go new file mode 100644 index 0000000000..81fe12ff11 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/v1beta1/client.go @@ -0,0 +1,214 @@ +// 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 v1beta1 + +import ( + "context" + "fmt" + + "knative.dev/client-pkg/pkg/config" + + "k8s.io/client-go/util/retry" + + duckv1 "knative.dev/pkg/apis/duck/v1" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" + servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1" + "knative.dev/serving/pkg/client/clientset/versioned/scheme" + clientv1beta1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1" +) + +type DomainUpdateFunc func(origDomain *servingv1beta1.DomainMapping) (*servingv1beta1.DomainMapping, error) + +// KnServingClient to work with Serving v1beta1 resources +type KnServingClient interface { + // Namespace in which this client is operating for + Namespace() string + + // GetDomainMapping + GetDomainMapping(ctx context.Context, name string) (*servingv1beta1.DomainMapping, error) + + // CreateDomainMapping + CreateDomainMapping(ctx context.Context, domainMapping *servingv1beta1.DomainMapping) error + + // UpdateDomainMapping + UpdateDomainMapping(ctx context.Context, domainMapping *servingv1beta1.DomainMapping) error + + // UpdateDomainMappingWithRetry + UpdateDomainMappingWithRetry(ctx context.Context, name string, updateFunc DomainUpdateFunc, nrRetries int) error + + // DeleteDomainMapping + DeleteDomainMapping(ctx context.Context, name string) error + + // ListDomainMappings + ListDomainMappings(ctx context.Context) (*servingv1beta1.DomainMappingList, error) +} + +type knServingClient struct { + client clientv1beta1.ServingV1beta1Interface + namespace string +} + +// NewKnServingClient create a new client facade for the provided namespace +func NewKnServingClient(client clientv1beta1.ServingV1beta1Interface, namespace string) KnServingClient { + return &knServingClient{ + client: client, + namespace: namespace, + } +} + +// Namespace in which this client is operating for +func (cl *knServingClient) Namespace() string { + return cl.namespace +} + +// GetDomainMapping gets DomainMapping by name +func (cl *knServingClient) GetDomainMapping(ctx context.Context, name string) (*servingv1beta1.DomainMapping, error) { + dm, err := cl.client.DomainMappings(cl.namespace).Get(ctx, name, v1.GetOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + err = updateServingGvk(dm) + if err != nil { + return nil, err + } + return dm, nil +} + +// CreateDomainMapping creates provided DomainMapping +func (cl *knServingClient) CreateDomainMapping(ctx context.Context, domainMapping *servingv1beta1.DomainMapping) error { + _, err := cl.client.DomainMappings(cl.namespace).Create(ctx, domainMapping, v1.CreateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return updateServingGvk(domainMapping) +} + +// UpdateDomainMapping updates provided DomainMapping +func (cl *knServingClient) UpdateDomainMapping(ctx context.Context, domainMapping *servingv1beta1.DomainMapping) error { + _, err := cl.client.DomainMappings(cl.namespace).Update(ctx, domainMapping, v1.UpdateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return updateServingGvk(domainMapping) +} + +func (cl *knServingClient) UpdateDomainMappingWithRetry(ctx context.Context, name string, updateFunc DomainUpdateFunc, nrRetries int) error { + return updateDomainMappingWithRetry(ctx, cl, name, updateFunc, nrRetries) +} + +func updateDomainMappingWithRetry(ctx context.Context, cl KnServingClient, name string, updateFunc DomainUpdateFunc, nrRetries int) error { + b := config.DefaultRetry + b.Steps = nrRetries + err := retry.RetryOnConflict(b, func() error { + return updateDomain(ctx, cl, name, updateFunc) + }) + return err +} + +func updateDomain(ctx context.Context, c KnServingClient, name string, updateFunc DomainUpdateFunc) error { + sub, err := c.GetDomainMapping(ctx, name) + if err != nil { + return err + } + if sub.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't update domain mapping %s because it has been marked for deletion", name) + } + updatedSource, err := updateFunc(sub.DeepCopy()) + if err != nil { + return err + } + + return c.UpdateDomainMapping(ctx, updatedSource) +} + +// DeleteDomainMapping deletes DomainMapping by name +func (cl *knServingClient) DeleteDomainMapping(ctx context.Context, name string) error { + err := cl.client.DomainMappings(cl.namespace).Delete(ctx, name, v1.DeleteOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +// ListDomainMappings lists all DomainMappings +func (cl *knServingClient) ListDomainMappings(ctx context.Context) (*servingv1beta1.DomainMappingList, error) { + domainMappingList, err := cl.client.DomainMappings(cl.namespace).List(ctx, v1.ListOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + dmListNew := domainMappingList.DeepCopy() + err = updateServingGvk(dmListNew) + if err != nil { + return nil, err + } + dmListNew.Items = make([]servingv1beta1.DomainMapping, len(domainMappingList.Items)) + for idx, domainMapping := range domainMappingList.Items { + domainMappingClone := domainMapping.DeepCopy() + err := updateServingGvk(domainMappingClone) + if err != nil { + return nil, err + } + dmListNew.Items[idx] = *domainMappingClone + } + return dmListNew, nil +} + +func updateServingGvk(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, servingv1beta1.SchemeGroupVersion, scheme.Scheme) +} + +// DomainMappingBuilder is for building the domainMapping +type DomainMappingBuilder struct { + domainMapping *servingv1beta1.DomainMapping +} + +// NewDomainMappingBuilder for building domainMapping object +func NewDomainMappingBuilder(name string) *DomainMappingBuilder { + return &DomainMappingBuilder{domainMapping: &servingv1beta1.DomainMapping{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + }, + }} +} + +// Namespace for domainMapping builder +func (b *DomainMappingBuilder) Namespace(ns string) *DomainMappingBuilder { + b.domainMapping.Namespace = ns + return b +} + +// Reference for domainMapping builder +func (b *DomainMappingBuilder) Reference(reference duckv1.KReference) *DomainMappingBuilder { + b.domainMapping.Spec.Ref = reference + return b +} + +// TLS for domainMapping builder +func (b *DomainMappingBuilder) TLS(cert string) *DomainMappingBuilder { + if cert == "" { + return b + } + b.domainMapping.Spec.TLS = &servingv1beta1.SecretTLS{SecretName: cert} + return b +} + +// Build to return an instance of domainMapping object +func (b *DomainMappingBuilder) Build() *servingv1beta1.DomainMapping { + return b.domainMapping +} diff --git a/vendor/knative.dev/client-pkg/pkg/serving/v1beta1/client_mock.go b/vendor/knative.dev/client-pkg/pkg/serving/v1beta1/client_mock.go new file mode 100644 index 0000000000..470b956c1a --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/serving/v1beta1/client_mock.go @@ -0,0 +1,120 @@ +// 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 v1beta1 + +import ( + "context" + "testing" + + "knative.dev/client-pkg/pkg/util/mock" + servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1" +) + +// MockKnServingClient client mock +type MockKnServingClient struct { + t *testing.T + recorder *ServingRecorder +} + +// NewMockKnServiceClient returns a new mock instance which you need to record for +func NewMockKnServiceClient(t *testing.T, ns ...string) *MockKnServingClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnServingClient{ + t: t, + recorder: &ServingRecorder{mock.NewRecorder(t, namespace)}, + } +} + +// ServingRecorder recorder for service +type ServingRecorder struct { + r *mock.Recorder +} + +// Recorder returns the record instance +func (c *MockKnServingClient) Recorder() *ServingRecorder { + return c.recorder +} + +// Validate checks that every recorded method has been called +func (sr *ServingRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} + +// Namespace of this client +func (c *MockKnServingClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// GetDomainMapping mock function recorder +func (sr *ServingRecorder) GetDomainMapping(name interface{}, domainMapping *servingv1beta1.DomainMapping, err error) { + sr.r.Add("GetDomainMapping", []interface{}{name}, []interface{}{domainMapping, err}) +} + +// GetDomainMapping mock function +func (c *MockKnServingClient) GetDomainMapping(ctx context.Context, name string) (*servingv1beta1.DomainMapping, error) { + call := c.recorder.r.VerifyCall("GetDomainMapping", name) + return call.Result[0].(*servingv1beta1.DomainMapping), mock.ErrorOrNil(call.Result[1]) +} + +// CreateDomainMapping recorder function +func (sr *ServingRecorder) CreateDomainMapping(domainMapping interface{}, err error) { + sr.r.Add("CreateDomainMapping", []interface{}{domainMapping}, []interface{}{err}) +} + +// CreateDomainMapping mock function +func (c *MockKnServingClient) CreateDomainMapping(ctx context.Context, domainMapping *servingv1beta1.DomainMapping) error { + call := c.recorder.r.VerifyCall("CreateDomainMapping", domainMapping) + return mock.ErrorOrNil(call.Result[0]) +} + +// UpdateDomainMapping recorder function +func (sr *ServingRecorder) UpdateDomainMapping(domainMapping interface{}, err error) { + sr.r.Add("UpdateDomainMapping", []interface{}{domainMapping}, []interface{}{err}) +} + +// UpdateDomainMapping mock function +func (c *MockKnServingClient) UpdateDomainMapping(ctx context.Context, domainMapping *servingv1beta1.DomainMapping) error { + call := c.recorder.r.VerifyCall("UpdateDomainMapping", domainMapping) + return mock.ErrorOrNil(call.Result[0]) +} + +func (cl *MockKnServingClient) UpdateDomainMappingWithRetry(ctx context.Context, name string, updateFunc DomainUpdateFunc, nrRetries int) error { + return updateDomainMappingWithRetry(ctx, cl, name, updateFunc, nrRetries) +} + +// DeleteDomainMapping recorder function +func (sr *ServingRecorder) DeleteDomainMapping(name string, err error) { + sr.r.Add("DeleteDomainMapping", []interface{}{name}, []interface{}{err}) +} + +// DeleteDomainMapping mock function +func (c *MockKnServingClient) DeleteDomainMapping(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeleteDomainMapping", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListDomainMappings recorder function +func (sr *ServingRecorder) ListDomainMappings(domainMappingList *servingv1beta1.DomainMappingList, err error) { + sr.r.Add("ListDomainMappings", nil, []interface{}{domainMappingList, err}) +} + +// ListDomainMappings mock function +func (c *MockKnServingClient) ListDomainMappings(ctx context.Context) (*servingv1beta1.DomainMappingList, error) { + call := c.recorder.r.VerifyCall("ListDomainMappings") + return call.Result[0].(*servingv1beta1.DomainMappingList), mock.ErrorOrNil(call.Result[1]) +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1/apiserver_client.go b/vendor/knative.dev/client-pkg/pkg/sources/v1/apiserver_client.go new file mode 100644 index 0000000000..f84d3bcff4 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1/apiserver_client.go @@ -0,0 +1,218 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" + + v1 "knative.dev/eventing/pkg/apis/sources/v1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + clientv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +// KnAPIServerSourcesClient interface for working with ApiServer sources +type KnAPIServerSourcesClient interface { + + // Get an ApiServerSource by name + GetAPIServerSource(ctx context.Context, name string) (*v1.ApiServerSource, error) + + // Create an ApiServerSource by object + CreateAPIServerSource(ctx context.Context, apiSource *v1.ApiServerSource) error + + // Update an ApiServerSource by object + UpdateAPIServerSource(ctx context.Context, apiSource *v1.ApiServerSource) error + + // Delete an ApiServerSource by name + DeleteAPIServerSource(ctx context.Context, name string) error + + // List ApiServerSource + // TODO: Support list configs like in service list + ListAPIServerSource(ctx context.Context) (*v1.ApiServerSourceList, error) + + // Get namespace for this client + Namespace() string +} + +// knSourcesClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type apiServerSourcesClient struct { + client clientv1.ApiServerSourceInterface + namespace string +} + +// newKnAPIServerSourcesClient is to invoke Eventing Sources Client API to create object +func newKnAPIServerSourcesClient(client clientv1.ApiServerSourceInterface, namespace string) KnAPIServerSourcesClient { + return &apiServerSourcesClient{ + client: client, + namespace: namespace, + } +} + +// GetAPIServerSource returns apiSource object if present +func (c *apiServerSourcesClient) GetAPIServerSource(ctx context.Context, name string) (*v1.ApiServerSource, error) { + apiSource, err := c.client.Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + err = updateSourceGVK(apiSource) + if err != nil { + return nil, err + } + return apiSource, nil +} + +// CreateAPIServerSource is used to create an instance of ApiServerSource +func (c *apiServerSourcesClient) CreateAPIServerSource(ctx context.Context, apiSource *v1.ApiServerSource) error { + _, err := c.client.Create(ctx, apiSource, metav1.CreateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + + return nil +} + +// UpdateAPIServerSource is used to update an instance of ApiServerSource +func (c *apiServerSourcesClient) UpdateAPIServerSource(ctx context.Context, apiSource *v1.ApiServerSource) error { + _, err := c.client.Update(ctx, apiSource, metav1.UpdateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + + return nil +} + +// DeleteAPIServerSource is used to create an instance of ApiServerSource +func (c *apiServerSourcesClient) DeleteAPIServerSource(ctx context.Context, name string) error { + err := c.client.Delete(ctx, name, metav1.DeleteOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +// Return the client's namespace +func (c *apiServerSourcesClient) Namespace() string { + return c.namespace +} + +// ListAPIServerSource returns the available ApiServer type sources +func (c *apiServerSourcesClient) ListAPIServerSource(ctx context.Context) (*v1.ApiServerSourceList, error) { + sourceList, err := c.client.List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + + return updateAPIServerSourceListGVK(sourceList) +} + +func updateAPIServerSourceListGVK(sourceList *v1.ApiServerSourceList) (*v1.ApiServerSourceList, error) { + sourceListNew := sourceList.DeepCopy() + err := updateSourceGVK(sourceListNew) + if err != nil { + return nil, err + } + + sourceListNew.Items = make([]v1.ApiServerSource, len(sourceList.Items)) + for idx, source := range sourceList.Items { + sourceClone := source.DeepCopy() + err := updateSourceGVK(sourceClone) + if err != nil { + return nil, err + } + sourceListNew.Items[idx] = *sourceClone + } + return sourceListNew, nil +} + +func updateSourceGVK(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, v1.SchemeGroupVersion, scheme.Scheme) +} + +// APIServerSourceBuilder is for building the source +type APIServerSourceBuilder struct { + apiServerSource *v1.ApiServerSource +} + +// NewAPIServerSourceBuilder for building ApiServer source object +func NewAPIServerSourceBuilder(name string) *APIServerSourceBuilder { + return &APIServerSourceBuilder{apiServerSource: &v1.ApiServerSource{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }} +} + +// NewAPIServerSourceBuilderFromExisting for building the object from existing ApiServerSource object +func NewAPIServerSourceBuilderFromExisting(apiServerSource *v1.ApiServerSource) *APIServerSourceBuilder { + return &APIServerSourceBuilder{apiServerSource: apiServerSource.DeepCopy()} +} + +// Resources which should be streamed +func (b *APIServerSourceBuilder) Resources(resources []v1.APIVersionKindSelector) *APIServerSourceBuilder { + b.apiServerSource.Spec.Resources = resources + return b +} + +// ServiceAccount with which this source should operate +func (b *APIServerSourceBuilder) ServiceAccount(sa string) *APIServerSourceBuilder { + b.apiServerSource.Spec.ServiceAccountName = sa + return b +} + +// EventMode for whether to send resource 'Ref' or complete 'Resource' +func (b *APIServerSourceBuilder) EventMode(eventMode string) *APIServerSourceBuilder { + b.apiServerSource.Spec.EventMode = eventMode + return b +} + +// Sink or destination of the source +func (b *APIServerSourceBuilder) Sink(sink duckv1.Destination) *APIServerSourceBuilder { + b.apiServerSource.Spec.Sink = sink + return b +} + +// CloudEventOverrides adds given Cloud Event override extensions map to source spec +func (b *APIServerSourceBuilder) CloudEventOverrides(ceo map[string]string, toRemove []string) *APIServerSourceBuilder { + if ceo == nil && len(toRemove) == 0 { + return b + } + + ceOverrides := b.apiServerSource.Spec.CloudEventOverrides + if ceOverrides == nil { + ceOverrides = &duckv1.CloudEventOverrides{Extensions: map[string]string{}} + b.apiServerSource.Spec.CloudEventOverrides = ceOverrides + } + for k, v := range ceo { + ceOverrides.Extensions[k] = v + } + for _, r := range toRemove { + delete(ceOverrides.Extensions, r) + } + + return b +} + +// Build the ApiServerSource object +func (b *APIServerSourceBuilder) Build() *v1.ApiServerSource { + return b.apiServerSource +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1/apiserver_client_mock.go b/vendor/knative.dev/client-pkg/pkg/sources/v1/apiserver_client_mock.go new file mode 100644 index 0000000000..9fffb66bad --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1/apiserver_client_mock.go @@ -0,0 +1,120 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + "testing" + + v1 "knative.dev/eventing/pkg/apis/sources/v1" + + "knative.dev/client-pkg/pkg/util/mock" +) + +// MockKnAPIServerSourceClient for mocking the client +type MockKnAPIServerSourceClient struct { + t *testing.T + recorder *APIServerSourcesRecorder +} + +// NewMockKnAPIServerSourceClient returns a new mock instance which you need to record for +func NewMockKnAPIServerSourceClient(t *testing.T, ns ...string) *MockKnAPIServerSourceClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnAPIServerSourceClient{ + t: t, + recorder: &APIServerSourcesRecorder{mock.NewRecorder(t, namespace)}, + } +} + +// Ensure that the interface is implemented +var _ KnAPIServerSourcesClient = &MockKnAPIServerSourceClient{} + +// APIServerSourcesRecorder for recording actions on source +type APIServerSourcesRecorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnAPIServerSourceClient) Recorder() *APIServerSourcesRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnAPIServerSourceClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// GetAPIServerSource records a call for GetApiServerSource with the expected object or error. Either apiServerSource or err should be nil +func (sr *APIServerSourcesRecorder) GetAPIServerSource(name interface{}, apiServerSource *v1.ApiServerSource, err error) { + sr.r.Add("GetApiServerSource", []interface{}{name}, []interface{}{apiServerSource, err}) +} + +// GetAPIServerSource performs a previously recorded action, failing if non has been registered +func (c *MockKnAPIServerSourceClient) GetAPIServerSource(ctx context.Context, name string) (*v1.ApiServerSource, error) { + call := c.recorder.r.VerifyCall("GetApiServerSource", name) + return call.Result[0].(*v1.ApiServerSource), mock.ErrorOrNil(call.Result[1]) +} + +// CreateAPIServerSource records a call for CreateApiServerSource with the expected error +func (sr *APIServerSourcesRecorder) CreateAPIServerSource(apiServerSource interface{}, err error) { + sr.r.Add("CreateApiServerSource", []interface{}{apiServerSource}, []interface{}{err}) +} + +// CreateAPIServerSource performs a previously recorded action, failing if non has been registered +func (c *MockKnAPIServerSourceClient) CreateAPIServerSource(ctx context.Context, apiServerSource *v1.ApiServerSource) error { + call := c.recorder.r.VerifyCall("CreateApiServerSource", apiServerSource) + return mock.ErrorOrNil(call.Result[0]) +} + +// UpdateAPIServerSource records a call for UpdateAPIServerSource with the expected error (nil if none) +func (sr *APIServerSourcesRecorder) UpdateAPIServerSource(apiServerSource interface{}, err error) { + sr.r.Add("UpdateAPIServerSource", []interface{}{apiServerSource}, []interface{}{err}) +} + +// UpdateAPIServerSource performs a previously recorded action, failing if non has been registered +func (c *MockKnAPIServerSourceClient) UpdateAPIServerSource(ctx context.Context, apiServerSource *v1.ApiServerSource) error { + call := c.recorder.r.VerifyCall("UpdateAPIServerSource", apiServerSource) + return mock.ErrorOrNil(call.Result[0]) +} + +// DeleteAPIServerSource records a call for DeleteAPIServerSource with the expected error (nil if none) +func (sr *APIServerSourcesRecorder) DeleteAPIServerSource(name interface{}, err error) { + sr.r.Add("DeleteAPIServerSource", []interface{}{name}, []interface{}{err}) +} + +// DeleteAPIServerSource performs a previously recorded action, failing if non has been registered +func (c *MockKnAPIServerSourceClient) DeleteAPIServerSource(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeleteAPIServerSource", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListAPIServerSource records a call for ListAPIServerSource with the expected error (nil if none) +func (sr *APIServerSourcesRecorder) ListAPIServerSource(apiJobSourceList *v1.ApiServerSourceList, err error) { + sr.r.Add("ListAPIServerSource", []interface{}{}, []interface{}{apiJobSourceList, err}) +} + +// ListAPIServerSource performs a previously recorded action, failing if non has been registered +func (c *MockKnAPIServerSourceClient) ListAPIServerSource(context.Context) (*v1.ApiServerSourceList, error) { + call := c.recorder.r.VerifyCall("ListAPIServerSource") + return call.Result[0].(*v1.ApiServerSourceList), mock.ErrorOrNil(call.Result[1]) +} + +// Validate validates whether every recorded action has been called +func (sr *APIServerSourcesRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1/binding_client.go b/vendor/knative.dev/client-pkg/pkg/sources/v1/binding_client.go new file mode 100644 index 0000000000..fd197dfe96 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1/binding_client.go @@ -0,0 +1,277 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + "fmt" + + apisv1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + v1 "knative.dev/eventing/pkg/apis/sources/v1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + clientv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1" + duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/pkg/tracker" + + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" +) + +// KnSinkBindingClient to Eventing Sources. All methods are relative to the +// namespace specified during construction +type KnSinkBindingClient interface { + // Namespace in which this client is operating for + Namespace() string + // CreateSinkBinding is used to create an instance of binding + CreateSinkBinding(ctx context.Context, binding *v1.SinkBinding) error + // DeleteSinkBinding is used to delete an instance of binding + DeleteSinkBinding(ctx context.Context, name string) error + // GetSinkBinding is used to get an instance of binding + GetSinkBinding(ctx context.Context, name string) (*v1.SinkBinding, error) + // ListSinkBinding returns list of binding CRDs + ListSinkBindings(ctx context.Context) (*v1.SinkBindingList, error) + // UpdateSinkBinding is used to update an instance of binding + UpdateSinkBinding(ctx context.Context, binding *v1.SinkBinding) error +} + +// KnSinkBindingClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type knBindingClient struct { + client clientv1.SinkBindingInterface + namespace string +} + +// NewKnSourcesClient is to invoke Eventing Sources Client API to create object +func newKnSinkBindingClient(client clientv1.SinkBindingInterface, namespace string) KnSinkBindingClient { + return &knBindingClient{ + client: client, + namespace: namespace, + } +} + +// CreateSinkBinding is used to create an instance of binding +func (c *knBindingClient) CreateSinkBinding(ctx context.Context, binding *v1.SinkBinding) error { + _, err := c.client.Create(ctx, binding, metav1.CreateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +// DeleteSinkBinding is used to delete an instance of binding +func (c *knBindingClient) DeleteSinkBinding(ctx context.Context, name string) error { + err := c.client.Delete(ctx, name, apisv1.DeleteOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +// GetSinkBinding is used to get an instance of binding +func (c *knBindingClient) GetSinkBinding(ctx context.Context, name string) (*v1.SinkBinding, error) { + binding, err := c.client.Get(ctx, name, apisv1.GetOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + err = updateSinkBindingGvk(binding) + if err != nil { + return nil, err + } + return binding, nil +} + +func (c *knBindingClient) ListSinkBindings(ctx context.Context) (*v1.SinkBindingList, error) { + bindingList, err := c.client.List(ctx, apisv1.ListOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + bindingListNew := bindingList.DeepCopy() + err = updateSinkBindingGvk(bindingListNew) + if err != nil { + return nil, err + } + + bindingListNew.Items = make([]v1.SinkBinding, len(bindingList.Items)) + for idx, binding := range bindingList.Items { + bindingClone := binding.DeepCopy() + err := updateSinkBindingGvk(bindingClone) + if err != nil { + return nil, err + } + bindingListNew.Items[idx] = *bindingClone + } + return bindingListNew, nil +} + +// CreateSinkBinding is used to create an instance of binding +func (c *knBindingClient) UpdateSinkBinding(ctx context.Context, binding *v1.SinkBinding) error { + _, err := c.client.Update(ctx, binding, metav1.UpdateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +// Return the client's namespace +func (c *knBindingClient) Namespace() string { + return c.namespace +} + +// update with the v1 group + version +func updateSinkBindingGvk(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, v1.SchemeGroupVersion, scheme.Scheme) +} + +// SinkBindingBuilder is for building the binding +type SinkBindingBuilder struct { + binding *v1.SinkBinding + sGvk *schema.GroupVersionKind + sName string + sLabelSelector map[string]string + sNamespace string + + // When set directly: + subject *tracker.Reference +} + +// NewSinkBindingBuilder for building binding object +func NewSinkBindingBuilder(name string) *SinkBindingBuilder { + return &SinkBindingBuilder{binding: &v1.SinkBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }} +} + +// NewSinkBindingBuilderFromExisting for building the object from existing SinkBinding object +func NewSinkBindingBuilderFromExisting(binding *v1.SinkBinding) *SinkBindingBuilder { + return &SinkBindingBuilder{binding: binding.DeepCopy()} +} + +// Namespace for this binding +func (b *SinkBindingBuilder) Namespace(ns string) *SinkBindingBuilder { + b.binding.Namespace = ns + return b +} + +// Subscriber for the binding to send to (it's a Sink actually) +func (b *SinkBindingBuilder) Subject(subject *tracker.Reference) *SinkBindingBuilder { + b.subject = subject + return b +} + +// Add a GVK of the subject +func (b *SinkBindingBuilder) SubjectGVK(gvk *schema.GroupVersionKind) *SinkBindingBuilder { + b.sGvk = gvk + return b +} + +// Add a subject name for building up the name +func (b *SinkBindingBuilder) SubjectName(name string) *SinkBindingBuilder { + b.sName = name + return b +} + +// Add a subject namespace for building up the name +func (b *SinkBindingBuilder) SubjectNamespace(ns string) *SinkBindingBuilder { + b.sNamespace = ns + return b +} + +// Add a label match part for building up the subject +func (b *SinkBindingBuilder) AddSubjectMatchLabel(labelKey, labelValue string) *SinkBindingBuilder { + if b.sLabelSelector == nil { + b.sLabelSelector = map[string]string{} + } + b.sLabelSelector[labelKey] = labelValue + return b +} + +// Broker to set the broker of binding object +func (b *SinkBindingBuilder) Sink(sink *duckv1.Destination) *SinkBindingBuilder { + b.binding.Spec.Sink = *sink + return b +} + +// CloudEventOverrides adds given Cloud Event override extensions map to source spec +func (b *SinkBindingBuilder) CloudEventOverrides(ceo map[string]string, toRemove []string) *SinkBindingBuilder { + if ceo == nil && len(toRemove) == 0 { + return b + } + + ceOverrides := b.binding.Spec.CloudEventOverrides + if ceOverrides == nil { + ceOverrides = &duckv1.CloudEventOverrides{Extensions: map[string]string{}} + b.binding.Spec.CloudEventOverrides = ceOverrides + } + for k, v := range ceo { + ceOverrides.Extensions[k] = v + } + for _, r := range toRemove { + delete(ceOverrides.Extensions, r) + } + + return b +} + +// Build to return an instance of binding object +func (b *SinkBindingBuilder) Build() (*v1.SinkBinding, error) { + // If set directly, return the sink binding directly + if b.subject != nil { + b.binding.Spec.Subject = *b.subject + return b.binding, nil + } + + if b.sGvk == nil && b.sName == "" && b.sLabelSelector == nil { + // None of the subject methods has been called, so no subject build up + return b.binding, nil + } + + // Otherwise, validate and build up the subject + if b.sGvk == nil { + return nil, fmt.Errorf("no group-version-kind provided for creating binding %s", b.binding.Name) + } + + if b.sName != "" && b.sLabelSelector != nil { + return nil, fmt.Errorf("either a subject name or label selector can be used for creating binding %s, but not both (subject name: %s, label selector: %v", b.binding.Name, b.sName, b.sLabelSelector) + } + + subject := b.prepareBaseSubject() + if b.sName != "" { + subject.Name = b.sName + } else { + subject.Selector = &metav1.LabelSelector{ + MatchLabels: b.sLabelSelector, + } + } + + b.binding.Spec.Subject = subject + return b.binding, nil +} + +func (b *SinkBindingBuilder) prepareBaseSubject() tracker.Reference { + subject := tracker.Reference{ + APIVersion: b.sGvk.GroupVersion().String(), + Kind: b.sGvk.Kind, + } + if b.sNamespace != "" { + subject.Namespace = b.sNamespace + } + return subject +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1/binding_client_mock.go b/vendor/knative.dev/client-pkg/pkg/sources/v1/binding_client_mock.go new file mode 100644 index 0000000000..ab79482364 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1/binding_client_mock.go @@ -0,0 +1,120 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "context" + "testing" + + v1 "knative.dev/eventing/pkg/apis/sources/v1" + + "knative.dev/client-pkg/pkg/util/mock" +) + +// MockKnSinkBindingClient is a combine of test object and recorder +type MockKnSinkBindingClient struct { + t *testing.T + recorder *EventingRecorder +} + +// NewMockKnSinkBindingClient returns a new mock instance which you need to record for +func NewMockKnSinkBindingClient(t *testing.T, ns ...string) *MockKnSinkBindingClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnSinkBindingClient{ + t: t, + recorder: &EventingRecorder{mock.NewRecorder(t, namespace)}, + } +} + +// Ensure that the interface is implemented +var _ KnSinkBindingClient = &MockKnSinkBindingClient{} + +// EventingRecorder is recorder for eventing objects +type EventingRecorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnSinkBindingClient) Recorder() *EventingRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnSinkBindingClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// CreateSinkBinding records a call for CreateSinkBinding with the expected error +func (sr *EventingRecorder) CreateSinkBinding(binding interface{}, err error) { + sr.r.Add("CreateSinkBinding", []interface{}{binding}, []interface{}{err}) +} + +// CreateSinkBinding performs a previously recorded action +func (c *MockKnSinkBindingClient) CreateSinkBinding(ctx context.Context, binding *v1.SinkBinding) error { + call := c.recorder.r.VerifyCall("CreateSinkBinding", binding) + return mock.ErrorOrNil(call.Result[0]) +} + +// GetSinkBinding records a call for GetSinkBinding with the expected object or error. Either binding or err should be nil +func (sr *EventingRecorder) GetSinkBinding(name interface{}, binding *v1.SinkBinding, err error) { + sr.r.Add("GetSinkBinding", []interface{}{name}, []interface{}{binding, err}) +} + +// GetSinkBinding performs a previously recorded action +func (c *MockKnSinkBindingClient) GetSinkBinding(ctx context.Context, name string) (*v1.SinkBinding, error) { + call := c.recorder.r.VerifyCall("GetSinkBinding", name) + return call.Result[0].(*v1.SinkBinding), mock.ErrorOrNil(call.Result[1]) +} + +// DeleteSinkBinding records a call for DeleteSinkBinding with the expected error (nil if none) +func (sr *EventingRecorder) DeleteSinkBinding(name interface{}, err error) { + sr.r.Add("DeleteSinkBinding", []interface{}{name}, []interface{}{err}) +} + +// DeleteSinkBinding performs a previously recorded action, failing if non has been registered +func (c *MockKnSinkBindingClient) DeleteSinkBinding(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeleteSinkBinding", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListSinkBindings records a call for ListSinkBindings with the expected result and error (nil if none) +func (sr *EventingRecorder) ListSinkBindings(bindingList *v1.SinkBindingList, err error) { + sr.r.Add("ListSinkBindings", nil, []interface{}{bindingList, err}) +} + +// ListSinkBindings performs a previously recorded action +func (c *MockKnSinkBindingClient) ListSinkBindings(context.Context) (*v1.SinkBindingList, error) { + call := c.recorder.r.VerifyCall("ListSinkBindings") + return call.Result[0].(*v1.SinkBindingList), mock.ErrorOrNil(call.Result[1]) +} + +// UpdateSinkBinding records a call for ListSinkBindings with the expected result and error (nil if none) +func (sr *EventingRecorder) UpdateSinkBinding(binding interface{}, err error) { + sr.r.Add("UpdateSinkBinding", []interface{}{binding}, []interface{}{err}) +} + +// UpdateSinkBinding performs a previously recorded action +func (c *MockKnSinkBindingClient) UpdateSinkBinding(ctx context.Context, binding *v1.SinkBinding) error { + call := c.recorder.r.VerifyCall("UpdateSinkBinding") + return mock.ErrorOrNil(call.Result[0]) +} + +// Validate validates whether every recorded action has been called +func (sr *EventingRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1/client.go b/vendor/knative.dev/client-pkg/pkg/sources/v1/client.go new file mode 100644 index 0000000000..dd6ee74172 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1/client.go @@ -0,0 +1,63 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + clientv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1" +) + +// KnSinkBindingClient to Eventing Sources. All methods are relative to the +// namespace specified during construction +type KnSourcesClient interface { + // Get client for sink binding sources + SinkBindingClient() KnSinkBindingClient + + // Get client for ApiServer sources + APIServerSourcesClient() KnAPIServerSourcesClient + + // Get client for container sources + ContainerSourcesClient() KnContainerSourcesClient +} + +// sourcesClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type sourcesClient struct { + client clientv1.SourcesV1Interface + namespace string +} + +// NewKnSourcesClient for managing all eventing built-in sources +func NewKnSourcesClient(client clientv1.SourcesV1Interface, namespace string) KnSourcesClient { + return &sourcesClient{ + client: client, + namespace: namespace, + } +} + +// ApiServerSourcesClient for dealing with ApiServer sources +func (c *sourcesClient) SinkBindingClient() KnSinkBindingClient { + return newKnSinkBindingClient(c.client.SinkBindings(c.namespace), c.namespace) +} + +// ApiServerSourcesClient for dealing with ApiServer sources +func (c *sourcesClient) APIServerSourcesClient() KnAPIServerSourcesClient { + return newKnAPIServerSourcesClient(c.client.ApiServerSources(c.namespace), c.namespace) +} + +// ApiServerSourcesClient for dealing with ApiServer sources +func (c *sourcesClient) ContainerSourcesClient() KnContainerSourcesClient { + return newKnContainerSourcesClient(c.client.ContainerSources(c.namespace), c.namespace) +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1/container_client.go b/vendor/knative.dev/client-pkg/pkg/sources/v1/container_client.go new file mode 100644 index 0000000000..7aaef5118f --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1/container_client.go @@ -0,0 +1,215 @@ +/* +Copyright 2020 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 v1 + +import ( + "context" + "fmt" + + "knative.dev/client-pkg/pkg/config" + + "k8s.io/client-go/util/retry" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + knerrors "knative.dev/client-pkg/pkg/errors" + "knative.dev/client-pkg/pkg/util" + v1 "knative.dev/eventing/pkg/apis/sources/v1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + clientv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +type ContainerUpdateFunc func(source *v1.ContainerSource) (*v1.ContainerSource, error) + +// KnContainerSourcesClient interface for working with ApiServer sources +type KnContainerSourcesClient interface { + + // Get an ContainerSource by name + GetContainerSource(ctx context.Context, name string) (*v1.ContainerSource, error) + + // Create an ContainerSource by object + CreateContainerSource(ctx context.Context, containerSrc *v1.ContainerSource) error + + // Update an ContainerSource by object + UpdateContainerSource(ctx context.Context, containerSrc *v1.ContainerSource) error + + // Update an ContainerSource by object and retry on conflict + UpdateContainerSourceWithRetry(ctx context.Context, name string, updateFunc ContainerUpdateFunc, nrRetries int) error + + // Delete an ContainerSource by name + DeleteContainerSource(name string, ctx context.Context) error + + // List ContainerSource + ListContainerSources(ctx context.Context) (*v1.ContainerSourceList, error) + + // Get namespace for this client + Namespace() string +} + +// knSourcesClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type containerSourcesClient struct { + client clientv1.ContainerSourceInterface + namespace string +} + +func (c *containerSourcesClient) UpdateContainerSourceWithRetry(ctx context.Context, name string, updateFunc ContainerUpdateFunc, nrRetries int) error { + return updateContainerSourceWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +func updateContainerSourceWithRetry(ctx context.Context, c KnContainerSourcesClient, name string, updateFunc ContainerUpdateFunc, nrRetries int) error { + b := config.DefaultRetry + b.Steps = nrRetries + err := retry.RetryOnConflict(b, func() error { + return updateContainerSource(ctx, c, name, updateFunc) + }) + return err +} + +func updateContainerSource(ctx context.Context, c KnContainerSourcesClient, name string, updateFunc ContainerUpdateFunc) error { + source, err := c.GetContainerSource(ctx, name) + if err != nil { + return err + } + if source.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't update container source %s because it has been marked for deletion", name) + } + updatedSource, err := updateFunc(source.DeepCopy()) + if err != nil { + return err + } + + return c.UpdateContainerSource(ctx, updatedSource) +} + +// newKnContainerSourcesClient is to invoke Eventing Sources Client API to create object +func newKnContainerSourcesClient(client clientv1.ContainerSourceInterface, namespace string) KnContainerSourcesClient { + return &containerSourcesClient{ + client: client, + namespace: namespace, + } +} + +// GetContainerSource returns containerSrc object if present +func (c *containerSourcesClient) GetContainerSource(ctx context.Context, name string) (*v1.ContainerSource, error) { + containerSrc, err := c.client.Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + + return containerSrc, nil +} + +// CreateContainerSource is used to create an instance of ContainerSource +func (c *containerSourcesClient) CreateContainerSource(ctx context.Context, containerSrc *v1.ContainerSource) error { + _, err := c.client.Create(ctx, containerSrc, metav1.CreateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + + return nil +} + +// UpdateContainerSource is used to update an instance of ContainerSource +func (c *containerSourcesClient) UpdateContainerSource(ctx context.Context, containerSrc *v1.ContainerSource) error { + _, err := c.client.Update(ctx, containerSrc, metav1.UpdateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + + return nil +} + +// DeleteContainerSource is used to create an instance of ContainerSource +func (c *containerSourcesClient) DeleteContainerSource(name string, ctx context.Context) error { + return c.client.Delete(ctx, name, metav1.DeleteOptions{}) +} + +// Return the client's namespace +func (c *containerSourcesClient) Namespace() string { + return c.namespace +} + +// ListContainerSource returns the available container sources +func (c *containerSourcesClient) ListContainerSources(ctx context.Context) (*v1.ContainerSourceList, error) { + sourceList, err := c.client.List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + + containerListNew := sourceList.DeepCopy() + err = updateContainerSourceGvk(containerListNew) + if err != nil { + return nil, err + } + + containerListNew.Items = make([]v1.ContainerSource, len(sourceList.Items)) + for idx, binding := range sourceList.Items { + bindingClone := binding.DeepCopy() + err := updateSinkBindingGvk(bindingClone) + if err != nil { + return nil, err + } + containerListNew.Items[idx] = *bindingClone + } + + return containerListNew, nil +} + +// update with the v1 group + version +func updateContainerSourceGvk(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, v1.SchemeGroupVersion, scheme.Scheme) +} + +// ContainerSourceBuilder is for building the source +type ContainerSourceBuilder struct { + ContainerSource *v1.ContainerSource +} + +// NewContainerSourceBuilder for building Container source object +func NewContainerSourceBuilder(name string) *ContainerSourceBuilder { + return &ContainerSourceBuilder{ContainerSource: &v1.ContainerSource{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }} +} + +// NewContainerSourceBuilderFromExisting for building the object from existing ContainerSource object +func NewContainerSourceBuilderFromExisting(ContainerSource *v1.ContainerSource) *ContainerSourceBuilder { + return &ContainerSourceBuilder{ContainerSource: ContainerSource.DeepCopy()} +} + +// Sink or destination of the source +func (b *ContainerSourceBuilder) Sink(sink duckv1.Destination) *ContainerSourceBuilder { + b.ContainerSource.Spec.Sink = sink + return b +} + +// Build the ContainerSource object +func (b *ContainerSourceBuilder) Build() *v1.ContainerSource { + return b.ContainerSource +} + +// PodSpec defines the PodSpec +func (b *ContainerSourceBuilder) PodSpec(podSpec corev1.PodSpec) *ContainerSourceBuilder { + b.ContainerSource.Spec.Template.Spec = podSpec + return b +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1/container_client_mock.go b/vendor/knative.dev/client-pkg/pkg/sources/v1/container_client_mock.go new file mode 100644 index 0000000000..59416e61d2 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1/container_client_mock.go @@ -0,0 +1,127 @@ +/* +Copyright 2020 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 v1 + +import ( + "context" + "testing" + + "knative.dev/client-pkg/pkg/util/mock" + v1 "knative.dev/eventing/pkg/apis/sources/v1" +) + +// MockKnContainerSourceClient is a combine of test object and recorder +type MockKnContainerSourceClient struct { + t *testing.T + recorder *ConainterSourceRecorder + namespace string +} + +// NewMockKnContainerSourceClient returns a new mock instance which you need to record for +func NewMockKnContainerSourceClient(t *testing.T, ns ...string) *MockKnContainerSourceClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnContainerSourceClient{ + t: t, + recorder: &ConainterSourceRecorder{mock.NewRecorder(t, namespace)}, + namespace: namespace, + } +} + +// Ensure that the interface is implemented +var _ KnContainerSourcesClient = &MockKnContainerSourceClient{} + +// ConainterSourceRecorder is recorder for eventing objects +type ConainterSourceRecorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnContainerSourceClient) Recorder() *ConainterSourceRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnContainerSourceClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// CreateContainerSource records a call for CreateContainerSource with the expected error +func (sr *ConainterSourceRecorder) CreateContainerSource(binding interface{}, err error) { + sr.r.Add("CreateContainerSource", []interface{}{binding}, []interface{}{err}) +} + +// CreateContainerSource performs a previously recorded action +func (c *MockKnContainerSourceClient) CreateContainerSource(ctx context.Context, binding *v1.ContainerSource) error { + call := c.recorder.r.VerifyCall("CreateContainerSource", binding) + return mock.ErrorOrNil(call.Result[0]) +} + +// GetContainerSource records a call for GetContainerSource with the expected object or error. Either binding or err should be nil +func (sr *ConainterSourceRecorder) GetContainerSource(name interface{}, binding *v1.ContainerSource, err error) { + sr.r.Add("GetContainerSource", []interface{}{name}, []interface{}{binding, err}) +} + +// GetContainerSource performs a previously recorded action +func (c *MockKnContainerSourceClient) GetContainerSource(ctx context.Context, name string) (*v1.ContainerSource, error) { + call := c.recorder.r.VerifyCall("GetContainerSource", name) + return call.Result[0].(*v1.ContainerSource), mock.ErrorOrNil(call.Result[1]) +} + +// DeleteContainerSource records a call for DeleteContainerSource with the expected error (nil if none) +func (sr *ConainterSourceRecorder) DeleteContainerSource(name interface{}, err error) { + sr.r.Add("DeleteContainerSource", []interface{}{name}, []interface{}{err}) +} + +// DeleteContainerSource performs a previously recorded action, failing if non has been registered +func (c *MockKnContainerSourceClient) DeleteContainerSource(name string, ctx context.Context) error { + call := c.recorder.r.VerifyCall("DeleteContainerSource", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListContainerSources records a call for ListContainerSources with the expected result and error (nil if none) +func (sr *ConainterSourceRecorder) ListContainerSources(bindingList *v1.ContainerSourceList, err error) { + sr.r.Add("ListContainerSources", nil, []interface{}{bindingList, err}) +} + +// ListContainerSources performs a previously recorded action +func (c *MockKnContainerSourceClient) ListContainerSources(context.Context) (*v1.ContainerSourceList, error) { + call := c.recorder.r.VerifyCall("ListContainerSources") + return call.Result[0].(*v1.ContainerSourceList), mock.ErrorOrNil(call.Result[1]) +} + +// UpdateContainerSource records a call for ListContainerSources with the expected result and error (nil if none) +func (sr *ConainterSourceRecorder) UpdateContainerSource(binding interface{}, err error) { + sr.r.Add("UpdateContainerSource", []interface{}{binding}, []interface{}{err}) +} + +// UpdateContainerSource performs a previously recorded action +func (c *MockKnContainerSourceClient) UpdateContainerSource(ctx context.Context, containerSrc *v1.ContainerSource) error { + call := c.recorder.r.VerifyCall("UpdateContainerSource") + return mock.ErrorOrNil(call.Result[0]) +} + +func (c *MockKnContainerSourceClient) UpdateContainerSourceWithRetry(ctx context.Context, name string, updateFunc ContainerUpdateFunc, nrRetries int) error { + return updateContainerSourceWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +// Validate validates whether every recorded action has been called +func (sr *ConainterSourceRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/client.go b/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/client.go new file mode 100644 index 0000000000..0a9f37d8a9 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/client.go @@ -0,0 +1,47 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1beta2 + +import ( + clientv1beta2 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1beta2" +) + +// KnSinkBindingClient to Eventing Sources. All methods are relative to the +// namespace specified during construction +type KnSourcesClient interface { + // Get client for Ping sources + PingSourcesClient() KnPingSourcesClient +} + +// sourcesClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type sourcesClient struct { + client clientv1beta2.SourcesV1beta2Interface + namespace string +} + +// NewKnSourcesClient for managing all eventing built-in sources +func NewKnSourcesClient(client clientv1beta2.SourcesV1beta2Interface, namespace string) KnSourcesClient { + return &sourcesClient{ + client: client, + namespace: namespace, + } +} + +// Get the client for dealing with Ping sources +func (c *sourcesClient) PingSourcesClient() KnPingSourcesClient { + return newKnPingSourcesClient(c.client.PingSources(c.namespace), c.namespace) +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/ping_client.go b/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/ping_client.go new file mode 100644 index 0000000000..2d0e1e94ba --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/ping_client.go @@ -0,0 +1,249 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1beta2 + +import ( + "context" + "fmt" + + "knative.dev/client-pkg/pkg/config" + + "k8s.io/client-go/util/retry" + + "k8s.io/apimachinery/pkg/runtime" + "knative.dev/client-pkg/pkg/util" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + + knerrors "knative.dev/client-pkg/pkg/errors" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" + + clientv1beta2 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1beta2" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +type PingSourceUpdateFunc func(origSource *sourcesv1beta2.PingSource) (*sourcesv1beta2.PingSource, error) + +// Interface for interacting with a Ping source +type KnPingSourcesClient interface { + + // GetPingSource fetches a Ping source by its name + GetPingSource(ctx context.Context, name string) (*sourcesv1beta2.PingSource, error) + + // CreatePingSource creates a Ping source + CreatePingSource(ctx context.Context, pingSource *sourcesv1beta2.PingSource) error + + // UpdatePingSource updates a Ping source + UpdatePingSource(ctx context.Context, pingSource *sourcesv1beta2.PingSource) error + + // UpdatePingSourceWithRetry updates a Ping source and retries on conflict + UpdatePingSourceWithRetry(ctx context.Context, name string, updateFunc PingSourceUpdateFunc, nrRetries int) error + + // DeletePingSource deletes a Ping source + DeletePingSource(ctx context.Context, name string) error + + // ListPingSource lists all Ping sources + // TODO: Support list configs like in service list + ListPingSource(ctx context.Context) (*sourcesv1beta2.PingSourceList, error) + + // Get namespace for this source + Namespace() string +} + +// knSourcesClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type pingSourcesClient struct { + client clientv1beta2.PingSourceInterface + namespace string +} + +// NewKnSourcesClient is to invoke Eventing Sources Client API to create object +func newKnPingSourcesClient(client clientv1beta2.PingSourceInterface, namespace string) KnPingSourcesClient { + return &pingSourcesClient{ + client: client, + namespace: namespace, + } +} + +// Get the namespace for which this client has been created +func (c *pingSourcesClient) Namespace() string { + return c.namespace +} + +func (c *pingSourcesClient) CreatePingSource(ctx context.Context, pingsource *sourcesv1beta2.PingSource) error { + if pingsource.Spec.Sink.Ref == nil && pingsource.Spec.Sink.URI == nil { + return fmt.Errorf("a sink is required for creating a source") + } + _, err := c.client.Create(ctx, pingsource, metav1.CreateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +func (c *pingSourcesClient) UpdatePingSource(ctx context.Context, pingSource *sourcesv1beta2.PingSource) error { + _, err := c.client.Update(ctx, pingSource, metav1.UpdateOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +func (c *pingSourcesClient) UpdatePingSourceWithRetry(ctx context.Context, name string, updateFunc PingSourceUpdateFunc, nrRetries int) error { + return updatePingSourceWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +func updatePingSourceWithRetry(ctx context.Context, c KnPingSourcesClient, name string, updateFunc PingSourceUpdateFunc, nrRetries int) error { + b := config.DefaultRetry + b.Steps = nrRetries + err := retry.RetryOnConflict(b, func() error { + return updatePingSource(ctx, c, name, updateFunc) + }) + return err +} + +func updatePingSource(ctx context.Context, c KnPingSourcesClient, name string, updateFunc PingSourceUpdateFunc) error { + source, err := c.GetPingSource(ctx, name) + if err != nil { + return err + } + if source.GetDeletionTimestamp() != nil { + return fmt.Errorf("can't update ping source %s because it has been marked for deletion", name) + } + updatedSource, err := updateFunc(source.DeepCopy()) + if err != nil { + return err + } + + return c.UpdatePingSource(ctx, updatedSource) +} + +func (c *pingSourcesClient) DeletePingSource(ctx context.Context, name string) error { + err := c.client.Delete(ctx, name, metav1.DeleteOptions{}) + if err != nil { + return knerrors.GetError(err) + } + return nil +} + +func (c *pingSourcesClient) GetPingSource(ctx context.Context, name string) (*sourcesv1beta2.PingSource, error) { + source, err := c.client.Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + err = updateSourceGVK(source) + if err != nil { + return nil, err + } + return source, nil +} + +// ListPingSource returns the available Ping sources +func (c *pingSourcesClient) ListPingSource(ctx context.Context) (*sourcesv1beta2.PingSourceList, error) { + sourceList, err := c.client.List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, knerrors.GetError(err) + } + + return updatePingSourceListGVK(sourceList) +} + +func updateSourceGVK(obj runtime.Object) error { + return util.UpdateGroupVersionKindWithScheme(obj, sourcesv1beta2.SchemeGroupVersion, scheme.Scheme) +} + +func updatePingSourceListGVK(sourceList *sourcesv1beta2.PingSourceList) (*sourcesv1beta2.PingSourceList, error) { + sourceListNew := sourceList.DeepCopy() + err := updateSourceGVK(sourceListNew) + if err != nil { + return nil, err + } + + sourceListNew.Items = make([]sourcesv1beta2.PingSource, len(sourceList.Items)) + for idx, source := range sourceList.Items { + sourceClone := source.DeepCopy() + err := updateSourceGVK(sourceClone) + if err != nil { + return nil, err + } + sourceListNew.Items[idx] = *sourceClone + } + return sourceListNew, nil +} + +// Builder for building up Ping sources + +type PingSourceBuilder struct { + pingSource *sourcesv1beta2.PingSource +} + +func NewPingSourceBuilder(name string) *PingSourceBuilder { + return &PingSourceBuilder{pingSource: &sourcesv1beta2.PingSource{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }} +} + +func NewPingSourceBuilderFromExisting(pingsource *sourcesv1beta2.PingSource) *PingSourceBuilder { + return &PingSourceBuilder{pingSource: pingsource.DeepCopy()} +} + +func (b *PingSourceBuilder) Schedule(schedule string) *PingSourceBuilder { + b.pingSource.Spec.Schedule = schedule + return b +} + +func (b *PingSourceBuilder) Data(data string) *PingSourceBuilder { + b.pingSource.Spec.Data = data + return b +} + +func (b *PingSourceBuilder) DataBase64(data string) *PingSourceBuilder { + b.pingSource.Spec.DataBase64 = data + return b +} + +func (b *PingSourceBuilder) Sink(sink duckv1.Destination) *PingSourceBuilder { + b.pingSource.Spec.Sink = sink + return b +} + +// CloudEventOverrides adds given Cloud Event override extensions map to source spec +func (b *PingSourceBuilder) CloudEventOverrides(ceo map[string]string, toRemove []string) *PingSourceBuilder { + if ceo == nil && len(toRemove) == 0 { + return b + } + + ceOverrides := b.pingSource.Spec.CloudEventOverrides + if ceOverrides == nil { + ceOverrides = &duckv1.CloudEventOverrides{Extensions: map[string]string{}} + b.pingSource.Spec.CloudEventOverrides = ceOverrides + } + for k, v := range ceo { + ceOverrides.Extensions[k] = v + } + for _, r := range toRemove { + delete(ceOverrides.Extensions, r) + } + + return b +} + +func (b *PingSourceBuilder) Build() *sourcesv1beta2.PingSource { + return b.pingSource +} diff --git a/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/ping_client_mock.go b/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/ping_client_mock.go new file mode 100644 index 0000000000..42623f0369 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/sources/v1beta2/ping_client_mock.go @@ -0,0 +1,122 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1beta2 + +import ( + "context" + "testing" + + "knative.dev/client-pkg/pkg/util/mock" + sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" +) + +type MockKnPingSourceClient struct { + t *testing.T + recorder *PingSourcesRecorder +} + +// NewMockKnPingSourceClient returns a new mock instance which you need to record for +func NewMockKnPingSourceClient(t *testing.T, ns ...string) *MockKnPingSourceClient { + namespace := "default" + if len(ns) > 0 { + namespace = ns[0] + } + return &MockKnPingSourceClient{ + t: t, + recorder: &PingSourcesRecorder{mock.NewRecorder(t, namespace)}, + } +} + +// Ensure that the interface is implemented +var _ KnPingSourcesClient = &MockKnPingSourceClient{} + +// recorder for service +type PingSourcesRecorder struct { + r *mock.Recorder +} + +// Recorder returns the recorder for registering API calls +func (c *MockKnPingSourceClient) Recorder() *PingSourcesRecorder { + return c.recorder +} + +// Namespace of this client +func (c *MockKnPingSourceClient) Namespace() string { + return c.recorder.r.Namespace() +} + +// CreatePingSource records a call for CreatePingSource with the expected error +func (sr *PingSourcesRecorder) CreatePingSource(pingSource interface{}, err error) { + sr.r.Add("CreatePingSource", []interface{}{pingSource}, []interface{}{err}) +} + +// CreatePingSource performs a previously recorded action, failing if non has been registered +func (c *MockKnPingSourceClient) CreatePingSource(ctx context.Context, pingSource *sourcesv1beta2.PingSource) error { + call := c.recorder.r.VerifyCall("CreatePingSource", pingSource) + return mock.ErrorOrNil(call.Result[0]) +} + +// GetPingSource records a call for GetPingSource with the expected object or error. Either pingsource or err should be nil +func (sr *PingSourcesRecorder) GetPingSource(name interface{}, pingSource *sourcesv1beta2.PingSource, err error) { + sr.r.Add("GetPingSource", []interface{}{name}, []interface{}{pingSource, err}) +} + +// GetPingSource performs a previously recorded action, failing if non has been registered +func (c *MockKnPingSourceClient) GetPingSource(ctx context.Context, name string) (*sourcesv1beta2.PingSource, error) { + call := c.recorder.r.VerifyCall("GetPingSource", name) + return call.Result[0].(*sourcesv1beta2.PingSource), mock.ErrorOrNil(call.Result[1]) +} + +// UpdatePingSource records a call for UpdatePingSource with the expected error (nil if none) +func (sr *PingSourcesRecorder) UpdatePingSource(pingSource interface{}, err error) { + sr.r.Add("UpdatePingSource", []interface{}{pingSource}, []interface{}{err}) +} + +// UpdatePingSource performs a previously recorded action, failing if non has been registered +func (c *MockKnPingSourceClient) UpdatePingSource(ctx context.Context, pingSource *sourcesv1beta2.PingSource) error { + call := c.recorder.r.VerifyCall("UpdatePingSource", pingSource) + return mock.ErrorOrNil(call.Result[0]) +} + +func (c *MockKnPingSourceClient) UpdatePingSourceWithRetry(ctx context.Context, name string, updateFunc PingSourceUpdateFunc, nrRetries int) error { + return updatePingSourceWithRetry(ctx, c, name, updateFunc, nrRetries) +} + +// UpdatePingSource records a call for DeletePingSource with the expected error (nil if none) +func (sr *PingSourcesRecorder) DeletePingSource(name interface{}, err error) { + sr.r.Add("DeletePingSource", []interface{}{name}, []interface{}{err}) +} + +// DeletePingSource performs a previously recorded action, failing if non has been registered +func (c *MockKnPingSourceClient) DeletePingSource(ctx context.Context, name string) error { + call := c.recorder.r.VerifyCall("DeletePingSource", name) + return mock.ErrorOrNil(call.Result[0]) +} + +// ListPingSource records a call for ListPingSource with the expected error (nil if none) +func (sr *PingSourcesRecorder) ListPingSource(pingSourceList *sourcesv1beta2.PingSourceList, err error) { + sr.r.Add("ListPingSource", []interface{}{}, []interface{}{pingSourceList, err}) +} + +// ListPingSource performs a previously recorded action, failing if non has been registered +func (c *MockKnPingSourceClient) ListPingSource(context.Context) (*sourcesv1beta2.PingSourceList, error) { + call := c.recorder.r.VerifyCall("ListPingSource") + return call.Result[0].(*sourcesv1beta2.PingSourceList), mock.ErrorOrNil(call.Result[1]) +} + +// Validates validates whether every recorded action has been called +func (sr *PingSourcesRecorder) Validate() { + sr.r.CheckThatAllRecordedMethodsHaveBeenCalled() +} diff --git a/pkg/util/compare.go b/vendor/knative.dev/client-pkg/pkg/util/compare.go similarity index 100% rename from pkg/util/compare.go rename to vendor/knative.dev/client-pkg/pkg/util/compare.go diff --git a/pkg/util/corev1_helper.go b/vendor/knative.dev/client-pkg/pkg/util/corev1_helper.go similarity index 100% rename from pkg/util/corev1_helper.go rename to vendor/knative.dev/client-pkg/pkg/util/corev1_helper.go diff --git a/pkg/util/logging_http_transport.go b/vendor/knative.dev/client-pkg/pkg/util/logging_http_transport.go similarity index 100% rename from pkg/util/logging_http_transport.go rename to vendor/knative.dev/client-pkg/pkg/util/logging_http_transport.go diff --git a/pkg/util/mock/mock_helper.go b/vendor/knative.dev/client-pkg/pkg/util/mock/mock_helper.go similarity index 100% rename from pkg/util/mock/mock_helper.go rename to vendor/knative.dev/client-pkg/pkg/util/mock/mock_helper.go diff --git a/pkg/util/orderedmap.go b/vendor/knative.dev/client-pkg/pkg/util/orderedmap.go similarity index 100% rename from pkg/util/orderedmap.go rename to vendor/knative.dev/client-pkg/pkg/util/orderedmap.go diff --git a/pkg/util/parsing_helper.go b/vendor/knative.dev/client-pkg/pkg/util/parsing_helper.go similarity index 100% rename from pkg/util/parsing_helper.go rename to vendor/knative.dev/client-pkg/pkg/util/parsing_helper.go diff --git a/pkg/util/schema_handling.go b/vendor/knative.dev/client-pkg/pkg/util/schema_handling.go similarity index 100% rename from pkg/util/schema_handling.go rename to vendor/knative.dev/client-pkg/pkg/util/schema_handling.go diff --git a/lib/test/broker.go b/vendor/knative.dev/client-pkg/pkg/util/test/broker.go similarity index 98% rename from lib/test/broker.go rename to vendor/knative.dev/client-pkg/pkg/util/test/broker.go index 83ddf9dffd..dc057f8e56 100644 --- a/lib/test/broker.go +++ b/vendor/knative.dev/client-pkg/pkg/util/test/broker.go @@ -19,7 +19,7 @@ import ( "time" "gotest.tools/v3/assert" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" "k8s.io/apimachinery/pkg/util/wait" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" diff --git a/lib/test/capture_output.go b/vendor/knative.dev/client-pkg/pkg/util/test/capture_output.go similarity index 100% rename from lib/test/capture_output.go rename to vendor/knative.dev/client-pkg/pkg/util/test/capture_output.go diff --git a/lib/test/channel.go b/vendor/knative.dev/client-pkg/pkg/util/test/channel.go similarity index 98% rename from lib/test/channel.go rename to vendor/knative.dev/client-pkg/pkg/util/test/channel.go index dae8f3545f..6f6ca5385b 100644 --- a/lib/test/channel.go +++ b/vendor/knative.dev/client-pkg/pkg/util/test/channel.go @@ -19,7 +19,7 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func ChannelCreate(r *KnRunResultCollector, cname string, args ...string) { diff --git a/lib/test/cli.go b/vendor/knative.dev/client-pkg/pkg/util/test/cli.go similarity index 100% rename from lib/test/cli.go rename to vendor/knative.dev/client-pkg/pkg/util/test/cli.go diff --git a/lib/test/eventtype.go b/vendor/knative.dev/client-pkg/pkg/util/test/eventtype.go similarity index 98% rename from lib/test/eventtype.go rename to vendor/knative.dev/client-pkg/pkg/util/test/eventtype.go index 2608286a32..ac3cc09096 100644 --- a/lib/test/eventtype.go +++ b/vendor/knative.dev/client-pkg/pkg/util/test/eventtype.go @@ -16,7 +16,7 @@ package test import ( "gotest.tools/v3/assert" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // EventtypeCreate creates an eventtype with the given name. diff --git a/lib/test/flags.go b/vendor/knative.dev/client-pkg/pkg/util/test/flags.go similarity index 100% rename from lib/test/flags.go rename to vendor/knative.dev/client-pkg/pkg/util/test/flags.go diff --git a/lib/test/integration.go b/vendor/knative.dev/client-pkg/pkg/util/test/integration.go similarity index 100% rename from lib/test/integration.go rename to vendor/knative.dev/client-pkg/pkg/util/test/integration.go diff --git a/lib/test/result_collector.go b/vendor/knative.dev/client-pkg/pkg/util/test/result_collector.go similarity index 100% rename from lib/test/result_collector.go rename to vendor/knative.dev/client-pkg/pkg/util/test/result_collector.go diff --git a/lib/test/revision.go b/vendor/knative.dev/client-pkg/pkg/util/test/revision.go similarity index 99% rename from lib/test/revision.go rename to vendor/knative.dev/client-pkg/pkg/util/test/revision.go index 7d389655ab..46521e7d83 100644 --- a/lib/test/revision.go +++ b/vendor/knative.dev/client-pkg/pkg/util/test/revision.go @@ -20,7 +20,7 @@ import ( "strings" "gotest.tools/v3/assert" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // RevisionListForService list revisions of given service and verifies if their status is True diff --git a/lib/test/service.go b/vendor/knative.dev/client-pkg/pkg/util/test/service.go similarity index 92% rename from lib/test/service.go rename to vendor/knative.dev/client-pkg/pkg/util/test/service.go index deec4b81db..2bbddca03f 100644 --- a/lib/test/service.go +++ b/vendor/knative.dev/client-pkg/pkg/util/test/service.go @@ -25,14 +25,14 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - clientv1alpha1 "knative.dev/client/pkg/apis/client/v1alpha1" + clientv1alpha1 "knative.dev/client-pkg/pkg/apis/client/v1alpha1" "knative.dev/pkg/ptr" pkgtest "knative.dev/pkg/test" "knative.dev/serving/pkg/apis/config" servingv1 "knative.dev/serving/pkg/apis/serving/v1" servingtest "knative.dev/serving/pkg/testing/v1" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) // ExpectedServiceListOption enables further configuration of a ServiceList. @@ -51,20 +51,6 @@ func ServiceCreate(r *KnRunResultCollector, serviceName string) { assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "creating", "namespace", r.KnTest().Kn().Namespace(), "ready")) } -// ServiceCreate verifies given service creation async mode and also verifies output -func ServiceCreateNoWait(r *KnRunResultCollector, serviceName string) { - out := r.KnTest().Kn().Run("service", "create", serviceName, "--no-wait", "--image", pkgtest.ImagePath("helloworld")) - r.AssertNoError(out) - assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "created", "namespace", r.KnTest().Kn().Namespace())) -} - -// ServiceWait waits for service to be ready and also verifies output -func ServiceWait(r *KnRunResultCollector, serviceName string) { - out := r.KnTest().Kn().Run("service", "wait", serviceName) - r.AssertNoError(out) - assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "ready", "namespace", r.KnTest().Kn().Namespace())) -} - // ServiceListEmpty verifies that there are no services present func ServiceListEmpty(r *KnRunResultCollector) { out := r.KnTest().Kn().Run("service", "list") diff --git a/lib/test/subscription.go b/vendor/knative.dev/client-pkg/pkg/util/test/subscription.go similarity index 98% rename from lib/test/subscription.go rename to vendor/knative.dev/client-pkg/pkg/util/test/subscription.go index 537e2f4188..f61f5ef1f1 100644 --- a/lib/test/subscription.go +++ b/vendor/knative.dev/client-pkg/pkg/util/test/subscription.go @@ -21,7 +21,7 @@ import ( "gotest.tools/v3/assert" - "knative.dev/client/pkg/util" + "knative.dev/client-pkg/pkg/util" ) func SubscriptionCreate(r *KnRunResultCollector, sname string, args ...string) { diff --git a/lib/test/utils.go b/vendor/knative.dev/client-pkg/pkg/util/test/utils.go similarity index 100% rename from lib/test/utils.go rename to vendor/knative.dev/client-pkg/pkg/util/test/utils.go diff --git a/pkg/util/unstructured.go b/vendor/knative.dev/client-pkg/pkg/util/unstructured.go similarity index 100% rename from pkg/util/unstructured.go rename to vendor/knative.dev/client-pkg/pkg/util/unstructured.go diff --git a/pkg/wait/poll_watcher.go b/vendor/knative.dev/client-pkg/pkg/wait/poll_watcher.go similarity index 100% rename from pkg/wait/poll_watcher.go rename to vendor/knative.dev/client-pkg/pkg/wait/poll_watcher.go diff --git a/pkg/wait/test_wait_helper.go b/vendor/knative.dev/client-pkg/pkg/wait/test_wait_helper.go similarity index 100% rename from pkg/wait/test_wait_helper.go rename to vendor/knative.dev/client-pkg/pkg/wait/test_wait_helper.go diff --git a/pkg/wait/wait_for_ready.go b/vendor/knative.dev/client-pkg/pkg/wait/wait_for_ready.go similarity index 100% rename from pkg/wait/wait_for_ready.go rename to vendor/knative.dev/client-pkg/pkg/wait/wait_for_ready.go diff --git a/vendor/modules.txt b/vendor/modules.txt index 7f8f072e64..edb2cf114e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -960,9 +960,32 @@ k8s.io/utils/pointer k8s.io/utils/ptr k8s.io/utils/strings/slices k8s.io/utils/trace -# knative.dev/client-pkg v0.0.0-20240327121233-6984d81a90ec +# knative.dev/client-pkg v0.0.0-20240327121233-6984d81a90ec => github.com/cardil/knative-client-pkg v0.0.0-20240416095801-87f6a5d7889a ## explicit; go 1.21 +knative.dev/client-pkg/pkg/apis/client +knative.dev/client-pkg/pkg/apis/client/v1alpha1 +knative.dev/client-pkg/pkg/commands +knative.dev/client-pkg/pkg/commands/flags/list +knative.dev/client-pkg/pkg/commands/flags/sink +knative.dev/client-pkg/pkg/config +knative.dev/client-pkg/pkg/dynamic +knative.dev/client-pkg/pkg/dynamic/fake +knative.dev/client-pkg/pkg/errors +knative.dev/client-pkg/pkg/eventing/v1 +knative.dev/client-pkg/pkg/eventing/v1beta2 +knative.dev/client-pkg/pkg/flags +knative.dev/client-pkg/pkg/messaging/v1 knative.dev/client-pkg/pkg/plugin +knative.dev/client-pkg/pkg/printers +knative.dev/client-pkg/pkg/serving +knative.dev/client-pkg/pkg/serving/v1 +knative.dev/client-pkg/pkg/serving/v1beta1 +knative.dev/client-pkg/pkg/sources/v1 +knative.dev/client-pkg/pkg/sources/v1beta2 +knative.dev/client-pkg/pkg/util +knative.dev/client-pkg/pkg/util/mock +knative.dev/client-pkg/pkg/util/test +knative.dev/client-pkg/pkg/wait # knative.dev/eventing v0.40.1-0.20240327131403-47543259ceba ## explicit; go 1.21 knative.dev/eventing/pkg/apis/config @@ -1192,3 +1215,4 @@ sigs.k8s.io/structured-merge-diff/v4/value ## explicit; go 1.12 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 +# knative.dev/client-pkg => github.com/cardil/knative-client-pkg v0.0.0-20240416095801-87f6a5d7889a