From a6673e521b1ef9dc94afbc93fddc59673760e72a Mon Sep 17 00:00:00 2001 From: Arghya Sadhu Date: Thu, 12 Nov 2020 18:37:32 +0530 Subject: [PATCH] add url output for broker and channel Signed-off-by: Arghya Sadhu --- CHANGELOG.adoc | 5 ++++ docs/cmd/kn_broker_describe.md | 10 +++++-- docs/cmd/kn_channel_describe.md | 5 +++- pkg/kn/commands/broker/describe.go | 36 ++++++++++++++++++++++-- pkg/kn/commands/broker/describe_test.go | 13 +++++++++ pkg/kn/commands/channel/channel_test.go | 18 ++++++++++++ pkg/kn/commands/channel/describe.go | 27 ++++++++++++++---- pkg/kn/commands/channel/describe_test.go | 10 +++++++ 8 files changed, 112 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index dbbbed9c0d..e673fcd887 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -22,6 +22,11 @@ | https://github.com/knative/client/pull/1117[#1117] |=== +| 🎁 +| Add "url" output format to return broker url in broker describe and channel url in channel describe +| https://github.com/knative/client/pull/1118[#1118] +|=== + ### v0.19.0 (2020-11-11) [cols="1,10,3", options="header", width="100%"] |=== diff --git a/docs/cmd/kn_broker_describe.md b/docs/cmd/kn_broker_describe.md index 454fc0e76e..ecdb8629cf 100644 --- a/docs/cmd/kn_broker_describe.md +++ b/docs/cmd/kn_broker_describe.md @@ -19,13 +19,19 @@ kn broker describe NAME # Describe broker 'mybroker' in the 'myproject' namespace kn broker describe mybroker --namespace myproject + + # Print only broker URL + kn broker describe mybroker -o url ``` ### Options ``` - -h, --help help for describe - -n, --namespace string Specify the namespace to operate in. + --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) + -h, --help help for describe + -n, --namespace string Specify the namespace to operate in. + -o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file|url. + --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. ``` ### Options inherited from parent commands diff --git a/docs/cmd/kn_channel_describe.md b/docs/cmd/kn_channel_describe.md index 88df50d168..c907eceafb 100644 --- a/docs/cmd/kn_channel_describe.md +++ b/docs/cmd/kn_channel_describe.md @@ -16,6 +16,9 @@ kn channel describe NAME # Describe a channel 'pipe' kn channel describe pipe + + # Print only channel URL + kn channel describe pipe -o url ``` ### Options @@ -24,7 +27,7 @@ kn channel describe NAME --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) -h, --help help for describe -n, --namespace string Specify the namespace to operate in. - -o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file. + -o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file|url. --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. -v, --verbose More output. ``` diff --git a/pkg/kn/commands/broker/describe.go b/pkg/kn/commands/broker/describe.go index f18c9d469a..7851817376 100644 --- a/pkg/kn/commands/broker/describe.go +++ b/pkg/kn/commands/broker/describe.go @@ -18,7 +18,11 @@ package broker import ( "errors" + "fmt" "io" + "strings" + + "k8s.io/cli-runtime/pkg/genericclioptions" "github.com/spf13/cobra" @@ -33,11 +37,17 @@ var describeExample = ` kn broker describe mybroker # Describe broker 'mybroker' in the 'myproject' namespace - kn broker describe mybroker --namespace myproject` + kn broker describe mybroker --namespace myproject + + # Print only broker URL + kn broker describe mybroker -o url` // NewBrokerDescribeCommand represents command to describe details of broker instance func NewBrokerDescribeCommand(p *commands.KnParams) *cobra.Command { + // For machine readable output + machineReadablePrintFlags := genericclioptions.NewPrintFlags("") + cmd := &cobra.Command{ Use: "describe NAME", Short: "Describe broker", @@ -62,10 +72,26 @@ func NewBrokerDescribeCommand(p *commands.KnParams) *cobra.Command { if err != nil { return err } - return describeBroker(cmd.OutOrStdout(), broker, false) + + out := cmd.OutOrStdout() + + if machineReadablePrintFlags.OutputFlagSpecified() { + if strings.ToLower(*machineReadablePrintFlags.OutputFormat) == "url" { + fmt.Fprintf(out, "%s\n", extractURL(broker)) + return nil + } + printer, err := machineReadablePrintFlags.ToPrinter() + if err != nil { + return err + } + return printer.PrintObj(broker, out) + } + return describeBroker(out, broker, false) }, } commands.AddNamespaceFlags(cmd.Flags(), false) + machineReadablePrintFlags.AddFlags(cmd) + cmd.Flag("output").Usage = fmt.Sprintf("Output format. One of: %s.", strings.Join(append(machineReadablePrintFlags.AllowedFormats(), "url"), "|")) return cmd } @@ -74,7 +100,7 @@ func describeBroker(out io.Writer, broker *v1beta1.Broker, printDetails bool) er dw := printers.NewPrefixWriter(out) commands.WriteMetadata(dw, &broker.ObjectMeta, printDetails) dw.WriteLine() - dw.WriteAttribute("Address", "").WriteAttribute("URL", broker.Status.Address.URL.String()) + dw.WriteAttribute("Address", "").WriteAttribute("URL", extractURL(broker)) dw.WriteLine() commands.WriteConditions(dw, broker.Status.Conditions, printDetails) if err := dw.Flush(); err != nil { @@ -82,3 +108,7 @@ func describeBroker(out io.Writer, broker *v1beta1.Broker, printDetails bool) er } return nil } + +func extractURL(broker *v1beta1.Broker) string { + return broker.Status.Address.URL.String() +} diff --git a/pkg/kn/commands/broker/describe_test.go b/pkg/kn/commands/broker/describe_test.go index b37760f165..5af2f44b27 100644 --- a/pkg/kn/commands/broker/describe_test.go +++ b/pkg/kn/commands/broker/describe_test.go @@ -73,6 +73,19 @@ func TestDescribeError(t *testing.T) { recorder.Validate() } +func TestBrokerDescribeURL(t *testing.T) { + client := clientv1beta1.NewMockKnEventingClient(t, "mynamespace") + + recorder := client.Recorder() + recorder.GetBroker("foo", getBroker(), nil) + + out, err := executeBrokerCommand(client, "describe", "foo", "-o", "url") + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(out, "http://foo-broker.test")) + + recorder.Validate() +} + func getBroker() *v1beta1.Broker { return &v1beta1.Broker{ TypeMeta: v1.TypeMeta{}, diff --git a/pkg/kn/commands/channel/channel_test.go b/pkg/kn/commands/channel/channel_test.go index f015f7c33d..3c5d000840 100644 --- a/pkg/kn/commands/channel/channel_test.go +++ b/pkg/kn/commands/channel/channel_test.go @@ -17,12 +17,16 @@ package channel import ( "bytes" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/tools/clientcmd" "knative.dev/eventing/pkg/apis/messaging/v1beta1" "knative.dev/client/pkg/kn/commands" clientv1beta1 "knative.dev/client/pkg/messaging/v1beta1" + eventingduck "knative.dev/eventing/pkg/apis/duck/v1beta1" ) // Helper methods @@ -79,3 +83,17 @@ func cleanupChannelMockClient() { func createChannel(name, namespace string, gvk *schema.GroupVersionKind) *v1beta1.Channel { return clientv1beta1.NewChannelBuilder(name, namespace).Type(gvk).Build() } + +func createChannelWithStatus(name string, gvk *schema.GroupVersionKind) *v1beta1.Channel { + channel := clientv1beta1.NewChannelBuilder(name).Type(gvk).Build() + channel.Status = v1beta1.ChannelStatus{ + ChannelableStatus: eventingduck.ChannelableStatus{ + AddressStatus: duckv1.AddressStatus{ + Address: &duckv1.Addressable{ + URL: &apis.URL{Scheme: "http", Host: "pipe-channel.test"}, + }, + }, + }, + } + return channel +} diff --git a/pkg/kn/commands/channel/describe.go b/pkg/kn/commands/channel/describe.go index 747507b501..721588fc94 100644 --- a/pkg/kn/commands/channel/describe.go +++ b/pkg/kn/commands/channel/describe.go @@ -17,6 +17,7 @@ package channel import ( "errors" "fmt" + "strings" "github.com/spf13/cobra" @@ -28,6 +29,13 @@ import ( "knative.dev/client/pkg/printers" ) +var describeExample = ` + # Describe a channel 'pipe' + kn channel describe pipe + + # Print only channel URL + kn channel describe pipe -o url` + // NewChannelDescribeCommand returns a new command for describe a channel object func NewChannelDescribeCommand(p *commands.KnParams) *cobra.Command { @@ -35,11 +43,9 @@ func NewChannelDescribeCommand(p *commands.KnParams) *cobra.Command { machineReadablePrintFlags := genericclioptions.NewPrintFlags("") cmd := &cobra.Command{ - Use: "describe NAME", - Short: "Show details of a channel", - Example: ` - # Describe a channel 'pipe' - kn channel describe pipe`, + Use: "describe NAME", + Short: "Show details of a channel", + Example: describeExample, RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return errors.New("'kn channel describe' requires the channel name given as single argument") @@ -59,6 +65,10 @@ func NewChannelDescribeCommand(p *commands.KnParams) *cobra.Command { out := cmd.OutOrStdout() if machineReadablePrintFlags.OutputFlagSpecified() { + if strings.ToLower(*machineReadablePrintFlags.OutputFormat) == "url" { + fmt.Fprintf(out, "%s\n", extractURL(channel)) + return nil + } printer, err := machineReadablePrintFlags.ToPrinter() if err != nil { return err @@ -92,6 +102,7 @@ func NewChannelDescribeCommand(p *commands.KnParams) *cobra.Command { commands.AddNamespaceFlags(flags, false) flags.BoolP("verbose", "v", false, "More output.") machineReadablePrintFlags.AddFlags(cmd) + cmd.Flag("output").Usage = fmt.Sprintf("Output format. One of: %s.", strings.Join(append(machineReadablePrintFlags.AllowedFormats(), "url"), "|")) return cmd } @@ -100,6 +111,10 @@ func writeChannel(dw printers.PrefixWriter, channel *messagingv1beta1.Channel, p ctype := fmt.Sprintf("%s (%s)", channel.Spec.ChannelTemplate.Kind, channel.Spec.ChannelTemplate.APIVersion) dw.WriteAttribute("Type", ctype) if channel.Status.Address != nil { - dw.WriteAttribute("URL", channel.Status.Address.URL.String()) + dw.WriteAttribute("URL", extractURL(channel)) } } + +func extractURL(channel *messagingv1beta1.Channel) string { + return channel.Status.Address.URL.String() +} diff --git a/pkg/kn/commands/channel/describe_test.go b/pkg/kn/commands/channel/describe_test.go index 70154cdabb..4a8bf8f02d 100644 --- a/pkg/kn/commands/channel/describe_test.go +++ b/pkg/kn/commands/channel/describe_test.go @@ -51,3 +51,13 @@ func TestDescribeChannel(t *testing.T) { assert.Assert(t, util.ContainsAll(out, "messaging.knative.dev", "v1beta1", "InMemoryChannel", "pipe")) cRecorder.Validate() } + +func TestDescribeChannelURL(t *testing.T) { + cClient := v1beta1.NewMockKnChannelsClient(t) + cRecorder := cClient.Recorder() + cRecorder.GetChannel("pipe", createChannelWithStatus("pipe", &schema.GroupVersionKind{Group: "messaging.knative.dev", Version: "v1beta1", Kind: "InMemoryChannel"}), nil) + out, err := executeChannelCommand(cClient, "describe", "pipe", "-o", "url") + assert.NilError(t, err, "channel should be described with url as output") + assert.Assert(t, util.ContainsAll(out, "pipe-channel.test")) + cRecorder.Validate() +}