github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/command/v6/services_command.go (about) 1 package v6 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 8 "code.cloudfoundry.org/cli/actor/sharedaction" 9 "code.cloudfoundry.org/cli/actor/v2action" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 11 "code.cloudfoundry.org/cli/command" 12 "code.cloudfoundry.org/cli/command/v6/shared" 13 "code.cloudfoundry.org/cli/util/sorting" 14 ) 15 16 //go:generate counterfeiter . ServiceInstancesActor 17 18 type ServiceInstancesActor interface { 19 GetServiceInstancesSummaryBySpace(spaceGUID string) ([]v2action.ServiceInstanceSummary, v2action.Warnings, error) 20 } 21 22 type ServicesCommand struct { 23 usage interface{} `usage:"CF_NAME services"` 24 relatedCommands interface{} `related_commands:"create-service, marketplace"` 25 26 UI command.UI 27 Config command.Config 28 SharedActor command.SharedActor 29 Actor ServiceInstancesActor 30 } 31 32 func (cmd *ServicesCommand) Setup(config command.Config, ui command.UI) error { 33 cmd.Config = config 34 cmd.UI = ui 35 cmd.SharedActor = sharedaction.NewActor(config) 36 ccClient, uaaClient, err := shared.NewClients(config, ui, true) 37 if err != nil { 38 return err 39 } 40 cmd.Actor = v2action.NewActor(ccClient, uaaClient, config) 41 42 return nil 43 } 44 45 func (cmd ServicesCommand) Execute(args []string) error { 46 err := cmd.SharedActor.CheckTarget(true, true) 47 if err != nil { 48 return err 49 } 50 51 user, err := cmd.Config.CurrentUser() 52 if err != nil { 53 return err 54 } 55 56 cmd.UI.DisplayTextWithFlavor("Getting services in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...", 57 map[string]interface{}{ 58 "OrgName": cmd.Config.TargetedOrganization().Name, 59 "SpaceName": cmd.Config.TargetedSpace().Name, 60 "CurrentUser": user.Name, 61 }) 62 cmd.UI.DisplayNewline() 63 64 instanceSummaries, warnings, err := cmd.Actor.GetServiceInstancesSummaryBySpace(cmd.Config.TargetedSpace().GUID) 65 cmd.UI.DisplayWarnings(warnings) 66 if err != nil { 67 return err 68 } 69 70 if len(instanceSummaries) == 0 { 71 cmd.UI.DisplayText("No services found") 72 return nil 73 } 74 75 sortServiceInstances(instanceSummaries) 76 77 table := [][]string{{ 78 cmd.UI.TranslateText("name"), 79 cmd.UI.TranslateText("service"), 80 cmd.UI.TranslateText("plan"), 81 cmd.UI.TranslateText("bound apps"), 82 cmd.UI.TranslateText("last operation"), 83 cmd.UI.TranslateText("broker"), 84 }} 85 86 var boundAppNames []string 87 88 for _, summary := range instanceSummaries { 89 serviceLabel := summary.Service.Label 90 if summary.ServiceInstance.Type == constant.UserProvidedService { 91 serviceLabel = "user-provided" 92 } 93 94 boundAppNames = []string{} 95 for _, boundApplication := range summary.BoundApplications { 96 boundAppNames = append(boundAppNames, boundApplication.AppName) 97 } 98 99 table = append(table, []string{ 100 summary.Name, 101 serviceLabel, 102 summary.ServicePlan.Name, 103 strings.Join(boundAppNames, ", "), 104 fmt.Sprintf("%s %s", summary.LastOperation.Type, summary.LastOperation.State), 105 summary.Service.ServiceBrokerName}, 106 ) 107 } 108 cmd.UI.DisplayTableWithHeader("", table, 3) 109 110 return nil 111 } 112 113 func sortServiceInstances(instanceSummaries []v2action.ServiceInstanceSummary) { 114 sort.Slice(instanceSummaries, func(i, j int) bool { 115 return sorting.LessIgnoreCase(instanceSummaries[i].Name, instanceSummaries[j].Name) 116 }) 117 118 for _, instance := range instanceSummaries { 119 sortBoundApps(instance) 120 } 121 } 122 123 func sortBoundApps(serviceInstance v2action.ServiceInstanceSummary) { 124 sort.Slice( 125 serviceInstance.BoundApplications, 126 func(i, j int) bool { 127 return sorting.LessIgnoreCase(serviceInstance.BoundApplications[i].AppName, serviceInstance.BoundApplications[j].AppName) 128 }) 129 }