github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+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/api/cloudcontroller/ccversion"
    12  	"code.cloudfoundry.org/cli/command"
    13  	"code.cloudfoundry.org/cli/command/v6/shared"
    14  	"code.cloudfoundry.org/cli/util/sorting"
    15  )
    16  
    17  //go:generate counterfeiter . ServiceInstancesActor
    18  
    19  type ServiceInstancesActor interface {
    20  	CloudControllerAPIVersion() string
    21  	GetServiceInstancesSummaryBySpace(spaceGUID string) ([]v2action.ServiceInstanceSummary, v2action.Warnings, error)
    22  }
    23  
    24  type ServicesCommand struct {
    25  	usage           interface{} `usage:"CF_NAME services"`
    26  	relatedCommands interface{} `related_commands:"create-service, marketplace"`
    27  
    28  	UI          command.UI
    29  	Config      command.Config
    30  	SharedActor command.SharedActor
    31  	Actor       ServiceInstancesActor
    32  }
    33  
    34  func (cmd *ServicesCommand) Setup(config command.Config, ui command.UI) error {
    35  	cmd.Config = config
    36  	cmd.UI = ui
    37  	cmd.SharedActor = sharedaction.NewActor(config)
    38  	ccClient, uaaClient, err := shared.GetNewClientsAndConnectToCF(config, ui)
    39  	if err != nil {
    40  		return err
    41  	}
    42  	cmd.Actor = v2action.NewActor(ccClient, uaaClient, config)
    43  
    44  	return nil
    45  }
    46  
    47  func (cmd ServicesCommand) Execute(args []string) error {
    48  	err := cmd.SharedActor.CheckTarget(true, true)
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	user, err := cmd.Config.CurrentUser()
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	cmd.UI.DisplayTextWithFlavor("Getting services in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...",
    59  		map[string]interface{}{
    60  			"OrgName":     cmd.Config.TargetedOrganization().Name,
    61  			"SpaceName":   cmd.Config.TargetedSpace().Name,
    62  			"CurrentUser": user.Name,
    63  		})
    64  	cmd.UI.DisplayNewline()
    65  
    66  	instanceSummaries, warnings, err := cmd.Actor.GetServiceInstancesSummaryBySpace(cmd.Config.TargetedSpace().GUID)
    67  	cmd.UI.DisplayWarnings(warnings)
    68  	if err != nil {
    69  		return err
    70  	}
    71  
    72  	if len(instanceSummaries) == 0 {
    73  		cmd.UI.DisplayText("No services found")
    74  		return nil
    75  	}
    76  
    77  	sortServiceInstances(instanceSummaries)
    78  
    79  	table := [][]string{{
    80  		cmd.UI.TranslateText("name"),
    81  		cmd.UI.TranslateText("service"),
    82  		cmd.UI.TranslateText("plan"),
    83  		cmd.UI.TranslateText("bound apps"),
    84  		cmd.UI.TranslateText("last operation"),
    85  		cmd.UI.TranslateText("broker"),
    86  		cmd.UI.TranslateText("upgrade available"),
    87  	}}
    88  
    89  	var boundAppNames []string
    90  
    91  	for _, summary := range instanceSummaries {
    92  		serviceLabel := summary.Service.Label
    93  		if summary.ServiceInstance.Type == constant.UserProvidedService {
    94  			serviceLabel = "user-provided"
    95  		}
    96  
    97  		boundAppNames = []string{}
    98  		for _, boundApplication := range summary.BoundApplications {
    99  			boundAppNames = append(boundAppNames, boundApplication.AppName)
   100  		}
   101  
   102  		table = append(
   103  			table,
   104  			[]string{
   105  				summary.Name,
   106  				serviceLabel,
   107  				summary.ServicePlan.Name,
   108  				strings.Join(boundAppNames, ", "),
   109  				fmt.Sprintf("%s %s", summary.LastOperation.Type, summary.LastOperation.State),
   110  				summary.Service.ServiceBrokerName,
   111  				upgradeAvailableSummary(summary),
   112  			},
   113  		)
   114  	}
   115  	cmd.UI.DisplayTableWithHeader("", table, 3)
   116  
   117  	isOutdated, err := command.CheckVersionOutdated(cmd.Actor.CloudControllerAPIVersion(), ccversion.MinVersionMaintenanceInfoInSummaryV2)
   118  	if err != nil {
   119  		return err
   120  	}
   121  
   122  	if isOutdated {
   123  		cmd.UI.DisplayNewline()
   124  		cmd.UI.DisplayText("TIP: Please upgrade to CC API v{{.version}} or higher for individual service upgrades",
   125  			map[string]interface{}{
   126  				"version": ccversion.MinVersionMaintenanceInfoInSummaryV2,
   127  			})
   128  	}
   129  
   130  	return nil
   131  }
   132  
   133  func sortServiceInstances(instanceSummaries []v2action.ServiceInstanceSummary) {
   134  	sort.Slice(instanceSummaries, func(i, j int) bool {
   135  		return sorting.LessIgnoreCase(instanceSummaries[i].Name, instanceSummaries[j].Name)
   136  	})
   137  
   138  	for _, instance := range instanceSummaries {
   139  		sortBoundApps(instance)
   140  	}
   141  }
   142  
   143  func sortBoundApps(serviceInstance v2action.ServiceInstanceSummary) {
   144  	sort.Slice(
   145  		serviceInstance.BoundApplications,
   146  		func(i, j int) bool {
   147  			return sorting.LessIgnoreCase(serviceInstance.BoundApplications[i].AppName, serviceInstance.BoundApplications[j].AppName)
   148  		})
   149  }
   150  
   151  func upgradeAvailableSummary(s v2action.ServiceInstanceSummary) string {
   152  	if s.UpgradeSupported() {
   153  		if s.UpgradeAvailable() {
   154  			return "yes"
   155  		}
   156  		return "no"
   157  	}
   158  	return ""
   159  }