github.com/loafoe/cli@v7.1.0+incompatible/actor/v3action/application.go (about) 1 package v3action 2 3 import ( 4 "time" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 9 "code.cloudfoundry.org/cli/resources" 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 SpaceGUID string 21 } 22 23 func (app Application) Started() bool { 24 return app.State == constant.ApplicationStarted 25 } 26 27 func (app Application) Stopped() bool { 28 return app.State == constant.ApplicationStopped 29 } 30 31 func (actor Actor) DeleteApplicationByNameAndSpace(name string, spaceGUID string) (Warnings, error) { 32 var allWarnings Warnings 33 34 app, getAppWarnings, err := actor.GetApplicationByNameAndSpace(name, spaceGUID) 35 allWarnings = append(allWarnings, getAppWarnings...) 36 if err != nil { 37 return allWarnings, err 38 } 39 40 jobURL, deleteAppWarnings, err := actor.CloudControllerClient.DeleteApplication(app.GUID) 41 allWarnings = append(allWarnings, deleteAppWarnings...) 42 if err != nil { 43 return allWarnings, err 44 } 45 46 pollWarnings, err := actor.CloudControllerClient.PollJob(jobURL) 47 allWarnings = append(allWarnings, pollWarnings...) 48 return allWarnings, err 49 } 50 51 // GetApplicationByNameAndSpace returns the application with the given 52 // name in the given space. 53 func (actor Actor) GetApplicationByNameAndSpace(appName string, spaceGUID string) (Application, Warnings, error) { 54 apps, warnings, err := actor.CloudControllerClient.GetApplications( 55 ccv3.Query{Key: ccv3.NameFilter, Values: []string{appName}}, 56 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}}, 57 ) 58 if err != nil { 59 return Application{}, Warnings(warnings), err 60 } 61 62 if len(apps) == 0 { 63 return Application{}, Warnings(warnings), actionerror.ApplicationNotFoundError{Name: appName} 64 } 65 66 return actor.convertCCToActorApplication(apps[0]), Warnings(warnings), nil 67 } 68 69 // GetApplicationsBySpace returns all applications in a space. 70 func (actor Actor) GetApplicationsBySpace(spaceGUID string) ([]Application, Warnings, error) { 71 ccApps, warnings, err := actor.CloudControllerClient.GetApplications( 72 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}}, 73 ) 74 75 if err != nil { 76 return []Application{}, Warnings(warnings), err 77 } 78 79 var apps []Application 80 for _, ccApp := range ccApps { 81 apps = append(apps, actor.convertCCToActorApplication(ccApp)) 82 } 83 return apps, Warnings(warnings), nil 84 } 85 86 // GetApplicationsByGUIDs returns all applications with the provided GUIDs. 87 func (actor Actor) GetApplicationsByGUIDs(appGUIDs ...string) ([]Application, Warnings, error) { 88 ccApps, warnings, err := actor.CloudControllerClient.GetApplications( 89 ccv3.Query{Key: ccv3.GUIDFilter, Values: appGUIDs}, 90 ) 91 92 if err != nil { 93 return []Application{}, Warnings(warnings), err 94 } 95 96 var apps []Application 97 for _, ccApp := range ccApps { 98 apps = append(apps, actor.convertCCToActorApplication(ccApp)) 99 } 100 return apps, Warnings(warnings), nil 101 } 102 103 // CreateApplicationInSpace creates and returns the application with the given 104 // name in the given space. 105 func (actor Actor) CreateApplicationInSpace(app Application, spaceGUID string) (Application, Warnings, error) { 106 createdApp, warnings, err := actor.CloudControllerClient.CreateApplication( 107 resources.Application{ 108 LifecycleType: app.LifecycleType, 109 LifecycleBuildpacks: app.LifecycleBuildpacks, 110 StackName: app.StackName, 111 Name: app.Name, 112 SpaceGUID: spaceGUID, 113 }) 114 115 if err != nil { 116 return Application{}, Warnings(warnings), err 117 } 118 119 return actor.convertCCToActorApplication(createdApp), Warnings(warnings), nil 120 } 121 122 // StopApplication stops an application. 123 func (actor Actor) StopApplication(appGUID string) (Warnings, error) { 124 _, warnings, err := actor.CloudControllerClient.UpdateApplicationStop(appGUID) 125 126 return Warnings(warnings), err 127 } 128 129 // StartApplication starts an application. 130 func (actor Actor) StartApplication(appGUID string) (Warnings, error) { 131 _, warnings, err := actor.CloudControllerClient.UpdateApplicationStart(appGUID) 132 if err != nil { 133 return Warnings(warnings), err 134 } 135 136 return Warnings(warnings), nil 137 } 138 139 // RestartApplication restarts an application. 140 func (actor Actor) RestartApplication(appGUID string) (Warnings, error) { 141 _, warnings, err := actor.CloudControllerClient.UpdateApplicationRestart(appGUID) 142 143 return Warnings(warnings), err 144 } 145 146 func (actor Actor) PollStart(appGUID string, warningsChannel chan<- Warnings) error { 147 processes, warnings, err := actor.CloudControllerClient.GetApplicationProcesses(appGUID) 148 warningsChannel <- Warnings(warnings) 149 if err != nil { 150 return err 151 } 152 153 timeout := time.Now().Add(actor.Config.StartupTimeout()) 154 for time.Now().Before(timeout) { 155 readyProcs := 0 156 for _, process := range processes { 157 ready, err := actor.processStatus(process, warningsChannel) 158 if err != nil { 159 return err 160 } 161 162 if ready { 163 readyProcs++ 164 } 165 } 166 167 if readyProcs == len(processes) { 168 return nil 169 } 170 time.Sleep(actor.Config.PollingInterval()) 171 } 172 173 return actionerror.StartupTimeoutError{} 174 } 175 176 // UpdateApplication updates the buildpacks on an application 177 func (actor Actor) UpdateApplication(app Application) (Application, Warnings, error) { 178 ccApp := resources.Application{ 179 GUID: app.GUID, 180 StackName: app.StackName, 181 LifecycleType: app.LifecycleType, 182 LifecycleBuildpacks: app.LifecycleBuildpacks, 183 } 184 185 updatedApp, warnings, err := actor.CloudControllerClient.UpdateApplication(ccApp) 186 if err != nil { 187 return Application{}, Warnings(warnings), err 188 } 189 190 return actor.convertCCToActorApplication(updatedApp), Warnings(warnings), nil 191 } 192 193 func (Actor) convertCCToActorApplication(app resources.Application) Application { 194 return Application{ 195 GUID: app.GUID, 196 StackName: app.StackName, 197 LifecycleType: app.LifecycleType, 198 LifecycleBuildpacks: app.LifecycleBuildpacks, 199 Name: app.Name, 200 State: app.State, 201 SpaceGUID: app.SpaceGUID, 202 } 203 } 204 205 func (actor Actor) processStatus(process ccv3.Process, warningsChannel chan<- Warnings) (bool, error) { 206 instances, warnings, err := actor.CloudControllerClient.GetProcessInstances(process.GUID) 207 warningsChannel <- Warnings(warnings) 208 if err != nil { 209 return false, err 210 } 211 if len(instances) == 0 { 212 return true, nil 213 } 214 215 for _, instance := range instances { 216 if instance.State == constant.ProcessInstanceRunning { 217 return true, nil 218 } 219 } 220 221 for _, instance := range instances { 222 if instance.State != constant.ProcessInstanceCrashed { 223 return false, nil 224 } 225 } 226 227 // all of the instances are crashed at this point 228 return true, nil 229 }