github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/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 CreatedAt string 30 UpdatedAt string 31 } 32 33 // MarshalJSON converts an Application into a Cloud Controller Application. 34 func (a Application) MarshalJSON() ([]byte, error) { 35 ccApp := ccApplication{ 36 Name: a.Name, 37 Metadata: a.Metadata, 38 } 39 40 if a.SpaceGUID != "" { 41 ccApp.Relationships = Relationships{ 42 constant.RelationshipTypeSpace: Relationship{GUID: a.SpaceGUID}, 43 } 44 } 45 46 if a.LifecycleType == constant.AppLifecycleTypeDocker { 47 ccApp.setDockerLifecycle() 48 } else if a.LifecycleType == constant.AppLifecycleTypeBuildpack { 49 if len(a.LifecycleBuildpacks) > 0 || a.StackName != "" { 50 if a.hasAutodetectedBuildpack() { 51 ccApp.setAutodetectedBuildpackLifecycle(a) 52 } else { 53 ccApp.setBuildpackLifecycle(a) 54 } 55 } 56 } 57 58 return json.Marshal(ccApp) 59 } 60 61 // UnmarshalJSON helps unmarshal a Cloud Controller Application response. 62 func (a *Application) UnmarshalJSON(data []byte) error { 63 lifecycle := ccLifecycle{} 64 ccApp := ccApplication{ 65 Lifecycle: &lifecycle, 66 } 67 68 err := cloudcontroller.DecodeJSON(data, &ccApp) 69 if err != nil { 70 return err 71 } 72 73 a.GUID = ccApp.GUID 74 a.StackName = lifecycle.Data.Stack 75 a.LifecycleBuildpacks = lifecycle.Data.Buildpacks 76 a.LifecycleType = lifecycle.Type 77 a.Name = ccApp.Name 78 a.SpaceGUID = ccApp.Relationships[constant.RelationshipTypeSpace].GUID 79 a.State = ccApp.State 80 a.Metadata = ccApp.Metadata 81 a.CreatedAt = ccApp.CreatedAt 82 a.UpdatedAt = ccApp.UpdatedAt 83 84 return nil 85 } 86 87 func (a Application) Started() bool { 88 return a.State == constant.ApplicationStarted 89 } 90 91 func (a Application) Stopped() bool { 92 return a.State == constant.ApplicationStopped 93 } 94 95 func (a Application) hasAutodetectedBuildpack() bool { 96 if len(a.LifecycleBuildpacks) == 0 { 97 return false 98 } 99 return a.LifecycleBuildpacks[0] == constant.AutodetectBuildpackValueDefault || a.LifecycleBuildpacks[0] == constant.AutodetectBuildpackValueNull 100 } 101 102 type ccLifecycle struct { 103 Type constant.AppLifecycleType `json:"type,omitempty"` 104 Data struct { 105 Buildpacks []string `json:"buildpacks,omitempty"` 106 Stack string `json:"stack,omitempty"` 107 } `json:"data"` 108 } 109 110 type ccApplication struct { 111 Name string `json:"name,omitempty"` 112 Relationships Relationships `json:"relationships,omitempty"` 113 Lifecycle interface{} `json:"lifecycle,omitempty"` 114 GUID string `json:"guid,omitempty"` 115 State constant.ApplicationState `json:"state,omitempty"` 116 Metadata *Metadata `json:"metadata,omitempty"` 117 CreatedAt string `json:"created_at,omitempty"` 118 UpdatedAt string `json:"updated_at,omitempty"` 119 } 120 121 func (ccApp *ccApplication) setAutodetectedBuildpackLifecycle(a Application) { 122 var nullBuildpackLifecycle struct { 123 Type constant.AppLifecycleType `json:"type,omitempty"` 124 Data struct { 125 Buildpacks []string `json:"buildpacks"` 126 Stack string `json:"stack,omitempty"` 127 } `json:"data"` 128 } 129 nullBuildpackLifecycle.Type = constant.AppLifecycleTypeBuildpack 130 nullBuildpackLifecycle.Data.Stack = a.StackName 131 ccApp.Lifecycle = nullBuildpackLifecycle 132 } 133 134 func (ccApp *ccApplication) setBuildpackLifecycle(a Application) { 135 var lifecycle ccLifecycle 136 lifecycle.Type = a.LifecycleType 137 lifecycle.Data.Buildpacks = a.LifecycleBuildpacks 138 lifecycle.Data.Stack = a.StackName 139 ccApp.Lifecycle = lifecycle 140 } 141 142 func (ccApp *ccApplication) setDockerLifecycle() { 143 ccApp.Lifecycle = ccLifecycle{ 144 Type: constant.AppLifecycleTypeDocker, 145 } 146 }