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  }