github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/api/cloudcontroller/ccv2/route.go (about) 1 package ccv2 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/url" 9 10 "code.cloudfoundry.org/cli/api/cloudcontroller" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 12 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/internal" 13 "code.cloudfoundry.org/cli/types" 14 ) 15 16 // Route represents a Cloud Controller Route. 17 type Route struct { 18 19 // GUID is the unique Route identifier. 20 GUID string `json:"-"` 21 22 // Host is the hostname of the route. 23 Host string `json:"host,omitempty"` 24 25 // Path is the path of the route. 26 Path string `json:"path,omitempty"` 27 28 // Port is the port number of the route. 29 Port types.NullInt `json:"port,omitempty"` 30 31 // DomainGUID is the unique Domain identifier. 32 DomainGUID string `json:"domain_guid"` 33 34 // SpaceGUID is the unique Space identifier. 35 SpaceGUID string `json:"space_guid"` 36 } 37 38 // UnmarshalJSON helps unmarshal a Cloud Controller Route response. 39 func (route *Route) UnmarshalJSON(data []byte) error { 40 var ccRoute struct { 41 Metadata internal.Metadata `json:"metadata"` 42 Entity struct { 43 Host string `json:"host"` 44 Path string `json:"path"` 45 Port types.NullInt `json:"port"` 46 DomainGUID string `json:"domain_guid"` 47 SpaceGUID string `json:"space_guid"` 48 } `json:"entity"` 49 } 50 err := cloudcontroller.DecodeJSON(data, &ccRoute) 51 if err != nil { 52 return err 53 } 54 55 route.GUID = ccRoute.Metadata.GUID 56 route.Host = ccRoute.Entity.Host 57 route.Path = ccRoute.Entity.Path 58 route.Port = ccRoute.Entity.Port 59 route.DomainGUID = ccRoute.Entity.DomainGUID 60 route.SpaceGUID = ccRoute.Entity.SpaceGUID 61 return nil 62 } 63 64 // CheckRoute returns true if the route exists in the CF instance. 65 func (client *Client) CheckRoute(route Route) (bool, Warnings, error) { 66 request, err := client.newHTTPRequest(requestOptions{ 67 RequestName: internal.GetRouteReservedRequest, 68 URIParams: map[string]string{"domain_guid": route.DomainGUID}, 69 }) 70 if err != nil { 71 return false, nil, err 72 } 73 74 queryParams := url.Values{} 75 if route.Host != "" { 76 queryParams.Add("host", route.Host) 77 } 78 if route.Path != "" { 79 queryParams.Add("path", route.Path) 80 } 81 if route.Port.IsSet { 82 queryParams.Add("port", fmt.Sprint(route.Port.Value)) 83 } 84 request.URL.RawQuery = queryParams.Encode() 85 86 var response cloudcontroller.Response 87 err = client.connection.Make(request, &response) 88 if _, ok := err.(ccerror.ResourceNotFoundError); ok { 89 return false, response.Warnings, nil 90 } 91 92 return response.HTTPResponse.StatusCode == http.StatusNoContent, response.Warnings, err 93 } 94 95 // CreateRoute creates the route with the given properties; SpaceGUID and 96 // DomainGUID are required Route properties. Additional configuration rules: 97 // - generatePort = true to generate a random port on the cloud controller. 98 // - generatePort takes precedence over the provided port. Setting the port and 99 // generatePort only works with CC API 2.53.0 or higher and when TCP router 100 // groups are enabled. 101 func (client *Client) CreateRoute(route Route, generatePort bool) (Route, Warnings, error) { 102 body, err := json.Marshal(route) 103 if err != nil { 104 return Route{}, nil, err 105 } 106 107 request, err := client.newHTTPRequest(requestOptions{ 108 RequestName: internal.PostRouteRequest, 109 Body: bytes.NewReader(body), 110 }) 111 if err != nil { 112 return Route{}, nil, err 113 } 114 115 if generatePort { 116 query := url.Values{} 117 query.Add("generate_port", "true") 118 request.URL.RawQuery = query.Encode() 119 } 120 121 var updatedRoute Route 122 response := cloudcontroller.Response{ 123 DecodeJSONResponseInto: &updatedRoute, 124 } 125 126 err = client.connection.Make(request, &response) 127 return updatedRoute, response.Warnings, err 128 } 129 130 // DeleteRoute deletes the Route associated with the provided Route GUID. 131 func (client *Client) DeleteRoute(routeGUID string) (Warnings, error) { 132 request, err := client.newHTTPRequest(requestOptions{ 133 RequestName: internal.DeleteRouteRequest, 134 URIParams: map[string]string{"route_guid": routeGUID}, 135 }) 136 if err != nil { 137 return nil, err 138 } 139 140 var response cloudcontroller.Response 141 err = client.connection.Make(request, &response) 142 return response.Warnings, err 143 } 144 145 // DeleteRouteApplication removes the link between the route and application. 146 func (client *Client) DeleteRouteApplication(routeGUID string, appGUID string) (Warnings, error) { 147 request, err := client.newHTTPRequest(requestOptions{ 148 RequestName: internal.DeleteRouteAppRequest, 149 URIParams: map[string]string{ 150 "app_guid": appGUID, 151 "route_guid": routeGUID, 152 }, 153 }) 154 if err != nil { 155 return nil, err 156 } 157 158 var response cloudcontroller.Response 159 err = client.connection.Make(request, &response) 160 return response.Warnings, err 161 } 162 163 // DeleteSpaceUnmappedRoutes deletes Routes within a specified Space not mapped 164 // to an Application 165 func (client *Client) DeleteSpaceUnmappedRoutes(spaceGUID string) (Warnings, error) { 166 request, err := client.newHTTPRequest(requestOptions{ 167 RequestName: internal.DeleteSpaceUnmappedRoutesRequest, 168 URIParams: map[string]string{"space_guid": spaceGUID}, 169 }) 170 if err != nil { 171 return nil, err 172 } 173 174 var response cloudcontroller.Response 175 err = client.connection.Make(request, &response) 176 return response.Warnings, err 177 } 178 179 // GetApplicationRoutes returns a list of Routes associated with the provided 180 // Application GUID, and filtered by the provided filters. 181 func (client *Client) GetApplicationRoutes(appGUID string, filters ...Filter) ([]Route, Warnings, error) { 182 request, err := client.newHTTPRequest(requestOptions{ 183 RequestName: internal.GetAppRoutesRequest, 184 URIParams: map[string]string{"app_guid": appGUID}, 185 Query: ConvertFilterParameters(filters), 186 }) 187 if err != nil { 188 return nil, nil, err 189 } 190 191 var fullRoutesList []Route 192 warnings, err := client.paginate(request, Route{}, func(item interface{}) error { 193 if route, ok := item.(Route); ok { 194 fullRoutesList = append(fullRoutesList, route) 195 } else { 196 return ccerror.UnknownObjectInListError{ 197 Expected: Route{}, 198 Unexpected: item, 199 } 200 } 201 return nil 202 }) 203 204 return fullRoutesList, warnings, err 205 } 206 207 // GetRoute returns a route with the provided guid. 208 func (client *Client) GetRoute(guid string) (Route, Warnings, error) { 209 request, err := client.newHTTPRequest(requestOptions{ 210 RequestName: internal.GetRouteRequest, 211 URIParams: Params{"route_guid": guid}, 212 }) 213 if err != nil { 214 return Route{}, nil, err 215 } 216 217 var route Route 218 response := cloudcontroller.Response{ 219 DecodeJSONResponseInto: &route, 220 } 221 222 err = client.connection.Make(request, &response) 223 return route, response.Warnings, err 224 } 225 226 // GetRoutes returns a list of Routes based off of the provided filters. 227 func (client *Client) GetRoutes(filters ...Filter) ([]Route, Warnings, error) { 228 request, err := client.newHTTPRequest(requestOptions{ 229 RequestName: internal.GetRoutesRequest, 230 Query: ConvertFilterParameters(filters), 231 }) 232 if err != nil { 233 return nil, nil, err 234 } 235 236 var fullRoutesList []Route 237 warnings, err := client.paginate(request, Route{}, func(item interface{}) error { 238 if route, ok := item.(Route); ok { 239 fullRoutesList = append(fullRoutesList, route) 240 } else { 241 return ccerror.UnknownObjectInListError{ 242 Expected: Route{}, 243 Unexpected: item, 244 } 245 } 246 return nil 247 }) 248 249 return fullRoutesList, warnings, err 250 } 251 252 // GetSpaceRoutes returns a list of Routes associated with the provided Space 253 // GUID, and filtered by the provided filters. 254 func (client *Client) GetSpaceRoutes(spaceGUID string, filters ...Filter) ([]Route, Warnings, error) { 255 request, err := client.newHTTPRequest(requestOptions{ 256 RequestName: internal.GetSpaceRoutesRequest, 257 URIParams: map[string]string{"space_guid": spaceGUID}, 258 Query: ConvertFilterParameters(filters), 259 }) 260 if err != nil { 261 return nil, nil, err 262 } 263 264 var fullRoutesList []Route 265 warnings, err := client.paginate(request, Route{}, func(item interface{}) error { 266 if route, ok := item.(Route); ok { 267 fullRoutesList = append(fullRoutesList, route) 268 } else { 269 return ccerror.UnknownObjectInListError{ 270 Expected: Route{}, 271 Unexpected: item, 272 } 273 } 274 return nil 275 }) 276 277 return fullRoutesList, warnings, err 278 } 279 280 // UpdateRouteApplication creates a link between the route and application. 281 func (client *Client) UpdateRouteApplication(routeGUID string, appGUID string) (Route, Warnings, error) { 282 request, err := client.newHTTPRequest(requestOptions{ 283 RequestName: internal.PutRouteAppRequest, 284 URIParams: map[string]string{ 285 "app_guid": appGUID, 286 "route_guid": routeGUID, 287 }, 288 }) 289 if err != nil { 290 return Route{}, nil, err 291 } 292 293 var route Route 294 response := cloudcontroller.Response{ 295 DecodeJSONResponseInto: &route, 296 } 297 err = client.connection.Make(request, &response) 298 299 return route, response.Warnings, err 300 } 301 302 func (client *Client) checkRouteDeprecated(domainGUID string, host string, path string) (bool, Warnings, error) { 303 request, err := client.newHTTPRequest(requestOptions{ 304 RequestName: internal.GetRouteReservedDeprecatedRequest, 305 URIParams: map[string]string{"domain_guid": domainGUID, "host": host}, 306 }) 307 if err != nil { 308 return false, nil, err 309 } 310 311 queryParams := url.Values{} 312 if path != "" { 313 queryParams.Add("path", path) 314 } 315 request.URL.RawQuery = queryParams.Encode() 316 317 var response cloudcontroller.Response 318 err = client.connection.Make(request, &response) 319 if _, ok := err.(ccerror.ResourceNotFoundError); ok { 320 return false, response.Warnings, nil 321 } 322 323 return response.HTTPResponse.StatusCode == http.StatusNoContent, response.Warnings, err 324 }