github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/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.GetInfoReturns(ccv3.Info{ 96 Links: ccv3.InfoLinks{ 97 AppSSH: resources.APILink{HREF: ""}, 98 }, 99 }, nil, nil) 100 }) 101 102 It("creates an ssh-endpoint-not-set error", func() { 103 Expect(executeErr).To(MatchError("SSH endpoint not set")) 104 }) 105 }) 106 107 When("the app ssh hostkey fingerprint is empty", func() { 108 BeforeEach(func() { 109 fakeCloudControllerClient.GetInfoReturns(ccv3.Info{ 110 Links: ccv3.InfoLinks{ 111 AppSSH: resources.APILink{HREF: "some-app-ssh-endpoint"}, 112 }, 113 }, nil, nil) 114 }) 115 116 It("creates an ssh-hostkey-fingerprint-not-set error", func() { 117 Expect(executeErr).To(MatchError("SSH hostkey fingerprint not set")) 118 }) 119 }) 120 121 When("ssh endpoint and fingerprint are set", func() { 122 BeforeEach(func() { 123 fakeCloudControllerClient.GetInfoReturns(ccv3.Info{ 124 Links: ccv3.InfoLinks{ 125 AppSSH: resources.APILink{ 126 HREF: "some-app-ssh-endpoint", 127 Meta: resources.APILinkMeta{HostKeyFingerprint: "some-app-ssh-fingerprint"}, 128 }, 129 }, 130 }, nil, nil) 131 }) 132 133 It("looks up the passcode with the config credentials", func() { 134 Expect(fakeUAAClient.GetSSHPasscodeCallCount()).To(Equal(1)) 135 accessTokenArg, oathClientArg := fakeUAAClient.GetSSHPasscodeArgsForCall(0) 136 Expect(accessTokenArg).To(Equal("some-access-token")) 137 Expect(oathClientArg).To(Equal("some-access-oauth-client")) 138 }) 139 140 When("getting the ssh passcode errors", func() { 141 BeforeEach(func() { 142 fakeUAAClient.GetSSHPasscodeReturns("", errors.New("some-ssh-passcode-error")) 143 }) 144 145 It("returns the error", func() { 146 Expect(executeErr).To(MatchError("some-ssh-passcode-error")) 147 }) 148 }) 149 150 When("getting the ssh passcode succeeds", func() { 151 BeforeEach(func() { 152 fakeUAAClient.GetSSHPasscodeReturns("some-ssh-passcode", nil) 153 }) 154 155 When("getting the application errors", func() { 156 BeforeEach(func() { 157 fakeCloudControllerClient.GetApplicationsReturns(nil, ccv3.Warnings{"some-app-warnings"}, errors.New("some-application-error")) 158 }) 159 160 It("returns all warnings and the error", func() { 161 Expect(executeErr).To(MatchError("some-application-error")) 162 Expect(warnings).To(ConsistOf("some-app-warnings")) 163 }) 164 }) 165 166 When("getting the application succeeds with a started application", func() { 167 BeforeEach(func() { 168 fakeCloudControllerClient.GetApplicationsReturns( 169 []resources.Application{ 170 {Name: "some-app", State: constant.ApplicationStarted}, 171 }, 172 ccv3.Warnings{"some-app-warnings"}, 173 nil) 174 }) 175 176 When("getting the process summaries fails", func() { 177 BeforeEach(func() { 178 fakeCloudControllerClient.GetApplicationProcessesReturns(nil, ccv3.Warnings{"some-process-warnings"}, errors.New("some-process-error")) 179 }) 180 181 It("returns all warnings and the error", func() { 182 Expect(executeErr).To(MatchError("some-process-error")) 183 Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings")) 184 }) 185 }) 186 187 When("getting the process summaries succeeds", func() { 188 When("the process does not exist", func() { 189 BeforeEach(func() { 190 fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{}, ccv3.Warnings{"some-process-warnings"}, nil) 191 }) 192 193 It("returns all warnings and the error", func() { 194 Expect(executeErr).To(MatchError(actionerror.ProcessNotFoundError{ProcessType: "some-process-type"})) 195 Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings")) 196 }) 197 }) 198 199 When("the process doesn't have the specified instance index", func() { 200 BeforeEach(func() { 201 fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil) 202 fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil) 203 }) 204 205 It("returns a ProcessIndexNotFoundError", func() { 206 Expect(executeErr).To(MatchError(actionerror.ProcessInstanceNotFoundError{ProcessType: "some-process-type", InstanceIndex: 0})) 207 }) 208 }) 209 210 When("the process instance is not RUNNING", func() { 211 BeforeEach(func() { 212 fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil) 213 fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil) 214 fakeCloudControllerClient.GetProcessInstancesReturns([]ccv3.ProcessInstance{{State: constant.ProcessInstanceDown, Index: 0}}, ccv3.Warnings{"some-instance-warnings"}, nil) 215 }) 216 217 It("returns a ProcessInstanceNotRunningError", func() { 218 Expect(executeErr).To(MatchError(actionerror.ProcessInstanceNotRunningError{ProcessType: "some-process-type", InstanceIndex: 0})) 219 }) 220 }) 221 222 When("the specified process and index exist and the instance is RUNNING", func() { 223 BeforeEach(func() { 224 fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil) 225 fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil) 226 fakeCloudControllerClient.GetProcessInstancesReturns([]ccv3.ProcessInstance{{State: constant.ProcessInstanceRunning, Index: 0}}, ccv3.Warnings{"some-instance-warnings"}, nil) 227 }) 228 229 When("starting the secure session succeeds", func() { 230 It("returns all warnings", func() { 231 Expect(executeErr).ToNot(HaveOccurred()) 232 Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings", "some-instance-warnings")) 233 234 Expect(sshAuth).To(Equal(SSHAuthentication{ 235 Endpoint: "some-app-ssh-endpoint", 236 HostKeyFingerprint: "some-app-ssh-fingerprint", 237 Passcode: "some-ssh-passcode", 238 Username: "cf:some-process-guid/0", 239 })) 240 241 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 242 Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf( 243 ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app"}}, 244 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}}, 245 )) 246 }) 247 }) 248 }) 249 }) 250 }) 251 252 When("getting the application succeeds with a stopped application", func() { 253 BeforeEach(func() { 254 fakeCloudControllerClient.GetApplicationsReturns( 255 []resources.Application{ 256 {Name: "some-app", State: constant.ApplicationStopped}, 257 }, 258 ccv3.Warnings{"some-app-warnings"}, 259 nil) 260 }) 261 262 It("returns a ApplicationNotStartedError", func() { 263 Expect(executeErr).To(MatchError(actionerror.ApplicationNotStartedError{Name: "some-app"})) 264 Expect(warnings).To(ConsistOf("some-app-warnings")) 265 }) 266 }) 267 }) 268 }) 269 }) 270 })