github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/api/cloudcontroller/ccv2/service.go (about) 1 package ccv2 2 3 import ( 4 "encoding/json" 5 "net/url" 6 "strconv" 7 8 "code.cloudfoundry.org/cli/api/cloudcontroller" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/internal" 11 ) 12 13 // Service represents a Cloud Controller Service. 14 type Service struct { 15 // GUID is the unique Service identifier. 16 GUID string 17 // Label is the name of the service. 18 Label string 19 // Description is a short blurb describing the service. 20 Description string 21 // DocumentationURL is a url that points to a documentation page for the 22 // service. 23 DocumentationURL string 24 // ServiceBrokerName is name of the service broker associated with the service 25 ServiceBrokerName string 26 // ServiceBrokerGUID is guid of the service broker associated with the service 27 ServiceBrokerGUID string 28 // Extra is a field with extra data pertaining to the service. 29 Extra ServiceExtra 30 } 31 32 // DeleteService deletes the service with the given GUID, and returns any errors and warnings. 33 func (client *Client) DeleteService(serviceGUID string, purge bool) (Warnings, error) { 34 queryParams := url.Values{} 35 queryParams.Set("purge", strconv.FormatBool(purge)) 36 queryParams.Set("async", "true") 37 38 request, err := client.newHTTPRequest(requestOptions{ 39 RequestName: internal.DeleteServiceRequest, 40 Query: queryParams, 41 URIParams: Params{"service_guid": serviceGUID}, 42 }) 43 if err != nil { 44 return nil, err 45 } 46 47 response := cloudcontroller.Response{} 48 49 err = client.connection.Make(request, &response) 50 return response.Warnings, err 51 } 52 53 // UnmarshalJSON helps unmarshal a Cloud Controller Service response. 54 func (service *Service) UnmarshalJSON(data []byte) error { 55 var ccService struct { 56 Metadata internal.Metadata 57 Entity struct { 58 Label string `json:"label"` 59 Description string `json:"description"` 60 DocumentationURL string `json:"documentation_url"` 61 ServiceBrokerName string `json:"service_broker_name"` 62 ServiceBrokerGUID string `json:"service_broker_guid"` 63 Extra string `json:"extra"` 64 } 65 } 66 67 err := cloudcontroller.DecodeJSON(data, &ccService) 68 if err != nil { 69 return err 70 } 71 72 service.GUID = ccService.Metadata.GUID 73 service.Label = ccService.Entity.Label 74 service.Description = ccService.Entity.Description 75 service.DocumentationURL = ccService.Entity.DocumentationURL 76 service.ServiceBrokerName = ccService.Entity.ServiceBrokerName 77 service.ServiceBrokerGUID = ccService.Entity.ServiceBrokerGUID 78 79 // We explicitly unmarshal the Extra field to type string because CC returns 80 // a stringified JSON object ONLY for the 'extra' key (see test stub JSON 81 // response). This unmarshal strips escaped quotes, at which time we can then 82 // unmarshal into the ServiceExtra object. 83 // If 'extra' is null or not provided, this means sharing is NOT enabled 84 if len(ccService.Entity.Extra) != 0 { 85 extra := ServiceExtra{} 86 err = json.Unmarshal([]byte(ccService.Entity.Extra), &extra) 87 if err != nil { 88 return err 89 } 90 service.Extra.Shareable = extra.Shareable 91 if service.DocumentationURL == "" { 92 service.DocumentationURL = extra.DocumentationURL 93 } 94 } 95 96 return nil 97 } 98 99 // GetService returns the service with the given GUID. 100 func (client *Client) GetService(serviceGUID string) (Service, Warnings, error) { 101 request, err := client.newHTTPRequest(requestOptions{ 102 RequestName: internal.GetServiceRequest, 103 URIParams: Params{"service_guid": serviceGUID}, 104 }) 105 if err != nil { 106 return Service{}, nil, err 107 } 108 109 var service Service 110 response := cloudcontroller.Response{ 111 DecodeJSONResponseInto: &service, 112 } 113 114 err = client.connection.Make(request, &response) 115 return service, response.Warnings, err 116 } 117 118 // GetServices returns a list of Services given the provided filters. 119 func (client *Client) GetServices(filters ...Filter) ([]Service, Warnings, error) { 120 opts := requestOptions{ 121 RequestName: internal.GetServicesRequest, 122 Query: ConvertFilterParameters(filters), 123 } 124 125 return client.makeServicesRequest(opts) 126 } 127 128 func (client *Client) GetSpaceServices(spaceGUID string, filters ...Filter) ([]Service, Warnings, error) { 129 opts := requestOptions{ 130 RequestName: internal.GetSpaceServicesRequest, 131 Query: ConvertFilterParameters(filters), 132 URIParams: Params{"space_guid": spaceGUID}, 133 } 134 135 return client.makeServicesRequest(opts) 136 } 137 138 func (client *Client) makeServicesRequest(opts requestOptions) ([]Service, Warnings, error) { 139 request, err := client.newHTTPRequest(opts) 140 141 if err != nil { 142 return nil, nil, err 143 } 144 145 var fullServicesList []Service 146 warnings, err := client.paginate(request, Service{}, func(item interface{}) error { 147 if service, ok := item.(Service); ok { 148 fullServicesList = append(fullServicesList, service) 149 } else { 150 return ccerror.UnknownObjectInListError{ 151 Expected: Service{}, 152 Unexpected: item, 153 } 154 } 155 return nil 156 }) 157 return fullServicesList, warnings, err 158 }