github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/actor/v7action/route.go (about) 1 package v7action 2 3 import ( 4 "sort" 5 "strings" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 11 "code.cloudfoundry.org/cli/util/sorting" 12 ) 13 14 type RouteDestination struct { 15 GUID string 16 App RouteDestinationApp 17 } 18 19 type RouteDestinationApp ccv3.RouteDestinationApp 20 21 type Route struct { 22 GUID string 23 SpaceGUID string 24 DomainGUID string 25 Host string 26 Path string 27 DomainName string 28 SpaceName string 29 URL string 30 Destinations []RouteDestination 31 Metadata *Metadata 32 } 33 34 type RouteSummary struct { 35 Route 36 AppNames []string 37 } 38 39 func (actor Actor) CreateRoute(spaceGUID, domainName, hostname, path string) (Route, Warnings, error) { 40 allWarnings := Warnings{} 41 domain, warnings, err := actor.GetDomainByName(domainName) 42 allWarnings = append(allWarnings, warnings...) 43 44 if err != nil { 45 return Route{}, allWarnings, err 46 } 47 48 route, apiWarnings, err := actor.CloudControllerClient.CreateRoute(ccv3.Route{ 49 SpaceGUID: spaceGUID, 50 DomainGUID: domain.GUID, 51 Host: hostname, 52 Path: path, 53 }) 54 55 actorWarnings := Warnings(apiWarnings) 56 allWarnings = append(allWarnings, actorWarnings...) 57 58 if _, ok := err.(ccerror.RouteNotUniqueError); ok { 59 return Route{}, allWarnings, actionerror.RouteAlreadyExistsError{Err: err} 60 } 61 62 return Route{ 63 GUID: route.GUID, 64 Host: route.Host, 65 Path: route.Path, 66 SpaceGUID: route.SpaceGUID, 67 DomainGUID: route.DomainGUID, 68 SpaceName: spaceGUID, 69 DomainName: domainName, 70 }, allWarnings, err 71 } 72 73 func (actor Actor) GetRouteDestinations(routeGUID string) ([]RouteDestination, Warnings, error) { 74 destinations, warnings, err := actor.CloudControllerClient.GetRouteDestinations(routeGUID) 75 76 actorDestinations := []RouteDestination{} 77 for _, dst := range destinations { 78 actorDestinations = append(actorDestinations, RouteDestination{ 79 GUID: dst.GUID, 80 App: RouteDestinationApp(dst.App), 81 }) 82 } 83 84 return actorDestinations, Warnings(warnings), err 85 } 86 87 func (actor Actor) GetRouteDestinationByAppGUID(routeGUID string, appGUID string) (RouteDestination, Warnings, error) { 88 allDestinations, warnings, err := actor.GetRouteDestinations(routeGUID) 89 if err != nil { 90 return RouteDestination{}, warnings, err 91 } 92 93 for _, destination := range allDestinations { 94 if destination.App.GUID == appGUID && destination.App.Process.Type == constant.ProcessTypeWeb { 95 return destination, warnings, nil 96 } 97 } 98 99 return RouteDestination{}, warnings, actionerror.RouteDestinationNotFoundError{ 100 AppGUID: appGUID, 101 ProcessType: constant.ProcessTypeWeb, 102 RouteGUID: routeGUID, 103 } 104 } 105 106 func (actor Actor) GetRoutesBySpace(spaceGUID string, labelSelector string) ([]Route, Warnings, error) { 107 allWarnings := Warnings{} 108 queries := []ccv3.Query{ 109 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}}, 110 } 111 if len(labelSelector) > 0 { 112 queries = append(queries, ccv3.Query{Key: ccv3.LabelSelectorFilter, Values: []string{labelSelector}}) 113 } 114 115 routes, warnings, err := actor.CloudControllerClient.GetRoutes(queries...) 116 allWarnings = append(allWarnings, warnings...) 117 if err != nil { 118 return nil, allWarnings, err 119 } 120 121 ret, actor_warnings, err := actor.createActionRoutes(routes, allWarnings) 122 123 return ret, actor_warnings, err 124 } 125 126 func (actor Actor) parseRoutePath(routePath string) (string, string, string, string, Warnings, error) { 127 var warnings Warnings 128 var hostPart = "" 129 var pathPart = "" 130 routeParts := strings.SplitN(routePath, "/", 2) 131 domainName := routeParts[0] 132 if len(routeParts) > 1 { 133 pathPart = "/" + routeParts[1] 134 } 135 domainParts := strings.SplitN(domainName, ".", 2) 136 domainHasMultipleParts := len(domainParts) > 1 137 138 domain, allWarnings, err := actor.GetDomainByName(domainName) 139 140 _, domainNotFound := err.(actionerror.DomainNotFoundError) 141 142 needToCheckForHost := domainNotFound && domainHasMultipleParts 143 if err != nil && !needToCheckForHost { 144 return "", "", "", "", allWarnings, err 145 } 146 147 if needToCheckForHost { 148 domainName = domainParts[1] 149 hostPart = domainParts[0] 150 domain, warnings, err = actor.GetDomainByName(domainName) 151 allWarnings = append(allWarnings, warnings...) 152 if err != nil { 153 return "", "", "", "", allWarnings, err 154 } 155 } 156 157 return hostPart, pathPart, domainName, domain.GUID, allWarnings, nil 158 } 159 160 func (actor Actor) GetRoute(routePath string, spaceGUID string) (Route, Warnings, error) { 161 filters := []ccv3.Query{ 162 ccv3.Query{ 163 Key: ccv3.SpaceGUIDFilter, 164 Values: []string{spaceGUID}, 165 }, 166 } 167 hostPart, pathPart, domainName, domainGUID, allWarnings, err := actor.parseRoutePath(routePath) 168 if err != nil { 169 return Route{}, allWarnings, err 170 } 171 filters = append(filters, ccv3.Query{ 172 Key: ccv3.DomainGUIDFilter, 173 Values: []string{domainGUID}, 174 }) 175 filters = append(filters, ccv3.Query{Key: ccv3.HostsFilter, 176 Values: []string{hostPart}, 177 }) 178 filters = append(filters, ccv3.Query{Key: ccv3.PathsFilter, 179 Values: []string{pathPart}, 180 }) 181 routes, warnings, err := actor.CloudControllerClient.GetRoutes(filters...) 182 allWarnings = append(allWarnings, warnings...) 183 if err != nil { 184 return Route{}, allWarnings, err 185 } 186 if len(routes) == 0 { 187 return Route{}, allWarnings, actionerror.RouteNotFoundError{ 188 Host: hostPart, 189 DomainName: domainName, 190 Path: pathPart, 191 } 192 } 193 194 actionRoutes, allWarnings, err := actor.createActionRoutes(routes, allWarnings) 195 if err != nil { 196 return Route{}, allWarnings, err 197 } 198 return actionRoutes[0], allWarnings, nil 199 } 200 201 func (actor Actor) GetRoutesByOrg(orgGUID string, labelSelector string) ([]Route, Warnings, error) { 202 allWarnings := Warnings{} 203 queries := []ccv3.Query{ 204 ccv3.Query{Key: ccv3.OrganizationGUIDFilter, Values: []string{orgGUID}}, 205 } 206 if len(labelSelector) > 0 { 207 queries = append(queries, ccv3.Query{Key: ccv3.LabelSelectorFilter, Values: []string{labelSelector}}) 208 } 209 210 routes, warnings, err := actor.CloudControllerClient.GetRoutes(queries...) 211 allWarnings = append(allWarnings, warnings...) 212 if err != nil { 213 return nil, allWarnings, err 214 } 215 216 return actor.createActionRoutes(routes, allWarnings) 217 } 218 219 func (actor Actor) GetRouteSummaries(routes []Route) ([]RouteSummary, Warnings, error) { 220 var allWarnings Warnings 221 var routeSummaries []RouteSummary 222 223 destinationAppGUIDsByRouteGUID := make(map[string][]string) 224 destinationAppGUIDs := make(map[string]bool) 225 var uniqueAppGUIDs []string 226 227 for _, route := range routes { 228 for _, destination := range route.Destinations { 229 appGUID := destination.App.GUID 230 231 if _, ok := destinationAppGUIDs[appGUID]; !ok { 232 destinationAppGUIDs[appGUID] = true 233 uniqueAppGUIDs = append(uniqueAppGUIDs, appGUID) 234 } 235 236 destinationAppGUIDsByRouteGUID[route.GUID] = append(destinationAppGUIDsByRouteGUID[route.GUID], appGUID) 237 } 238 } 239 240 apps, warnings, err := actor.GetApplicationsByGUIDs(uniqueAppGUIDs) 241 allWarnings = append(allWarnings, warnings...) 242 if err != nil { 243 return nil, allWarnings, err 244 } 245 246 appNamesByGUID := make(map[string]string) 247 for _, app := range apps { 248 appNamesByGUID[app.GUID] = app.Name 249 } 250 251 for _, route := range routes { 252 var appNames []string 253 254 appGUIDs := destinationAppGUIDsByRouteGUID[route.GUID] 255 for _, appGUID := range appGUIDs { 256 appNames = append(appNames, appNamesByGUID[appGUID]) 257 } 258 259 routeSummaries = append(routeSummaries, RouteSummary{ 260 Route: route, 261 AppNames: appNames, 262 }) 263 } 264 265 sort.Slice(routeSummaries, func(i, j int) bool { 266 return sorting.LessIgnoreCase(routeSummaries[i].SpaceName, routeSummaries[j].SpaceName) 267 }) 268 269 return routeSummaries, allWarnings, nil 270 } 271 272 func (actor Actor) DeleteOrphanedRoutes(spaceGUID string) (Warnings, error) { 273 var allWarnings Warnings 274 275 jobURL, warnings, err := actor.CloudControllerClient.DeleteOrphanedRoutes(spaceGUID) 276 allWarnings = append(allWarnings, warnings...) 277 if err != nil { 278 return allWarnings, err 279 } 280 281 warnings, err = actor.CloudControllerClient.PollJob(jobURL) 282 allWarnings = append(allWarnings, warnings...) 283 284 return allWarnings, err 285 } 286 287 func (actor Actor) DeleteRoute(domainName, hostname, path string) (Warnings, error) { 288 allWarnings := Warnings{} 289 domain, warnings, err := actor.GetDomainByName(domainName) 290 allWarnings = append(allWarnings, warnings...) 291 292 if _, ok := err.(actionerror.DomainNotFoundError); ok { 293 allWarnings = append(allWarnings, err.Error()) 294 return allWarnings, nil 295 } 296 297 if err != nil { 298 return allWarnings, err 299 } 300 301 queryArray := []ccv3.Query{ 302 {Key: ccv3.DomainGUIDFilter, Values: []string{domain.GUID}}, 303 {Key: ccv3.HostsFilter, Values: []string{hostname}}, 304 {Key: ccv3.PathsFilter, Values: []string{path}}, 305 } 306 307 routes, apiWarnings, err := actor.CloudControllerClient.GetRoutes(queryArray...) 308 309 actorWarnings := Warnings(apiWarnings) 310 allWarnings = append(allWarnings, actorWarnings...) 311 312 if err != nil { 313 return allWarnings, err 314 } 315 316 if len(routes) == 0 { 317 return allWarnings, actionerror.RouteNotFoundError{ 318 DomainName: domainName, 319 Host: hostname, 320 Path: path, 321 } 322 } 323 324 jobURL, apiWarnings, err := actor.CloudControllerClient.DeleteRoute(routes[0].GUID) 325 actorWarnings = Warnings(apiWarnings) 326 allWarnings = append(allWarnings, actorWarnings...) 327 328 if err != nil { 329 return allWarnings, err 330 } 331 332 pollJobWarnings, err := actor.CloudControllerClient.PollJob(jobURL) 333 allWarnings = append(allWarnings, Warnings(pollJobWarnings)...) 334 335 return allWarnings, err 336 } 337 338 func (actor Actor) GetRouteByAttributes(domainName string, domainGUID string, hostname string, path string) (Route, Warnings, error) { 339 ccRoutes, ccWarnings, err := actor.CloudControllerClient.GetRoutes( 340 ccv3.Query{Key: ccv3.DomainGUIDFilter, Values: []string{domainGUID}}, 341 ccv3.Query{Key: ccv3.HostsFilter, Values: []string{hostname}}, 342 ccv3.Query{Key: ccv3.PathsFilter, Values: []string{path}}, 343 ) 344 345 if err != nil { 346 return Route{}, Warnings(ccWarnings), err 347 } 348 349 if len(ccRoutes) < 1 { 350 return Route{}, Warnings(ccWarnings), actionerror.RouteNotFoundError{ 351 DomainName: domainName, 352 DomainGUID: domainGUID, 353 Host: hostname, 354 Path: path, 355 } 356 } 357 358 return Route{ 359 GUID: ccRoutes[0].GUID, 360 Host: ccRoutes[0].Host, 361 Path: ccRoutes[0].Path, 362 SpaceGUID: ccRoutes[0].SpaceGUID, 363 DomainGUID: ccRoutes[0].DomainGUID, 364 }, Warnings(ccWarnings), nil 365 } 366 367 func (actor Actor) MapRoute(routeGUID string, appGUID string) (Warnings, error) { 368 warnings, err := actor.CloudControllerClient.MapRoute(routeGUID, appGUID) 369 return Warnings(warnings), err 370 } 371 372 func (actor Actor) UnmapRoute(routeGUID string, destinationGUID string) (Warnings, error) { 373 warnings, err := actor.CloudControllerClient.UnmapRoute(routeGUID, destinationGUID) 374 return Warnings(warnings), err 375 } 376 377 func (actor Actor) GetApplicationRoutes(appGUID string) ([]Route, Warnings, error) { 378 allWarnings := Warnings{} 379 380 routes, warnings, err := actor.CloudControllerClient.GetApplicationRoutes(appGUID) 381 allWarnings = append(allWarnings, warnings...) 382 if err != nil { 383 return nil, allWarnings, err 384 } 385 386 if len(routes) == 0 { 387 return nil, allWarnings, err 388 } 389 390 return actor.createActionRoutes(routes, allWarnings) 391 } 392 393 func (actor Actor) createActionRoutes(routes []ccv3.Route, allWarnings Warnings) ([]Route, Warnings, error) { 394 spaceGUIDsSet := map[string]struct{}{} 395 spacesQuery := ccv3.Query{Key: ccv3.GUIDFilter, Values: []string{}} 396 397 for _, route := range routes { 398 if _, ok := spaceGUIDsSet[route.SpaceGUID]; !ok { 399 spacesQuery.Values = append(spacesQuery.Values, route.SpaceGUID) 400 spaceGUIDsSet[route.SpaceGUID] = struct{}{} 401 } 402 } 403 404 spaces, warnings, err := actor.CloudControllerClient.GetSpaces(spacesQuery) 405 allWarnings = append(allWarnings, warnings...) 406 if err != nil { 407 return nil, allWarnings, err 408 } 409 410 spacesByGUID := map[string]ccv3.Space{} 411 for _, space := range spaces { 412 spacesByGUID[space.GUID] = space 413 } 414 415 actorRoutes := []Route{} 416 for _, route := range routes { 417 destinations := make([]RouteDestination, len(route.Destinations)) 418 for i, destination := range route.Destinations { 419 destinations[i] = RouteDestination{ 420 GUID: destination.GUID, 421 App: RouteDestinationApp(destination.App), 422 } 423 } 424 425 actorRoute := Route{ 426 GUID: route.GUID, 427 Host: route.Host, 428 Path: route.Path, 429 SpaceGUID: route.SpaceGUID, 430 DomainGUID: route.DomainGUID, 431 URL: route.URL, 432 SpaceName: spacesByGUID[route.SpaceGUID].Name, 433 DomainName: getDomainName(route.URL, route.Host, route.Path), 434 Destinations: destinations, 435 } 436 437 if route.Metadata != nil { 438 metadata := Metadata(*route.Metadata) 439 actorRoute.Metadata = &metadata 440 } 441 442 actorRoutes = append(actorRoutes, actorRoute) 443 } 444 445 return actorRoutes, allWarnings, nil 446 } 447 448 func getDomainName(fullURL, host, path string) string { 449 domainWithoutHost := strings.TrimPrefix(fullURL, host+".") 450 return strings.TrimSuffix(domainWithoutHost, path) 451 }