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

     1  package v7
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  
     8  	"code.cloudfoundry.org/cli/actor/sharedaction"
     9  	"code.cloudfoundry.org/cli/actor/v7action"
    10  	"code.cloudfoundry.org/cli/command"
    11  	"code.cloudfoundry.org/cli/command/flag"
    12  	"code.cloudfoundry.org/cli/command/translatableerror"
    13  	"code.cloudfoundry.org/cli/command/v7/shared"
    14  	"code.cloudfoundry.org/cli/types"
    15  	"code.cloudfoundry.org/cli/util/ui"
    16  	"code.cloudfoundry.org/clock"
    17  )
    18  
    19  type ResourceType string
    20  
    21  const (
    22  	App           ResourceType = "app"
    23  	Buildpack     ResourceType = "buildpack"
    24  	Domain        ResourceType = "domain"
    25  	Org           ResourceType = "org"
    26  	Route         ResourceType = "route"
    27  	Space         ResourceType = "space"
    28  	Stack         ResourceType = "stack"
    29  	ServiceBroker ResourceType = "service-broker"
    30  )
    31  
    32  //go:generate counterfeiter . LabelsActor
    33  
    34  type LabelsActor interface {
    35  	GetApplicationLabels(appName string, spaceGUID string) (map[string]types.NullString, v7action.Warnings, error)
    36  	GetDomainLabels(domainName string) (map[string]types.NullString, v7action.Warnings, error)
    37  	GetOrganizationLabels(orgName string) (map[string]types.NullString, v7action.Warnings, error)
    38  	GetRouteLabels(routeName string, spaceGUID string) (map[string]types.NullString, v7action.Warnings, error)
    39  	GetSpaceLabels(spaceName string, orgGUID string) (map[string]types.NullString, v7action.Warnings, error)
    40  	GetBuildpackLabels(buildpackName string, buildpackStack string) (map[string]types.NullString, v7action.Warnings, error)
    41  	GetStackLabels(stackName string) (map[string]types.NullString, v7action.Warnings, error)
    42  }
    43  
    44  type LabelsCommand struct {
    45  	RequiredArgs    flag.LabelsArgs `positional-args:"yes"`
    46  	BuildpackStack  string          `long:"stack" short:"s" description:"Specify stack to disambiguate buildpacks with the same name"`
    47  	usage           interface{}     `usage:"CF_NAME labels RESOURCE RESOURCE_NAME\n\nEXAMPLES:\n   cf labels app dora\n   cf labels org business\n   cf labels buildpack go_buildpack --stack cflinuxfs3 \n\nRESOURCES:\n   app\n   buildpack\n   domain\n   org\n   route\n   space\n   stack"`
    48  	relatedCommands interface{}     `related_commands:"set-label, unset-label"`
    49  	UI              command.UI
    50  	Config          command.Config
    51  	SharedActor     command.SharedActor
    52  	Actor           LabelsActor
    53  }
    54  
    55  func (cmd *LabelsCommand) Setup(config command.Config, ui command.UI) error {
    56  	cmd.UI = ui
    57  	cmd.Config = config
    58  	cmd.SharedActor = sharedaction.NewActor(config)
    59  	ccClient, _, err := shared.GetNewClientsAndConnectToCF(config, ui, "")
    60  	if err != nil {
    61  		return err
    62  	}
    63  	cmd.Actor = v7action.NewActor(ccClient, config, nil, nil, clock.NewClock())
    64  	return nil
    65  }
    66  
    67  func (cmd LabelsCommand) Execute(args []string) error {
    68  	var (
    69  		labels   map[string]types.NullString
    70  		warnings v7action.Warnings
    71  	)
    72  	username, err := cmd.Config.CurrentUserName()
    73  	if err != nil {
    74  		return err
    75  	}
    76  
    77  	err = cmd.validateFlags()
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	switch cmd.canonicalResourceTypeForName() {
    83  	case App:
    84  		labels, warnings, err = cmd.fetchAppLabels(username)
    85  	case Buildpack:
    86  		labels, warnings, err = cmd.fetchBuildpackLabels(username)
    87  	case Domain:
    88  		labels, warnings, err = cmd.fetchDomainLabels(username)
    89  	case Org:
    90  		labels, warnings, err = cmd.fetchOrgLabels(username)
    91  	case Route:
    92  		labels, warnings, err = cmd.fetchRouteLabels(username)
    93  	case Space:
    94  		labels, warnings, err = cmd.fetchSpaceLabels(username)
    95  	case Stack:
    96  		labels, warnings, err = cmd.fetchStackLabels(username)
    97  	default:
    98  		err = fmt.Errorf("Unsupported resource type of '%s'", cmd.RequiredArgs.ResourceType)
    99  	}
   100  	cmd.UI.DisplayWarnings(warnings)
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	cmd.printLabels(labels)
   106  	return nil
   107  }
   108  
   109  func (cmd LabelsCommand) fetchAppLabels(username string) (map[string]types.NullString, v7action.Warnings, error) {
   110  	err := cmd.SharedActor.CheckTarget(true, true)
   111  	if err != nil {
   112  		return nil, nil, err
   113  	}
   114  
   115  	cmd.UI.DisplayTextWithFlavor("Getting labels for app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{
   116  		"AppName":   cmd.RequiredArgs.ResourceName,
   117  		"OrgName":   cmd.Config.TargetedOrganization().Name,
   118  		"SpaceName": cmd.Config.TargetedSpace().Name,
   119  		"Username":  username,
   120  	})
   121  
   122  	cmd.UI.DisplayNewline()
   123  	return cmd.Actor.GetApplicationLabels(cmd.RequiredArgs.ResourceName, cmd.Config.TargetedSpace().GUID)
   124  }
   125  
   126  func (cmd LabelsCommand) fetchDomainLabels(username string) (map[string]types.NullString, v7action.Warnings, error) {
   127  	err := cmd.SharedActor.CheckTarget(false, false)
   128  	if err != nil {
   129  		return nil, nil, err
   130  	}
   131  
   132  	cmd.UI.DisplayTextWithFlavor("Getting labels for domain {{.DomainName}} as {{.Username}}...", map[string]interface{}{
   133  		"DomainName": cmd.RequiredArgs.ResourceName,
   134  		"Username":   username,
   135  	})
   136  
   137  	cmd.UI.DisplayNewline()
   138  
   139  	return cmd.Actor.GetDomainLabels(cmd.RequiredArgs.ResourceName)
   140  }
   141  
   142  func (cmd LabelsCommand) fetchOrgLabels(username string) (map[string]types.NullString, v7action.Warnings, error) {
   143  	err := cmd.SharedActor.CheckTarget(false, false)
   144  	if err != nil {
   145  		return nil, nil, err
   146  	}
   147  
   148  	cmd.UI.DisplayTextWithFlavor("Getting labels for org {{.OrgName}} as {{.Username}}...", map[string]interface{}{
   149  		"OrgName":  cmd.RequiredArgs.ResourceName,
   150  		"Username": username,
   151  	})
   152  
   153  	cmd.UI.DisplayNewline()
   154  	return cmd.Actor.GetOrganizationLabels(cmd.RequiredArgs.ResourceName)
   155  }
   156  
   157  func (cmd LabelsCommand) fetchRouteLabels(username string) (map[string]types.NullString, v7action.Warnings, error) {
   158  	err := cmd.SharedActor.CheckTarget(true, true)
   159  	if err != nil {
   160  		return nil, nil, err
   161  	}
   162  
   163  	cmd.UI.DisplayTextWithFlavor("Getting labels for route {{.RouteName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{
   164  		"RouteName": cmd.RequiredArgs.ResourceName,
   165  		"OrgName":   cmd.Config.TargetedOrganization().Name,
   166  		"SpaceName": cmd.Config.TargetedSpace().Name,
   167  		"Username":  username,
   168  	})
   169  
   170  	cmd.UI.DisplayNewline()
   171  
   172  	return cmd.Actor.GetRouteLabels(cmd.RequiredArgs.ResourceName, cmd.Config.TargetedSpace().GUID)
   173  }
   174  
   175  func (cmd LabelsCommand) fetchSpaceLabels(username string) (map[string]types.NullString, v7action.Warnings, error) {
   176  	err := cmd.SharedActor.CheckTarget(true, false)
   177  	if err != nil {
   178  		return nil, nil, err
   179  	}
   180  
   181  	cmd.UI.DisplayTextWithFlavor("Getting labels for space {{.SpaceName}} in org {{.OrgName}} as {{.Username}}...", map[string]interface{}{
   182  		"SpaceName": cmd.RequiredArgs.ResourceName,
   183  		"OrgName":   cmd.Config.TargetedOrganization().Name,
   184  		"Username":  username,
   185  	})
   186  
   187  	cmd.UI.DisplayNewline()
   188  
   189  	return cmd.Actor.GetSpaceLabels(cmd.RequiredArgs.ResourceName, cmd.Config.TargetedOrganization().GUID)
   190  }
   191  
   192  func (cmd LabelsCommand) fetchStackLabels(username string) (map[string]types.NullString, v7action.Warnings, error) {
   193  	err := cmd.SharedActor.CheckTarget(false, false)
   194  	if err != nil {
   195  		return nil, nil, err
   196  	}
   197  
   198  	cmd.UI.DisplayTextWithFlavor("Getting labels for stack {{.StackName}} as {{.Username}}...", map[string]interface{}{
   199  		"StackName": cmd.RequiredArgs.ResourceName,
   200  		"Username":  username,
   201  	})
   202  
   203  	cmd.UI.DisplayNewline()
   204  
   205  	return cmd.Actor.GetStackLabels(cmd.RequiredArgs.ResourceName)
   206  }
   207  
   208  func (cmd LabelsCommand) fetchBuildpackLabels(username string) (map[string]types.NullString, v7action.Warnings, error) {
   209  	err := cmd.SharedActor.CheckTarget(false, false)
   210  	if err != nil {
   211  		return nil, nil, err
   212  	}
   213  
   214  	var template string
   215  	if cmd.BuildpackStack != "" {
   216  		template = "Getting labels for %s {{.ResourceName}} with stack {{.StackName}} as {{.User}}..."
   217  	} else {
   218  		template = "Getting labels for %s {{.ResourceName}} as {{.User}}..."
   219  	}
   220  	preFlavoringText := fmt.Sprintf(template, cmd.RequiredArgs.ResourceType)
   221  	cmd.UI.DisplayTextWithFlavor(
   222  		preFlavoringText,
   223  		map[string]interface{}{
   224  			"ResourceName": cmd.RequiredArgs.ResourceName,
   225  			"StackName":    cmd.BuildpackStack,
   226  			"User":         username,
   227  		},
   228  	)
   229  
   230  	cmd.UI.DisplayNewline()
   231  
   232  	return cmd.Actor.GetBuildpackLabels(cmd.RequiredArgs.ResourceName, cmd.BuildpackStack)
   233  }
   234  
   235  func (cmd LabelsCommand) canonicalResourceTypeForName() ResourceType {
   236  	return ResourceType(strings.ToLower(cmd.RequiredArgs.ResourceType))
   237  }
   238  
   239  func (cmd LabelsCommand) printLabels(labels map[string]types.NullString) {
   240  	if len(labels) == 0 {
   241  		cmd.UI.DisplayText("No labels found.")
   242  		return
   243  	}
   244  
   245  	keys := make([]string, 0, len(labels))
   246  	for key := range labels {
   247  		keys = append(keys, key)
   248  	}
   249  	sort.Strings(keys)
   250  
   251  	table := [][]string{
   252  		{
   253  			cmd.UI.TranslateText("key"),
   254  			cmd.UI.TranslateText("value"),
   255  		},
   256  	}
   257  
   258  	for _, key := range keys {
   259  		table = append(table, []string{key, labels[key].Value})
   260  	}
   261  
   262  	cmd.UI.DisplayTableWithHeader("", table, ui.DefaultTableSpacePadding)
   263  }
   264  
   265  func (cmd LabelsCommand) validateFlags() error {
   266  	if cmd.BuildpackStack != "" && cmd.canonicalResourceTypeForName() != Buildpack {
   267  		return translatableerror.ArgumentCombinationError{
   268  			Args: []string{
   269  				cmd.RequiredArgs.ResourceType, "--stack, -s",
   270  			},
   271  		}
   272  	}
   273  	return nil
   274  }