Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Include namespaced brokers in svcat get brokers #2227

Merged
merged 11 commits into from
Jul 31, 2018
23 changes: 17 additions & 6 deletions cmd/svcat/broker/get_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,40 @@ package broker
import (
"github.com/kubernetes-incubator/service-catalog/cmd/svcat/command"
"github.com/kubernetes-incubator/service-catalog/cmd/svcat/output"
"github.com/kubernetes-incubator/service-catalog/pkg/svcat/service-catalog"
"github.com/spf13/cobra"
)

type getCmd struct {
*command.Context
*command.Namespaced
*command.Formatted
*command.Scoped
name string
}

// NewGetCmd builds a "svcat get brokers" command
func NewGetCmd(cxt *command.Context) *cobra.Command {
getCmd := &getCmd{
Context: cxt,
Formatted: command.NewFormatted(),
Namespaced: command.NewNamespaced(cxt),
Formatted: command.NewFormatted(),
Scoped: command.NewScoped(),
}
cmd := &cobra.Command{
Use: "brokers [NAME]",
Aliases: []string{"broker", "brk"},
Short: "List brokers, optionally filtered by name",
Short: "List brokers, optionally filtered by name, scope or namespace",
Example: command.NormalizeExamples(`
svcat get brokers
svcat get broker asb
svcat get brokers --scope=cluster
svcat get brokers --scope=all
svcat get broker minibroker
`),
PreRunE: command.PreRunE(getCmd),
RunE: command.RunE(getCmd),
}
getCmd.AddOutputFlags(cmd.Flags())
getCmd.AddScopedFlags(cmd.Flags(), true)
getCmd.AddNamespaceFlags(cmd.Flags(), true)
return cmd
}

Expand All @@ -66,7 +73,11 @@ func (c *getCmd) Run() error {
}

