code.cloudfoundry.org/cli@v7.1.0+incompatible/command/v7/label_updater.go (about)

     1  package v7
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"code.cloudfoundry.org/cli/actor/v7action"
     9  	"code.cloudfoundry.org/cli/command"
    10  	"code.cloudfoundry.org/cli/command/translatableerror"
    11  	"code.cloudfoundry.org/cli/types"
    12  )
    13  
    14  //go:generate counterfeiter . SetLabelActor
    15  
    16  type SetLabelActor interface {
    17  	UpdateApplicationLabelsByApplicationName(string, string, map[string]types.NullString) (v7action.Warnings, error)
    18  	UpdateBuildpackLabelsByBuildpackNameAndStack(string, string, map[string]types.NullString) (v7action.Warnings, error)
    19  	UpdateDomainLabelsByDomainName(string, map[string]types.NullString) (v7action.Warnings, error)
    20  	UpdateOrganizationLabelsByOrganizationName(string, map[string]types.NullString) (v7action.Warnings, error)
    21  	UpdateRouteLabels(string, string, map[string]types.NullString) (v7action.Warnings, error)
    22  	UpdateSpaceLabelsBySpaceName(string, string, map[string]types.NullString) (v7action.Warnings, error)
    23  	UpdateStackLabelsByStackName(string, map[string]types.NullString) (v7action.Warnings, error)
    24  	UpdateServiceBrokerLabelsByServiceBrokerName(string, map[string]types.NullString) (v7action.Warnings, error)
    25  	UpdateServiceOfferingLabels(serviceOfferingName string, serviceBrokerName string, labels map[string]types.NullString) (v7action.Warnings, error)
    26  	UpdateServicePlanLabels(servicePlanName string, serviceOfferingName string, serviceBrokerName string, labels map[string]types.NullString) (v7action.Warnings, error)
    27  }
    28  
    29  type ActionType string
    30  
    31  const (
    32  	Unset ActionType = "Removing"
    33  	Set   ActionType = "Setting"
    34  )
    35  
    36  type TargetResource struct {
    37  	ResourceType    string
    38  	ResourceName    string
    39  	BuildpackStack  string
    40  	ServiceBroker   string
    41  	ServiceOffering string
    42  }
    43  
    44  type LabelUpdater struct {
    45  	targetResource TargetResource
    46  	labels         map[string]types.NullString
    47  
    48  	UI          command.UI
    49  	Config      command.Config
    50  	SharedActor command.SharedActor
    51  	Actor       SetLabelActor
    52  
    53  	Username string
    54  	Action   ActionType
    55  }
    56  
    57  func (cmd *LabelUpdater) Execute(targetResource TargetResource, labels map[string]types.NullString) error {
    58  	cmd.targetResource = targetResource
    59  	cmd.labels = labels
    60  	cmd.targetResource.ResourceType = strings.ToLower(cmd.targetResource.ResourceType)
    61  
    62  	var err error
    63  	cmd.Username, err = cmd.Config.CurrentUserName()
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	if err := cmd.validateFlags(); err != nil {
    69  		return err
    70  	}
    71  
    72  	if err := cmd.checkTarget(); err != nil {
    73  		return err
    74  	}
    75  
    76  	var warnings v7action.Warnings
    77  	switch ResourceType(cmd.targetResource.ResourceType) {
    78  	case App:
    79  		cmd.displayMessageWithOrgAndSpace()
    80  		warnings, err = cmd.Actor.UpdateApplicationLabelsByApplicationName(cmd.targetResource.ResourceName, cmd.Config.TargetedSpace().GUID, cmd.labels)
    81  	case Buildpack:
    82  		cmd.displayMessageWithStack()
    83  		warnings, err = cmd.Actor.UpdateBuildpackLabelsByBuildpackNameAndStack(cmd.targetResource.ResourceName, cmd.targetResource.BuildpackStack, cmd.labels)
    84  	case Domain:
    85  		cmd.displayMessageDefault()
    86  		warnings, err = cmd.Actor.UpdateDomainLabelsByDomainName(cmd.targetResource.ResourceName, cmd.labels)
    87  	case Org:
    88  		cmd.displayMessageDefault()
    89  		warnings, err = cmd.Actor.UpdateOrganizationLabelsByOrganizationName(cmd.targetResource.ResourceName, cmd.labels)
    90  	case Route:
    91  		cmd.displayMessageWithOrgAndSpace()
    92  		warnings, err = cmd.Actor.UpdateRouteLabels(cmd.targetResource.ResourceName, cmd.Config.TargetedSpace().GUID, cmd.labels)
    93  	case ServiceBroker:
    94  		cmd.displayMessageDefault()
    95  		warnings, err = cmd.Actor.UpdateServiceBrokerLabelsByServiceBrokerName(cmd.targetResource.ResourceName, cmd.labels)
    96  	case Space:
    97  		cmd.displayMessageWithOrg()
    98  		warnings, err = cmd.Actor.UpdateSpaceLabelsBySpaceName(cmd.targetResource.ResourceName, cmd.Config.TargetedOrganization().GUID, cmd.labels)
    99  	case Stack:
   100  		cmd.displayMessageDefault()
   101  		warnings, err = cmd.Actor.UpdateStackLabelsByStackName(cmd.targetResource.ResourceName, cmd.labels)
   102  	case ServiceOffering:
   103  		cmd.displayMessageForServiceCommands()
   104  		warnings, err = cmd.Actor.UpdateServiceOfferingLabels(cmd.targetResource.ResourceName, cmd.targetResource.ServiceBroker, cmd.labels)
   105  	case ServicePlan:
   106  		cmd.displayMessageForServiceCommands()
   107  		warnings, err = cmd.Actor.UpdateServicePlanLabels(cmd.targetResource.ResourceName, cmd.targetResource.ServiceOffering, cmd.targetResource.ServiceBroker, cmd.labels)
   108  	}
   109  
   110  	cmd.UI.DisplayWarnings(warnings)
   111  	if err != nil {
   112  		return err
   113  	}
   114  
   115  	cmd.UI.DisplayOK()
   116  	return nil
   117  }
   118  
   119  func (cmd *LabelUpdater) checkTarget() error {
   120  	switch ResourceType(cmd.targetResource.ResourceType) {
   121  	case App, Route:
   122  		return cmd.SharedActor.CheckTarget(true, true)
   123  	case Space:
   124  		return cmd.SharedActor.CheckTarget(true, false)
   125  	default:
   126  		return cmd.SharedActor.CheckTarget(false, false)
   127  	}
   128  }
   129  
   130  func (cmd *LabelUpdater) validateFlags() error {
   131  	resourceType := ResourceType(cmd.targetResource.ResourceType)
   132  	switch resourceType {
   133  	case App, Buildpack, Domain, Org, Route, ServiceBroker, Space, Stack, ServiceOffering, ServicePlan:
   134  	default:
   135  		return errors.New(cmd.UI.TranslateText("Unsupported resource type of '{{.ResourceType}}'", map[string]interface{}{"ResourceType": cmd.targetResource.ResourceType}))
   136  	}
   137  
   138  	if cmd.targetResource.BuildpackStack != "" && resourceType != Buildpack {
   139  		return translatableerror.ArgumentCombinationError{
   140  			Args: []string{
   141  				cmd.targetResource.ResourceType, "--stack, -s",
   142  			},
   143  		}
   144  	}
   145  
   146  	if cmd.targetResource.ServiceBroker != "" && !(resourceType == ServiceOffering || resourceType == ServicePlan) {
   147  		return translatableerror.ArgumentCombinationError{
   148  			Args: []string{
   149  				cmd.targetResource.ResourceType, "--broker, -b",
   150  			},
   151  		}
   152  	}
   153  
   154  	if cmd.targetResource.ServiceOffering != "" && resourceType != ServicePlan {
   155  		return translatableerror.ArgumentCombinationError{
   156  			Args: []string{
   157  				cmd.targetResource.ResourceType, "--offering, -o",
   158  			},
   159  		}
   160  	}
   161  
   162  	return nil
   163  }
   164  
   165  func actionForResourceString(action string, resourceType string) string {
   166  	return fmt.Sprintf("%s label(s) for %s", action, resourceType)
   167  }
   168  
   169  func (cmd *LabelUpdater) displayMessageDefault() {
   170  	cmd.UI.DisplayTextWithFlavor(actionForResourceString(string(cmd.Action), cmd.targetResource.ResourceType)+" {{.ResourceName}} as {{.User}}...", map[string]interface{}{
   171  		"ResourceName": cmd.targetResource.ResourceName,
   172  		"User":         cmd.Username,
   173  	})
   174  }
   175  
   176  func (cmd *LabelUpdater) displayMessageWithOrgAndSpace() {
   177  	cmd.UI.DisplayTextWithFlavor(actionForResourceString(string(cmd.Action), cmd.targetResource.ResourceType)+" {{.ResourceName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.User}}...", map[string]interface{}{
   178  		"ResourceName": cmd.targetResource.ResourceName,
   179  		"OrgName":      cmd.Config.TargetedOrganization().Name,
   180  		"SpaceName":    cmd.Config.TargetedSpace().Name,
   181  		"User":         cmd.Username,
   182  	})
   183  }
   184  
   185  func (cmd *LabelUpdater) displayMessageWithStack() {
   186  	var template string
   187  	if cmd.targetResource.BuildpackStack == "" {
   188  		template = actionForResourceString(string(cmd.Action), cmd.targetResource.ResourceType) + " {{.ResourceName}} as {{.User}}..."
   189  	} else {
   190  		template = actionForResourceString(string(cmd.Action), cmd.targetResource.ResourceType) + " {{.ResourceName}} with stack {{.StackName}} as {{.User}}..."
   191  	}
   192  
   193  	cmd.UI.DisplayTextWithFlavor(template, map[string]interface{}{
   194  		"ResourceName": cmd.targetResource.ResourceName,
   195  		"StackName":    cmd.targetResource.BuildpackStack,
   196  		"User":         cmd.Username,
   197  	})
   198  }
   199  
   200  func (cmd *LabelUpdater) displayMessageForServiceCommands() {
   201  	template := actionForResourceString(string(cmd.Action), cmd.targetResource.ResourceType) + " {{.ResourceName}}"
   202  
   203  	if cmd.targetResource.ServiceOffering != "" || cmd.targetResource.ServiceBroker != "" {
   204  		template += " from"
   205  
   206  		if cmd.targetResource.ServiceOffering != "" {
   207  			template += " service offering {{.ServiceOffering}}"
   208  			if cmd.targetResource.ServiceBroker != "" {
   209  				template += " /"
   210  			}
   211  		}
   212  
   213  		if cmd.targetResource.ServiceBroker != "" {
   214  			template += " service broker {{.ServiceBroker}}"
   215  		}
   216  	}
   217  
   218  	template += " as {{.User}}..."
   219  	cmd.UI.DisplayTextWithFlavor(template, map[string]interface{}{
   220  		"ResourceName":    cmd.targetResource.ResourceName,
   221  		"ServiceBroker":   cmd.targetResource.ServiceBroker,
   222  		"ServiceOffering": cmd.targetResource.ServiceOffering,
   223  		"User":            cmd.Username,
   224  	})
   225  }
   226  
   227  func (cmd *LabelUpdater) displayMessageWithOrg() {
   228  	cmd.UI.DisplayTextWithFlavor(actionForResourceString(string(cmd.Action), cmd.targetResource.ResourceType)+" {{.ResourceName}} in org {{.OrgName}} as {{.User}}...", map[string]interface{}{
   229  		"ResourceName": cmd.targetResource.ResourceName,
   230  		"OrgName":      cmd.Config.TargetedOrganization().Name,
   231  		"User":         cmd.Username,
   232  	})
   233  }