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

     1  package v6
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/actor/sharedaction"
     5  	"code.cloudfoundry.org/cli/actor/v3action"
     6  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccversion"
     7  	"code.cloudfoundry.org/cli/command"
     8  	"code.cloudfoundry.org/cli/command/flag"
     9  	"code.cloudfoundry.org/cli/command/translatableerror"
    10  	"code.cloudfoundry.org/cli/command/v6/shared"
    11  	"code.cloudfoundry.org/cli/util/clissh"
    12  )
    13  
    14  //go:generate counterfeiter . SSHActor
    15  
    16  type SSHActor interface {
    17  	ExecuteSecureShell(sshClient sharedaction.SecureShellClient, sshOptions sharedaction.SSHOptions) error
    18  }
    19  
    20  //go:generate counterfeiter . V3SSHActor
    21  
    22  type V3SSHActor interface {
    23  	CloudControllerAPIVersion() string
    24  	GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndex(appName string, spaceGUID string, processType string, processIndex uint) (v3action.SSHAuthentication, v3action.Warnings, error)
    25  }
    26  
    27  type V3SSHCommand struct {
    28  	RequiredArgs          flag.AppName             `positional-args:"yes"`
    29  	ProcessIndex          uint                     `long:"app-instance-index" short:"i" default:"0" description:"App process instance index"`
    30  	Commands              []string                 `long:"command" short:"c" description:"Command to run"`
    31  	DisablePseudoTTY      bool                     `long:"disable-pseudo-tty" short:"T" description:"Disable pseudo-tty allocation"`
    32  	ForcePseudoTTY        bool                     `long:"force-pseudo-tty" description:"Force pseudo-tty allocation"`
    33  	LocalPortForwardSpecs []flag.SSHPortForwarding `short:"L" description:"Local port forward specification"`
    34  	ProcessType           string                   `long:"process" default:"web" description:"App process name"`
    35  	RequestPseudoTTY      bool                     `long:"request-pseudo-tty" short:"t" description:"Request pseudo-tty allocation"`
    36  	SkipHostValidation    bool                     `long:"skip-host-validation" short:"k" description:"Skip host key validation. Not recommended!"`
    37  	SkipRemoteExecution   bool                     `long:"skip-remote-execution" short:"N" description:"Do not execute a remote command"`
    38  
    39  	usage           interface{} `usage:"CF_NAME v3-ssh APP_NAME [--process PROCESS] [-i INDEX] [-c COMMAND]\n   [-L [BIND_ADDRESS:]LOCAL_PORT:REMOTE_HOST:REMOTE_PORT]... [--skip-remote-execution]\n   [--disable-pseudo-tty | --force-pseudo-tty | --request-pseudo-tty] [--skip-host-validation]"`
    40  	relatedCommands interface{} `related_commands:"allow-space-ssh, enable-ssh, space-ssh-allowed, ssh-code, ssh-enabled"`
    41  	allproxy        interface{} `environmentName:"all_proxy" environmentDescription:"Specify a proxy server to enable proxying for all requests"`
    42  
    43  	UI          command.UI
    44  	Config      command.Config
    45  	SharedActor command.SharedActor
    46  	Actor       V3SSHActor
    47  	SSHActor    SSHActor
    48  	SSHClient   *clissh.SecureShell
    49  }
    50  
    51  func (cmd *V3SSHCommand) Setup(config command.Config, ui command.UI) error {
    52  	cmd.UI = ui
    53  	cmd.Config = config
    54  	sharedActor := sharedaction.NewActor(config)
    55  	cmd.SharedActor = sharedActor
    56  	cmd.SSHActor = sharedActor
    57  
    58  	ccClient, uaaClient, err := shared.NewV3BasedClients(config, ui, true, "")
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	cmd.Actor = v3action.NewActor(ccClient, config, sharedActor, uaaClient)
    64  
    65  	cmd.SSHClient = clissh.NewDefaultSecureShell()
    66  
    67  	return nil
    68  }
    69  
    70  func (cmd V3SSHCommand) Execute(args []string) error {
    71  	cmd.UI.DisplayWarning(command.ExperimentalWarning)
    72  
    73  	err := command.MinimumCCAPIVersionCheck(cmd.Actor.CloudControllerAPIVersion(), ccversion.MinVersionApplicationFlowV3)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	err = cmd.SharedActor.CheckTarget(true, true)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	ttyOption, err := cmd.EvaluateTTYOption()
    84  	if err != nil {
    85  		return err
    86  	}
    87  
    88  	var forwardSpecs []sharedaction.LocalPortForward
    89  	for _, spec := range cmd.LocalPortForwardSpecs {
    90  		forwardSpecs = append(forwardSpecs, sharedaction.LocalPortForward(spec))
    91  	}
    92  
    93  	sshAuth, warnings, err := cmd.Actor.GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndex(
    94  		cmd.RequiredArgs.AppName,
    95  		cmd.Config.TargetedSpace().GUID,
    96  		cmd.ProcessType,
    97  		cmd.ProcessIndex,
    98  	)
    99  	cmd.UI.DisplayWarnings(warnings)
   100  	if err != nil {
   101  		return err
   102  	}
   103  
   104  	err = cmd.SSHActor.ExecuteSecureShell(
   105  		cmd.SSHClient,
   106  		sharedaction.SSHOptions{
   107  			Commands:              cmd.Commands,
   108  			Endpoint:              sshAuth.Endpoint,
   109  			HostKeyFingerprint:    sshAuth.HostKeyFingerprint,
   110  			LocalPortForwardSpecs: forwardSpecs,
   111  			Passcode:              sshAuth.Passcode,
   112  			SkipHostValidation:    cmd.SkipHostValidation,
   113  			SkipRemoteExecution:   cmd.SkipRemoteExecution,
   114  			TTYOption:             ttyOption,
   115  			Username:              sshAuth.Username,
   116  		})
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	return nil
   122  }
   123  
   124  func (cmd V3SSHCommand) parseForwardSpecs() ([]sharedaction.LocalPortForward, error) {
   125  	return nil, nil
   126  }
   127  
   128  // EvaluateTTYOption determines which TTY options are mutually exclusive and
   129  // returns an error accordingly.
   130  func (cmd V3SSHCommand) EvaluateTTYOption() (sharedaction.TTYOption, error) {
   131  	var count int
   132  
   133  	option := sharedaction.RequestTTYAuto
   134  	if cmd.DisablePseudoTTY {
   135  		option = sharedaction.RequestTTYNo
   136  		count++
   137  	}
   138  	if cmd.ForcePseudoTTY {
   139  		option = sharedaction.RequestTTYForce
   140  		count++
   141  	}
   142  	if cmd.RequestPseudoTTY {
   143  		option = sharedaction.RequestTTYYes
   144  		count++
   145  	}
   146  
   147  	if count > 1 {
   148  		return option, translatableerror.ArgumentCombinationError{Args: []string{
   149  			"--disable-pseudo-tty", "-T", "--force-pseudo-tty", "--request-pseudo-tty", "-t",
   150  		}}
   151  	}
   152  
   153  	return option, nil
   154  }