github.com/randomtask1155/cli@v6.41.1-0.20181227003417-a98eed78cbde+incompatible/actor/v7action/application.go (about) 1 package v7action 2 3 import ( 4 "time" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 10 ) 11 12 // Application represents a V3 actor application. 13 type Application struct { 14 Name string 15 GUID string 16 StackName string 17 State constant.ApplicationState 18 LifecycleType constant.AppLifecycleType 19 LifecycleBuildpacks []string 20 } 21 22 func (app Application) Started() bool { 23 return app.State == constant.ApplicationStarted 24 } 25 26 func (app Application) Stopped() bool { 27 return app.State == constant.ApplicationStopped 28 } 29 30 func (actor Actor) DeleteApplicationByNameAndSpace(name string, spaceGUID string) (Warnings, error) { 31 var allWarnings Warnings 32 33 app, getAppWarnings, err := actor.GetApplicationByNameAndSpace(name, spaceGUID) 34 allWarnings = append(allWarnings, getAppWarnings...) 35 if err != nil { 36 return allWarnings, err 37 } 38 39 jobURL, deleteAppWarnings, err := actor.CloudControllerClient.DeleteApplication(app.GUID) 40 allWarnings = append(allWarnings, deleteAppWarnings...) 41 if err != nil { 42 return allWarnings, err 43 } 44 45 pollWarnings, err := actor.CloudControllerClient.PollJob(jobURL) 46 allWarnings = append(allWarnings, pollWarnings...) 47 return allWarnings, err 48 } 49 50 // GetApplicationByNameAndSpace returns the application with the given 51 // name in the given space. 52 func (actor Actor) GetApplicationByNameAndSpace(appName string, spaceGUID string) (Application, Warnings, error) { 53 apps, warnings, err := actor.CloudControllerClient.GetApplications( 54 ccv3.Query{Key: ccv3.NameFilter, Values: []string{appName}}, 55 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}}, 56 ) 57 if err != nil { 58 return Application{}, Warnings(warnings), err 59 } 60 61 if len(apps) == 0 { 62 return Application{}, Warnings(warnings), actionerror.ApplicationNotFoundError{Name: appName} 63 } 64 65 return actor.convertCCToActorApplication(apps[0]), Warnings(warnings), nil 66 } 67 68 // GetApplicationsBySpace returns all applications in a space. 69 func (actor Actor) GetApplicationsBySpace(spaceGUID string) ([]Application, Warnings, error) { 70 ccApps, warnings, err := actor.CloudControllerClient.GetApplications( 71 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}}, 72 ) 73 74 if err != nil { 75 return []Application{}, Warnings(warnings), err 76 } 77 78 var apps []Application 79 for _, ccApp := range ccApps { 80 apps = append(apps, actor.convertCCToActorApplication(ccApp)) 81 } 82 return apps, Warnings(warnings), nil 83 } 84 85 // CreateApplicationInSpace creates and returns the application with the given 86 // name in the given space. 87 func (actor Actor) CreateApplicationInSpace(app Application, spaceGUID string) (Application, Warnings, error) { 88 createdApp, warnings, err := actor.CloudControllerClient.CreateApplication( 89 ccv3.Application{ 90 LifecycleType: app.LifecycleType, 91 LifecycleBuildpacks: app.LifecycleBuildpacks, 92 StackName: app.StackName, 93 Name: app.Name, 94 Relationships: ccv3.Relationships{ 95 constant.RelationshipTypeSpace: ccv3.Relationship{GUID: spaceGUID}, 96 }, 97 }) 98 99 if err != nil { 100 if _, ok := err.(ccerror.NameNotUniqueInSpaceError); ok { 101 return Application{}, Warnings(warnings), actionerror.ApplicationAlreadyExistsError{Name: app.Name} 102 } 103 return Application{}, Warnings(warnings), err 104 } 105 106 return actor.convertCCToActorApplication(createdApp), Warnings(warnings), nil 107 } 108 109 // SetApplicationProcessHealthCheckTypeByNameAndSpace sets the health check 110 // information of the provided processType for an application with the given 111 // name and space GUID. 112 func (actor Actor) SetApplicationProcessHealthCheckTypeByNameAndSpace( 113 appName string, 114 spaceGUID string, 115 healthCheckType constant.HealthCheckType, 116 httpEndpoint string, 117 processType string, 118 invocationTimeout int, 119 ) (Application, Warnings, error) { 120 121 app, getWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID) 122 if err != nil { 123 return Application{}, getWarnings, err 124 } 125 126 setWarnings, err := actor.UpdateProcessByTypeAndApplication( 127 processType, 128 app.GUID, 129 Process{ 130 HealthCheckType: healthCheckType, 131 HealthCheckEndpoint: httpEndpoint, 132 HealthCheckInvocationTimeout: invocationTimeout, 133 }) 134 return app, append(getWarnings, setWarnings...), err 135 } 136 137 // StopApplication stops an application. 138 func (actor Actor) StopApplication(appGUID string) (Warnings, error) { 139 _, warnings, err := actor.CloudControllerClient.UpdateApplicationStop(appGUID) 140 141 return Warnings(warnings), err 142 } 143 144 // StartApplication starts an application. 145 func (actor Actor) StartApplication(appGUID string) (Application, Warnings, error) { 146 updatedApp, warnings, err := actor.CloudControllerClient.UpdateApplicationStart(appGUID) 147 if err != nil { 148 return Application{}, Warnings(warnings), err 149 } 150 151 return actor.convertCCToActorApplication(updatedApp), Warnings(warnings), nil 152 } 153 154 // RestartApplication restarts an application and waits for it to start. 155 func (actor Actor) RestartApplication(appGUID string) (Warnings, error) { 156 var allWarnings Warnings 157 _, warnings, err := actor.CloudControllerClient.UpdateApplicationRestart(appGUID) 158 allWarnings = append(allWarnings, warnings...) 159 if err != nil { 160 return allWarnings, err 161 } 162 163 pollingWarnings, err := actor.PollStart(appGUID) 164 allWarnings = append(allWarnings, pollingWarnings...) 165 return allWarnings, err 166 } 167 168 func (actor Actor) PollStart(appGUID string) (Warnings, error) { 169 var allWarnings Warnings 170 processes, warnings, err := actor.CloudControllerClient.GetApplicationProcesses(appGUID) 171 allWarnings = append(allWarnings, warnings...) 172 if err != nil { 173 return allWarnings, err 174 } 175 176 timeout := time.Now().Add(actor.Config.StartupTimeout()) 177 for time.Now().Before(timeout) { 178 allProcessesDone := true 179 for _, process := range processes { 180 shouldContinuePolling, warnings, err := actor.shouldContinuePollingProcessStatus(process) 181 allWarnings = append(allWarnings, warnings...) 182 if err != nil { 183 return allWarnings, err 184 } 185 186 if shouldContinuePolling { 187 allProcessesDone = false 188 break 189 } 190 } 191 192 if allProcessesDone { 193 return allWarnings, nil 194 } 195 time.Sleep(actor.Config.PollingInterval()) 196 } 197 198 return allWarnings, actionerror.StartupTimeoutError{} 199 } 200 201 // UpdateApplication updates the buildpacks on an application 202 func (actor Actor) UpdateApplication(app Application) (Application, Warnings, error) { 203 ccApp := ccv3.Application{ 204 GUID: app.GUID, 205 StackName: app.StackName, 206 LifecycleType: app.LifecycleType, 207 LifecycleBuildpacks: app.LifecycleBuildpacks, 208 } 209 210 updatedApp, warnings, err := actor.CloudControllerClient.UpdateApplication(ccApp) 211 if err != nil { 212 return Application{}, Warnings(warnings), err 213 } 214 215 return actor.convertCCToActorApplication(updatedApp), Warnings(warnings), nil 216 } 217 218 func (Actor) convertCCToActorApplication(app ccv3.Application) Application { 219 return Application{ 220 GUID: app.GUID, 221 StackName: app.StackName, 222 LifecycleType: app.LifecycleType, 223 LifecycleBuildpacks: app.LifecycleBuildpacks, 224 Name: app.Name, 225 State: app.State, 226 } 227 } 228 229 func (actor Actor) shouldContinuePollingProcessStatus(process ccv3.Process) (bool, Warnings, error) { 230 ccInstances, ccWarnings, err := actor.CloudControllerClient.GetProcessInstances(process.GUID) 231 instances := ProcessInstances(ccInstances) 232 warnings := Warnings(ccWarnings) 233 if err != nil { 234 return true, warnings, err 235 } 236 237 if instances.Empty() || instances.AnyRunning() { 238 return false, warnings, nil 239 } else if instances.AllCrashed() { 240 return false, warnings, actionerror.AllInstancesCrashedError{} 241 } 242 243 return true, warnings, nil 244 }