github.com/cloudfoundry/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  }