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  }