func (p *SSHPlugin) GetMetadata() plugin.PluginMetadata { return plugin.PluginMetadata{ Name: "Diego-SSH", Version: plugin.VersionType{ Major: 0, Minor: 1, Build: 2, }, Commands: []plugin.Command{ { Name: "ssh", HelpText: "ssh to an application container instance", UsageDetails: plugin.Usage{ Usage: options.SSHUsage(), }, }, { Name: "enable-ssh", HelpText: "enable ssh for the application", UsageDetails: plugin.Usage{ Usage: cmd.EnableSSHUsage, }, }, { Name: "disable-ssh", HelpText: "disable ssh for the application", UsageDetails: plugin.Usage{ Usage: cmd.DisableSSHUsage, }, }, { Name: "ssh-enabled", HelpText: "reports whether SSH is enabled on an application container instance", UsageDetails: plugin.Usage{ Usage: cmd.SSHEnabledUsage, }, }, { Name: "allow-space-ssh", HelpText: "allow SSH access for the space", UsageDetails: plugin.Usage{ Usage: cmd.AllowSSHUsage, }, }, { Name: "disallow-space-ssh", HelpText: "disallow SSH access for the space", UsageDetails: plugin.Usage{ Usage: cmd.DisallowSSHUsage, }, }, { Name: "space-ssh-allowed", HelpText: "reports whether SSH is allowed in a space", UsageDetails: plugin.Usage{ Usage: cmd.SSHAllowedUsage, }, }, }, } }
func (p *SSHPlugin) Run(cli plugin.CliConnection, args []string) { p.OutputWriter = os.Stdout appFactory := app.NewAppFactory(cli, models.Curl) spaceFactory := space.NewSpaceFactory(cli, models.Curl) switch args[0] { case "CLI-MESSAGE-UNINSTALL": return case "enable-ssh": err := cmd.EnableSSH(args, appFactory) if err != nil { p.Fatal(err) } case "disable-ssh": err := cmd.DisableSSH(args, appFactory) if err != nil { p.Fatal(err) } case "ssh-enabled": err := cmd.SSHEnabled(args, appFactory, p.OutputWriter) if err != nil { p.Fatal(err) } case "allow-space-ssh": err := cmd.AllowSSH(args, spaceFactory) if err != nil { p.Fatal(err) } case "disallow-space-ssh": err := cmd.DisallowSSH(args, spaceFactory) if err != nil { p.Fatal(err) } case "space-ssh-allowed": err := cmd.SSHAllowed(args, spaceFactory, p.OutputWriter) if err != nil { p.Fatal(err) } case "ssh": opts := options.NewSSHOptions() err := opts.Parse(args) if err != nil { p.Fail(err.Error()) fmt.Fprintf(p.OutputWriter, options.SSHUsage()) return } secureShell := cmd.NewSecureShell( cmd.DefaultSecureDialer(), terminal.DefaultHelper(), cmd.DefaultListenerFactory(), 30*time.Second, appFactory, info.NewInfoFactory(cli), credential.NewCredentialFactory(cli), ) err = secureShell.Connect(opts) if err != nil { p.Fail(err.Error()) return } defer secureShell.Close() err = secureShell.LocalPortForward() if err != nil { return } if opts.SkipRemoteExecution { err = secureShell.Wait() } else { err = secureShell.InteractiveSession() } if err == nil { return } if exitError, ok := err.(*ssh.ExitError); ok { exitStatus := exitError.ExitStatus() if sig := exitError.Signal(); sig != "" { fmt.Printf("Process terminated by signal: %s. Exited with %d.\n", sig, exitStatus) } os.Exit(exitStatus) } else { p.Fail(err.Error()) } default: p.Fail("Invalid command") } }
}) }) Context("when -N is specified", func() { BeforeEach(func() { args = append(args, "app-name", "-N") }) It("indicates that no remote command should be run", func() { Expect(parseError).ToNot(HaveOccurred()) Expect(opts.SkipRemoteExecution).To(BeTrue()) Expect(opts.AppName).To(Equal("app-name")) }) }) }) Describe("SSHUsage", func() { It("prints usage information", func() { usage := options.SSHUsage() Expect(usage).To(ContainSubstring("Usage: ssh [-kNTt] [-i app-instance-index] [-L [bind_address:]port:host:hostport] app-name [command]")) Expect(usage).To(ContainSubstring("-i, --index=app-instance-index")) Expect(usage).To(ContainSubstring("-k, --skip-host-validation")) Expect(usage).To(ContainSubstring("-L [bind_address:]port:host:hostport")) Expect(usage).To(ContainSubstring("-N do not execute a remote command")) Expect(usage).To(ContainSubstring("-T disable pseudo-tty allocation")) Expect(usage).To(ContainSubstring("-t force pseudo-tty allocation")) }) }) })