github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/actor/v7action/ssh_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/resources"
     5  	"errors"
     6  
     7  	"code.cloudfoundry.org/cli/actor/actionerror"
     8  	. "code.cloudfoundry.org/cli/actor/v7action"
     9  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    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)
    33  	})
    34  
    35  	Describe("GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndex", func() {
    36  		var sshAuth SSHAuthentication
    37  
    38  		BeforeEach(func() {
    39  			fakeConfig.AccessTokenReturns("some-access-token")
    40  			fakeConfig.SSHOAuthClientReturns("some-access-oauth-client")
    41  		})
    42  
    43  		JustBeforeEach(func() {
    44  			sshAuth, warnings, executeErr = actor.GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndex("some-app", "some-space-guid", "some-process-type", 0)
    45  		})
    46  
    47  		When("the app ssh endpoint is empty", func() {
    48  			BeforeEach(func() {
    49  				fakeCloudControllerClient.AppSSHEndpointReturns("")
    50  			})
    51  			It("creates an ssh-endpoint-not-set error", func() {
    52  				Expect(executeErr).To(MatchError("SSH endpoint not set"))
    53  			})
    54  		})
    55  
    56  		When("the app ssh hostkey fingerprint is empty", func() {
    57  			BeforeEach(func() {
    58  				fakeCloudControllerClient.AppSSHEndpointReturns("some-app-ssh-endpoint")
    59  				fakeCloudControllerClient.AppSSHHostKeyFingerprintReturns("")
    60  			})
    61  			It("creates an ssh-hostkey-fingerprint-not-set error", func() {
    62  				Expect(executeErr).To(MatchError("SSH hostkey fingerprint not set"))
    63  			})
    64  		})
    65  
    66  		When("ssh endpoint and fingerprint are set", func() {
    67  			BeforeEach(func() {
    68  				fakeCloudControllerClient.AppSSHEndpointReturns("some-app-ssh-endpoint")
    69  				fakeCloudControllerClient.AppSSHHostKeyFingerprintReturns("some-app-ssh-fingerprint")
    70  			})
    71  
    72  			It("looks up the passcode with the config credentials", func() {
    73  				Expect(fakeUAAClient.GetSSHPasscodeCallCount()).To(Equal(1))
    74  				accessTokenArg, oathClientArg := fakeUAAClient.GetSSHPasscodeArgsForCall(0)
    75  				Expect(accessTokenArg).To(Equal("some-access-token"))
    76  				Expect(oathClientArg).To(Equal("some-access-oauth-client"))
    77  			})
    78  
    79  			When("getting the ssh passcode errors", func() {
    80  				BeforeEach(func() {
    81  					fakeUAAClient.GetSSHPasscodeReturns("", errors.New("some-ssh-passcode-error"))
    82  				})
    83  
    84  				It("returns the error", func() {
    85  					Expect(executeErr).To(MatchError("some-ssh-passcode-error"))
    86  				})
    87  			})
    88  
    89  			When("getting the ssh passcode succeeds", func() {
    90  				BeforeEach(func() {
    91  					fakeUAAClient.GetSSHPasscodeReturns("some-ssh-passcode", nil)
    92  				})
    93  
    94  				When("getting the application errors", func() {
    95  					BeforeEach(func() {
    96  						fakeCloudControllerClient.GetApplicationsReturns(nil, ccv3.Warnings{"some-app-warnings"}, errors.New("some-application-error"))
    97  					})
    98  
    99  					It("returns all warnings and the error", func() {
   100  						Expect(executeErr).To(MatchError("some-application-error"))
   101  						Expect(warnings).To(ConsistOf("some-app-warnings"))
   102  					})
   103  				})
   104  
   105  				When("getting the application succeeds with a started application", func() {
   106  					BeforeEach(func() {
   107  						fakeCloudControllerClient.GetApplicationsReturns(
   108  							[]resources.Application{
   109  								{Name: "some-app", State: constant.ApplicationStarted},
   110  							},
   111  							ccv3.Warnings{"some-app-warnings"},
   112  							nil)
   113  					})
   114  
   115  					When("getting the process summaries fails", func() {
   116  						BeforeEach(func() {
   117  							fakeCloudControllerClient.GetApplicationProcessesReturns(nil, ccv3.Warnings{"some-process-warnings"}, errors.New("some-process-error"))
   118  						})
   119  
   120  						It("returns all warnings and the error", func() {
   121  							Expect(executeErr).To(MatchError("some-process-error"))
   122  							Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings"))
   123  						})
   124  					})
   125  
   126  					When("getting the process summaries succeeds", func() {
   127  						When("the process does not exist", func() {
   128  							BeforeEach(func() {
   129  								fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{}, ccv3.Warnings{"some-process-warnings"}, nil)
   130  							})
   131  
   132  							It("returns all warnings and the error", func() {
   133  								Expect(executeErr).To(MatchError(actionerror.ProcessNotFoundError{ProcessType: "some-process-type"}))
   134  								Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings"))
   135  							})
   136  						})
   137  
   138  						When("the process doesn't have the specified instance index", func() {
   139  							BeforeEach(func() {
   140  								fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil)
   141  								fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil)
   142  							})
   143  
   144  							It("returns a ProcessIndexNotFoundError", func() {
   145  								Expect(executeErr).To(MatchError(actionerror.ProcessInstanceNotFoundError{ProcessType: "some-process-type", InstanceIndex: 0}))
   146  							})
   147  						})
   148  
   149  						When("the process instance is not RUNNING", func() {
   150  							BeforeEach(func() {
   151  								fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil)
   152  								fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil)
   153  								fakeCloudControllerClient.GetProcessInstancesReturns([]ccv3.ProcessInstance{{State: constant.ProcessInstanceDown, Index: 0}}, ccv3.Warnings{"some-instance-warnings"}, nil)
   154  							})
   155  
   156  							It("returns a ProcessInstanceNotRunningError", func() {
   157  								Expect(executeErr).To(MatchError(actionerror.ProcessInstanceNotRunningError{ProcessType: "some-process-type", InstanceIndex: 0}))
   158  							})
   159  						})
   160  
   161  						When("the specified process and index exist and the instance is RUNNING", func() {
   162  							BeforeEach(func() {
   163  								fakeCloudControllerClient.GetApplicationsReturns([]resources.Application{{Name: "some-app", State: constant.ApplicationStarted}}, ccv3.Warnings{"some-app-warnings"}, nil)
   164  								fakeCloudControllerClient.GetApplicationProcessesReturns([]resources.Process{{Type: "some-process-type", GUID: "some-process-guid"}}, ccv3.Warnings{"some-process-warnings"}, nil)
   165  								fakeCloudControllerClient.GetProcessInstancesReturns([]ccv3.ProcessInstance{{State: constant.ProcessInstanceRunning, Index: 0}}, ccv3.Warnings{"some-instance-warnings"}, nil)
   166  							})
   167  
   168  							When("starting the secure session succeeds", func() {
   169  								It("returns all warnings", func() {
   170  									Expect(executeErr).ToNot(HaveOccurred())
   171  									Expect(warnings).To(ConsistOf("some-app-warnings", "some-process-warnings", "some-instance-warnings"))
   172  
   173  									Expect(sshAuth).To(Equal(SSHAuthentication{
   174  										Endpoint:           "some-app-ssh-endpoint",
   175  										HostKeyFingerprint: "some-app-ssh-fingerprint",
   176  										Passcode:           "some-ssh-passcode",
   177  										Username:           "cf:some-process-guid/0",
   178  									}))
   179  
   180  									Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
   181  									Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
   182  										ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app"}},
   183  										ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}},
   184  									))
   185  								})
   186  							})
   187  						})
   188  					})
   189  				})
   190  
   191  				When("getting the application succeeds with a stopped application", func() {
   192  					BeforeEach(func() {
   193  						fakeCloudControllerClient.GetApplicationsReturns(
   194  							[]resources.Application{
   195  								{Name: "some-app", State: constant.ApplicationStopped},
   196  							},
   197  							ccv3.Warnings{"some-app-warnings"},
   198  							nil)
   199  					})
   200  
   201  					It("returns a ApplicationNotStartedError", func() {
   202  						Expect(executeErr).To(MatchError(actionerror.ApplicationNotStartedError{Name: "some-app"}))
   203  						Expect(warnings).To(ConsistOf("some-app-warnings"))
   204  					})
   205  				})
   206  			})
   207  		})
   208  	})
   209  })