func (*AppDialer) Dial(appName string, instanceIndex int, config *config_package.Config) (Client, error) { diegoSSHUser := fmt.Sprintf("diego:%s/%d", appName, instanceIndex) address := fmt.Sprintf("%s:2222", config.Target()) client, err := sshapi.New(diegoSSHUser, config.Username(), config.Password(), address) if err != nil { return nil, err } return client, nil }
fakeExitHandler = &fake_exit_handler.FakeExitHandler{} fakeSecureShell = &fake_secure_shell.FakeSecureShell{} }) Describe("SSHCommand", func() { var sshCommand cli.Command BeforeEach(func() { commandFactory := command_factory.NewSSHCommandFactory(config, terminalUI, fakeExitHandler, fakeSecureShell) sshCommand = commandFactory.MakeSSHCommand() }) It("should ssh to instance 0 given an app name", func() { test_helpers.ExecuteCommandWithArgs(sshCommand, []string{"app-name"}) Expect(outputBuffer).To(test_helpers.SayLine("Connecting to app-name/0 at %s", config.Target())) Expect(fakeSecureShell.ConnectToShellCallCount()).To(Equal(1)) appName, instanceIndex, command, actualConfig := fakeSecureShell.ConnectToShellArgsForCall(0) Expect(appName).To(Equal("app-name")) Expect(instanceIndex).To(Equal(0)) Expect(command).To(BeEmpty()) Expect(actualConfig).To(Equal(config)) }) It("should ssh to instance index specified", func() { test_helpers.ExecuteCommandWithArgs(sshCommand, []string{"--instance", "2", "app-name"}) Expect(outputBuffer).To(test_helpers.SayLine("Connecting to app-name/2 at %s", config.Target())) Expect(fakeSecureShell.ConnectToShellCallCount()).To(Equal(1))
func cliCommands(ltcConfigRoot string, exitHandler exit_handler.ExitHandler, config *config.Config, logger lager.Logger, targetVerifier target_verifier.TargetVerifier, ui terminal.UI) []cli.Command { receptorClient := receptor.NewClient(config.Receptor()) noaaConsumer := noaa.NewConsumer(LoggregatorUrl(config.Loggregator()), nil, nil) appRunner := app_runner.New(receptorClient, config.Target()) clock := clock.NewClock() logReader := logs.NewLogReader(noaaConsumer) tailedLogsOutputter := console_tailed_logs_outputter.NewConsoleTailedLogsOutputter(ui, logReader) taskExaminer := task_examiner.New(receptorClient) taskExaminerCommandFactory := task_examiner_command_factory.NewTaskExaminerCommandFactory(taskExaminer, ui, exitHandler) taskRunner := task_runner.New(receptorClient, taskExaminer) taskRunnerCommandFactory := task_runner_command_factory.NewTaskRunnerCommandFactory(taskRunner, ui, exitHandler) appExaminer := app_examiner.New(receptorClient, app_examiner.NewNoaaConsumer(noaaConsumer)) graphicalVisualizer := graphical.NewGraphicalVisualizer(appExaminer) appExaminerCommandFactory := app_examiner_command_factory.NewAppExaminerCommandFactory(appExaminer, ui, clock, exitHandler, graphicalVisualizer, taskExaminer, config.Target()) appRunnerCommandFactoryConfig := app_runner_command_factory.AppRunnerCommandFactoryConfig{ AppRunner: appRunner, AppExaminer: appExaminer, UI: ui, Domain: config.Target(), Env: os.Environ(), Clock: clock, Logger: logger, TailedLogsOutputter: tailedLogsOutputter, ExitHandler: exitHandler, } appRunnerCommandFactory := app_runner_command_factory.NewAppRunnerCommandFactory(appRunnerCommandFactoryConfig) dockerRunnerCommandFactoryConfig := docker_runner_command_factory.DockerRunnerCommandFactoryConfig{ AppRunner: appRunner, AppExaminer: appExaminer, UI: ui, Domain: config.Target(), Env: os.Environ(), Clock: clock, Logger: logger, ExitHandler: exitHandler, TailedLogsOutputter: tailedLogsOutputter, DockerMetadataFetcher: docker_metadata_fetcher.New(docker_metadata_fetcher.NewDockerSessionFactory()), } dockerRunnerCommandFactory := docker_runner_command_factory.NewDockerRunnerCommandFactory(dockerRunnerCommandFactoryConfig) logsCommandFactory := logs_command_factory.NewLogsCommandFactory(appExaminer, taskExaminer, ui, tailedLogsOutputter, exitHandler) clusterTestRunner := cluster_test.NewClusterTestRunner(config, ltcConfigRoot) clusterTestCommandFactory := cluster_test_command_factory.NewClusterTestCommandFactory(clusterTestRunner) blobStore := blob_store.New(config) blobStoreVerifier := blob_store.NewVerifier(config) dropletRunner := droplet_runner.New(appRunner, taskRunner, config, blobStore, appExaminer) cfIgnore := cf_ignore.New() zipper := &zipper_package.DropletArtifactZipper{} dropletRunnerCommandFactory := droplet_runner_command_factory.NewDropletRunnerCommandFactory(*appRunnerCommandFactory, blobStoreVerifier, taskExaminer, dropletRunner, cfIgnore, zipper, config) configCommandFactory := config_command_factory.NewConfigCommandFactory(config, ui, targetVerifier, blobStoreVerifier, exitHandler) helpCommand := cli.Command{ Name: "help", Aliases: []string{"h"}, Usage: "Shows a list of commands or help for one command", Description: "ltc help", Action: defaultAction, } return []cli.Command{ appExaminerCommandFactory.MakeCellsCommand(), dockerRunnerCommandFactory.MakeCreateAppCommand(), appRunnerCommandFactory.MakeSubmitLrpCommand(), logsCommandFactory.MakeDebugLogsCommand(), appExaminerCommandFactory.MakeListAppCommand(), logsCommandFactory.MakeLogsCommand(), appRunnerCommandFactory.MakeRemoveAppCommand(), appRunnerCommandFactory.MakeScaleAppCommand(), appExaminerCommandFactory.MakeStatusCommand(), taskRunnerCommandFactory.MakeSubmitTaskCommand(), configCommandFactory.MakeTargetCommand(), taskExaminerCommandFactory.MakeTaskCommand(), taskRunnerCommandFactory.MakeDeleteTaskCommand(), taskRunnerCommandFactory.MakeCancelTaskCommand(), clusterTestCommandFactory.MakeClusterTestCommand(), appRunnerCommandFactory.MakeUpdateRoutesCommand(), appRunnerCommandFactory.MakeUpdateCommand(), appExaminerCommandFactory.MakeVisualizeCommand(), dropletRunnerCommandFactory.MakeBuildDropletCommand(), dropletRunnerCommandFactory.MakeListDropletsCommand(), dropletRunnerCommandFactory.MakeLaunchDropletCommand(), dropletRunnerCommandFactory.MakeRemoveDropletCommand(), dropletRunnerCommandFactory.MakeImportDropletCommand(), dropletRunnerCommandFactory.MakeExportDropletCommand(), helpCommand, } }
BeforeEach(func() { fakeTargetVerifier.VerifyTargetReturns(true, false, nil) fakeBlobStoreVerifier.VerifyReturns(true, nil) fakePasswordReader.PromptForPasswordReturns("testpassword") }) It("prompts for credentials and stores them in the config", func() { doneChan := test_helpers.AsyncExecuteCommandWithArgs(targetCommand, []string{"myapi.com"}) Eventually(outputBuffer).Should(test_helpers.Say("Username: "******"testusername\n")) Eventually(doneChan, 3).Should(BeClosed()) Expect(config.Target()).To(Equal("myapi.com")) Expect(config.Receptor()).To(Equal("http://*****:*****@receptor.myapi.com")) Expect(outputBuffer).To(test_helpers.SayLine("API location set.")) Expect(fakePasswordReader.PromptForPasswordCallCount()).To(Equal(1)) Expect(fakePasswordReader.PromptForPasswordArgsForCall(0)).To(Equal("Password")) Expect(fakeTargetVerifier.VerifyTargetCallCount()).To(Equal(2)) Expect(fakeTargetVerifier.VerifyTargetArgsForCall(0)).To(Equal("http://receptor.myapi.com")) Expect(fakeTargetVerifier.VerifyTargetArgsForCall(1)).To(Equal("http://*****:*****@receptor.myapi.com")) }) Context("when provided receptor credentials are invalid", func() { It("does not save the config", func() { fakePasswordReader.PromptForPasswordReturns("some-invalid-password") doneChan := test_helpers.AsyncExecuteCommandWithArgs(targetCommand, []string{"newtarget.com"})
func (ss *SecureShell) ConnectToShell(appName string, instanceIndex int, command string, config *config_package.Config) error { diegoSSHUser := fmt.Sprintf("diego:%s/%d", appName, instanceIndex) address := fmt.Sprintf("%s:2222", config.Target()) session, err := ss.Dialer.Dial(diegoSSHUser, config.Username(), config.Password(), address) if err != nil { return err } defer session.Close() sessionIn, err := session.StdinPipe() if err != nil { return err } sessionOut, err := session.StdoutPipe() if err != nil { return err } sessionErr, err := session.StderrPipe() if err != nil { return err } modes := ssh.TerminalModes{ ssh.ECHO: 1, ssh.TTY_OP_ISPEED: 115200, ssh.TTY_OP_OSPEED: 115200, } width, height := ss.Term.GetWinsize(os.Stdout.Fd()) terminalType := os.Getenv("TERM") if terminalType == "" { terminalType = "xterm" } if err := session.RequestPty(terminalType, height, width, modes); err != nil { return err } if state, err := ss.Term.SetRawTerminal(os.Stdin.Fd()); err == nil { defer ss.Term.RestoreTerminal(os.Stdin.Fd(), state) } go copyAndClose(nil, sessionIn, os.Stdin) go io.Copy(os.Stdout, sessionOut) go io.Copy(os.Stderr, sessionErr) resized := make(chan os.Signal, 16) signal.Notify(resized, syscall.SIGWINCH) defer func() { signal.Stop(resized) close(resized) }() go ss.resize(resized, session, os.Stdout.Fd(), width, height) keepaliveStopCh := make(chan struct{}) defer close(keepaliveStopCh) go ss.keepalive(session, keepaliveStopCh) if command == "" { session.Shell() session.Wait() } else { session.Run(command) } return nil }
func cliCommands(ltcConfigRoot string, exitHandler exit_handler.ExitHandler, config *config.Config, logger lager.Logger, receptorClientCreator receptor_client.Creator, targetVerifier target_verifier.TargetVerifier, ui terminal.UI) []cli.Command { receptorClient := receptorClientCreator.CreateReceptorClient(config.Receptor()) noaaConsumer := noaa.NewConsumer(LoggregatorUrl(config.Loggregator()), nil, nil) appRunner := app_runner.New(receptorClient, config.Target(), &keygen_package.KeyGenerator{RandReader: rand.Reader}) clock := clock.NewClock() logReader := logs.NewLogReader(noaaConsumer) tailedLogsOutputter := console_tailed_logs_outputter.NewConsoleTailedLogsOutputter(ui, logReader) taskExaminer := task_examiner.New(receptorClient) taskExaminerCommandFactory := task_examiner_command_factory.NewTaskExaminerCommandFactory(taskExaminer, ui, exitHandler) taskRunner := task_runner.New(receptorClient, taskExaminer) taskRunnerCommandFactory := task_runner_command_factory.NewTaskRunnerCommandFactory(taskRunner, ui, exitHandler) appExaminer := app_examiner.New(receptorClient, app_examiner.NewNoaaConsumer(noaaConsumer)) graphicalVisualizer := graphical.NewGraphicalVisualizer(appExaminer) dockerTerminal := &app_examiner_command_factory.DockerTerminal{} appExaminerCommandFactory := app_examiner_command_factory.NewAppExaminerCommandFactory(appExaminer, ui, dockerTerminal, clock, exitHandler, graphicalVisualizer, taskExaminer, config.Target()) appRunnerCommandFactoryConfig := app_runner_command_factory.AppRunnerCommandFactoryConfig{ AppRunner: appRunner, AppExaminer: appExaminer, UI: ui, Domain: config.Target(), Env: os.Environ(), Clock: clock, Logger: logger, TailedLogsOutputter: tailedLogsOutputter, ExitHandler: exitHandler, } appRunnerCommandFactory := app_runner_command_factory.NewAppRunnerCommandFactory(appRunnerCommandFactoryConfig) dockerRunnerCommandFactoryConfig := docker_runner_command_factory.DockerRunnerCommandFactoryConfig{ AppRunner: appRunner, AppExaminer: appExaminer, UI: ui, Domain: config.Target(), Env: os.Environ(), Clock: clock, Logger: logger, ExitHandler: exitHandler, TailedLogsOutputter: tailedLogsOutputter, DockerMetadataFetcher: docker_metadata_fetcher.New(docker_metadata_fetcher.NewDockerSessionFactory()), } dockerRunnerCommandFactory := docker_runner_command_factory.NewDockerRunnerCommandFactory(dockerRunnerCommandFactoryConfig) logsCommandFactory := logs_command_factory.NewLogsCommandFactory(appExaminer, taskExaminer, ui, tailedLogsOutputter, exitHandler) clusterTestRunner := cluster_test.NewClusterTestRunner(config, ltcConfigRoot) clusterTestCommandFactory := cluster_test_command_factory.NewClusterTestCommandFactory(clusterTestRunner) blobStore := blob_store.New(config) blobStoreVerifier := blob_store.BlobStoreVerifier{ DAVBlobStoreVerifier: dav_blob_store.Verifier{}, S3BlobStoreVerifier: s3_blob_store.Verifier{}, } httpProxyConfReader := &droplet_runner.HTTPProxyConfReader{ URL: fmt.Sprintf("http://%s:8444/proxyconf.json", config.Target()), } dropletRunner := droplet_runner.New(appRunner, taskRunner, config, blobStore, appExaminer, httpProxyConfReader) cfIgnore := cf_ignore.New() zipper := &zipper_package.DropletArtifactZipper{} dropletRunnerCommandFactory := droplet_runner_command_factory.NewDropletRunnerCommandFactory(*appRunnerCommandFactory, blobStoreVerifier, taskExaminer, dropletRunner, cfIgnore, zipper, config) configCommandFactory := config_command_factory.NewConfigCommandFactory(config, ui, targetVerifier, blobStoreVerifier, exitHandler) secureDialer := &secure_shell.SecureDialer{DialFunc: ssh.Dial} secureTerm := &secure_shell.SecureTerm{} keepaliveInterval := 30 * time.Second secureShell := &secure_shell.SecureShell{ Dialer: secureDialer, Term: secureTerm, Clock: clock, Ticker: clock.NewTicker(keepaliveInterval), } sshCommandFactory := ssh_command_factory.NewSSHCommandFactory(config, ui, exitHandler, appExaminer, secureShell) helpCommand := cli.Command{ Name: "help", Aliases: []string{"h"}, Usage: "Shows a list of commands or help for one command", Description: "ltc help", Action: defaultAction, } return []cli.Command{ appExaminerCommandFactory.MakeCellsCommand(), dockerRunnerCommandFactory.MakeCreateAppCommand(), appRunnerCommandFactory.MakeSubmitLrpCommand(), logsCommandFactory.MakeDebugLogsCommand(), appExaminerCommandFactory.MakeListAppCommand(), logsCommandFactory.MakeLogsCommand(), appRunnerCommandFactory.MakeRemoveAppCommand(), appRunnerCommandFactory.MakeScaleAppCommand(), appExaminerCommandFactory.MakeStatusCommand(), taskRunnerCommandFactory.MakeSubmitTaskCommand(), configCommandFactory.MakeTargetCommand(), taskExaminerCommandFactory.MakeTaskCommand(), taskRunnerCommandFactory.MakeDeleteTaskCommand(), taskRunnerCommandFactory.MakeCancelTaskCommand(), clusterTestCommandFactory.MakeClusterTestCommand(), appRunnerCommandFactory.MakeUpdateRoutesCommand(), appRunnerCommandFactory.MakeUpdateCommand(), appExaminerCommandFactory.MakeVisualizeCommand(), dropletRunnerCommandFactory.MakeBuildDropletCommand(), dropletRunnerCommandFactory.MakeListDropletsCommand(), dropletRunnerCommandFactory.MakeLaunchDropletCommand(), dropletRunnerCommandFactory.MakeRemoveDropletCommand(), dropletRunnerCommandFactory.MakeImportDropletCommand(), dropletRunnerCommandFactory.MakeExportDropletCommand(), sshCommandFactory.MakeSSHCommand(), helpCommand, } }
func cliCommands(ltcConfigRoot string, exitHandler exit_handler.ExitHandler, config *config.Config, logger lager.Logger, targetVerifier target_verifier.TargetVerifier, ui terminal.UI) []cli.Command { receptorClient := receptor.NewClient(config.Receptor()) noaaConsumer := noaa.NewConsumer(LoggregatorUrl(config.Loggregator()), nil, nil) appRunner := app_runner.New(receptorClient, config.Target()) clock := clock.NewClock() logReader := logs.NewLogReader(noaaConsumer) tailedLogsOutputter := console_tailed_logs_outputter.NewConsoleTailedLogsOutputter(ui, logReader) taskExaminer := task_examiner.New(receptorClient) taskExaminerCommandFactory := task_examiner_command_factory.NewTaskExaminerCommandFactory(taskExaminer, ui, exitHandler) taskRunner := task_runner.New(receptorClient, taskExaminer) taskRunnerCommandFactory := task_runner_command_factory.NewTaskRunnerCommandFactory(taskRunner, ui, exitHandler) appExaminer := app_examiner.New(receptorClient, app_examiner.NewNoaaConsumer(noaaConsumer)) graphicalVisualizer := graphical.NewGraphicalVisualizer(appExaminer) appExaminerCommandFactory := app_examiner_command_factory.NewAppExaminerCommandFactory(appExaminer, ui, clock, exitHandler, graphicalVisualizer, taskExaminer) appRunnerCommandFactoryConfig := app_runner_command_factory.AppRunnerCommandFactoryConfig{ AppRunner: appRunner, AppExaminer: appExaminer, UI: ui, Domain: config.Target(), Env: os.Environ(), Clock: clock, Logger: logger, TailedLogsOutputter: tailedLogsOutputter, ExitHandler: exitHandler, } appRunnerCommandFactory := app_runner_command_factory.NewAppRunnerCommandFactory(appRunnerCommandFactoryConfig) dockerRunnerCommandFactoryConfig := docker_runner_command_factory.DockerRunnerCommandFactoryConfig{ AppRunner: appRunner, AppExaminer: appExaminer, UI: ui, Domain: config.Target(), Env: os.Environ(), Clock: clock, Logger: logger, ExitHandler: exitHandler, TailedLogsOutputter: tailedLogsOutputter, DockerMetadataFetcher: docker_metadata_fetcher.New(docker_metadata_fetcher.NewDockerSessionFactory()), } dockerRunnerCommandFactory := docker_runner_command_factory.NewDockerRunnerCommandFactory(dockerRunnerCommandFactoryConfig) logsCommandFactory := logs_command_factory.NewLogsCommandFactory(appExaminer, ui, tailedLogsOutputter, exitHandler) configCommandFactory := config_command_factory.NewConfigCommandFactory(config, ui, targetVerifier, exitHandler) testRunner := integration_test.NewIntegrationTestRunner(config, ltcConfigRoot) integrationTestCommandFactory := integration_test_command_factory.NewIntegrationTestCommandFactory(testRunner) s3Auth := aws.Auth{ AccessKey: config.BlobTarget().AccessKey, SecretKey: config.BlobTarget().SecretKey, } s3S3 := s3.New(s3Auth, awsRegion, &http.Client{ Transport: &http.Transport{ Proxy: config.BlobTarget().Proxy(), Dial: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).Dial, TLSHandshakeTimeout: 10 * time.Second, }, }) blobStore := blob_store.NewBlobStore(config, s3S3) blobBucket := blobStore.Bucket(config.BlobTarget().BucketName) dropletRunner := droplet_runner.New(appRunner, taskRunner, config, blobStore, blobBucket, targetVerifier, appExaminer) cfIgnore := cf_ignore.New() dropletRunnerCommandFactory := droplet_runner_command_factory.NewDropletRunnerCommandFactory(*appRunnerCommandFactory, taskExaminer, dropletRunner, cfIgnore) helpCommand := cli.Command{ Name: "help", Aliases: []string{"h"}, Usage: "Shows a list of commands or help for one command", Description: "ltc help", Action: defaultAction, } return []cli.Command{ appExaminerCommandFactory.MakeCellsCommand(), dockerRunnerCommandFactory.MakeCreateAppCommand(), appRunnerCommandFactory.MakeSubmitLrpCommand(), logsCommandFactory.MakeDebugLogsCommand(), appExaminerCommandFactory.MakeListAppCommand(), logsCommandFactory.MakeLogsCommand(), appRunnerCommandFactory.MakeRemoveAppCommand(), appRunnerCommandFactory.MakeScaleAppCommand(), appExaminerCommandFactory.MakeStatusCommand(), taskRunnerCommandFactory.MakeSubmitTaskCommand(), configCommandFactory.MakeTargetCommand(), configCommandFactory.MakeTargetBlobCommand(), taskExaminerCommandFactory.MakeTaskCommand(), taskRunnerCommandFactory.MakeDeleteTaskCommand(), taskRunnerCommandFactory.MakeCancelTaskCommand(), integrationTestCommandFactory.MakeIntegrationTestCommand(), appRunnerCommandFactory.MakeUpdateRoutesCommand(), appExaminerCommandFactory.MakeVisualizeCommand(), dropletRunnerCommandFactory.MakeBuildDropletCommand(), dropletRunnerCommandFactory.MakeListDropletsCommand(), dropletRunnerCommandFactory.MakeLaunchDropletCommand(), dropletRunnerCommandFactory.MakeRemoveDropletCommand(), helpCommand, } }
var _ = Describe("Config", func() { var ( testPersister *fakePersister testConfig *config.Config ) BeforeEach(func() { testPersister = &fakePersister{} testConfig = config.New(testPersister) }) Describe("Target", func() { It("sets the target", func() { testConfig.SetTarget("mynewapi.com") Expect(testConfig.Target()).To(Equal("mynewapi.com")) }) }) Describe("Username", func() { It("sets the target", func() { testConfig.SetLogin("ausername", "apassword") Expect(testConfig.Username()).To(Equal("ausername")) }) }) Describe("Receptor", func() { It("returns the Receptor with a username and password", func() { testConfig.SetTarget("mynewapi.com") testConfig.SetLogin("testusername", "testpassword")
Expect(outputBuffer).To(test_helpers.SayLine("Error connecting to good-name/0: connection failed")) Expect(fakeSSH.ConnectCallCount()).To(Equal(1)) Expect(fakeSSH.ForwardCallCount()).To(Equal(0)) Expect(fakeSSH.ShellCallCount()).To(Equal(0)) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed})) }) }) Describe("port forwarding", func() { It("should forward a local port to a remote host and port", func() { fakeAppExaminer.AppStatusReturns(app_examiner.AppInfo{ActualRunningInstances: 1}, nil) test_helpers.ExecuteCommandWithArgs(sshCommand, []string{"app-name", "-N", "-L", "mrlocalhost:1234:remotehost:5678"}) Expect(outputBuffer).To(test_helpers.SayLine("Forwarding mrlocalhost:1234 to remotehost:5678 via app-name/0 at %s", config.Target())) Expect(fakeSSH.ConnectCallCount()).To(Equal(1)) appName, instanceIndex, actualConfig := fakeSSH.ConnectArgsForCall(0) Expect(appName).To(Equal("app-name")) Expect(instanceIndex).To(Equal(0)) Expect(actualConfig).To(Equal(config)) Expect(fakeSSH.ForwardCallCount()).To(Equal(1)) localAddr, remoteAddr := fakeSSH.ForwardArgsForCall(0) Expect(localAddr).To(Equal("mrlocalhost:1234")) Expect(remoteAddr).To(Equal("remotehost:5678")) Expect(fakeAppExaminer.AppStatusCallCount()).To(Equal(1)) Expect(fakeAppExaminer.AppStatusArgsForCall(0)).To(Equal("app-name")) })