github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/api/cloudcontroller/ccv3/application.go (about)

     1  package ccv3
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/internal"
    11  )
    12  
    13  // Application represents a Cloud Controller V3 Application.
    14  type Application struct {
    15  	// GUID is the unique application identifier.
    16  	GUID string
    17  	// StackName is the name of the stack on which the application runs.
    18  	StackName string
    19  	// LifecycleBuildpacks is a list of the names of buildpacks.
    20  	LifecycleBuildpacks []string
    21  	// LifecycleType is the type of the lifecycle.
    22  	LifecycleType constant.AppLifecycleType
    23  	// Name is the name given to the application.
    24  	Name string
    25  	// Relationships list the relationships to the application.
    26  	Relationships Relationships
    27  	// State is the desired state of the application.
    28  	State constant.ApplicationState
    29  }
    30  
    31  // MarshalJSON converts an Application into a Cloud Controller Application.
    32  func (a Application) MarshalJSON() ([]byte, error) {
    33  	ccApp := ccApplication{
    34  		Name:          a.Name,
    35  		Relationships: a.Relationships,
    36  	}
    37  
    38  	if a.LifecycleType == constant.AppLifecycleTypeDocker {
    39  		ccApp.setDockerLifecycle()
    40  	} else if a.LifecycleType == constant.AppLifecycleTypeBuildpack {
    41  		if len(a.LifecycleBuildpacks) > 0 || a.StackName != "" {
    42  			if a.hasAutodetectedBuildpack() {
    43  				ccApp.setAutodetectedBuildpackLifecycle(a)
    44  			} else {
    45  				ccApp.setBuildpackLifecycle(a)
    46  			}
    47  		}
    48  	}
    49  
    50  	return json.Marshal(ccApp)
    51  }
    52  
    53  // UnmarshalJSON helps unmarshal a Cloud Controller Application response.
    54  func (a *Application) UnmarshalJSON(data []byte) error {
    55  	lifecycle := ccLifecycle{}
    56  	ccApp := ccApplication{
    57  		Lifecycle: &lifecycle,
    58  	}
    59  
    60  	err := cloudcontroller.DecodeJSON(data, &ccApp)
    61  	if err != nil {
    62  		return err
    63  	}
    64  
    65  	a.GUID = ccApp.GUID
    66  	a.StackName = lifecycle.Data.Stack
    67  	a.LifecycleBuildpacks = lifecycle.Data.Buildpacks
    68  	a.LifecycleType = lifecycle.Type
    69  	a.Name = ccApp.Name
    70  	a.Relationships = ccApp.Relationships
    71  	a.State = ccApp.State
    72  
    73  	return nil
    74  }
    75  
    76  func (a Application) hasAutodetectedBuildpack() bool {
    77  	if len(a.LifecycleBuildpacks) == 0 {
    78  		return false
    79  	}
    80  	return a.LifecycleBuildpacks[0] == constant.AutodetectBuildpackValueDefault || a.LifecycleBuildpacks[0] == constant.AutodetectBuildpackValueNull
    81  }
    82  
    83  type ccLifecycle struct {
    84  	Type constant.AppLifecycleType `json:"type,omitempty"`
    85  	Data struct {
    86  		Buildpacks []string `json:"buildpacks,omitempty"`
    87  		Stack      string   `json:"stack,omitempty"`
    88  	} `json:"data"`
    89  }
    90  
    91  type ccApplication struct {
    92  	Name          string                    `json:"name,omitempty"`
    93  	Relationships Relationships             `json:"relationships,omitempty"`
    94  	Lifecycle     interface{}               `json:"lifecycle,omitempty"`
    95  	GUID          string                    `json:"guid,omitempty"`
    96  	State         constant.ApplicationState `json:"state,omitempty"`
    97  }
    98  
    99  func (ccApp *ccApplication) setAutodetectedBuildpackLifecycle(a Application) {
   100  	var nullBuildpackLifecycle struct {
   101  		Type constant.AppLifecycleType `json:"type,omitempty"`
   102  		Data struct {
   103  			Buildpacks []string `json:"buildpacks"`
   104  			Stack      string   `json:"stack,omitempty"`
   105  		} `json:"data"`
   106  	}
   107  	nullBuildpackLifecycle.Type = constant.AppLifecycleTypeBuildpack
   108  	nullBuildpackLifecycle.Data.Stack = a.StackName
   109  	ccApp.Lifecycle = nullBuildpackLifecycle
   110  }
   111  
   112  func (ccApp *ccApplication) setBuildpackLifecycle(a Application) {
   113  	var lifecycle ccLifecycle
   114  	lifecycle.Type = a.LifecycleType
   115  	lifecycle.Data.Buildpacks = a.LifecycleBuildpacks
   116  	lifecycle.Data.Stack = a.StackName
   117  	ccApp.Lifecycle = lifecycle
   118  }
   119  
   120  func (ccApp *ccApplication) setDockerLifecycle() {
   121  	ccApp.Lifecycle = ccLifecycle{
   122  		Type: constant.AppLifecycleTypeDocker,
   123  	}
   124  }
   125  
   126  // CreateApplication creates an application with the given settings.
   127  func (client *Client) CreateApplication(app Application) (Application, Warnings, error) {
   128  	bodyBytes, err := json.Marshal(app)
   129  	if err != nil {
   130  		return Application{}, nil, err
   131  	}
   132  
   133  	request, err := client.newHTTPRequest(requestOptions{
   134  		RequestName: internal.PostApplicationRequest,
   135  		Body:        bytes.NewReader(bodyBytes),
   136  	})
   137  	if err != nil {
   138  		return Application{}, nil, err
   139  	}
   140  
   141  	var responseApp Application
   142  	response := cloudcontroller.Response{
   143  		DecodeJSONResponseInto: &responseApp,
   144  	}
   145  	err = client.connection.Make(request, &response)
   146  
   147  	return responseApp, response.Warnings, err
   148  }
   149  
   150  // GetApplications lists applications with optional queries.
   151  func (client *Client) GetApplications(query ...Query) ([]Application, Warnings, error) {
   152  	request, err := client.newHTTPRequest(requestOptions{
   153  		RequestName: internal.GetApplicationsRequest,
   154  		Query:       query,
   155  	})
   156  	if err != nil {
   157  		return nil, nil, err
   158  	}
   159  
   160  	var fullAppsList []Application
   161  	warnings, err := client.paginate(request, Application{}, func(item interface{}) error {
   162  		if app, ok := item.(Application); ok {
   163  			fullAppsList = append(fullAppsList, app)
   164  		} else {
   165  			return ccerror.UnknownObjectInListError{
   166  				Expected:   Application{},
   167  				Unexpected: item,
   168  			}
   169  		}
   170  		return nil
   171  	})
   172  
   173  	return fullAppsList, warnings, err
   174  }
   175  
   176  // UpdateApplication updates an application with the given settings.
   177  func (client *Client) UpdateApplication(app Application) (Application, Warnings, error) {
   178  	bodyBytes, err := json.Marshal(app)
   179  	if err != nil {
   180  		return Application{}, nil, err
   181  	}
   182  
   183  	request, err := client.newHTTPRequest(requestOptions{
   184  		RequestName: internal.PatchApplicationRequest,
   185  		Body:        bytes.NewReader(bodyBytes),
   186  		URIParams:   map[string]string{"app_guid": app.GUID},
   187  	})
   188  	if err != nil {
   189  		return Application{}, nil, err
   190  	}
   191  
   192  	var responseApp Application
   193  	response := cloudcontroller.Response{
   194  		DecodeJSONResponseInto: &responseApp,
   195  	}
   196  	err = client.connection.Make(request, &response)
   197  
   198  	return responseApp, response.Warnings, err
   199  }
   200  
   201  // UpdateApplicationRestart restarts the given application.
   202  func (client *Client) UpdateApplicationRestart(appGUID string) (Application, Warnings, error) {
   203  	request, err := client.newHTTPRequest(requestOptions{
   204  		RequestName: internal.PostApplicationActionRestartRequest,
   205  		URIParams:   map[string]string{"app_guid": appGUID},
   206  	})
   207  	if err != nil {
   208  		return Application{}, nil, err
   209  	}
   210  
   211  	var responseApp Application
   212  	response := cloudcontroller.Response{
   213  		DecodeJSONResponseInto: &responseApp,
   214  	}
   215  	err = client.connection.Make(request, &response)
   216  
   217  	return responseApp, response.Warnings, err
   218  }
   219  
   220  // UpdateApplicationStart starts the given application.
   221  func (client *Client) UpdateApplicationStart(appGUID string) (Application, Warnings, error) {
   222  	request, err := client.newHTTPRequest(requestOptions{
   223  		RequestName: internal.PostApplicationActionStartRequest,
   224  		URIParams:   map[string]string{"app_guid": appGUID},
   225  	})
   226  	if err != nil {
   227  		return Application{}, nil, err
   228  	}
   229  
   230  	var responseApp Application
   231  	response := cloudcontroller.Response{
   232  		DecodeJSONResponseInto: &responseApp,
   233  	}
   234  	err = client.connection.Make(request, &response)
   235  
   236  	return responseApp, response.Warnings, err
   237  }
   238  
   239  // UpdateApplicationStop stops the given application.
   240  func (client *Client) UpdateApplicationStop(appGUID string) (Application, Warnings, error) {
   241  	request, err := client.newHTTPRequest(requestOptions{
   242  		RequestName: internal.PostApplicationActionStopRequest,
   243  		URIParams:   map[string]string{"app_guid": appGUID},
   244  	})
   245  	if err != nil {
   246  		return Application{}, nil, err
   247  	}
   248  
   249  	var responseApp Application
   250  	response := cloudcontroller.Response{
   251  		DecodeJSONResponseInto: &responseApp,
   252  	}
   253  	err = client.connection.Make(request, &response)
   254  
   255  	return responseApp, response.Warnings, err
   256  }