func (c *getCmd) getAll() error {
brokers, err := c.App.RetrieveBrokers()
opts := servicecatalog.ScopeOptions{
Namespace: c.Namespace,
Scope: c.Scope,
}
brokers, err := c.App.RetrieveBrokers(opts)
if err != nil {
return err
}
Expand Down
158 changes: 158 additions & 0 deletions cmd/svcat/broker/get_cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
Copyright 2018 The Kubernetes 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 broker

import (
"bytes"

"github.com/kubernetes-incubator/service-catalog/cmd/svcat/command"
"github.com/kubernetes-incubator/service-catalog/cmd/svcat/test"
"github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1"
"github.com/kubernetes-incubator/service-catalog/pkg/svcat"
"github.com/kubernetes-incubator/service-catalog/pkg/svcat/service-catalog"
"github.com/kubernetes-incubator/service-catalog/pkg/svcat/service-catalog/service-catalogfakes"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = Describe("Get Broker Command", func() {
Describe("NewGetBrokerCmd", func() {
It("Builds and returns a cobra command", func() {
cxt := &command.Context{}
cmd := NewGetCmd(cxt)
Expect(*cmd).NotTo(BeNil())
Expect(cmd.Use).To(Equal("brokers [NAME]"))
Expect(cmd.Short).To(ContainSubstring("List brokers, optionally filtered by name, scope or namespace"))
Expect(cmd.Example).To(ContainSubstring("svcat get brokers"))
Expect(cmd.Example).To(ContainSubstring("svcat get brokers --scope=cluster"))
Expect(cmd.Example).To(ContainSubstring("svcat get brokers --scope=all"))
Expect(cmd.Example).To(ContainSubstring("svcat get broker minibroker"))
Expect(len(cmd.Aliases)).To(Equal(2))
})
})
Describe("Validate", func() {
It("allows broker name arg to be empty", func() {
cmd := &getCmd{}
err := cmd.Validate([]string{})
Expect(err).To(BeNil())
})
It("optionally parses the broker name argument", func() {
cmd := &getCmd{}
err := cmd.Validate([]string{"minibroker"})
Expect(err).To(BeNil())
Expect(cmd.name).To(Equal("minibroker"))
})
})
Describe("Run", func() {
It("Calls the pkg/svcat libs RetrieveBrokers with namespace scope and current namespace", func() {
outputBuffer := &bytes.Buffer{}

fakeApp, _ := svcat.NewApp(nil, nil, "default")
fakeSDK := new(servicecatalogfakes.FakeSvcatClient)
fakeSDK.RetrieveBrokersReturns(
[]servicecatalog.Broker{&v1beta1.ServiceBroker{ObjectMeta: v1.ObjectMeta{Name: "minibroker", Namespace: "default"}}},
nil)
fakeApp.SvcatClient = fakeSDK
cmd := getCmd{
Namespaced: &command.Namespaced{Context: svcattest.NewContext(outputBuffer, fakeApp)},
Scoped: command.NewScoped(),
Formatted: command.NewFormatted(),
}
cmd.Namespace = "default"
cmd.Scope = servicecatalog.NamespaceScope

err := cmd.Run()

Expect(err).NotTo(HaveOccurred())
scopeArg := fakeSDK.RetrieveBrokersArgsForCall(0)
Expect(scopeArg).To(Equal(servicecatalog.ScopeOptions{
Namespace: "default",
Scope: servicecatalog.NamespaceScope,
}))

output := outputBuffer.String()
Expect(output).To(ContainSubstring("minibroker"))
})
It("Calls the pkg/svcat libs RetrieveBrokers with namespace scope and all namespaces", func() {
outputBuffer := &bytes.Buffer{}

fakeApp, _ := svcat.NewApp(nil, nil, "default")
fakeSDK := new(servicecatalogfakes.FakeSvcatClient)
fakeSDK.RetrieveBrokersReturns(
[]servicecatalog.Broker{
&v1beta1.ServiceBroker{ObjectMeta: v1.ObjectMeta{Name: "minibroker", Namespace: "default"}},
&v1beta1.ServiceBroker{ObjectMeta: v1.ObjectMeta{Name: "ups-broker", Namespace: "test-ns"}},
},
nil)
fakeApp.SvcatClient = fakeSDK
cmd := getCmd{
Namespaced: &command.Namespaced{Context: svcattest.NewContext(outputBuffer, fakeApp)},
Scoped: command.NewScoped(),
Formatted: command.NewFormatted(),
}
cmd.Namespace = ""
cmd.Scope = servicecatalog.NamespaceScope

err := cmd.Run()

Expect(err).NotTo(HaveOccurred())
scopeArg := fakeSDK.RetrieveBrokersArgsForCall(0)
Expect(scopeArg).To(Equal(servicecatalog.ScopeOptions{
Namespace: "",
Scope: servicecatalog.NamespaceScope,
}))

output := outputBuffer.String()
Expect(output).To(ContainSubstring("minibroker"))
Expect(output).To(ContainSubstring("ups-broker"))
})
It("Calls the pkg/svcat libs RetrieveBrokers with all scope and current namespaces", func() {
outputBuffer := &bytes.Buffer{}

fakeApp, _ := svcat.NewApp(nil, nil, "default")
fakeSDK := new(servicecatalogfakes.FakeSvcatClient)
fakeSDK.RetrieveBrokersReturns(
[]servicecatalog.Broker{
&v1beta1.ClusterServiceBroker{ObjectMeta: v1.ObjectMeta{Name: "global-broker"}},
&v1beta1.ServiceBroker{ObjectMeta: v1.ObjectMeta{Name: "minibroker", Namespace: "default"}},
},
nil)
fakeApp.SvcatClient = fakeSDK
cmd := getCmd{
Namespaced: &command.Namespaced{Context: svcattest.NewContext(outputBuffer, fakeApp)},
Scoped: command.NewScoped(),
Formatted: command.NewFormatted(),
}
cmd.Namespace = "default"
cmd.Scope = servicecatalog.AllScope

err := cmd.Run()

Expect(err).NotTo(HaveOccurred())
scopeArg := fakeSDK.RetrieveBrokersArgsForCall(0)
Expect(scopeArg).To(Equal(servicecatalog.ScopeOptions{
Namespace: "default",
Scope: servicecatalog.AllScope,
}))

output := outputBuffer.String()
Expect(output).To(ContainSubstring("global-broker"))
Expect(output).To(ContainSubstring("minibroker"))
})
})
})
48 changes: 18 additions & 30 deletions cmd/svcat/output/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,56 +17,55 @@ limitations under the License.
package output

import (
"fmt"
"io"

"github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1"
"github.com/kubernetes-incubator/service-catalog/pkg/svcat/service-catalog"
)

func getBrokerStatusCondition(status v1beta1.ClusterServiceBrokerStatus) v1beta1.ServiceBrokerCondition {
func getBrokerStatusCondition(status v1beta1.CommonServiceBrokerStatus) v1beta1.ServiceBrokerCondition {
if len(status.Conditions) > 0 {
return status.Conditions[len(status.Conditions)-1]
}
return v1beta1.ServiceBrokerCondition{}
}

func getBrokerStatusShort(status v1beta1.ClusterServiceBrokerStatus) string {
func getBrokerStatusShort(status v1beta1.CommonServiceBrokerStatus) string {
lastCond := getBrokerStatusCondition(status)
return formatStatusShort(string(lastCond.Type), lastCond.Status, lastCond.Reason)
}

func getBrokerStatusFull(status v1beta1.ClusterServiceBrokerStatus) string {
func getBrokerStatusFull(status v1beta1.CommonServiceBrokerStatus) string {
lastCond := getBrokerStatusCondition(status)
return formatStatusFull(string(lastCond.Type), lastCond.Status, lastCond.Reason, lastCond.Message, lastCond.LastTransitionTime)
}

func writeBrokerListTable(w io.Writer, brokers []v1beta1.ClusterServiceBroker) {
func writeBrokerListTable(w io.Writer, brokers []servicecatalog.Broker) {
t := NewListTable(w)
t.SetHeader([]string{
"Name",
"Namespace",
"URL",
"Status",
})
for _, broker := range brokers {
t.Append([]string{
broker.Name,
broker.Spec.URL,
getBrokerStatusShort(broker.Status),
broker.GetName(),
broker.GetNamespace(),
broker.GetURL(),
getBrokerStatusShort(broker.GetStatus()),
})
}
t.Render()
}

// WriteBrokerList prints a list of brokers in the specified output format.
func WriteBrokerList(w io.Writer, outputFormat string, brokers ...v1beta1.ClusterServiceBroker) {
l := v1beta1.ClusterServiceBrokerList{
Items: brokers,
}
func WriteBrokerList(w io.Writer, outputFormat string, brokers ...servicecatalog.Broker) {
switch outputFormat {
case FormatJSON:
writeJSON(w, l)
writeJSON(w, brokers)
case FormatYAML:
writeYAML(w, l, 0)
writeYAML(w, brokers, 0)
case FormatTable:
writeBrokerListTable(w, brokers)
}
Expand All @@ -80,29 +79,18 @@ func WriteBroker(w io.Writer, outputFormat string, broker v1beta1.ClusterService
case FormatYAML:
writeYAML(w, broker, 0)
case FormatTable:
writeBrokerListTable(w, []v1beta1.ClusterServiceBroker{broker})
writeBrokerListTable(w, []servicecatalog.Broker{&broker})
}
}

// WriteParentBroker prints identifying information for a parent broker.
func WriteParentBroker(w io.Writer, broker *v1beta1.ClusterServiceBroker) {
fmt.Fprintln(w, "\nBroker:")
t := NewDetailsTable(w)
t.AppendBulk([][]string{
{"Name:", broker.Name},
{"Status:", getBrokerStatusShort(broker.Status)},
})
t.Render()
}

// WriteBrokerDetails prints details for a single broker.
func WriteBrokerDetails(w io.Writer, broker *v1beta1.ClusterServiceBroker) {
func WriteBrokerDetails(w io.Writer, broker servicecatalog.Broker) {
t := NewDetailsTable(w)

t.AppendBulk([][]string{
{"Name:", broker.Name},
{"URL:", broker.Spec.URL},
{"Status:", getBrokerStatusFull(broker.Status)},
{"Name:", broker.GetName()},
{"URL:", broker.GetURL()},
{"Status:", getBrokerStatusFull(broker.GetStatus())},
})

t.Render()
Expand Down
7 changes: 7 additions & 0 deletions cmd/svcat/testdata/output/completion-bash.txt
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,16 @@ _svcat_get_brokers()
flags_with_completion=()
flags_completion=()

flags+=("--all-namespaces")
local_nonpersistent_flags+=("--all-namespaces")
flags+=("--namespace=")
two_word_flags+=("-n")
local_nonpersistent_flags+=("--namespace=")
flags+=("--output=")
two_word_flags+=("-o")
local_nonpersistent_flags+=("--output=")
flags+=("--scope=")
local_nonpersistent_flags+=("--scope=")
flags+=("--context=")
flags+=("--kubeconfig=")
flags+=("--logtostderr")
Expand Down
7 changes: 7 additions & 0 deletions cmd/svcat/testdata/output/completion-zsh.txt
Original file line number Diff line number Diff line change
Expand Up @@ -666,9 +666,16 @@ _svcat_get_brokers()
flags_with_completion=()
flags_completion=()

flags+=("--all-namespaces")
local_nonpersistent_flags+=("--all-namespaces")
flags+=("--namespace=")
two_word_flags+=("-n")
local_nonpersistent_flags+=("--namespace=")
flags+=("--output=")
two_word_flags+=("-o")
local_nonpersistent_flags+=("--output=")
flags+=("--scope=")
local_nonpersistent_flags+=("--scope=")
flags+=("--context=")
flags+=("--kubeconfig=")
flags+=("--logtostderr")
Expand Down
6 changes: 3 additions & 3 deletions cmd/svcat/testdata/output/get-broker.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
NAME URL STATUS
+------------+-----------------------------------------------------------+--------+
ups-broker http://ups-broker-ups-broker.ups-broker.svc.cluster.local Ready
NAME NAMESPACE URL STATUS
+------------+-----------+-----------------------------------------------------------+--------+
ups-broker http://ups-broker-ups-broker.ups-broker.svc.cluster.local Ready
Loading