github.com/sleungcy-sap/cli@v7.1.0+incompatible/actor/v7action/ssh_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	. "code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    11  	"code.cloudfoundry.org/cli/resources"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  )
    15  
    16  var _ = Describe("SSH Actions", func() {
    17  	var (
    18  		actor                     *Actor
    19  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    20  		fakeConfig                *v7actionfakes.FakeConfig
    21  		fakeSharedActor           *v7actionfakes.FakeSharedActor
    22  		fakeUAAClient             *v7actionfakes.FakeUAAClient
    23  		executeErr                error
    24  		warnings                  Warnings
    25  	)
    26  
    27  	BeforeEach(func() {
    28  		fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
    29  		fakeConfig = new(v7actionfakes.FakeConfig)
    30  		fakeSharedActor = new(v7actionfakes.FakeSharedActor)
    31  		fakeUAAClient = new(v7actionfakes.FakeUAAClient)
    32  		actor = NewActor(fakeCloudControllerClient, fakeConfig, fakeSharedActor, fakeUAAClient, nil, nil)
    33  	})
    34  
    35  	Describe("GetSSHPasscode", func() {
    36  		var uaaAccessToken string
    37  
    38  		BeforeEach(func() {
    39  			uaaAccessToken = "4cc3sst0k3n"
    40  			fakeConfig.AccessTokenReturns(uaaAccessToken)
    41  			fakeConfig.SSHOAuthClientReturns("some-id")
    42  		})
    43  
    44  		When("no errors are encountered getting the ssh passcode", func() {
    45  			var expectedCode string
    46  
    47  			BeforeEach(func() {
    48  				expectedCode = "s3curep4ss"
    49  				fakeUAAClient.GetSSHPasscodeReturns(expectedCode, nil)
    50  			})
    51  
    52  			It("returns the ssh passcode", func() {
    53  				code, err := actor.GetSSHPasscode()
    54  				Expect(err).ToNot(HaveOccurred())
    55  				Expect(code).To(Equal(expectedCode))
    56  				Expect(fakeUAAClient.GetSSHPasscodeCallCount()).To(Equal(1))
    57  				accessTokenArg, sshOAuthClientArg := fakeUAAClient.GetSSHPasscodeArgsForCall(0)
    58  				Expect(accessTokenArg).To(Equal(uaaAccessToken))
    59  				Expect(sshOAuthClientArg).To(Equal("some-id"))
    60  			})
    61  		})
    62  
    63  		When("an error is encountered getting the ssh passcode", func() {
    64  			var expectedErr error
    65  
    66  			BeforeEach(func() {
    67  				expectedErr = errors.New("failed fetching code")
    68  				fakeUAAClient.GetSSHPasscodeReturns("", expectedErr)
    69  			})
    70  
    71  			It("returns the error", func() {
    72  				_, err := actor.GetSSHPasscode()
    73  				Expect(err).To(MatchError(expectedErr))
    74  				Expect(fakeUAAClient.GetSSHPasscodeCallCount()).To(Equal(1))
    75  				accessTokenArg, sshOAuthClientArg := fakeUAAClient.GetSSHPasscodeArgsForCall(0)
    76  				Expect(accessTokenArg).To(Equal(uaaAccessToken))
    77  				Expect(sshOAuthClientArg).To(Equal("some-id"))
    78  			})
    79  		})
    80  	})
    81  	Describe("GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndex", func() {
    82  		var sshAuth SSHAuthentication
    83  
    84  		BeforeEach(func() {
    85  			fakeConfig.AccessTokenReturns("some-access-token")
    86  			fakeConfig.SSHOAuthClientReturns("some-access-oauth-client")
    87  		})
    88  
    89  		JustBeforeEach(func() {
    90  			sshAuth, warnings, executeErr = actor.GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndex("some-app", "some-space-guid", "some-process-type", 0)
    91  		})
    92  
    93  		When("the app ssh endpoint is empty", func() {
    94  			BeforeEach(func() {
    95  				fakeCloudControllerClient.AppSSHEndpointReturns("")
    96  			})
    97  			It("creates an ssh-endpoint-not-set error", func() {
    98  				Expect(executeErr).To(MatchError("SSH endpoint not set"))
    99  			})
   100  		})
   101  
   102  		When("the app ssh hostkey fingerprint is empty", func() {
   103  			BeforeEach(func() {
   104  				fakeCloudControllerClient.AppSSHEndpointReturns("some-app-ssh-endpoint")
   105  				fakeCloudControllerClient.AppSSHHostKeyFingerprintReturns("")
   106  			})
   107  			It("creates an ssh-hostkey-fingerprint-not-set error", func() {
   108  				Expect(executeErr).To(MatchError("SSH hostkey fingerprint not set"))
   109  			})
   110  		})
   111  
   112  		When("ssh endpoint and fingerprint are set", func() {
   113  			BeforeEach(func() {
   114  				fakeCloudControllerClient.AppSSHEndpointReturns("some-app-ssh-endpoint")
   115  				fakeCloudControllerClient.AppSSHHostKeyFingerprintReturns("some-app-ssh-fingerprint")
   116  			})
   117  
   118  			It("looks up the passcode with the config credentials", func() {
   119  				Expect(fakeUAAClient.GetSSHPasscodeCallCount()).To(Equal(1))
   120  				accessTokenArg, oathClientArg := fakeUAAClient.GetSSHPasscodeArgsForCall(0)
   121  				Expect(accessTokenArg).To(Equal("some-access-token"))
   122  				Expect(oathClientArg).To(Equal("some-access-oauth-client"))
   123  			})
   124  
   125  			When("getting the ssh passcode errors", func() {
   126  				BeforeEach(func() {
   127  					fakeUAAClient.GetSSHPasscodeReturns("", errors.New("some-ssh-passcode-error"))
   128  				})
   129  
   130  				It("returns the error", func() {
   131  					Expect(executeErr).To(MatchError("some-ssh-passcode-error"))
   132  				})
   133  			})
   134  
   135  			When("getting the ssh passcode succeeds", func() {
   136  				BeforeEach(func() {
   137  					fakeUAAClient.GetSSHPasscodeReturns("some-ssh-passcode", nil)
   138  				})
   139  
   140  				When("getting the application errors", func() {
   141  					BeforeEach(func() {
   142  						fakeCloudControllerClient.GetApplicationsReturns(nil, ccv3.Warnings{"some-app-warnings"}, errors.New("some-application-error"))
   143  					})
   144  
   145  					It("returns all warnings and the error", func() {
   146  						Expect(executeErr).To(MatchError("some-application-error"))
   147  						Expect(warnings).To(ConsistOf("some-app-warnings"))
   148  					})
   149  				})
   150  
   151  				When("getting the application succeeds with a started application", func() {
   152  					BeforeEach(func() {
   153  						fakeCloudControllerClient.GetApplicationsReturns(
   154  							[]resources.Application{
   155  								{Name: "some-app", State: constant.ApplicationStarted},
   156  							},
   157  							ccv3.Warnings{"some-app-warnings"},
   158  							nil)
   159  					})
   160  
   161  					When("getting the process summaries fails", func() {
   162  						BeforeEach(func() {
   163  							fakeCloudControllerClient.GetApplicationProcessesReturns(nil, ccv3.Warnings{"some-process-warnings"}, errors.New("some-process-error"))
   164  						})
   165  
   166  						It("returns all warnings and the error", func() {
   167  							Expect(executeErr).To(MatchError("some-process-error"))
   168  							Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings"))
   169  						})
   170  					})
   171  
   172  					When("getting the process summaries succeeds", func() {
   173  						When("the process does not exist", func() {
   174  							BeforeEach(func() {
   175  								fakeCloudControllerClient.GetApplicationProcessesReturns([]ccv3.Process{}, ccv3.Warnings{"some-process-warnings"}, nil)
   176  							})
   177  
   178  							It("returns all warnings and the error", func() {
   179  								Expect(executeErr).To(MatchError(actionerror.ProcessNotFoundError{ProcessType: "some-process-type"}))
   180  								Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings"))
   181  							})
   182  						})
   183  
   184  						When("the process doesn't have the specified instance index", func() {
   185  							BeforeEach(func() {
   186  								fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil)
   187  								fakeCloudControllerClient.GetApplicationProcessesReturns([]ccv3.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil)
   188  							})
   189  
   190  							It("returns a ProcessIndexNotFoundError", func() {
   191  								Expect(executeErr).To(MatchError(actionerror.ProcessInstanceNotFoundError{ProcessType: "some-process-type", InstanceIndex: 0}))
   192  							})
   193  						})
   194  
   195  						When("the process instance is not RUNNING", func() {
   196  							BeforeEach(func() {
   197  								fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil)
   198  								fakeCloudControllerClient.GetApplicationProcessesReturns([]ccv3.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil)
   199  								fakeCloudControllerClient.GetProcessInstancesReturns([]ccv3.ProcessInstance{{State: constant.ProcessInstanceDown, Index: 0}}, ccv3.Warnings{"some-instance-warnings"}, nil)
   200  							})
   201  
   202  							It("returns a ProcessInstanceNotRunningError", func() {
   203  								Expect(executeErr).To(MatchError(actionerror.ProcessInstanceNotRunningError{ProcessType: "some-process-type", InstanceIndex: 0}))
   204  							})
   205  						})
   206  
   207  						When("the specified process and index exist and the instance is RUNNING", func() {
   208  							BeforeEach(func() {
   209  								fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil)
   210  								fakeCloudControllerClient.GetApplicationProcessesReturns([]ccv3.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil)
   211  								fakeCloudControllerClient.GetProcessInstancesReturns([]ccv3.ProcessInstance{{State: constant.ProcessInstanceRunning, Index: 0}}, ccv3.Warnings{"some-instance-warnings"}, nil)
   212  							})
   213  
   214  							When("starting the secure session succeeds", func() {
   215  								It("returns all warnings", func() {
   216  									Expect(executeErr).ToNot(HaveOccurred())
   217  									Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings", "some-instance-warnings"))
   218  
   219  									Expect(sshAuth).To(Equal(SSHAuthentication{
   220  										Endpoint:           "some-app-ssh-endpoint",
   221  										HostKeyFingerprint: "some-app-ssh-fingerprint",
   222  										Passcode:           "some-ssh-passcode",
   223  										Username:           "cf:some-process-guid/0",
   224  									}))
   225  
   226  									Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
   227  									Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
   228  										ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app"}},
   229  										ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}},
   230  									))
   231  								})
   232  							})
   233  						})
   234  					})
   235  				})
   236  
   237  				When("getting the application succeeds with a stopped application", func() {
   238  					BeforeEach(func() {
   239  						fakeCloudControllerClient.GetApplicationsReturns(
   240  							[]resources.Application{
   241  								{Name: "some-app", State: constant.ApplicationStopped},
   242  							},
   243  							ccv3.Warnings{"some-app-warnings"},
   244  							nil)
   245  					})
   246  
   247  					It("returns a ApplicationNotStartedError", func() {
   248  						Expect(executeErr).To(MatchError(actionerror.ApplicationNotStartedError{Name: "some-app"}))
   249  						Expect(warnings).To(ConsistOf("some-app-warnings"))
   250  					})
   251  				})
   252  			})
   253  		})
   254  	})
   255  })