github.com/sacloud/iaas-api-go@v1.12.0/testutil/cleanup.go (about) 1 // Copyright 2022-2023 The sacloud/iaas-api-go Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package testutil 16 17 import ( 18 "context" 19 "sync" 20 21 "github.com/hashicorp/go-multierror" 22 "github.com/sacloud/iaas-api-go" 23 "github.com/sacloud/iaas-api-go/search" 24 "github.com/sacloud/iaas-api-go/types" 25 ) 26 27 func ComposeCleanupFuncs(funcs ...func(context.Context, iaas.APICaller) error) func(context.Context, iaas.APICaller) error { 28 return func(ctx context.Context, caller iaas.APICaller) error { 29 for _, f := range funcs { 30 if err := f(ctx, caller); err != nil { 31 return err 32 } 33 } 34 return nil 35 } 36 } 37 38 func ComposeCleanupResourceFunc(prefix string, targets ...CleanupTarget) func(context.Context, iaas.APICaller) error { 39 var funcs []func(context.Context, iaas.APICaller) error 40 for _, t := range targets { 41 funcs = append(funcs, func(ctx context.Context, caller iaas.APICaller) error { 42 return CleanupResource(ctx, caller, prefix, t) 43 }) 44 } 45 return ComposeCleanupFuncs(funcs...) 46 } 47 48 func CleanupResource(ctx context.Context, caller iaas.APICaller, prefix string, target CleanupTarget) error { 49 if !IsAccTest() { 50 return nil 51 } 52 if prefix == "" { 53 prefix = TestResourcePrefix 54 } 55 cleanupFindCondition = &iaas.FindCondition{ 56 Filter: search.Filter{ 57 search.Key("Name"): search.PartialMatch(prefix), 58 }, 59 } 60 61 searched, err := target.finder(ctx, caller) 62 if err != nil { 63 return err 64 } 65 66 var errs *multierror.Error 67 var wg sync.WaitGroup 68 for i := range searched { 69 wg.Add(1) 70 go func(target *cleanupTarget) { 71 defer wg.Done() 72 if target.prepareFunc != nil { 73 if err := target.prepareFunc(ctx); err != nil { 74 multierror.Append(errs, err) //nolint 75 return 76 } 77 } 78 if target.deleteFunc != nil { 79 if err := target.deleteFunc(ctx); err != nil { 80 multierror.Append(errs, err) //nolint 81 return 82 } 83 } 84 }(searched[i]) 85 } 86 wg.Wait() 87 88 return errs.ErrorOrNil() 89 } 90 91 type CleanupTarget struct { 92 finder cleanupTargetFindFunc 93 } 94 95 // CleanupTargets クリーンアップ対象のリソース。CleanupResourceに渡す 96 var CleanupTargets = struct { 97 Archive CleanupTarget 98 AutoBackup CleanupTarget 99 Bridge CleanupTarget 100 ContainerRegistry CleanupTarget 101 CDROM CleanupTarget 102 Database CleanupTarget 103 Disk CleanupTarget 104 DNS CleanupTarget 105 GSLB CleanupTarget 106 Icon CleanupTarget 107 Internet CleanupTarget 108 License CleanupTarget 109 LoadBalancer CleanupTarget 110 MobileGateway CleanupTarget 111 NFS CleanupTarget 112 Note CleanupTarget 113 PacketFilter CleanupTarget 114 PrivateHost CleanupTarget 115 ProxyLB CleanupTarget 116 Server CleanupTarget 117 SIM CleanupTarget 118 SimpleMonitor CleanupTarget 119 SSHKey CleanupTarget 120 Switch CleanupTarget 121 VPCRouter CleanupTarget 122 }{ 123 Archive: CleanupTarget{finder: findArchive}, 124 AutoBackup: CleanupTarget{finder: findAutoBackup}, 125 Bridge: CleanupTarget{finder: findBridge}, 126 ContainerRegistry: CleanupTarget{finder: findContainerRegistry}, 127 CDROM: CleanupTarget{finder: findCDROM}, 128 Database: CleanupTarget{finder: findDatabase}, 129 Disk: CleanupTarget{finder: findDisk}, 130 DNS: CleanupTarget{finder: findDNS}, 131 GSLB: CleanupTarget{finder: findGSLB}, 132 Icon: CleanupTarget{finder: findIcon}, 133 Internet: CleanupTarget{finder: findInternet}, 134 License: CleanupTarget{finder: findLicense}, 135 LoadBalancer: CleanupTarget{finder: findLoadBalancer}, 136 MobileGateway: CleanupTarget{finder: findMobileGateway}, 137 NFS: CleanupTarget{finder: findNFS}, 138 Note: CleanupTarget{finder: findNote}, 139 PacketFilter: CleanupTarget{finder: findPacketFilter}, 140 PrivateHost: CleanupTarget{finder: findPrivateHost}, 141 ProxyLB: CleanupTarget{finder: findProxyLB}, 142 Server: CleanupTarget{finder: findServer}, 143 SIM: CleanupTarget{finder: findSIM}, 144 SimpleMonitor: CleanupTarget{finder: findSimpleMonitor}, 145 SSHKey: CleanupTarget{finder: findSSHKey}, 146 Switch: CleanupTarget{finder: findSwitch}, 147 VPCRouter: CleanupTarget{finder: findVPCRouter}, 148 } 149 150 // CleanupTestResources 指定プレフィックスを持つリソースの削除を行う 151 // 152 // TESTACC環境変数が設定されている場合のみ実施される 153 func CleanupTestResources(ctx context.Context, caller iaas.APICaller) error { 154 if !IsAccTest() { 155 return nil 156 } 157 cleanupFindCondition = &iaas.FindCondition{ 158 Filter: search.Filter{ 159 search.Key("Name"): search.PartialMatch(TestResourcePrefix), 160 }, 161 } 162 var errs *multierror.Error 163 164 // cleanup: primary group 165 doCleanup(ctx, correctCleanupTargets(ctx, caller, cleanupPrimaryGroup, errs), errs) 166 // cleanup: secondary group 167 doCleanup(ctx, correctCleanupTargets(ctx, caller, cleanupSecondaryGroup, errs), errs) 168 169 return errs.ErrorOrNil() 170 } 171 172 func doCleanup(ctx context.Context, targets []*cleanupTarget, errs *multierror.Error) { 173 var wg sync.WaitGroup 174 for i := range targets { 175 wg.Add(1) 176 go func(target *cleanupTarget) { 177 defer wg.Done() 178 if target.prepareFunc != nil { 179 if err := target.prepareFunc(ctx); err != nil { 180 multierror.Append(errs, err) //nolint 181 return 182 } 183 } 184 if target.deleteFunc != nil { 185 if err := target.deleteFunc(ctx); err != nil { 186 multierror.Append(errs, err) //nolint 187 return 188 } 189 } 190 }(targets[i]) 191 } 192 wg.Wait() 193 } 194 195 func correctCleanupTargets(ctx context.Context, caller iaas.APICaller, finders []cleanupTargetFindFunc, errs *multierror.Error) []*cleanupTarget { 196 var targets []*cleanupTarget 197 var wg sync.WaitGroup 198 for i := range finders { 199 wg.Add(1) 200 go func(finder cleanupTargetFindFunc) { 201 defer wg.Done() 202 203 res, err := finder(ctx, caller) 204 if err != nil { 205 multierror.Append(errs, err) //nolint 206 return 207 } 208 targets = append(targets, res...) 209 }(finders[i]) 210 } 211 wg.Wait() 212 return targets 213 } 214 215 type cleanupTargetFindFunc func(context.Context, iaas.APICaller) ([]*cleanupTarget, error) 216 217 var cleanupPrimaryGroup = []cleanupTargetFindFunc{ 218 findArchive, 219 findAutoBackup, 220 findContainerRegistry, 221 findDatabase, 222 findDNS, 223 findGSLB, 224 findIcon, 225 findLicense, 226 findLoadBalancer, 227 findNFS, 228 findNote, 229 findPacketFilter, 230 findProxyLB, 231 findServer, 232 findSimpleMonitor, 233 findSSHKey, 234 findVPCRouter, 235 findMobileGateway, 236 } 237 238 var cleanupSecondaryGroup = []cleanupTargetFindFunc{ 239 findBridge, 240 findCDROM, 241 findDisk, 242 findInternet, 243 findSwitch, 244 findPrivateHost, 245 findSIM, 246 } 247 248 var cleanupFindCondition = &iaas.FindCondition{ 249 Filter: search.Filter{ 250 search.Key("Name"): search.PartialMatch(TestResourcePrefix), 251 }, 252 } 253 254 type cleanupTarget struct { 255 resource interface{} 256 prepareFunc func(context.Context) error 257 deleteFunc func(context.Context) error 258 } 259 260 func findBridge(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 261 op := iaas.NewBridgeOp(caller) 262 searched, err := op.Find(ctx, iaas.APIDefaultZone, cleanupFindCondition) 263 if err != nil { 264 return nil, err 265 } 266 var res []*cleanupTarget 267 for i := range searched.Bridges { 268 v := searched.Bridges[i] 269 res = append(res, &cleanupTarget{ 270 resource: v, 271 deleteFunc: func(ctx context.Context) error { 272 return op.Delete(ctx, iaas.APIDefaultZone, v.ID) 273 }, 274 }) 275 } 276 return res, nil 277 } 278 279 func findContainerRegistry(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 280 op := iaas.NewContainerRegistryOp(caller) 281 searched, err := op.Find(ctx, cleanupFindCondition) 282 if err != nil { 283 return nil, err 284 } 285 var res []*cleanupTarget 286 for i := range searched.ContainerRegistries { 287 v := searched.ContainerRegistries[i] 288 res = append(res, &cleanupTarget{ 289 resource: v, 290 deleteFunc: func(ctx context.Context) error { 291 return op.Delete(ctx, v.ID) 292 }, 293 }) 294 } 295 return res, nil 296 } 297 298 func findCDROM(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 299 op := iaas.NewCDROMOp(caller) 300 var res []*cleanupTarget 301 302 for i := range types.ZoneNames { 303 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 304 if err != nil { 305 return nil, err 306 } 307 zone := types.ZoneNames[i] 308 for j := range searched.CDROMs { 309 v := searched.CDROMs[j] 310 res = append(res, &cleanupTarget{ 311 resource: v, 312 deleteFunc: func(ctx context.Context) error { 313 return op.Delete(ctx, zone, v.ID) 314 }, 315 }) 316 } 317 } 318 return res, nil 319 } 320 321 func findInternet(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 322 op := iaas.NewInternetOp(caller) 323 var res []*cleanupTarget 324 325 for i := range types.ZoneNames { 326 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 327 if err != nil { 328 return nil, err 329 } 330 zone := types.ZoneNames[i] 331 for j := range searched.Internet { 332 v := searched.Internet[j] 333 res = append(res, &cleanupTarget{ 334 resource: v, 335 deleteFunc: func(ctx context.Context) error { 336 return op.Delete(ctx, zone, v.ID) 337 }, 338 }) 339 } 340 } 341 return res, nil 342 } 343 344 func findSwitch(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 345 op := iaas.NewSwitchOp(caller) 346 var res []*cleanupTarget 347 348 for i := range types.ZoneNames { 349 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 350 if err != nil { 351 return nil, err 352 } 353 zone := types.ZoneNames[i] 354 for j := range searched.Switches { 355 v := searched.Switches[j] 356 res = append(res, &cleanupTarget{ 357 resource: v, 358 deleteFunc: func(ctx context.Context) error { 359 return op.Delete(ctx, zone, v.ID) 360 }, 361 }) 362 } 363 } 364 return res, nil 365 } 366 367 func findPrivateHost(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 368 op := iaas.NewPrivateHostOp(caller) 369 var res []*cleanupTarget 370 371 for i := range types.ZoneNames { 372 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 373 if err != nil { 374 return nil, err 375 } 376 zone := types.ZoneNames[i] 377 for j := range searched.PrivateHosts { 378 v := searched.PrivateHosts[j] 379 res = append(res, &cleanupTarget{ 380 resource: v, 381 deleteFunc: func(ctx context.Context) error { 382 return op.Delete(ctx, zone, v.ID) 383 }, 384 }) 385 } 386 } 387 return res, nil 388 } 389 390 func findArchive(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 391 op := iaas.NewArchiveOp(caller) 392 var res []*cleanupTarget 393 394 for i := range types.ZoneNames { 395 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 396 if err != nil { 397 return nil, err 398 } 399 zone := types.ZoneNames[i] 400 for j := range searched.Archives { 401 v := searched.Archives[j] 402 res = append(res, &cleanupTarget{ 403 resource: v, 404 deleteFunc: func(ctx context.Context) error { 405 return op.Delete(ctx, zone, v.ID) 406 }, 407 }) 408 } 409 } 410 return res, nil 411 } 412 413 func findAutoBackup(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 414 op := iaas.NewAutoBackupOp(caller) 415 var res []*cleanupTarget 416 417 for i := range types.ZoneNames { 418 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 419 if err != nil { 420 return nil, err 421 } 422 zone := types.ZoneNames[i] 423 for j := range searched.AutoBackups { 424 v := searched.AutoBackups[j] 425 res = append(res, &cleanupTarget{ 426 resource: v, 427 deleteFunc: func(ctx context.Context) error { 428 return op.Delete(ctx, zone, v.ID) 429 }, 430 }) 431 } 432 } 433 return res, nil 434 } 435 436 func findDatabase(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 437 op := iaas.NewDatabaseOp(caller) 438 var res []*cleanupTarget 439 440 for i := range types.ZoneNames { 441 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 442 if err != nil { 443 return nil, err 444 } 445 zone := types.ZoneNames[i] 446 for j := range searched.Databases { 447 v := searched.Databases[j] 448 res = append(res, &cleanupTarget{ 449 resource: v, 450 prepareFunc: func(ctx context.Context) error { 451 if err := op.Shutdown(ctx, zone, v.ID, &iaas.ShutdownOption{Force: true}); err != nil { 452 return err 453 } 454 _, err := iaas.WaiterForDown(func() (interface{}, error) { 455 return op.Read(ctx, zone, v.ID) 456 }).WaitForState(ctx) 457 return err 458 }, 459 deleteFunc: func(ctx context.Context) error { 460 return op.Delete(ctx, zone, v.ID) 461 }, 462 }) 463 } 464 } 465 return res, nil 466 } 467 468 func findDisk(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 469 op := iaas.NewDiskOp(caller) 470 var res []*cleanupTarget 471 472 for i := range types.ZoneNames { 473 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 474 if err != nil { 475 return nil, err 476 } 477 zone := types.ZoneNames[i] 478 for j := range searched.Disks { 479 v := searched.Disks[j] 480 res = append(res, &cleanupTarget{ 481 resource: v, 482 deleteFunc: func(ctx context.Context) error { 483 return op.Delete(ctx, zone, v.ID) 484 }, 485 }) 486 } 487 } 488 return res, nil 489 } 490 491 func findDNS(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 492 op := iaas.NewDNSOp(caller) 493 var res []*cleanupTarget 494 495 searched, err := op.Find(ctx, cleanupFindCondition) 496 if err != nil { 497 return nil, err 498 } 499 for i := range searched.DNS { 500 v := searched.DNS[i] 501 res = append(res, &cleanupTarget{ 502 resource: v, 503 deleteFunc: func(ctx context.Context) error { 504 return op.Delete(ctx, v.ID) 505 }, 506 }) 507 } 508 return res, nil 509 } 510 511 func findGSLB(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 512 op := iaas.NewGSLBOp(caller) 513 var res []*cleanupTarget 514 515 searched, err := op.Find(ctx, cleanupFindCondition) 516 if err != nil { 517 return nil, err 518 } 519 for i := range searched.GSLBs { 520 v := searched.GSLBs[i] 521 res = append(res, &cleanupTarget{ 522 resource: v, 523 deleteFunc: func(ctx context.Context) error { 524 return op.Delete(ctx, v.ID) 525 }, 526 }) 527 } 528 return res, nil 529 } 530 531 func findIcon(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 532 op := iaas.NewIconOp(caller) 533 var res []*cleanupTarget 534 535 searched, err := op.Find(ctx, cleanupFindCondition) 536 if err != nil { 537 return nil, err 538 } 539 for i := range searched.Icons { 540 v := searched.Icons[i] 541 res = append(res, &cleanupTarget{ 542 resource: v, 543 deleteFunc: func(ctx context.Context) error { 544 return op.Delete(ctx, v.ID) 545 }, 546 }) 547 } 548 return res, nil 549 } 550 551 func findLicense(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 552 op := iaas.NewLicenseOp(caller) 553 var res []*cleanupTarget 554 555 searched, err := op.Find(ctx, cleanupFindCondition) 556 if err != nil { 557 return nil, err 558 } 559 for i := range searched.Licenses { 560 v := searched.Licenses[i] 561 res = append(res, &cleanupTarget{ 562 resource: v, 563 deleteFunc: func(ctx context.Context) error { 564 return op.Delete(ctx, v.ID) 565 }, 566 }) 567 } 568 return res, nil 569 } 570 571 func findLoadBalancer(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 572 op := iaas.NewLoadBalancerOp(caller) 573 var res []*cleanupTarget 574 575 for i := range types.ZoneNames { 576 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 577 if err != nil { 578 return nil, err 579 } 580 zone := types.ZoneNames[i] 581 for j := range searched.LoadBalancers { 582 v := searched.LoadBalancers[j] 583 res = append(res, &cleanupTarget{ 584 resource: v, 585 prepareFunc: func(ctx context.Context) error { 586 if err := op.Shutdown(ctx, zone, v.ID, &iaas.ShutdownOption{Force: true}); err != nil { 587 return err 588 } 589 _, err := iaas.WaiterForDown(func() (interface{}, error) { 590 return op.Read(ctx, zone, v.ID) 591 }).WaitForState(ctx) 592 return err 593 }, 594 deleteFunc: func(ctx context.Context) error { 595 return op.Delete(ctx, zone, v.ID) 596 }, 597 }) 598 } 599 } 600 return res, nil 601 } 602 603 func findMobileGateway(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 604 op := iaas.NewMobileGatewayOp(caller) 605 var res []*cleanupTarget 606 607 for i := range types.ZoneNames { 608 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 609 if err != nil { 610 return nil, err 611 } 612 zone := types.ZoneNames[i] 613 for j := range searched.MobileGateways { 614 v := searched.MobileGateways[j] 615 res = append(res, &cleanupTarget{ 616 resource: v, 617 prepareFunc: func(ctx context.Context) error { 618 // delete sim routes 619 if err := op.SetSIMRoutes(ctx, zone, v.ID, []*iaas.MobileGatewaySIMRouteParam{}); err != nil { 620 return err 621 } 622 623 // delete SIMs 624 sims, err := op.ListSIM(ctx, zone, v.ID) 625 if err != nil { 626 return err 627 } 628 for _, sim := range sims { 629 if err := op.DeleteSIM(ctx, zone, v.ID, types.StringID(sim.ResourceID)); err != nil { 630 return err 631 } 632 } 633 634 if err := op.Shutdown(ctx, zone, v.ID, &iaas.ShutdownOption{Force: true}); err != nil { 635 return err 636 } 637 _, err = iaas.WaiterForDown(func() (interface{}, error) { 638 return op.Read(ctx, zone, v.ID) 639 }).WaitForState(ctx) 640 return err 641 }, 642 deleteFunc: func(ctx context.Context) error { 643 return op.Delete(ctx, zone, v.ID) 644 }, 645 }) 646 } 647 } 648 return res, nil 649 } 650 651 func findNFS(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 652 op := iaas.NewNFSOp(caller) 653 var res []*cleanupTarget 654 655 for i := range types.ZoneNames { 656 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 657 if err != nil { 658 return nil, err 659 } 660 zone := types.ZoneNames[i] 661 for j := range searched.NFS { 662 v := searched.NFS[j] 663 res = append(res, &cleanupTarget{ 664 resource: v, 665 prepareFunc: func(ctx context.Context) error { 666 if err := op.Shutdown(ctx, zone, v.ID, &iaas.ShutdownOption{Force: true}); err != nil { 667 return err 668 } 669 _, err := iaas.WaiterForDown(func() (interface{}, error) { 670 return op.Read(ctx, zone, v.ID) 671 }).WaitForState(ctx) 672 return err 673 }, 674 deleteFunc: func(ctx context.Context) error { 675 return op.Delete(ctx, zone, v.ID) 676 }, 677 }) 678 } 679 } 680 return res, nil 681 } 682 683 func findNote(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 684 op := iaas.NewNoteOp(caller) 685 var res []*cleanupTarget 686 687 searched, err := op.Find(ctx, cleanupFindCondition) 688 if err != nil { 689 return nil, err 690 } 691 for i := range searched.Notes { 692 v := searched.Notes[i] 693 res = append(res, &cleanupTarget{ 694 resource: v, 695 deleteFunc: func(ctx context.Context) error { 696 return op.Delete(ctx, v.ID) 697 }, 698 }) 699 } 700 return res, nil 701 } 702 703 func findPacketFilter(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 704 op := iaas.NewPacketFilterOp(caller) 705 var res []*cleanupTarget 706 707 for i := range types.ZoneNames { 708 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 709 if err != nil { 710 return nil, err 711 } 712 zone := types.ZoneNames[i] 713 for j := range searched.PacketFilters { 714 v := searched.PacketFilters[j] 715 res = append(res, &cleanupTarget{ 716 resource: v, 717 deleteFunc: func(ctx context.Context) error { 718 return op.Delete(ctx, zone, v.ID) 719 }, 720 }) 721 } 722 } 723 return res, nil 724 } 725 726 func findProxyLB(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 727 op := iaas.NewProxyLBOp(caller) 728 var res []*cleanupTarget 729 730 searched, err := op.Find(ctx, cleanupFindCondition) 731 if err != nil { 732 return nil, err 733 } 734 for i := range searched.ProxyLBs { 735 v := searched.ProxyLBs[i] 736 res = append(res, &cleanupTarget{ 737 resource: v, 738 deleteFunc: func(ctx context.Context) error { 739 return op.Delete(ctx, v.ID) 740 }, 741 }) 742 } 743 return res, nil 744 } 745 746 func findServer(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 747 op := iaas.NewServerOp(caller) 748 var res []*cleanupTarget 749 750 for i := range types.ZoneNames { 751 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 752 if err != nil { 753 return nil, err 754 } 755 zone := types.ZoneNames[i] 756 for j := range searched.Servers { 757 v := searched.Servers[j] 758 res = append(res, &cleanupTarget{ 759 resource: v, 760 prepareFunc: func(ctx context.Context) error { 761 if err := op.Shutdown(ctx, zone, v.ID, &iaas.ShutdownOption{Force: true}); err != nil { 762 return err 763 } 764 _, err := iaas.WaiterForDown(func() (interface{}, error) { 765 return op.Read(ctx, zone, v.ID) 766 }).WaitForState(ctx) 767 return err 768 }, 769 deleteFunc: func(ctx context.Context) error { 770 return op.Delete(ctx, zone, v.ID) 771 }, 772 }) 773 } 774 } 775 return res, nil 776 } 777 778 func findSIM(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 779 op := iaas.NewSIMOp(caller) 780 var res []*cleanupTarget 781 782 searched, err := op.Find(ctx, cleanupFindCondition) 783 if err != nil { 784 return nil, err 785 } 786 for i := range searched.SIMs { 787 v := searched.SIMs[i] 788 res = append(res, &cleanupTarget{ 789 resource: v, 790 deleteFunc: func(ctx context.Context) error { 791 return op.Delete(ctx, v.ID) 792 }, 793 }) 794 } 795 return res, nil 796 } 797 798 func findSimpleMonitor(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 799 op := iaas.NewSimpleMonitorOp(caller) 800 var res []*cleanupTarget 801 802 searched, err := op.Find(ctx, cleanupFindCondition) 803 if err != nil { 804 return nil, err 805 } 806 for i := range searched.SimpleMonitors { 807 v := searched.SimpleMonitors[i] 808 res = append(res, &cleanupTarget{ 809 resource: v, 810 deleteFunc: func(ctx context.Context) error { 811 return op.Delete(ctx, v.ID) 812 }, 813 }) 814 } 815 return res, nil 816 } 817 818 func findSSHKey(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 819 op := iaas.NewSSHKeyOp(caller) 820 var res []*cleanupTarget 821 822 searched, err := op.Find(ctx, cleanupFindCondition) 823 if err != nil { 824 return nil, err 825 } 826 for i := range searched.SSHKeys { 827 v := searched.SSHKeys[i] 828 res = append(res, &cleanupTarget{ 829 resource: v, 830 deleteFunc: func(ctx context.Context) error { 831 return op.Delete(ctx, v.ID) 832 }, 833 }) 834 } 835 return res, nil 836 } 837 838 func findVPCRouter(ctx context.Context, caller iaas.APICaller) ([]*cleanupTarget, error) { 839 op := iaas.NewVPCRouterOp(caller) 840 var res []*cleanupTarget 841 842 for i := range types.ZoneNames { 843 searched, err := op.Find(ctx, types.ZoneNames[i], cleanupFindCondition) 844 if err != nil { 845 return nil, err 846 } 847 zone := types.ZoneNames[i] 848 for j := range searched.VPCRouters { 849 v := searched.VPCRouters[j] 850 res = append(res, &cleanupTarget{ 851 resource: v, 852 prepareFunc: func(ctx context.Context) error { 853 if err := op.Shutdown(ctx, zone, v.ID, &iaas.ShutdownOption{Force: true}); err != nil { 854 return err 855 } 856 _, err := iaas.WaiterForDown(func() (interface{}, error) { 857 return op.Read(ctx, zone, v.ID) 858 }).WaitForState(ctx) 859 return err 860 }, 861 deleteFunc: func(ctx context.Context) error { 862 return op.Delete(ctx, zone, v.ID) 863 }, 864 }) 865 } 866 } 867 return res, nil 868 }