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