github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/networking/v2/extensions/layer3/routers/testing/requests_test.go (about) 1 package testing 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "testing" 8 "time" 9 10 fake "github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/common" 11 "github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/extensions/layer3/routers" 12 "github.com/vnpaycloud-console/gophercloud/v2/pagination" 13 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 14 ) 15 16 func TestList(t *testing.T) { 17 th.SetupHTTP() 18 defer th.TeardownHTTP() 19 20 th.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { 21 th.TestMethod(t, r, "GET") 22 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 23 24 w.Header().Add("Content-Type", "application/json") 25 w.WriteHeader(http.StatusOK) 26 27 fmt.Fprint(w, ` 28 { 29 "routers": [ 30 { 31 "status": "ACTIVE", 32 "external_gateway_info": null, 33 "name": "second_routers", 34 "admin_state_up": true, 35 "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", 36 "distributed": false, 37 "id": "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b" 38 }, 39 { 40 "status": "ACTIVE", 41 "external_gateway_info": { 42 "network_id": "3c5bcddd-6af9-4e6b-9c3e-c153e521cab8" 43 }, 44 "name": "router1", 45 "admin_state_up": true, 46 "tenant_id": "33a40233088643acb66ff6eb0ebea679", 47 "distributed": false, 48 "id": "a9254bdb-2613-4a13-ac4c-adc581fba50d" 49 }, 50 { 51 "status": "ACTIVE", 52 "external_gateway_info": { 53 "network_id": "2b37576e-b050-4891-8b20-e1e37a93942a", 54 "external_fixed_ips": [ 55 {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, 56 {"ip_address": "198.51.100.33", "subnet_id": "1d699529-bdfd-43f8-bcaa-bff00c547af2"} 57 ], 58 "qos_policy_id": "6601bae5-f15a-4687-8be9-ddec9a2f8a8b" 59 }, 60 "name": "gateway", 61 "admin_state_up": true, 62 "tenant_id": "a3e881e0a6534880c5473d95b9442099", 63 "distributed": false, 64 "id": "308a035c-005d-4452-a9fe-6f8f2f0c28d8" 65 } 66 ] 67 } 68 `) 69 }) 70 71 count := 0 72 73 err := routers.List(fake.ServiceClient(), routers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { 74 count++ 75 actual, err := routers.ExtractRouters(page) 76 if err != nil { 77 t.Errorf("Failed to extract routers: %v", err) 78 return false, err 79 } 80 81 expected := []routers.Router{ 82 { 83 Status: "ACTIVE", 84 GatewayInfo: routers.GatewayInfo{NetworkID: ""}, 85 AdminStateUp: true, 86 Distributed: false, 87 Name: "second_routers", 88 ID: "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b", 89 TenantID: "6b96ff0cb17a4b859e1e575d221683d3", 90 }, 91 { 92 Status: "ACTIVE", 93 GatewayInfo: routers.GatewayInfo{NetworkID: "3c5bcddd-6af9-4e6b-9c3e-c153e521cab8"}, 94 AdminStateUp: true, 95 Distributed: false, 96 Name: "router1", 97 ID: "a9254bdb-2613-4a13-ac4c-adc581fba50d", 98 TenantID: "33a40233088643acb66ff6eb0ebea679", 99 }, 100 { 101 Status: "ACTIVE", 102 GatewayInfo: routers.GatewayInfo{ 103 NetworkID: "2b37576e-b050-4891-8b20-e1e37a93942a", 104 ExternalFixedIPs: []routers.ExternalFixedIP{ 105 {IPAddress: "192.0.2.17", SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, 106 {IPAddress: "198.51.100.33", SubnetID: "1d699529-bdfd-43f8-bcaa-bff00c547af2"}, 107 }, 108 QoSPolicyID: "6601bae5-f15a-4687-8be9-ddec9a2f8a8b", 109 }, 110 AdminStateUp: true, 111 Distributed: false, 112 Name: "gateway", 113 ID: "308a035c-005d-4452-a9fe-6f8f2f0c28d8", 114 TenantID: "a3e881e0a6534880c5473d95b9442099", 115 }, 116 } 117 118 th.CheckDeepEquals(t, expected, actual) 119 120 return true, nil 121 }) 122 th.AssertNoErr(t, err) 123 124 if count != 1 { 125 t.Errorf("Expected 1 page, got %d", count) 126 } 127 } 128 129 func TestCreate(t *testing.T) { 130 th.SetupHTTP() 131 defer th.TeardownHTTP() 132 133 th.Mux.HandleFunc("/v2.0/routers", func(w http.ResponseWriter, r *http.Request) { 134 th.TestMethod(t, r, "POST") 135 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 136 th.TestHeader(t, r, "Content-Type", "application/json") 137 th.TestHeader(t, r, "Accept", "application/json") 138 th.TestJSONRequest(t, r, ` 139 { 140 "router":{ 141 "name": "foo_router", 142 "admin_state_up": false, 143 "external_gateway_info":{ 144 "enable_snat": false, 145 "network_id":"8ca37218-28ff-41cb-9b10-039601ea7e6b", 146 "external_fixed_ips": [ 147 {"subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} 148 ], 149 "qos_policy_id": "6601bae5-f15a-4687-8be9-ddec9a2f8a8b" 150 }, 151 "availability_zone_hints": ["zone1", "zone2"] 152 } 153 } 154 `) 155 156 w.Header().Add("Content-Type", "application/json") 157 w.WriteHeader(http.StatusCreated) 158 159 fmt.Fprint(w, ` 160 { 161 "router": { 162 "status": "ACTIVE", 163 "external_gateway_info": { 164 "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", 165 "enable_snat": false, 166 "external_fixed_ips": [ 167 {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} 168 ], 169 "qos_policy_id": "6601bae5-f15a-4687-8be9-ddec9a2f8a8b" 170 }, 171 "name": "foo_router", 172 "admin_state_up": false, 173 "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", 174 "distributed": false, 175 "availability_zone_hints": ["zone1", "zone2"], 176 "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e" 177 } 178 } 179 `) 180 }) 181 182 asu := false 183 enableSNAT := false 184 qosID := "6601bae5-f15a-4687-8be9-ddec9a2f8a8b" 185 efi := []routers.ExternalFixedIP{ 186 { 187 SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def", 188 }, 189 } 190 gwi := routers.GatewayInfo{ 191 NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", 192 EnableSNAT: &enableSNAT, 193 ExternalFixedIPs: efi, 194 QoSPolicyID: qosID, 195 } 196 options := routers.CreateOpts{ 197 Name: "foo_router", 198 AdminStateUp: &asu, 199 GatewayInfo: &gwi, 200 AvailabilityZoneHints: []string{"zone1", "zone2"}, 201 } 202 r, err := routers.Create(context.TODO(), fake.ServiceClient(), options).Extract() 203 th.AssertNoErr(t, err) 204 205 gwi.ExternalFixedIPs = []routers.ExternalFixedIP{{ 206 IPAddress: "192.0.2.17", 207 SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def", 208 }} 209 210 th.AssertEquals(t, "foo_router", r.Name) 211 th.AssertEquals(t, false, r.AdminStateUp) 212 th.AssertDeepEquals(t, gwi, r.GatewayInfo) 213 th.AssertDeepEquals(t, []string{"zone1", "zone2"}, r.AvailabilityZoneHints) 214 } 215 216 func TestGet(t *testing.T) { 217 th.SetupHTTP() 218 defer th.TeardownHTTP() 219 220 th.Mux.HandleFunc("/v2.0/routers/a07eea83-7710-4860-931b-5fe220fae533", func(w http.ResponseWriter, r *http.Request) { 221 th.TestMethod(t, r, "GET") 222 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 223 224 w.Header().Add("Content-Type", "application/json") 225 w.WriteHeader(http.StatusOK) 226 227 fmt.Fprint(w, ` 228 { 229 "router": { 230 "status": "ACTIVE", 231 "external_gateway_info": { 232 "network_id": "85d76829-6415-48ff-9c63-5c5ca8c61ac6", 233 "external_fixed_ips": [ 234 {"ip_address": "198.51.100.33", "subnet_id": "1d699529-bdfd-43f8-bcaa-bff00c547af2"} 235 ], 236 "qos_policy_id": "6601bae5-f15a-4687-8be9-ddec9a2f8a8b" 237 }, 238 "routes": [ 239 { 240 "nexthop": "10.1.0.10", 241 "destination": "40.0.1.0/24" 242 } 243 ], 244 "name": "router1", 245 "admin_state_up": true, 246 "tenant_id": "d6554fe62e2f41efbb6e026fad5c1542", 247 "distributed": false, 248 "availability_zone_hints": ["zone1", "zone2"], 249 "id": "a07eea83-7710-4860-931b-5fe220fae533" 250 } 251 } 252 `) 253 }) 254 255 n, err := routers.Get(context.TODO(), fake.ServiceClient(), "a07eea83-7710-4860-931b-5fe220fae533").Extract() 256 th.AssertNoErr(t, err) 257 258 th.AssertEquals(t, n.Status, "ACTIVE") 259 th.AssertDeepEquals(t, n.GatewayInfo, routers.GatewayInfo{ 260 NetworkID: "85d76829-6415-48ff-9c63-5c5ca8c61ac6", 261 ExternalFixedIPs: []routers.ExternalFixedIP{ 262 {IPAddress: "198.51.100.33", SubnetID: "1d699529-bdfd-43f8-bcaa-bff00c547af2"}, 263 }, 264 QoSPolicyID: "6601bae5-f15a-4687-8be9-ddec9a2f8a8b", 265 }) 266 th.AssertEquals(t, n.Name, "router1") 267 th.AssertEquals(t, n.AdminStateUp, true) 268 th.AssertEquals(t, n.TenantID, "d6554fe62e2f41efbb6e026fad5c1542") 269 th.AssertEquals(t, n.ID, "a07eea83-7710-4860-931b-5fe220fae533") 270 th.AssertDeepEquals(t, n.Routes, []routers.Route{{DestinationCIDR: "40.0.1.0/24", NextHop: "10.1.0.10"}}) 271 th.AssertDeepEquals(t, n.AvailabilityZoneHints, []string{"zone1", "zone2"}) 272 } 273 274 func TestUpdate(t *testing.T) { 275 th.SetupHTTP() 276 defer th.TeardownHTTP() 277 278 th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { 279 th.TestMethod(t, r, "PUT") 280 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 281 th.TestHeader(t, r, "Content-Type", "application/json") 282 th.TestHeader(t, r, "Accept", "application/json") 283 th.TestJSONRequest(t, r, ` 284 { 285 "router": { 286 "name": "new_name", 287 "external_gateway_info": { 288 "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", 289 "qos_policy_id": "01ba32e5-f15a-4687-8be9-ddec92a2f8a8" 290 }, 291 "routes": [ 292 { 293 "nexthop": "10.1.0.10", 294 "destination": "40.0.1.0/24" 295 } 296 ] 297 } 298 } 299 `) 300 301 w.Header().Add("Content-Type", "application/json") 302 w.WriteHeader(http.StatusOK) 303 304 fmt.Fprint(w, ` 305 { 306 "router": { 307 "status": "ACTIVE", 308 "external_gateway_info": { 309 "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", 310 "external_fixed_ips": [ 311 {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} 312 ], 313 "qos_policy_id": "01ba32e5-f15a-4687-8be9-ddec92a2f8a8" 314 }, 315 "name": "new_name", 316 "admin_state_up": true, 317 "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", 318 "distributed": false, 319 "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e", 320 "routes": [ 321 { 322 "nexthop": "10.1.0.10", 323 "destination": "40.0.1.0/24" 324 } 325 ] 326 } 327 } 328 `) 329 }) 330 331 gwi := routers.GatewayInfo{ 332 NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", 333 QoSPolicyID: "01ba32e5-f15a-4687-8be9-ddec92a2f8a8", 334 } 335 r := []routers.Route{{DestinationCIDR: "40.0.1.0/24", NextHop: "10.1.0.10"}} 336 options := routers.UpdateOpts{Name: "new_name", GatewayInfo: &gwi, Routes: &r} 337 338 n, err := routers.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() 339 th.AssertNoErr(t, err) 340 341 gwi.ExternalFixedIPs = []routers.ExternalFixedIP{ 342 {IPAddress: "192.0.2.17", SubnetID: "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"}, 343 } 344 345 th.AssertEquals(t, n.Name, "new_name") 346 th.AssertDeepEquals(t, n.GatewayInfo, gwi) 347 th.AssertDeepEquals(t, n.Routes, []routers.Route{{DestinationCIDR: "40.0.1.0/24", NextHop: "10.1.0.10"}}) 348 } 349 350 func TestUpdateWithoutRoutes(t *testing.T) { 351 th.SetupHTTP() 352 defer th.TeardownHTTP() 353 354 th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { 355 th.TestMethod(t, r, "PUT") 356 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 357 th.TestHeader(t, r, "Content-Type", "application/json") 358 th.TestHeader(t, r, "Accept", "application/json") 359 th.TestJSONRequest(t, r, ` 360 { 361 "router": { 362 "name": "new_name" 363 } 364 } 365 `) 366 367 w.Header().Add("Content-Type", "application/json") 368 w.WriteHeader(http.StatusOK) 369 370 fmt.Fprint(w, ` 371 { 372 "router": { 373 "status": "ACTIVE", 374 "external_gateway_info": { 375 "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b", 376 "external_fixed_ips": [ 377 {"ip_address": "192.0.2.17", "subnet_id": "ab561bc4-1a8e-48f2-9fbd-376fcb1a1def"} 378 ] 379 }, 380 "name": "new_name", 381 "admin_state_up": true, 382 "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", 383 "distributed": false, 384 "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e", 385 "routes": [ 386 { 387 "nexthop": "10.1.0.10", 388 "destination": "40.0.1.0/24" 389 } 390 ] 391 } 392 } 393 `) 394 }) 395 396 options := routers.UpdateOpts{Name: "new_name"} 397 398 n, err := routers.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() 399 th.AssertNoErr(t, err) 400 401 th.AssertEquals(t, n.Name, "new_name") 402 th.AssertDeepEquals(t, n.Routes, []routers.Route{{DestinationCIDR: "40.0.1.0/24", NextHop: "10.1.0.10"}}) 403 } 404 405 func TestAllRoutesRemoved(t *testing.T) { 406 th.SetupHTTP() 407 defer th.TeardownHTTP() 408 409 th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { 410 th.TestMethod(t, r, "PUT") 411 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 412 th.TestHeader(t, r, "Content-Type", "application/json") 413 th.TestHeader(t, r, "Accept", "application/json") 414 th.TestJSONRequest(t, r, ` 415 { 416 "router": { 417 "routes": [] 418 } 419 } 420 `) 421 422 w.Header().Add("Content-Type", "application/json") 423 w.WriteHeader(http.StatusOK) 424 425 fmt.Fprint(w, ` 426 { 427 "router": { 428 "status": "ACTIVE", 429 "external_gateway_info": { 430 "network_id": "8ca37218-28ff-41cb-9b10-039601ea7e6b" 431 }, 432 "name": "name", 433 "admin_state_up": true, 434 "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3", 435 "distributed": false, 436 "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e", 437 "routes": [] 438 } 439 } 440 `) 441 }) 442 443 r := []routers.Route{} 444 options := routers.UpdateOpts{Routes: &r} 445 446 n, err := routers.Update(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract() 447 th.AssertNoErr(t, err) 448 449 th.AssertDeepEquals(t, n.Routes, []routers.Route{}) 450 } 451 452 func TestDelete(t *testing.T) { 453 th.SetupHTTP() 454 defer th.TeardownHTTP() 455 456 th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) { 457 th.TestMethod(t, r, "DELETE") 458 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 459 w.WriteHeader(http.StatusNoContent) 460 }) 461 462 res := routers.Delete(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c") 463 th.AssertNoErr(t, res.Err) 464 } 465 466 func TestAddInterface(t *testing.T) { 467 th.SetupHTTP() 468 defer th.TeardownHTTP() 469 470 th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/add_router_interface", func(w http.ResponseWriter, r *http.Request) { 471 th.TestMethod(t, r, "PUT") 472 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 473 th.TestHeader(t, r, "Content-Type", "application/json") 474 th.TestHeader(t, r, "Accept", "application/json") 475 th.TestJSONRequest(t, r, ` 476 { 477 "subnet_id": "a2f1f29d-571b-4533-907f-5803ab96ead1" 478 } 479 `) 480 481 w.Header().Add("Content-Type", "application/json") 482 w.WriteHeader(http.StatusOK) 483 484 fmt.Fprint(w, ` 485 { 486 "subnet_id": "0d32a837-8069-4ec3-84c4-3eef3e10b188", 487 "tenant_id": "017d8de156df4177889f31a9bd6edc00", 488 "port_id": "3f990102-4485-4df1-97a0-2c35bdb85b31", 489 "id": "9a83fa11-8da5-436e-9afe-3d3ac5ce7770" 490 } 491 `) 492 }) 493 494 opts := routers.AddInterfaceOpts{SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1"} 495 res, err := routers.AddInterface(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() 496 th.AssertNoErr(t, err) 497 498 th.AssertEquals(t, "0d32a837-8069-4ec3-84c4-3eef3e10b188", res.SubnetID) 499 th.AssertEquals(t, "017d8de156df4177889f31a9bd6edc00", res.TenantID) 500 th.AssertEquals(t, "3f990102-4485-4df1-97a0-2c35bdb85b31", res.PortID) 501 th.AssertEquals(t, "9a83fa11-8da5-436e-9afe-3d3ac5ce7770", res.ID) 502 } 503 504 func TestAddInterfaceRequiredOpts(t *testing.T) { 505 _, err := routers.AddInterface(context.TODO(), fake.ServiceClient(), "foo", routers.AddInterfaceOpts{}).Extract() 506 if err == nil { 507 t.Fatalf("Expected error, got none") 508 } 509 _, err = routers.AddInterface(context.TODO(), fake.ServiceClient(), "foo", routers.AddInterfaceOpts{SubnetID: "bar", PortID: "baz"}).Extract() 510 if err == nil { 511 t.Fatalf("Expected error, got none") 512 } 513 } 514 515 func TestRemoveInterface(t *testing.T) { 516 th.SetupHTTP() 517 defer th.TeardownHTTP() 518 519 th.Mux.HandleFunc("/v2.0/routers/4e8e5957-649f-477b-9e5b-f1f75b21c03c/remove_router_interface", func(w http.ResponseWriter, r *http.Request) { 520 th.TestMethod(t, r, "PUT") 521 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 522 th.TestHeader(t, r, "Content-Type", "application/json") 523 th.TestHeader(t, r, "Accept", "application/json") 524 th.TestJSONRequest(t, r, ` 525 { 526 "subnet_id": "a2f1f29d-571b-4533-907f-5803ab96ead1" 527 } 528 `) 529 530 w.Header().Add("Content-Type", "application/json") 531 w.WriteHeader(http.StatusOK) 532 533 fmt.Fprint(w, ` 534 { 535 "subnet_id": "0d32a837-8069-4ec3-84c4-3eef3e10b188", 536 "tenant_id": "017d8de156df4177889f31a9bd6edc00", 537 "port_id": "3f990102-4485-4df1-97a0-2c35bdb85b31", 538 "id": "9a83fa11-8da5-436e-9afe-3d3ac5ce7770" 539 } 540 `) 541 }) 542 543 opts := routers.RemoveInterfaceOpts{SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1"} 544 res, err := routers.RemoveInterface(context.TODO(), fake.ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", opts).Extract() 545 th.AssertNoErr(t, err) 546 547 th.AssertEquals(t, "0d32a837-8069-4ec3-84c4-3eef3e10b188", res.SubnetID) 548 th.AssertEquals(t, "017d8de156df4177889f31a9bd6edc00", res.TenantID) 549 th.AssertEquals(t, "3f990102-4485-4df1-97a0-2c35bdb85b31", res.PortID) 550 th.AssertEquals(t, "9a83fa11-8da5-436e-9afe-3d3ac5ce7770", res.ID) 551 } 552 553 func TestListL3Agents(t *testing.T) { 554 th.SetupHTTP() 555 defer th.TeardownHTTP() 556 557 th.Mux.HandleFunc("/v2.0/routers/fa3a4aaa-c73f-48aa-a603-8c8bf642b7c0/l3-agents", func(w http.ResponseWriter, r *http.Request) { 558 th.TestMethod(t, r, "GET") 559 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 560 561 w.Header().Add("Content-Type", "application/json") 562 w.WriteHeader(http.StatusOK) 563 564 fmt.Fprint(w, ` 565 { 566 "agents": [ 567 { 568 "id": "ddbf087c-e38f-4a73-bcb3-c38f2a719a03", 569 "agent_type": "L3 agent", 570 "binary": "neutron-l3-agent", 571 "topic": "l3_agent", 572 "host": "os-ctrl-02", 573 "admin_state_up": true, 574 "created_at": "2017-07-26 23:15:44", 575 "started_at": "2018-06-26 21:46:19", 576 "heartbeat_timestamp": "2019-01-09 10:28:53", 577 "description": "My L3 agent for OpenStack", 578 "resources_synced": true, 579 "availability_zone": "nova", 580 "alive": true, 581 "configurations": { 582 "agent_mode": "legacy", 583 "ex_gw_ports": 2, 584 "floating_ips": 2, 585 "handle_internal_only_routers": true, 586 "interface_driver": "linuxbridge", 587 "interfaces": 1, 588 "log_agent_heartbeats": false, 589 "routers": 2 590 }, 591 "resource_versions": {}, 592 "ha_state": "standby" 593 }, 594 { 595 "id": "4541cc6c-87bc-4cee-bad2-36ca78836c91", 596 "agent_type": "L3 agent", 597 "binary": "neutron-l3-agent", 598 "topic": "l3_agent", 599 "host": "os-ctrl-03", 600 "admin_state_up": true, 601 "created_at": "2017-01-22 14:00:50", 602 "started_at": "2018-11-06 12:09:17", 603 "heartbeat_timestamp": "2019-01-09 10:28:50", 604 "description": "My L3 agent for OpenStack", 605 "resources_synced": true, 606 "availability_zone": "nova", 607 "alive": true, 608 "configurations": { 609 "agent_mode": "legacy", 610 "ex_gw_ports": 2, 611 "floating_ips": 2, 612 "handle_internal_only_routers": true, 613 "interface_driver": "linuxbridge", 614 "interfaces": 1, 615 "log_agent_heartbeats": false, 616 "routers": 2 617 }, 618 "resource_versions": {}, 619 "ha_state": "active" 620 } 621 ] 622 } 623 `) 624 }) 625 626 l3AgentsPages, err := routers.ListL3Agents(fake.ServiceClient(), "fa3a4aaa-c73f-48aa-a603-8c8bf642b7c0").AllPages(context.TODO()) 627 th.AssertNoErr(t, err) 628 actual, err := routers.ExtractL3Agents(l3AgentsPages) 629 th.AssertNoErr(t, err) 630 631 expected := []routers.L3Agent{ 632 { 633 ID: "ddbf087c-e38f-4a73-bcb3-c38f2a719a03", 634 AdminStateUp: true, 635 AgentType: "L3 agent", 636 Description: "My L3 agent for OpenStack", 637 Alive: true, 638 ResourcesSynced: true, 639 Binary: "neutron-l3-agent", 640 AvailabilityZone: "nova", 641 Configurations: map[string]any{ 642 "agent_mode": "legacy", 643 "ex_gw_ports": float64(2), 644 "floating_ips": float64(2), 645 "handle_internal_only_routers": true, 646 "interface_driver": "linuxbridge", 647 "interfaces": float64(1), 648 "log_agent_heartbeats": false, 649 "routers": float64(2), 650 }, 651 CreatedAt: time.Date(2017, 7, 26, 23, 15, 44, 0, time.UTC), 652 StartedAt: time.Date(2018, 6, 26, 21, 46, 19, 0, time.UTC), 653 HeartbeatTimestamp: time.Date(2019, 1, 9, 10, 28, 53, 0, time.UTC), 654 Host: "os-ctrl-02", 655 Topic: "l3_agent", 656 HAState: "standby", 657 ResourceVersions: map[string]any{}, 658 }, 659 { 660 ID: "4541cc6c-87bc-4cee-bad2-36ca78836c91", 661 AdminStateUp: true, 662 AgentType: "L3 agent", 663 Description: "My L3 agent for OpenStack", 664 Alive: true, 665 ResourcesSynced: true, 666 Binary: "neutron-l3-agent", 667 AvailabilityZone: "nova", 668 Configurations: map[string]any{ 669 "agent_mode": "legacy", 670 "ex_gw_ports": float64(2), 671 "floating_ips": float64(2), 672 "handle_internal_only_routers": true, 673 "interface_driver": "linuxbridge", 674 "interfaces": float64(1), 675 "log_agent_heartbeats": false, 676 "routers": float64(2), 677 }, 678 CreatedAt: time.Date(2017, 1, 22, 14, 00, 50, 0, time.UTC), 679 StartedAt: time.Date(2018, 11, 6, 12, 9, 17, 0, time.UTC), 680 HeartbeatTimestamp: time.Date(2019, 1, 9, 10, 28, 50, 0, time.UTC), 681 Host: "os-ctrl-03", 682 Topic: "l3_agent", 683 HAState: "active", 684 ResourceVersions: map[string]any{}, 685 }, 686 } 687 th.CheckDeepEquals(t, expected, actual) 688 }