diff --git a/pkg/kn/commands/revision/revision_describe.go b/pkg/kn/commands/revision/revision_describe.go index 2ca24eb20a..59541097f1 100644 --- a/pkg/kn/commands/revision/revision_describe.go +++ b/pkg/kn/commands/revision/revision_describe.go @@ -20,7 +20,6 @@ import ( "github.com/knative/client/pkg/kn/commands" "github.com/spf13/cobra" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -52,10 +51,10 @@ func NewRevisionDescribeCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - revision.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{ - Group: "knative.dev", - Version: "v1alpha1", - Kind: "Revision"}) + if err := client.UpdateGroupVersionKind(revision); err != nil { + return err + } + err = printer.PrintObj(revision, cmd.OutOrStdout()) if err != nil { return err diff --git a/pkg/kn/commands/revision/revision_describe_test.go b/pkg/kn/commands/revision/revision_describe_test.go index 9c1b2af4e5..b0aff04001 100644 --- a/pkg/kn/commands/revision/revision_describe_test.go +++ b/pkg/kn/commands/revision/revision_describe_test.go @@ -20,6 +20,7 @@ import ( "github.com/knative/client/pkg/kn/commands" "github.com/knative/serving/pkg/apis/serving/v1alpha1" + "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -29,8 +30,8 @@ import ( ) func fakeRevision(args []string, response *v1alpha1.Revision) (action client_testing.Action, output string, err error) { - knParams := &commands.KnParams{} - cmd, fakeServing, buf := commands.CreateTestKnCommand(NewRevisionCommand(knParams), knParams) + knParams := &commands.KnParams{} + cmd, fakeServing, buf := commands.CreateTestKnCommand(NewRevisionCommand(knParams), knParams) fakeServing.AddReactor("*", "*", func(a client_testing.Action) (bool, runtime.Object, error) { action = a diff --git a/pkg/kn/commands/revision/revision_list.go b/pkg/kn/commands/revision/revision_list.go index b9036a5624..e56c78721c 100644 --- a/pkg/kn/commands/revision/revision_list.go +++ b/pkg/kn/commands/revision/revision_list.go @@ -20,7 +20,6 @@ import ( "github.com/knative/client/pkg/kn/commands" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" ) // NewRevisionListCommand represents 'kn revision list' command @@ -47,10 +46,10 @@ func NewRevisionListCommand(p *commands.KnParams) *cobra.Command { fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n") return nil } - revision.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{ - Group: "knative.dev", - Version: "v1alpha1", - Kind: "revision"}) + if err := client.UpdateGroupVersionKind(revision); err != nil { + return err + } + printer, err := revisionListFlags.ToPrinter() if err != nil { return err diff --git a/pkg/kn/commands/revision/revision_list_test.go b/pkg/kn/commands/revision/revision_list_test.go index 005e09ced5..4768a58037 100644 --- a/pkg/kn/commands/revision/revision_list_test.go +++ b/pkg/kn/commands/revision/revision_list_test.go @@ -18,6 +18,9 @@ import ( "strings" "testing" + "github.com/knative/serving/pkg/apis/serving" + "github.com/knative/serving/pkg/apis/serving/v1alpha1" + "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" "github.com/knative/client/pkg/kn/commands" serving "github.com/knative/serving/pkg/apis/serving" v1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" diff --git a/pkg/kn/commands/root_test.go b/pkg/kn/commands/root_test.go new file mode 100644 index 0000000000..cba44f69eb --- /dev/null +++ b/pkg/kn/commands/root_test.go @@ -0,0 +1,17 @@ +package commands + +import ( + "github.com/knative/client/pkg/serving" + serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1" + "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" + "k8s.io/apimachinery/pkg/runtime" +) + +// Helper struct to adding UpdateGroupVersionKind to the fake client, too +type fakeServingV1alpha1Wrapper struct { + *fake.FakeServingV1alpha1 +} + +func (fakeServingV1alpha1Wrapper) UpdateGroupVersionKind(obj runtime.Object) error { + return serving.UpdateGroupVersionKind(obj, serving_v1alpha1_api.SchemeGroupVersion) +} diff --git a/pkg/kn/commands/service/service_describe.go b/pkg/kn/commands/service/service_describe.go index ce462c39cb..3aa28cc904 100644 --- a/pkg/kn/commands/service/service_describe.go +++ b/pkg/kn/commands/service/service_describe.go @@ -20,7 +20,6 @@ import ( "github.com/knative/client/pkg/kn/commands" "github.com/spf13/cobra" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/cli-runtime/pkg/genericclioptions" ) @@ -51,10 +50,10 @@ func NewServiceDescribeCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - describeService.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{ - Group: "knative.dev", - Version: "v1alpha1", - Kind: "Service"}) + if err := client.UpdateGroupVersionKind(describeService); err != nil { + return err + } + err = printer.PrintObj(describeService, cmd.OutOrStdout()) if err != nil { return err diff --git a/pkg/kn/commands/service/service_describe_test.go b/pkg/kn/commands/service/service_describe_test.go index a80b139a49..36f2866171 100644 --- a/pkg/kn/commands/service/service_describe_test.go +++ b/pkg/kn/commands/service/service_describe_test.go @@ -20,6 +20,7 @@ import ( "github.com/knative/client/pkg/kn/commands" "github.com/knative/serving/pkg/apis/serving/v1alpha1" + "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/kn/commands/service/service_list.go b/pkg/kn/commands/service/service_list.go index bc73863b1e..e3540442ed 100644 --- a/pkg/kn/commands/service/service_list.go +++ b/pkg/kn/commands/service/service_list.go @@ -20,7 +20,6 @@ import ( "github.com/knative/client/pkg/kn/commands" "github.com/spf13/cobra" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" ) // NewServiceListCommand represents 'kn service list' command @@ -47,10 +46,9 @@ func NewServiceListCommand(p *commands.KnParams) *cobra.Command { fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n") return nil } - service.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{ - Group: "knative.dev", - Version: "v1alpha1", - Kind: "Service"}) + if err := client.UpdateGroupVersionKind(service); err != nil { + return err + } printer, err := serviceListFlags.ToPrinter() if err != nil { diff --git a/pkg/kn/commands/service/service_list_test.go b/pkg/kn/commands/service/service_list_test.go index a57f35d55f..b183c5ad98 100644 --- a/pkg/kn/commands/service/service_list_test.go +++ b/pkg/kn/commands/service/service_list_test.go @@ -20,6 +20,8 @@ import ( "github.com/knative/client/pkg/kn/commands" duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" + "github.com/knative/serving/pkg/apis/serving/v1alpha1" + "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" v1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/kn/commands/service/service_update_test.go b/pkg/kn/commands/service/service_update_test.go index 4902a2007a..2538461b22 100644 --- a/pkg/kn/commands/service/service_update_test.go +++ b/pkg/kn/commands/service/service_update_test.go @@ -24,6 +24,7 @@ import ( "github.com/knative/client/pkg/kn/commands" servinglib "github.com/knative/client/pkg/serving" "github.com/knative/serving/pkg/apis/serving/v1alpha1" + "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/kn/core/root.go b/pkg/kn/core/root.go index 02ac60f7d9..39ba7235fb 100644 --- a/pkg/kn/core/root.go +++ b/pkg/kn/core/root.go @@ -17,10 +17,16 @@ package core import ( "flag" "fmt" + servinglib "github.com/knative/client/pkg/serving" + "io" + "k8s.io/apimachinery/pkg/runtime" "os" "path" "path/filepath" + serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1" + serving_v1alpha1_client "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" + "github.com/mitchellh/go-homedir" "github.com/knative/client/pkg/kn/commands" "github.com/knative/client/pkg/kn/commands/revision" "github.com/knative/client/pkg/kn/commands/service" @@ -31,6 +37,39 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" ) +var cfgFile string +var kubeCfgFile string + +// Extend v1alpha1 serving client by a method for updating GVK +type ServingV1alpha1InterfaceWithGvkUpdater interface { + serving_v1alpha1_client.ServingV1alpha1Interface + + // Update with the registered V1alpha1 GVK + UpdateGroupVersionKind(obj runtime.Object) error +} + +// Delegate to v1alpha1 client +type ServingV1alphaClientWithGvkUpdater struct { + *serving_v1alpha1_client.ServingV1alpha1Client +} + +// Update GVK from v1alpha1 schema. Needs to be called by any object returned from the client +func (cl ServingV1alphaClientWithGvkUpdater) UpdateGroupVersionKind(obj runtime.Object) error { + return servinglib.UpdateGroupVersionKind(obj, serving_v1alpha1_api.SchemeGroupVersion) +} + +// Parameters for creating commands. Useful for inserting mocks for testing. +type KnParams struct { + Output io.Writer + ServingFactory func() (ServingV1alpha1InterfaceWithGvkUpdater, error) +} + +func (c *KnParams) Initialize() { + if c.ServingFactory == nil { + c.ServingFactory = GetConfig + } +} + // rootCmd represents the base command when called without any subcommands func NewKnCommand(params ...commands.KnParams) *cobra.Command { var p *commands.KnParams @@ -124,3 +163,15 @@ func initConfig() { fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) } } + +func GetConfig() (ServingV1alpha1InterfaceWithGvkUpdater, error) { + config, err := clientcmd.BuildConfigFromFlags("", kubeCfgFile) + if err != nil { + return nil, err + } + client, err := serving_v1alpha1_client.NewForConfig(config) + if err != nil { + return nil, err + } + return ServingV1alphaClientWithGvkUpdater{client}, nil +} diff --git a/pkg/serving/schema_handling.go b/pkg/serving/schema_handling.go new file mode 100644 index 0000000000..ca46db0d5e --- /dev/null +++ b/pkg/serving/schema_handling.go @@ -0,0 +1,34 @@ +package serving + +import ( + "errors" + "fmt" + + "github.com/knative/serving/pkg/client/clientset/versioned/scheme" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// Update the GVK on the given object, based on the GVK registered in into the serving scheme +// for the given GroupVersion +func UpdateGroupVersionKind(obj runtime.Object, gv schema.GroupVersion) error { + gvk, err := getGroupVersionKind(obj, gv) + if err != nil { + return err + } + obj.GetObjectKind().SetGroupVersionKind(*gvk) + return nil +} + +func getGroupVersionKind(obj runtime.Object, gv schema.GroupVersion) (*schema.GroupVersionKind, error) { + gvks, _, err := scheme.Scheme.ObjectKinds(obj) + if err != nil { + return nil, err + } + for _, gvk := range gvks { + if gvk.GroupVersion() == gv { + return &gvk, nil + } + } + return nil, errors.New(fmt.Sprintf("no group version %s registered in %s", gv, scheme.Scheme.Name())) +} diff --git a/pkg/serving/schema_handling_test.go b/pkg/serving/schema_handling_test.go new file mode 100644 index 0000000000..221704267e --- /dev/null +++ b/pkg/serving/schema_handling_test.go @@ -0,0 +1,29 @@ +package serving + +import ( + "github.com/knative/serving/pkg/apis/serving/v1alpha1" + "k8s.io/apimachinery/pkg/runtime/schema" + "testing" +) + +func TestGVKUpdate(t *testing.T) { + service := v1alpha1.Service{} + err := UpdateGroupVersionKind(&service, v1alpha1.SchemeGroupVersion) + 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 != v1alpha1.SchemeGroupVersion.Group+"/"+v1alpha1.SchemeGroupVersion.Version { + t.Fatalf("wrong version '%s'", service.APIVersion) + } +} + +func TestGVKUpdateNegative(t *testing.T) { + service := v1alpha1.Service{} + err := UpdateGroupVersionKind(&service, schema.GroupVersion{Group: "bla", Version: "blub"}) + if err == nil { + t.Fatal("expect an error for an unregistered group version") + } +}