github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/api/cloudcontroller/ccv2/service_instance.go (about) 1 package ccv2 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "net/url" 7 8 "code.cloudfoundry.org/cli/api/cloudcontroller" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/internal" 12 ) 13 14 // ServiceInstance represents a Cloud Controller Service Instance. 15 type ServiceInstance struct { 16 // GUID is the unique service instance identifier. 17 GUID string 18 19 // Name is the name given to the service instance. 20 Name string 21 22 // SpaceGUID is the unique identifier of the space that this service instance 23 // belongs to. 24 SpaceGUID string 25 26 // ServiceGUID is the unique identifier of the service that this service 27 // instance belongs to. 28 ServiceGUID string 29 30 // ServicePlanGUID is the unique identifier of the service plan that this 31 // service instance belongs to. 32 ServicePlanGUID string 33 34 // Type is the type of service instance. 35 Type constant.ServiceInstanceType 36 37 // Tags is a list of all tags for the service instance. 38 Tags []string 39 40 // DashboardURL is the service-broker provided URL to access administrative 41 // features of the service instance. 42 DashboardURL string 43 44 // RouteServiceURL is the URL of the user-provided service to which requests 45 // for bound routes will be forwarded. 46 RouteServiceURL string 47 48 // LastOperation is the status of the last operation requested on the service 49 // instance. 50 LastOperation LastOperation 51 52 // MaintenanceInfo is the maintenance version of this service instance 53 MaintenanceInfo MaintenanceInfo 54 } 55 56 // Managed returns true if the Service Instance is a managed service. 57 func (serviceInstance ServiceInstance) Managed() bool { 58 return serviceInstance.Type == constant.ManagedService 59 } 60 61 // UnmarshalJSON helps unmarshal a Cloud Controller Service Instance response. 62 func (serviceInstance *ServiceInstance) UnmarshalJSON(data []byte) error { 63 var ccServiceInstance struct { 64 Metadata internal.Metadata 65 Entity struct { 66 Name string `json:"name"` 67 SpaceGUID string `json:"space_guid"` 68 ServiceGUID string `json:"service_guid"` 69 ServicePlanGUID string `json:"service_plan_guid"` 70 Type string `json:"type"` 71 Tags []string `json:"tags"` 72 DashboardURL string `json:"dashboard_url"` 73 RouteServiceURL string `json:"route_service_url"` 74 LastOperation LastOperation `json:"last_operation"` 75 MaintenanceInfo MaintenanceInfo `json:"maintenance_info"` 76 } 77 } 78 err := cloudcontroller.DecodeJSON(data, &ccServiceInstance) 79 if err != nil { 80 return err 81 } 82 83 serviceInstance.GUID = ccServiceInstance.Metadata.GUID 84 serviceInstance.Name = ccServiceInstance.Entity.Name 85 serviceInstance.SpaceGUID = ccServiceInstance.Entity.SpaceGUID 86 serviceInstance.ServiceGUID = ccServiceInstance.Entity.ServiceGUID 87 serviceInstance.ServicePlanGUID = ccServiceInstance.Entity.ServicePlanGUID 88 serviceInstance.Type = constant.ServiceInstanceType(ccServiceInstance.Entity.Type) 89 serviceInstance.Tags = ccServiceInstance.Entity.Tags 90 serviceInstance.DashboardURL = ccServiceInstance.Entity.DashboardURL 91 serviceInstance.RouteServiceURL = ccServiceInstance.Entity.RouteServiceURL 92 serviceInstance.LastOperation = ccServiceInstance.Entity.LastOperation 93 serviceInstance.MaintenanceInfo = ccServiceInstance.Entity.MaintenanceInfo 94 return nil 95 } 96 97 // UserProvided returns true if the Service Instance is a user provided 98 // service. 99 func (serviceInstance ServiceInstance) UserProvided() bool { 100 return serviceInstance.Type == constant.UserProvidedService 101 } 102 103 type createServiceInstanceRequestBody struct { 104 Name string `json:"name"` 105 ServicePlanGUID string `json:"service_plan_guid"` 106 SpaceGUID string `json:"space_guid"` 107 Parameters map[string]interface{} `json:"parameters,omitempty"` 108 Tags []string `json:"tags,omitempty"` 109 } 110 111 // CreateServiceInstance posts a service instance resource with the provided 112 // attributes to the api and returns the result. 113 func (client *Client) CreateServiceInstance(spaceGUID, servicePlanGUID, serviceInstance string, parameters map[string]interface{}, tags []string) (ServiceInstance, Warnings, error) { 114 requestBody := createServiceInstanceRequestBody{ 115 Name: serviceInstance, 116 ServicePlanGUID: servicePlanGUID, 117 SpaceGUID: spaceGUID, 118 Parameters: parameters, 119 Tags: tags, 120 } 121 122 bodyBytes, err := json.Marshal(requestBody) 123 if err != nil { 124 return ServiceInstance{}, nil, err 125 } 126 127 request, err := client.newHTTPRequest(requestOptions{ 128 RequestName: internal.PostServiceInstancesRequest, 129 Body: bytes.NewReader(bodyBytes), 130 Query: url.Values{"accepts_incomplete": {"true"}}, 131 }) 132 if err != nil { 133 return ServiceInstance{}, nil, err 134 } 135 136 var instance ServiceInstance 137 response := cloudcontroller.Response{ 138 DecodeJSONResponseInto: &instance, 139 } 140 141 err = client.connection.Make(request, &response) 142 return instance, response.Warnings, err 143 } 144 145 // GetServiceInstance returns the service instance with the given GUID. This 146 // service can be either a managed or user provided. 147 func (client *Client) GetServiceInstance(serviceInstanceGUID string) (ServiceInstance, Warnings, error) { 148 request, err := client.newHTTPRequest(requestOptions{ 149 RequestName: internal.GetServiceInstanceRequest, 150 URIParams: Params{"service_instance_guid": serviceInstanceGUID}, 151 }) 152 if err != nil { 153 return ServiceInstance{}, nil, err 154 } 155 156 var serviceInstance ServiceInstance 157 response := cloudcontroller.Response{ 158 DecodeJSONResponseInto: &serviceInstance, 159 } 160 161 err = client.connection.Make(request, &response) 162 return serviceInstance, response.Warnings, err 163 } 164 165 // GetServiceInstances returns back a list of *managed* Service Instances based 166 // off of the provided filters. 167 func (client *Client) GetServiceInstances(filters ...Filter) ([]ServiceInstance, Warnings, error) { 168 request, err := client.newHTTPRequest(requestOptions{ 169 RequestName: internal.GetServiceInstancesRequest, 170 Query: ConvertFilterParameters(filters), 171 }) 172 if err != nil { 173 return nil, nil, err 174 } 175 176 var fullInstancesList []ServiceInstance 177 warnings, err := client.paginate(request, ServiceInstance{}, func(item interface{}) error { 178 if instance, ok := item.(ServiceInstance); ok { 179 fullInstancesList = append(fullInstancesList, instance) 180 } else { 181 return ccerror.UnknownObjectInListError{ 182 Expected: ServiceInstance{}, 183 Unexpected: item, 184 } 185 } 186 return nil 187 }) 188 189 return fullInstancesList, warnings, err 190 } 191 192 // GetSpaceServiceInstances returns back a list of Service Instances based off 193 // of the space and filters provided. User provided services will be included 194 // if includeUserProvidedServices is set to true. 195 func (client *Client) GetSpaceServiceInstances(spaceGUID string, includeUserProvidedServices bool, filters ...Filter) ([]ServiceInstance, Warnings, error) { 196 query := ConvertFilterParameters(filters) 197 198 if includeUserProvidedServices { 199 query.Add("return_user_provided_service_instances", "true") 200 } 201 202 request, err := client.newHTTPRequest(requestOptions{ 203 RequestName: internal.GetSpaceServiceInstancesRequest, 204 URIParams: map[string]string{"guid": spaceGUID}, 205 Query: query, 206 }) 207 208 if err != nil { 209 return nil, nil, err 210 } 211 212 var fullInstancesList []ServiceInstance 213 warnings, err := client.paginate(request, ServiceInstance{}, func(item interface{}) error { 214 if instance, ok := item.(ServiceInstance); ok { 215 fullInstancesList = append(fullInstancesList, instance) 216 } else { 217 return ccerror.UnknownObjectInListError{ 218 Expected: ServiceInstance{}, 219 Unexpected: item, 220 } 221 } 222 return nil 223 }) 224 225 return fullInstancesList, warnings, err 226 } 227 228 type MaintenanceInfo struct { 229 Version string `json:"version,omitempty"` 230 Description string `json:"description,omitempty"` 231 } 232 233 type updateServiceInstanceRequestBody struct { 234 MaintenanceInfo MaintenanceInfo `json:"maintenance_info"` 235 } 236 237 func (client *Client) UpdateServiceInstanceMaintenanceInfo(serviceInstanceGUID string, maintenanceInfo MaintenanceInfo) (Warnings, error) { 238 requestBody := updateServiceInstanceRequestBody{ 239 MaintenanceInfo: maintenanceInfo, 240 } 241 242 bodyBytes, err := json.Marshal(requestBody) 243 if err != nil { 244 return nil, err 245 } 246 247 request, err := client.newHTTPRequest(requestOptions{ 248 RequestName: internal.PutServiceInstanceRequest, 249 URIParams: Params{"service_instance_guid": serviceInstanceGUID}, 250 Body: bytes.NewReader(bodyBytes), 251 Query: url.Values{"accepts_incomplete": {"true"}}, 252 }) 253 if err != nil { 254 return nil, err 255 } 256 257 response := cloudcontroller.Response{} 258 259 err = client.connection.Make(request, &response) 260 return response.Warnings, err 261 }