github.com/randomtask1155/cli@v6.41.1-0.20181227003417-a98eed78cbde+incompatible/command/v6/bind_service_command.go (about)

     1  package v6
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"code.cloudfoundry.org/cli/actor/sharedaction"
     7  	"code.cloudfoundry.org/cli/actor/v2action"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccversion"
    10  	"code.cloudfoundry.org/cli/command"
    11  	"code.cloudfoundry.org/cli/command/flag"
    12  	"code.cloudfoundry.org/cli/command/v6/shared"
    13  )
    14  
    15  //go:generate counterfeiter . BindServiceActor
    16  
    17  type BindServiceActor interface {
    18  	BindServiceBySpace(appName string, ServiceInstanceName string, spaceGUID string, bindingName string, parameters map[string]interface{}) (v2action.ServiceBinding, v2action.Warnings, error)
    19  	CloudControllerAPIVersion() string
    20  }
    21  
    22  type BindServiceCommand struct {
    23  	RequiredArgs     flag.BindServiceArgs          `positional-args:"yes"`
    24  	BindingName      flag.BindingName              `long:"binding-name" description:"Name to expose service instance to app process with (Default: service instance name)"`
    25  	ParametersAsJSON flag.JSONOrFileWithValidation `short:"c" description:"Valid JSON object containing service-specific configuration parameters, provided either in-line or in a file. For a list of supported configuration parameters, see documentation for the particular service offering."`
    26  	usage            interface{}                   `usage:"CF_NAME bind-service APP_NAME SERVICE_INSTANCE [-c PARAMETERS_AS_JSON] [--binding-name BINDING_NAME]\n\n   Optionally provide service-specific configuration parameters in a valid JSON object in-line:\n\n   CF_NAME bind-service APP_NAME SERVICE_INSTANCE -c '{\"name\":\"value\",\"name\":\"value\"}'\n\n   Optionally provide a file containing service-specific configuration parameters in a valid JSON object. \n   The path to the parameters file can be an absolute or relative path to a file.\n   CF_NAME bind-service APP_NAME SERVICE_INSTANCE -c PATH_TO_FILE\n\n   Example of valid JSON object:\n   {\n      \"permissions\": \"read-only\"\n   }\n\n   Optionally provide a binding name for the association between an app and a service instance:\n\n   CF_NAME bind-service APP_NAME SERVICE_INSTANCE --binding-name BINDING_NAME\n\nEXAMPLES:\n   Linux/Mac:\n      CF_NAME bind-service myapp mydb -c '{\"permissions\":\"read-only\"}'\n\n   Windows Command Line:\n      CF_NAME bind-service myapp mydb -c \"{\\\"permissions\\\":\\\"read-only\\\"}\"\n\n   Windows PowerShell:\n      CF_NAME bind-service myapp mydb -c '{\\\"permissions\\\":\\\"read-only\\\"}'\n\n   CF_NAME bind-service myapp mydb -c ~/workspace/tmp/instance_config.json --binding-name BINDING_NAME"`
    27  	relatedCommands  interface{}                   `related_commands:"services"`
    28  
    29  	UI          command.UI
    30  	Config      command.Config
    31  	SharedActor command.SharedActor
    32  	Actor       BindServiceActor
    33  }
    34  
    35  func (cmd *BindServiceCommand) Setup(config command.Config, ui command.UI) error {
    36  	cmd.UI = ui
    37  	cmd.Config = config
    38  	cmd.SharedActor = sharedaction.NewActor(config)
    39  
    40  	ccClient, uaaClient, err := shared.NewClients(config, ui, true)
    41  	if err != nil {
    42  		return err
    43  	}
    44  	cmd.Actor = v2action.NewActor(ccClient, uaaClient, config)
    45  
    46  	return nil
    47  }
    48  
    49  func (cmd BindServiceCommand) Execute(args []string) error {
    50  	template := "Binding service {{.ServiceName}} to app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}..."
    51  	if cmd.BindingName.Value != "" {
    52  		err := command.MinimumCCAPIVersionCheck(
    53  			cmd.Actor.CloudControllerAPIVersion(),
    54  			ccversion.MinVersionProvideNameForServiceBindingV2,
    55  			"Option '--name'")
    56  		if err != nil {
    57  			return err
    58  		}
    59  
    60  		template = "Binding service {{.ServiceName}} to app {{.AppName}} with binding name {{.BindingName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}..."
    61  	}
    62  
    63  	err := cmd.SharedActor.CheckTarget(true, true)
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	user, err := cmd.Config.CurrentUser()
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	cmd.UI.DisplayTextWithFlavor(template, map[string]interface{}{
    74  		"ServiceName": cmd.RequiredArgs.ServiceInstanceName,
    75  		"AppName":     cmd.RequiredArgs.AppName,
    76  		"BindingName": cmd.BindingName.Value,
    77  		"OrgName":     cmd.Config.TargetedOrganization().Name,
    78  		"SpaceName":   cmd.Config.TargetedSpace().Name,
    79  		"CurrentUser": user.Name,
    80  	})
    81  
    82  	serviceBinding, warnings, err := cmd.Actor.BindServiceBySpace(cmd.RequiredArgs.AppName, cmd.RequiredArgs.ServiceInstanceName, cmd.Config.TargetedSpace().GUID, cmd.BindingName.Value, cmd.ParametersAsJSON)
    83  	cmd.UI.DisplayWarnings(warnings)
    84  	if err != nil {
    85  		if _, isTakenError := err.(ccerror.ServiceBindingTakenError); isTakenError {
    86  			cmd.UI.DisplayText("App {{.AppName}} is already bound to {{.ServiceName}}.", map[string]interface{}{
    87  				"AppName":     cmd.RequiredArgs.AppName,
    88  				"ServiceName": cmd.RequiredArgs.ServiceInstanceName,
    89  			})
    90  			cmd.UI.DisplayOK()
    91  			return nil
    92  		}
    93  		return err
    94  	}
    95  
    96  	cmd.UI.DisplayOK()
    97  
    98  	if serviceBinding.IsInProgress() {
    99  		cmd.UI.DisplayNewline()
   100  		cmd.UI.DisplayText("Binding in progress. Use '{{.CFCommand}} {{.ServiceName}}' to check operation status.", map[string]interface{}{
   101  			"CFCommand":   fmt.Sprintf("%s service", cmd.Config.BinaryName()),
   102  			"ServiceName": cmd.RequiredArgs.ServiceInstanceName,
   103  		})
   104  		cmd.UI.DisplayText("TIP: Once this operation succeeds, use '{{.CFCommand}} {{.AppName}}' to ensure your env variable changes take effect.", map[string]interface{}{
   105  			"CFCommand": fmt.Sprintf("%s restage", cmd.Config.BinaryName()),
   106  			"AppName":   cmd.RequiredArgs.AppName,
   107  		})
   108  		return nil
   109  	}
   110  
   111  	cmd.UI.DisplayText("TIP: Use '{{.CFCommand}} {{.AppName}}' to ensure your env variable changes take effect", map[string]interface{}{
   112  		"CFCommand": fmt.Sprintf("%s restage", cmd.Config.BinaryName()),
   113  		"AppName":   cmd.RequiredArgs.AppName,
   114  	})
   115  
   116  	return nil
   117  }