github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/marketplace_command.go (about) 1 package v7 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action" 8 "github.com/LukasHeimann/cloudfoundrycli/v8/command/translatableerror" 9 "github.com/LukasHeimann/cloudfoundrycli/v8/resources" 10 "github.com/LukasHeimann/cloudfoundrycli/v8/util/ui" 11 ) 12 13 type MarketplaceCommand struct { 14 BaseCommand 15 16 ServiceOfferingName string `short:"e" description:"Show plan details for a particular service offering"` 17 ServiceBrokerName string `short:"b" description:"Only show details for a particular service broker"` 18 NoPlans bool `long:"no-plans" description:"Hide plan information for service offerings"` 19 ShowUnavailable bool `long:"show-unavailable" description:"Show plans that are not available for use"` 20 usage interface{} `usage:"CF_NAME marketplace [-e SERVICE_OFFERING] [-b SERVICE_BROKER] [--no-plans]"` 21 relatedCommands interface{} `related_commands:"create-service, services"` 22 } 23 24 func (cmd MarketplaceCommand) Execute(args []string) error { 25 var username string 26 27 filter, err := cmd.processFlags() 28 if err != nil { 29 return err 30 } 31 32 if cmd.BaseCommand.SharedActor.IsLoggedIn() { 33 username, err = cmd.processLoginContext() 34 if err != nil { 35 return err 36 } 37 38 filter.SpaceGUID = cmd.Config.TargetedSpace().GUID 39 } 40 41 cmd.displayMessage(username) 42 43 offerings, warnings, err := cmd.BaseCommand.Actor.Marketplace(filter) 44 cmd.UI.DisplayWarnings(warnings) 45 if err != nil { 46 return err 47 } 48 49 if len(offerings) == 0 { 50 cmd.UI.DisplayNewline() 51 cmd.UI.DisplayText("No service offerings found.") 52 return nil 53 } 54 55 switch cmd.ServiceOfferingName { 56 case "": 57 return cmd.displayOfferingsTable(offerings) 58 default: 59 return cmd.displayPlansTable(offerings) 60 } 61 } 62 63 func (cmd MarketplaceCommand) processFlags() (v7action.MarketplaceFilter, error) { 64 if cmd.ServiceOfferingName != "" && cmd.NoPlans { 65 return v7action.MarketplaceFilter{}, translatableerror.ArgumentCombinationError{Args: []string{"--no-plans", "-e"}} 66 } 67 68 return v7action.MarketplaceFilter{ 69 ServiceOfferingName: cmd.ServiceOfferingName, 70 ServiceBrokerName: cmd.ServiceBrokerName, 71 ShowUnavailable: cmd.ShowUnavailable, 72 }, nil 73 } 74 75 func (cmd MarketplaceCommand) processLoginContext() (string, error) { 76 if err := cmd.SharedActor.CheckTarget(true, true); err != nil { 77 return "", err 78 } 79 80 user, err := cmd.Actor.GetCurrentUser() 81 if err != nil { 82 return "", err 83 } 84 return user.Name, nil 85 } 86 87 func (cmd MarketplaceCommand) displayMessage(username string) { 88 var template string 89 90 switch cmd.ServiceOfferingName { 91 case "": 92 template = "Getting all service offerings from marketplace" 93 default: 94 template = "Getting service plan information for service offering {{.ServiceOfferingName}}" 95 } 96 97 if cmd.ServiceBrokerName != "" { 98 switch cmd.ServiceOfferingName { 99 case "": 100 template += " for " 101 default: 102 template += " from " 103 } 104 template += "service broker {{.ServiceBrokerName}}" 105 } 106 107 if username != "" { 108 template += " in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}" 109 } 110 111 cmd.UI.DisplayTextWithFlavor(template+"...", map[string]interface{}{ 112 "ServiceOfferingName": cmd.ServiceOfferingName, 113 "ServiceBrokerName": cmd.ServiceBrokerName, 114 "OrgName": cmd.Config.TargetedOrganization().Name, 115 "SpaceName": cmd.Config.TargetedSpace().Name, 116 "Username": username, 117 }) 118 } 119 120 func (cmd MarketplaceCommand) displayPlansTable(offerings []v7action.ServiceOfferingWithPlans) error { 121 for _, o := range offerings { 122 data := cmd.plansTableHeadings() 123 for _, p := range o.Plans { 124 data = append(data, cmd.plansTableRow(p)) 125 } 126 127 cmd.UI.DisplayNewline() 128 cmd.UI.DisplayTextWithFlavor("broker: {{.ServiceBrokerName}}", map[string]interface{}{ 129 "ServiceBrokerName": o.ServiceBrokerName, 130 }) 131 cmd.UI.DisplayTableWithHeader(" ", data, ui.DefaultTableSpacePadding) 132 } 133 134 return nil 135 } 136 137 func (cmd MarketplaceCommand) plansTableHeadings() [][]string { 138 switch cmd.ShowUnavailable { 139 case true: 140 return [][]string{{"plan", "description", "free or paid", "costs", "available"}} 141 default: 142 return [][]string{{"plan", "description", "free or paid", "costs"}} 143 } 144 } 145 146 func (cmd MarketplaceCommand) plansTableRow(p resources.ServicePlan) []string { 147 result := []string{p.Name, p.Description, freeOrPaid(p.Free), costsList(p.Costs)} 148 149 if cmd.ShowUnavailable { 150 result = append(result, available(p.Available)) 151 } 152 153 return result 154 } 155 156 func (cmd MarketplaceCommand) displayOfferingsTable(offerings []v7action.ServiceOfferingWithPlans) error { 157 var data [][]string 158 if cmd.NoPlans { 159 data = computeOfferingsTableWithPlanNames(offerings) 160 } else { 161 data = computeOfferingsTableWithoutPlanNames(offerings) 162 } 163 164 cmd.UI.DisplayNewline() 165 cmd.UI.DisplayTableWithHeader("", data, ui.DefaultTableSpacePadding) 166 cmd.UI.DisplayNewline() 167 cmd.UI.DisplayText("TIP: Use 'cf marketplace -e SERVICE_OFFERING' to view descriptions of individual plans of a given service offering.") 168 169 return nil 170 } 171 172 func computeOfferingsTableWithPlanNames(offerings []v7action.ServiceOfferingWithPlans) [][]string { 173 data := [][]string{{"offering", "description", "broker"}} 174 for _, o := range offerings { 175 data = append(data, []string{o.Name, o.Description, o.ServiceBrokerName}) 176 } 177 return data 178 } 179 180 func computeOfferingsTableWithoutPlanNames(offerings []v7action.ServiceOfferingWithPlans) [][]string { 181 data := [][]string{{"offering", "plans", "description", "broker"}} 182 for _, o := range offerings { 183 data = append(data, []string{o.Name, planNames(o.Plans), o.Description, o.ServiceBrokerName}) 184 } 185 return data 186 } 187 188 func planNames(plans []resources.ServicePlan) string { 189 var names []string 190 for _, p := range plans { 191 names = append(names, p.Name) 192 } 193 return strings.Join(names, ", ") 194 } 195 196 func freeOrPaid(free bool) string { 197 if free { 198 return "free" 199 } 200 return "paid" 201 } 202 203 func available(available bool) string { 204 if available { 205 return "yes" 206 } 207 return "no" 208 } 209 210 func costsList(costs []resources.ServicePlanCost) string { 211 var costsOutput []string 212 for _, cost := range costs { 213 costsOutput = append(costsOutput, fmt.Sprintf("%s %.2f/%s", cost.Currency, cost.Amount, cost.Unit)) 214 } 215 return strings.Join(costsOutput, ", ") 216 }