github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/api/cloudcontroller/ccv3/process.go (about) 1 package ccv3 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 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 "code.cloudfoundry.org/cli/api/cloudcontroller" 13 "code.cloudfoundry.org/cli/types" 14 ) 15 16 type Process struct { 17 GUID string 18 Type string 19 // Command is the process start command. Note: This value will be obfuscated when obtained from listing. 20 Command types.FilteredString 21 HealthCheckType constant.HealthCheckType 22 HealthCheckEndpoint string 23 HealthCheckInvocationTimeout int64 24 Instances types.NullInt 25 MemoryInMB types.NullUint64 26 DiskInMB types.NullUint64 27 } 28 29 func (p Process) MarshalJSON() ([]byte, error) { 30 var ccProcess marshalProcess 31 32 marshalCommand(p, &ccProcess) 33 marshalInstances(p, &ccProcess) 34 marshalMemory(p, &ccProcess) 35 marshalDisk(p, &ccProcess) 36 marshalHealthCheck(p, &ccProcess) 37 38 return json.Marshal(ccProcess) 39 } 40 41 func (p *Process) UnmarshalJSON(data []byte) error { 42 var ccProcess struct { 43 Command types.FilteredString `json:"command"` 44 DiskInMB types.NullUint64 `json:"disk_in_mb"` 45 GUID string `json:"guid"` 46 Instances types.NullInt `json:"instances"` 47 MemoryInMB types.NullUint64 `json:"memory_in_mb"` 48 Type string `json:"type"` 49 50 HealthCheck struct { 51 Type constant.HealthCheckType `json:"type"` 52 Data struct { 53 Endpoint string `json:"endpoint"` 54 InvocationTimeout int64 `json:"invocation_timeout"` 55 } `json:"data"` 56 } `json:"health_check"` 57 } 58 59 err := cloudcontroller.DecodeJSON(data, &ccProcess) 60 if err != nil { 61 return err 62 } 63 64 p.Command = ccProcess.Command 65 p.DiskInMB = ccProcess.DiskInMB 66 p.GUID = ccProcess.GUID 67 p.HealthCheckEndpoint = ccProcess.HealthCheck.Data.Endpoint 68 p.HealthCheckInvocationTimeout = ccProcess.HealthCheck.Data.InvocationTimeout 69 p.HealthCheckType = ccProcess.HealthCheck.Type 70 p.Instances = ccProcess.Instances 71 p.MemoryInMB = ccProcess.MemoryInMB 72 p.Type = ccProcess.Type 73 74 return nil 75 } 76 77 // CreateApplicationProcessScale updates process instances count, memory or disk 78 func (client *Client) CreateApplicationProcessScale(appGUID string, process Process) (Process, Warnings, error) { 79 body, err := json.Marshal(process) 80 if err != nil { 81 return Process{}, nil, err 82 } 83 84 request, err := client.newHTTPRequest(requestOptions{ 85 RequestName: internal.PostApplicationProcessActionScaleRequest, 86 Body: bytes.NewReader(body), 87 URIParams: internal.Params{"app_guid": appGUID, "type": process.Type}, 88 }) 89 if err != nil { 90 return Process{}, nil, err 91 } 92 93 var responseProcess Process 94 response := cloudcontroller.Response{ 95 DecodeJSONResponseInto: &responseProcess, 96 } 97 err = client.connection.Make(request, &response) 98 return responseProcess, response.Warnings, err 99 } 100 101 // GetApplicationProcessByType returns application process of specified type 102 func (client *Client) GetApplicationProcessByType(appGUID string, processType string) (Process, Warnings, error) { 103 request, err := client.newHTTPRequest(requestOptions{ 104 RequestName: internal.GetApplicationProcessRequest, 105 URIParams: map[string]string{ 106 "app_guid": appGUID, 107 "type": processType, 108 }, 109 }) 110 if err != nil { 111 return Process{}, nil, err 112 } 113 var process Process 114 response := cloudcontroller.Response{ 115 DecodeJSONResponseInto: &process, 116 } 117 118 err = client.connection.Make(request, &response) 119 return process, response.Warnings, err 120 } 121 122 // GetApplicationProcesses lists processes for a given application. **Note**: 123 // Due to security, the API obfuscates certain values such as `command`. 124 func (client *Client) GetApplicationProcesses(appGUID string) ([]Process, Warnings, error) { 125 request, err := client.newHTTPRequest(requestOptions{ 126 RequestName: internal.GetApplicationProcessesRequest, 127 URIParams: map[string]string{"app_guid": appGUID}, 128 }) 129 if err != nil { 130 return nil, nil, err 131 } 132 133 var fullProcessesList []Process 134 warnings, err := client.paginate(request, Process{}, func(item interface{}) error { 135 if process, ok := item.(Process); ok { 136 fullProcessesList = append(fullProcessesList, process) 137 } else { 138 return ccerror.UnknownObjectInListError{ 139 Expected: Process{}, 140 Unexpected: item, 141 } 142 } 143 return nil 144 }) 145 146 return fullProcessesList, warnings, err 147 } 148 149 // UpdateProcess updates the process's command or health check settings. GUID 150 // is always required; HealthCheckType is only required when updating health 151 // check settings. 152 func (client *Client) UpdateProcess(process Process) (Process, Warnings, error) { 153 body, err := json.Marshal(Process{ 154 Command: process.Command, 155 HealthCheckType: process.HealthCheckType, 156 HealthCheckEndpoint: process.HealthCheckEndpoint, 157 HealthCheckInvocationTimeout: process.HealthCheckInvocationTimeout, 158 }) 159 if err != nil { 160 return Process{}, nil, err 161 } 162 163 request, err := client.newHTTPRequest(requestOptions{ 164 RequestName: internal.PatchProcessRequest, 165 Body: bytes.NewReader(body), 166 URIParams: internal.Params{"process_guid": process.GUID}, 167 }) 168 if err != nil { 169 return Process{}, nil, err 170 } 171 172 var responseProcess Process 173 response := cloudcontroller.Response{ 174 DecodeJSONResponseInto: &responseProcess, 175 } 176 err = client.connection.Make(request, &response) 177 return responseProcess, response.Warnings, err 178 } 179 180 type healthCheck struct { 181 Type constant.HealthCheckType `json:"type"` 182 Data struct { 183 Endpoint interface{} `json:"endpoint"` 184 InvocationTimeout int64 `json:"invocation_timeout,omitempty"` 185 } `json:"data"` 186 } 187 188 type marshalProcess struct { 189 Command interface{} `json:"command,omitempty"` 190 Instances json.Number `json:"instances,omitempty"` 191 MemoryInMB json.Number `json:"memory_in_mb,omitempty"` 192 DiskInMB json.Number `json:"disk_in_mb,omitempty"` 193 194 HealthCheck *healthCheck `json:"health_check,omitempty"` 195 } 196 197 func marshalCommand(p Process, ccProcess *marshalProcess) { 198 if p.Command.IsSet { 199 ccProcess.Command = &p.Command 200 } 201 } 202 203 func marshalDisk(p Process, ccProcess *marshalProcess) { 204 if p.DiskInMB.IsSet { 205 ccProcess.DiskInMB = json.Number(fmt.Sprint(p.DiskInMB.Value)) 206 } 207 } 208 209 func marshalHealthCheck(p Process, ccProcess *marshalProcess) { 210 if p.HealthCheckType != "" || p.HealthCheckEndpoint != "" || p.HealthCheckInvocationTimeout != 0 { 211 ccProcess.HealthCheck = new(healthCheck) 212 ccProcess.HealthCheck.Type = p.HealthCheckType 213 ccProcess.HealthCheck.Data.InvocationTimeout = p.HealthCheckInvocationTimeout 214 if p.HealthCheckEndpoint != "" { 215 ccProcess.HealthCheck.Data.Endpoint = p.HealthCheckEndpoint 216 } 217 } 218 } 219 220 func marshalInstances(p Process, ccProcess *marshalProcess) { 221 if p.Instances.IsSet { 222 ccProcess.Instances = json.Number(fmt.Sprint(p.Instances.Value)) 223 } 224 } 225 226 func marshalMemory(p Process, ccProcess *marshalProcess) { 227 if p.MemoryInMB.IsSet { 228 ccProcess.MemoryInMB = json.Number(fmt.Sprint(p.MemoryInMB.Value)) 229 } 230 }