mirror of https://github.com/knative/client.git
List inbuilt sources if CRD access is restricted (#948)
* List inbuilt sources if CRD access is restricted Fixes #947 - Identify restricted access error - If server returns restricted access error, fallback to listing only eventing inbuilt sources using their GVKs. - List any inbuilt source (ApiServerSource) object and read the error to know if eventing is installed for `kn source list-types`. * Fix golint warnings * Remove unused imports * Verify each built in source before listing source types * Improve the check if sources are not installed in the cluster * Update finding forbidden error * Update finding errors * Add unit tests for IsForbiddenError util * Add unit tests * Add tests for dynamic pkg library * Add unit tests for case when no sources are installed * Update test name
This commit is contained in:
parent
4a3cf24550
commit
cc1b68e068
|
|
@ -15,6 +15,9 @@
|
|||
package dynamic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
|
@ -42,12 +45,15 @@ type KnDynamicClient interface {
|
|||
// ListCRDs returns list of CRDs with their type and name
|
||||
ListCRDs(options metav1.ListOptions) (*unstructured.UnstructuredList, error)
|
||||
|
||||
// ListSourceCRDs returns list of eventing sources CRDs
|
||||
// ListSourcesTypes returns list of eventing sources CRDs
|
||||
ListSourcesTypes() (*unstructured.UnstructuredList, error)
|
||||
|
||||
// ListSources returns list of available source objects
|
||||
ListSources(types ...WithType) (*unstructured.UnstructuredList, error)
|
||||
|
||||
// ListSourcesUsingGVKs returns list of available source objects using given list of GVKs
|
||||
ListSourcesUsingGVKs(*[]schema.GroupVersionKind, ...WithType) (*unstructured.UnstructuredList, error)
|
||||
|
||||
// RawClient returns the raw dynamic client interface
|
||||
RawClient() dynamic.Interface
|
||||
}
|
||||
|
|
@ -107,12 +113,17 @@ func (c *knDynamicClient) ListSources(types ...WithType) (*unstructured.Unstruct
|
|||
var (
|
||||
sourceList unstructured.UnstructuredList
|
||||
options metav1.ListOptions
|
||||
numberOfsourceTypesFound int
|
||||
numberOfSourceTypesFound int
|
||||
)
|
||||
sourceTypes, err := c.ListSourcesTypes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sourceTypes == nil || len(sourceTypes.Items) == 0 {
|
||||
return nil, errors.New("no sources found on the backend, please verify the installation")
|
||||
}
|
||||
|
||||
namespace := c.Namespace()
|
||||
filters := WithTypes(types).List()
|
||||
// For each source type available, find out each source types objects
|
||||
|
|
@ -141,14 +152,56 @@ func (c *knDynamicClient) ListSources(types ...WithType) (*unstructured.Unstruct
|
|||
|
||||
if len(sList.Items) > 0 {
|
||||
// keep a track if we found source objects of different types
|
||||
numberOfsourceTypesFound++
|
||||
numberOfSourceTypesFound++
|
||||
sourceList.Items = append(sourceList.Items, sList.Items...)
|
||||
sourceList.SetGroupVersionKind(sList.GetObjectKind().GroupVersionKind())
|
||||
}
|
||||
}
|
||||
// Clear the Group and Version for list if there are multiple types of source objects found
|
||||
// Keep the source's GVK if there is only one type of source objects found or requested via --type filter
|
||||
if numberOfsourceTypesFound > 1 {
|
||||
if numberOfSourceTypesFound > 1 {
|
||||
sourceList.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "", Kind: "List"})
|
||||
}
|
||||
return &sourceList, nil
|
||||
}
|
||||
|
||||
// ListSourcesUsingGVKs returns list of available source objects using given list of GVKs
|
||||
func (c *knDynamicClient) ListSourcesUsingGVKs(gvks *[]schema.GroupVersionKind, types ...WithType) (*unstructured.UnstructuredList, error) {
|
||||
if gvks == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var (
|
||||
sourceList unstructured.UnstructuredList
|
||||
options metav1.ListOptions
|
||||
numberOfSourceTypesFound int
|
||||
)
|
||||
namespace := c.Namespace()
|
||||
filters := WithTypes(types).List()
|
||||
|
||||
for _, gvk := range *gvks {
|
||||
if len(filters) > 0 && !util.SliceContainsIgnoreCase(filters, gvk.Kind) {
|
||||
continue
|
||||
}
|
||||
|
||||
gvr := gvk.GroupVersion().WithResource(strings.ToLower(gvk.Kind) + "s")
|
||||
|
||||
// list objects of source type with this GVR
|
||||
sList, err := c.client.Resource(gvr).Namespace(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(sList.Items) > 0 {
|
||||
// keep a track if we found source objects of different types
|
||||
numberOfSourceTypesFound++
|
||||
sourceList.Items = append(sourceList.Items, sList.Items...)
|
||||
sourceList.SetGroupVersionKind(sList.GetObjectKind().GroupVersionKind())
|
||||
}
|
||||
}
|
||||
// Clear the Group and Version for list if there are multiple types of source objects found
|
||||
// Keep the source's GVK if there is only one type of source objects found or requested via --type filter
|
||||
if numberOfSourceTypesFound > 1 {
|
||||
sourceList.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "", Kind: "List"})
|
||||
}
|
||||
return &sourceList, nil
|
||||
|
|
|
|||
|
|
@ -95,6 +95,13 @@ func TestListSources(t *testing.T) {
|
|||
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()
|
||||
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", "v1alpha1", "PingSource"),
|
||||
|
|
@ -118,6 +125,40 @@ func TestListSources(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
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(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", "v1alpha1", "PingSource"),
|
||||
newSourceCRDObjWithSpec("apiserversources", "sources.knative.dev", "v1alpha1", "ApiServerSource"),
|
||||
newSourceUnstructuredObj("p1", "sources.knative.dev/v1alpha1", "PingSource"),
|
||||
newSourceUnstructuredObj("a1", "sources.knative.dev/v1alpha1", "ApiServerSource"),
|
||||
)
|
||||
assert.Check(t, client.RawClient() != nil)
|
||||
gv := schema.GroupVersion{"sources.knative.dev", "v1alpha1"}
|
||||
gvks := []schema.GroupVersionKind{gv.WithKind("ApiServerSource"), gv.WithKind("PingSource")}
|
||||
|
||||
s, err := client.ListSourcesUsingGVKs(&gvks)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, s != nil)
|
||||
assert.Equal(t, len(s.Items), 2)
|
||||
|
||||
// withType
|
||||
s, err = client.ListSourcesUsingGVKs(&gvks, WithTypeFilter("PingSource"))
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, s != nil)
|
||||
assert.Equal(t, len(s.Items), 1)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ package dynamic
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
|
@ -123,3 +124,25 @@ func (types WithTypes) List() []string {
|
|||
}
|
||||
return stypes
|
||||
}
|
||||
|
||||
// UnstructuredCRDFromGVK constructs an unstructured object using the given GVK
|
||||
func UnstructuredCRDFromGVK(gvk schema.GroupVersionKind) *unstructured.Unstructured {
|
||||
name := fmt.Sprintf("%ss.%s", strings.ToLower(gvk.Kind), gvk.Group)
|
||||
plural := fmt.Sprintf("%ss", strings.ToLower(gvk.Kind))
|
||||
u := &unstructured.Unstructured{}
|
||||
u.SetUnstructuredContent(map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"name": name,
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"group": gvk.Group,
|
||||
"version": gvk.Version,
|
||||
"names": map[string]interface{}{
|
||||
"kind": gvk.Kind,
|
||||
"plural": plural,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return u
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"knative.dev/client/pkg/util"
|
||||
)
|
||||
|
|
@ -77,3 +78,22 @@ func TestGVRFromUnstructured(t *testing.T) {
|
|||
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{"sources.knative.dev", "v1alpha2", "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, "v1alpha2")
|
||||
|
||||
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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func newInvalidCRD(apiGroup string) *KNError {
|
|||
return NewKNError(msg)
|
||||
}
|
||||
|
||||
func newNoRouteToHost(errString string) error {
|
||||
func newNoRouteToHost(errString string) *KNError {
|
||||
parts := strings.SplitAfter(errString, "dial tcp")
|
||||
if len(parts) == 2 {
|
||||
return NewKNError(fmt.Sprintf("error connecting to the cluster, please verify connection at: %s", strings.Trim(parts[1], " ")))
|
||||
|
|
@ -34,6 +34,6 @@ func newNoRouteToHost(errString string) error {
|
|||
return NewKNError(fmt.Sprintf("error connecting to the cluster: %s", errString))
|
||||
}
|
||||
|
||||
func newNoKubeConfig(errString string) error {
|
||||
func newNoKubeConfig(errString string) *KNError {
|
||||
return NewKNError("no kubeconfig has been provided, please use a valid configuration to connect to the cluster")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
api_errors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
|
@ -63,3 +64,11 @@ func GetError(err error) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// IsForbiddenError returns true if given error can be converted to API status and of type forbidden access else false
|
||||
func IsForbiddenError(err error) bool {
|
||||
if status, ok := err.(api_errors.APIStatus); ok {
|
||||
return status.Status().Code == int32(http.StatusForbidden)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,11 @@ func TestKnErrors(t *testing.T) {
|
|||
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
|
||||
|
|
@ -130,3 +135,29 @@ func TestKnErrors(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
tc := tc
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert.Equal(t, IsForbiddenError(tc.Error), tc.Forbidden)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
|
||||
"knative.dev/client/pkg/dynamic"
|
||||
knerrors "knative.dev/client/pkg/errors"
|
||||
"knative.dev/client/pkg/kn/commands"
|
||||
"knative.dev/client/pkg/kn/commands/flags"
|
||||
"knative.dev/client/pkg/kn/commands/source/duck"
|
||||
sourcesv1alpha2 "knative.dev/client/pkg/sources/v1alpha2"
|
||||
)
|
||||
|
||||
var listExample = `
|
||||
|
|
@ -52,15 +54,25 @@ func NewListCommand(p *commands.KnParams) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var filters dynamic.WithTypes
|
||||
for _, filter := range filterFlags.Filters {
|
||||
filters = append(filters, dynamic.WithTypeFilter(filter))
|
||||
}
|
||||
|
||||
sourceList, err := dynamicClient.ListSources(filters...)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
switch {
|
||||
case knerrors.IsForbiddenError(err):
|
||||
gvks := sourcesv1alpha2.BuiltInSourcesGVKs()
|
||||
if sourceList, err = dynamicClient.ListSourcesUsingGVKs(&gvks, filters...); err != nil {
|
||||
return knerrors.GetError(err)
|
||||
}
|
||||
case err != nil:
|
||||
return knerrors.GetError(err)
|
||||
}
|
||||
if len(sourceList.Items) == 0 {
|
||||
|
||||
if sourceList == nil || len(sourceList.Items) == 0 {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "No sources found in %s namespace.\n", namespace)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
dynamicfake "k8s.io/client-go/dynamic/fake"
|
||||
clientdynamic "knative.dev/client/pkg/dynamic"
|
||||
"knative.dev/client/pkg/kn/commands"
|
||||
"knative.dev/client/pkg/util"
|
||||
)
|
||||
|
|
@ -51,6 +53,12 @@ func sourceFakeCmd(args []string, objects ...runtime.Object) (output []string, e
|
|||
return
|
||||
}
|
||||
|
||||
func TestSourceListTypesNoSourcesInstalled(t *testing.T) {
|
||||
_, err := sourceFakeCmd([]string{"source", "list-types"})
|
||||
assert.Check(t, err != nil)
|
||||
assert.Check(t, util.ContainsAll(err.Error(), "no sources", "found", "backend", "verify", "installation"))
|
||||
}
|
||||
|
||||
func TestSourceListTypes(t *testing.T) {
|
||||
output, err := sourceFakeCmd([]string{"source", "list-types"},
|
||||
newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1alpha1", "PingSource"),
|
||||
|
|
@ -71,6 +79,20 @@ func TestSourceListTypesNoHeaders(t *testing.T) {
|
|||
assert.Check(t, util.ContainsAll(output[0], "PingSource"))
|
||||
}
|
||||
|
||||
func TestListBuiltInSourceTypes(t *testing.T) {
|
||||
fakeDynamic := dynamicfake.NewSimpleDynamicClient(runtime.NewScheme())
|
||||
sources, err := listBuiltInSourceTypes(clientdynamic.NewKnDynamicClient(fakeDynamic, "current"))
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, sources != nil)
|
||||
assert.Equal(t, len(sources.Items), 4)
|
||||
}
|
||||
|
||||
func TestSourceListNoSourcesInstalled(t *testing.T) {
|
||||
_, err := sourceFakeCmd([]string{"source", "list"})
|
||||
assert.Check(t, err != nil)
|
||||
assert.Check(t, util.ContainsAll(err.Error(), "no sources", "found", "backend", "verify", "installation"))
|
||||
}
|
||||
|
||||
func TestSourceList(t *testing.T) {
|
||||
output, err := sourceFakeCmd([]string{"source", "list"},
|
||||
newSourceCRDObjWithSpec("pingsources", "sources.knative.dev", "v1alpha1", "PingSource"),
|
||||
|
|
|
|||
|
|
@ -18,9 +18,14 @@ import (
|
|||
"fmt"
|
||||
|
||||
"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/kn/commands"
|
||||
"knative.dev/client/pkg/kn/commands/flags"
|
||||
sourcesv1alpha2 "knative.dev/client/pkg/sources/v1alpha2"
|
||||
)
|
||||
|
||||
// NewListTypesCommand defines and processes `kn source list-types`
|
||||
|
|
@ -47,13 +52,17 @@ func NewListTypesCommand(p *commands.KnParams) *cobra.Command {
|
|||
}
|
||||
|
||||
sourceListTypes, err := dynamicClient.ListSourcesTypes()
|
||||
if err != nil {
|
||||
return err
|
||||
switch {
|
||||
case knerrors.IsForbiddenError(err):
|
||||
if sourceListTypes, err = listBuiltInSourceTypes(dynamicClient); err != nil {
|
||||
return knerrors.GetError(err)
|
||||
}
|
||||
case err != nil:
|
||||
return knerrors.GetError(err)
|
||||
}
|
||||
|
||||
if len(sourceListTypes.Items) == 0 {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "No sources found.\n")
|
||||
return nil
|
||||
if sourceListTypes == nil || len(sourceListTypes.Items) == 0 {
|
||||
return fmt.Errorf("no sources found on the backend, please verify the installation")
|
||||
}
|
||||
|
||||
printer, err := listTypesFlags.ToPrinter()
|
||||
|
|
@ -73,3 +82,22 @@ func NewListTypesCommand(p *commands.KnParams) *cobra.Command {
|
|||
listTypesFlags.AddFlags(listTypesCommand)
|
||||
return listTypesCommand
|
||||
}
|
||||
|
||||
func listBuiltInSourceTypes(d dynamic.KnDynamicClient) (*unstructured.UnstructuredList, error) {
|
||||
var err error
|
||||
uList := unstructured.UnstructuredList{}
|
||||
gvks := sourcesv1alpha2.BuiltInSourcesGVKs()
|
||||
for _, gvk := range gvks {
|
||||
_, err = d.ListSourcesUsingGVKs(&[]schema.GroupVersionKind{gvk})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
u := dynamic.UnstructuredCRDFromGVK(gvk)
|
||||
uList.Items = append(uList.Items, *u)
|
||||
}
|
||||
// if not even one source is found
|
||||
if len(uList.Items) == 0 && err != nil {
|
||||
return nil, knerrors.GetError(err)
|
||||
}
|
||||
return &uList, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ func (c *apiServerSourcesClient) Namespace() string {
|
|||
func (c *apiServerSourcesClient) ListAPIServerSource() (*v1alpha2.ApiServerSourceList, error) {
|
||||
sourceList, err := c.client.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, knerrors.GetError(err)
|
||||
}
|
||||
|
||||
return updateAPIServerSourceListGVK(sourceList)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
sourcesv1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2"
|
||||
clientv1alpha2 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha2"
|
||||
)
|
||||
|
||||
|
|
@ -61,3 +63,13 @@ func (c *sourcesClient) SinkBindingClient() KnSinkBindingClient {
|
|||
func (c *sourcesClient) APIServerSourcesClient() KnAPIServerSourcesClient {
|
||||
return newKnAPIServerSourcesClient(c.client.ApiServerSources(c.namespace), c.namespace)
|
||||
}
|
||||
|
||||
// BuiltInSourcesGVKs returns the GVKs for built in sources
|
||||
func BuiltInSourcesGVKs() []schema.GroupVersionKind {
|
||||
return []schema.GroupVersionKind{
|
||||
sourcesv1alpha2.SchemeGroupVersion.WithKind("ApiServerSource"),
|
||||
sourcesv1alpha2.SchemeGroupVersion.WithKind("ContainerSource"),
|
||||
sourcesv1alpha2.SchemeGroupVersion.WithKind("PingSource"),
|
||||
sourcesv1alpha2.SchemeGroupVersion.WithKind("SinkBinding"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
// 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 v1alpha2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
|
||||
sourcesv1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2"
|
||||
)
|
||||
|
||||
func TestBuiltInSourcesGVks(t *testing.T) {
|
||||
gvks := BuiltInSourcesGVKs()
|
||||
for _, each := range gvks {
|
||||
assert.DeepEqual(t, each.GroupVersion(), sourcesv1alpha2.SchemeGroupVersion)
|
||||
}
|
||||
assert.Equal(t, len(gvks), 4)
|
||||
}
|
||||
Loading…
Reference in New Issue