github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/resources/application_resource.go (about)

     1  package resources
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"code.cloudfoundry.org/cli/api/cloudcontroller"
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
     8  )
     9  
    10  // Application represents a Cloud Controller V3 Application.
    11  type Application struct {
    12  	// GUID is the unique application identifier.
    13  	GUID string
    14  	// StackName is the name of the stack on which the application runs.
    15  	StackName string
    16  	// LifecycleBuildpacks is a list of the names of buildpacks.
    17  	LifecycleBuildpacks []string
    18  	// LifecycleType is the type of the lifecycle.
    19  	LifecycleType constant.AppLifecycleType
    20  	// Metadata is used for custom tagging of API resources
    21  	Metadata *Metadata
    22  	// Name is the name given to the application.
    23  	Name string
    24  	// SpaceGUID is the unique identifier of the parent space.
    25  	SpaceGUID string
    26  	// State is the desired state of the application.
    27  	State constant.ApplicationState
    28  }
    29  
    30  // ApplicationNameOnly represents only the name field of a Cloud Controller V3 Application
    31  type ApplicationNameOnly struct {
    32  	// Name is the name given to the application.
    33  	Name string `json:"name,omitempty"`
    34  }
    35  
    36  // MarshalJSON converts an Application into a Cloud Controller Application.
    37  func (a Application) MarshalJSON() ([]byte, error) {
    38  	ccApp := ccApplication{
    39  		Name:     a.Name,
    40  		Metadata: a.Metadata,
    41  	}
    42  
    43  	if a.SpaceGUID != "" {
    44  		ccApp.Relationships = Relationships{
    45  			constant.RelationshipTypeSpace: Relationship{GUID: a.SpaceGUID},
    46  		}
    47  	}
    48  
    49  	if a.LifecycleType == constant.AppLifecycleTypeDocker {
    50  		ccApp.setDockerLifecycle()
    51  	} else if a.LifecycleType == constant.AppLifecycleTypeBuildpack {
    52  		if len(a.LifecycleBuildpacks) > 0 || a.StackName != "" {
    53  			if a.hasAutodetectedBuildpack() {
    54  				ccApp.setAutodetectedBuildpackLifecycle(a)
    55  			} else {
    56  				ccApp.setBuildpackLifecycle(a)
    57  			}
    58  		}
    59  	}
    60  
    61  	return json.Marshal(ccApp)
    62  }
    63  
    64  // UnmarshalJSON helps unmarshal a Cloud Controller Application response.
    65  func (a *Application) UnmarshalJSON(data []byte) error {
    66  	lifecycle := ccLifecycle{}
    67  	ccApp := ccApplication{
    68  		Lifecycle: &lifecycle,
    69  	}
    70  
    71  	err := cloudcontroller.DecodeJSON(data, &ccApp)
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	a.GUID = ccApp.GUID
    77  	a.StackName = lifecycle.Data.Stack
    78  	a.LifecycleBuildpacks = lifecycle.Data.Buildpacks
    79  	a.LifecycleType = lifecycle.Type
    80  	a.Name = ccApp.Name
    81  	a.SpaceGUID = ccApp.Relationships[constant.RelationshipTypeSpace].GUID
    82  	a.State = ccApp.State
    83  	a.Metadata = ccApp.Metadata
    84  
    85  	return nil
    86  }
    87  
    88  func (a Application) Started() bool {
    89  	return a.State == constant.ApplicationStarted
    90  }
    91  
    92  func (a Application) Stopped() bool {
    93  	return a.State == constant.ApplicationStopped
    94  }
    95  
    96  func (a Application) hasAutodetectedBuildpack() bool {
    97  	if len(a.LifecycleBuildpacks) == 0 {
    98  		return false
    99  	}
   100  	return a.LifecycleBuildpacks[0] == constant.AutodetectBuildpackValueDefault || a.LifecycleBuildpacks[0] == constant.AutodetectBuildpackValueNull
   101  }
   102  
   103  type ccLifecycle struct {
   104  	Type constant.AppLifecycleType `json:"type,omitempty"`
   105  	Data struct {
   106  		Buildpacks []string `json:"buildpacks,omitempty"`
   107  		Stack      string   `json:"stack,omitempty"`
   108  	} `json:"data"`
   109  }
   110  
   111  type ccApplication struct {
   112  	Name          string                    `json:"name,omitempty"`
   113  	Relationships Relationships             `json:"relationships,omitempty"`
   114  	Lifecycle     interface{}               `json:"lifecycle,omitempty"`
   115  	GUID          string                    `json:"guid,omitempty"`
   116  	State         constant.ApplicationState `json:"state,omitempty"`
   117  	Metadata      *Metadata                 `json:"metadata,omitempty"`
   118  }
   119  
   120  func (ccApp *ccApplication) setAutodetectedBuildpackLifecycle(a Application) {
   121  	var nullBuildpackLifecycle struct {
   122  		Type constant.AppLifecycleType `json:"type,omitempty"`
   123  		Data struct {
   124  			Buildpacks []string `json:"buildpacks"`
   125  			Stack      string   `json:"stack,omitempty"`
   126  		} `json:"data"`
   127  	}
   128  	nullBuildpackLifecycle.Type = constant.AppLifecycleTypeBuildpack
   129  	nullBuildpackLifecycle.Data.Stack = a.StackName
   130  	ccApp.Lifecycle = nullBuildpackLifecycle
   131  }
   132  
   133  func (ccApp *ccApplication) setBuildpackLifecycle(a Application) {
   134  	var lifecycle ccLifecycle
   135  	lifecycle.Type = a.LifecycleType
   136  	lifecycle.Data.Buildpacks = a.LifecycleBuildpacks
   137  	lifecycle.Data.Stack = a.StackName
   138  	ccApp.Lifecycle = lifecycle
   139  }
   140  
   141  func (ccApp *ccApplication) setDockerLifecycle() {
   142  	ccApp.Lifecycle = ccLifecycle{
   143  		Type: constant.AppLifecycleTypeDocker,
   144  	}
   145  }