github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v6/marketplace_command.go (about)

     1  package v6
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"code.cloudfoundry.org/cli/actor/sharedaction"
     9  	"code.cloudfoundry.org/cli/actor/v2action"
    10  	"code.cloudfoundry.org/cli/command"
    11  	"code.cloudfoundry.org/cli/command/translatableerror"
    12  	"code.cloudfoundry.org/cli/command/v6/shared"
    13  	"code.cloudfoundry.org/cli/util/ui"
    14  )
    15  
    16  //go:generate counterfeiter . ServicesSummariesActor
    17  
    18  type ServicesSummariesActor interface {
    19  	GetServicesSummaries() ([]v2action.ServiceSummary, v2action.Warnings, error)
    20  	GetServicesSummariesForSpace(spaceGUID string) ([]v2action.ServiceSummary, v2action.Warnings, error)
    21  
    22  	GetServiceSummaryByName(serviceName string) (v2action.ServiceSummary, v2action.Warnings, error)
    23  	GetServiceSummaryForSpaceByName(spaceGUID, serviceName string) (v2action.ServiceSummary, v2action.Warnings, error)
    24  }
    25  
    26  type MarketplaceCommand struct {
    27  	ServiceName     string      `short:"s" description:"Show plan details for a particular service offering"`
    28  	NoPlans         bool        `long:"no-plans" description:"Hide plan information for service offerings"`
    29  	usage           interface{} `usage:"CF_NAME marketplace [-s SERVICE] [--no-plans]"`
    30  	relatedCommands interface{} `related_commands:"create-service, services"`
    31  
    32  	UI          command.UI
    33  	SharedActor command.SharedActor
    34  	Actor       ServicesSummariesActor
    35  	Config      command.Config
    36  }
    37  
    38  func (cmd *MarketplaceCommand) Setup(config command.Config, ui command.UI) error {
    39  	cmd.Config = config
    40  	cmd.UI = ui
    41  	cmd.SharedActor = sharedaction.NewActor(config)
    42  
    43  	ccClient, uaaClient, err := shared.GetNewClientsAndConnectToCF(config, ui)
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	cmd.Actor = v2action.NewActor(ccClient, uaaClient, config)
    49  
    50  	return nil
    51  }
    52  
    53  func (cmd *MarketplaceCommand) Execute(args []string) error {
    54  	if len(args) > 0 {
    55  		return translatableerror.TooManyArgumentsError{
    56  			ExtraArgument: args[0],
    57  		}
    58  	}
    59  
    60  	if !cmd.SharedActor.IsLoggedIn() {
    61  		return cmd.publicMarketplace()
    62  	}
    63  
    64  	return cmd.marketplace()
    65  }
    66  
    67  func (cmd *MarketplaceCommand) marketplace() error {
    68  	user, err := cmd.Config.CurrentUser()
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	if cmd.ServiceName == "" {
    74  		if !cmd.SharedActor.IsOrgTargeted() || !cmd.SharedActor.IsSpaceTargeted() {
    75  			return errors.New("Cannot list marketplace services without a targeted space")
    76  		}
    77  
    78  		cmd.UI.DisplayTextWithFlavor("Getting services from marketplace in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{
    79  			"OrgName":   cmd.Config.TargetedOrganization().Name,
    80  			"SpaceName": cmd.Config.TargetedSpace().Name,
    81  			"Username":  user.Name,
    82  		})
    83  		serviceSummaries, warnings, err := cmd.Actor.GetServicesSummariesForSpace(cmd.Config.TargetedSpace().GUID)
    84  		cmd.UI.DisplayWarnings(warnings)
    85  		if err != nil {
    86  			return err
    87  		}
    88  
    89  		cmd.UI.DisplayOK()
    90  		cmd.displayServiceSummaries(serviceSummaries)
    91  	} else {
    92  		if !cmd.SharedActor.IsOrgTargeted() || !cmd.SharedActor.IsSpaceTargeted() {
    93  			return fmt.Errorf("Cannot list plan information for %s without a targeted space", cmd.ServiceName)
    94  		}
    95  
    96  		cmd.UI.DisplayTextWithFlavor("Getting service plan information for service {{.ServiceName}} as {{.Username}}...",
    97  			map[string]interface{}{
    98  				"ServiceName": cmd.ServiceName,
    99  				"Username":    user.Name,
   100  			})
   101  
   102  		serviceSummary, warnings, err := cmd.Actor.GetServiceSummaryForSpaceByName(cmd.Config.TargetedSpace().GUID, cmd.ServiceName)
   103  		cmd.UI.DisplayWarnings(warnings)
   104  		if err != nil {
   105  			return err
   106  		}
   107  
   108  		cmd.UI.DisplayOK()
   109  		cmd.displayServiceSummary(serviceSummary)
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  func (cmd *MarketplaceCommand) publicMarketplace() error {
   116  	if cmd.ServiceName == "" {
   117  		cmd.UI.DisplayText("Getting all services from marketplace...")
   118  
   119  		serviceSummaries, warnings, err := cmd.Actor.GetServicesSummaries()
   120  		cmd.UI.DisplayWarnings(warnings)
   121  		if err != nil {
   122  			return err
   123  		}
   124  
   125  		cmd.UI.DisplayOK()
   126  		cmd.displayServiceSummaries(serviceSummaries)
   127  	} else {
   128  		cmd.UI.DisplayTextWithFlavor("Getting service plan information for service {{.ServiceName}}...",
   129  			map[string]interface{}{
   130  				"ServiceName": cmd.ServiceName,
   131  			})
   132  
   133  		serviceSummary, warnings, err := cmd.Actor.GetServiceSummaryByName(cmd.ServiceName)
   134  		cmd.UI.DisplayWarnings(warnings)
   135  		if err != nil {
   136  			return err
   137  		}
   138  
   139  		cmd.UI.DisplayOK()
   140  		cmd.displayServiceSummary(serviceSummary)
   141  	}
   142  
   143  	return nil
   144  }
   145  
   146  func (cmd *MarketplaceCommand) displayServiceSummaries(serviceSummaries []v2action.ServiceSummary) {
   147  	if len(serviceSummaries) == 0 {
   148  		cmd.UI.DisplayText("No service offerings found")
   149  	} else {
   150  		var table = [][]string{}
   151  		if cmd.NoPlans {
   152  			tableHeaders := []string{"service", "description", "broker"}
   153  			table = [][]string{tableHeaders}
   154  			for _, serviceSummary := range serviceSummaries {
   155  				table = append(table, []string{
   156  					serviceSummary.Label,
   157  					serviceSummary.Description,
   158  					serviceSummary.ServiceBrokerName,
   159  				})
   160  			}
   161  		} else {
   162  			tableHeaders := []string{"service", "plans", "description", "broker"}
   163  			table = [][]string{tableHeaders}
   164  			for _, serviceSummary := range serviceSummaries {
   165  				table = append(table, []string{
   166  					serviceSummary.Label,
   167  					planNames(serviceSummary),
   168  					serviceSummary.Description,
   169  					serviceSummary.ServiceBrokerName,
   170  				})
   171  			}
   172  		}
   173  		cmd.UI.DisplayTableWithHeader("", table, ui.DefaultTableSpacePadding)
   174  		cmd.UI.DisplayNewline()
   175  		cmd.UI.DisplayText("TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service.")
   176  	}
   177  }
   178  
   179  func (cmd *MarketplaceCommand) displayServiceSummary(serviceSummary v2action.ServiceSummary) {
   180  	tableHeaders := []string{"service plan", "description", "free or paid"}
   181  	table := [][]string{tableHeaders}
   182  	for _, plan := range serviceSummary.Plans {
   183  		table = append(table, []string{
   184  			plan.Name,
   185  			plan.Description,
   186  			formatFreeOrPaid(plan.Free),
   187  		})
   188  	}
   189  	cmd.UI.DisplayTableWithHeader("", table, ui.DefaultTableSpacePadding)
   190  }
   191  
   192  func planNames(serviceSummary v2action.ServiceSummary) string {
   193  	names := []string{}
   194  	for _, planSummary := range serviceSummary.Plans {
   195  		names = append(names, planSummary.Name)
   196  	}
   197  	return strings.Join(names, ", ")
   198  }
   199  
   200  func formatFreeOrPaid(free bool) string {
   201  	if free {
   202  		return "free"
   203  	}
   204  	return "paid"
   205  }