github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/docs/MIGRATING.md (about) 1 # Migration guide 2 3 Gophercloud follows [semver](https://semver.org/) and each major release brings 4 a number of changes breaking backward compatibility. This guide details those 5 changes and explains how to migrate from one major version of Gophercloud to 6 another. 7 8 ## From v1 to v2 9 10 ### Change import path 11 12 The module is now named `github.com/vnpaycloud-console/gophercloud/v2`. Consequently, 13 you need to update all your imports: 14 15 ```diff 16 import ( 17 - "github.com/gophercloud/gophercloud" 18 - "github.com/gophercloud/gophercloud/pagination" 19 + "github.com/vnpaycloud-console/gophercloud/v2" 20 + "github.com/vnpaycloud-console/gophercloud/v2/pagination" 21 ) 22 ``` 23 24 If using [gophercloud/utils](https://github.com/gophercloud/utils), you will 25 also need to update those imports: 26 27 ```diff 28 import ( 29 - "github.com/gophercloud/gophercloud" 30 - serverutils "github.com/gophercloud/utils/openstack/compute/v2/servers" 31 + "github.com/vnpaycloud-console/gophercloud/v2" 32 + serverutils "github.com/gophercloud/utils/v2/openstack/compute/v2/servers" 33 ) 34 ``` 35 36 ### Go version 37 38 The minimum go version for Gophercloud v2 is now v1.22. 39 40 ### Context-awareness 41 42 Gophercloud is now context aware, for tracing and cancellation. All function 43 signatures triggering an HTTP call now take a `context.Context` as their first 44 argument. 45 46 While you previously called: 47 48 ```go 49 myServer, err := servers.Get(client, server.ID) 50 ``` 51 52 You now need to pass it a context, for example: 53 54 ```go 55 ctx := context.TODO() 56 myServer, err := servers.Get(ctx, client, server.ID) 57 ``` 58 59 Now that every method accept a context, it is no longer possible to attach 60 a context to the Provider client. Use per-call context instead. 61 62 The `WaitFor` functions now take a context as well, and we've dropped the 63 timeout argument. This means that the following code: 64 65 ```go 66 err = attachments.WaitForStatus(client, attachment.ID, "attached", 60) 67 ``` 68 69 Must be changed to use a context with timeout. For example: 70 71 ```go 72 ctx, cancel := context.WithTimeout(context.TODO(), 60*time.Second) 73 defer cancel() 74 75 err = attachments.WaitForStatus(ctx, client, attachment.ID, "attached") 76 ``` 77 78 ### Error handling 79 80 The error types for specific response codes (`ErrDefault400`, `ErrDefault401`, etc.) have been removed. 81 All unexpected response codes will now return `ErrUnexpectedResponseCode` instead. 82 For quickly checking whether a request resulted in a specific response code, use the new `ResponseCodeIs` function: 83 84 ```go 85 server, err := servers.Get(ctx, client, serverID).Extract() 86 87 // before 88 if _, ok := err.(gophercloud.ErrDefault404); ok { 89 handleServerNotFound() 90 } 91 92 // after 93 if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { 94 handleServerNotFound() 95 } 96 ``` 97 98 Furthermore, the error messages returned by ErrUnexpectedResponseCode now include less newlines than before. 99 If you match on error messages using regexes, please double-check your regexes. 100 101 #### With gophercloud/utils 102 103 If using the `utils` library, note that the `IDFromName` functions return 104 `ErrResourceNotFound` rather than `ErrUnexpectedResponseCode`. In that 105 scenario, type assertions for a "not found" error are still necessary: 106 107 ```Go 108 func IsNotFound(err error) bool { 109 if _, ok := err.(gophercloud.ErrResourceNotFound); ok { // <-- this 110 return true 111 } 112 113 return gophercloud.ResponseCodeIs(err, http.StatusNotFound) 114 } 115 ``` 116 117 ### Removal of `extensions` modules 118 119 A number of services previously supported API extensions but have long since 120 switched to using microversions to allow API changes. This is now reflected 121 in Gophercloud v2 and the contents of the follow modules have been largely 122 migrated: 123 124 - `openstack/blockstorage/extensions` 125 - `openstack/compute/v2/extensions` 126 - `openstack/identity/v2/extensions` 127 - `openstack/identity/v3/extensions` 128 129 The replacement for these depends on the type of the former extension. For 130 extensions that added wholly new APIs, these APIs have been moved into the 131 main module for the corresponding service. These are: 132 133 - `openstack/blockstorage/extensions/availabilityzones` 134 135 Moved to `openstack/blockstorage/v2/availabilityzones` and 136 `openstack/blockstorage/v3/availabilityzones`. 137 138 - `openstack/blockstorage/extensions/backups` 139 140 Moved to `openstack/blockstorage/v2/backups` and 141 `openstack/blockstorage/v3/backups`. 142 143 - `openstack/blockstorage/extensions/limits` 144 145 Moved to `openstack/blockstorage/v2/limits` and 146 `openstack/blockstorage/v3/limits`. 147 148 - `openstack/blockstorage/extensions/quotasets` 149 150 Moved to `openstack/blockstorage/v2/quotasets` and 151 `openstack/blockstorage/v3/quotasets`. 152 153 - `openstack/blockstorage/extensions/schedulerstats` 154 155 Moved to `openstack/blockstorage/v2/schedulerstats` and 156 `openstack/blockstorage/v3/schedulerstats`. 157 158 - `openstack/blockstorage/extensions/services` 159 160 Moved to `openstack/blockstorage/v2/services` and 161 `openstack/blockstorage/v3/services`. 162 163 - `openstack/blockstorage/extensions/volumetransfers` 164 165 Moved to `openstack/blockstorage/v2/transfers` and 166 `openstack/blockstorage/v3/transfers`. 167 168 - `openstack/compute/v2/extensions/aggregates` 169 170 Moved to `openstack/compute/v2/aggregates`. 171 172 - `openstack/compute/v2/extensions/attachinterfaces` 173 174 Moved to `openstack/compute/v2/attachinterfaces`. 175 176 - `openstack/compute/v2/extensions/diagnostics` 177 178 Moved to `openstack/compute/v2/diagnostics`. 179 180 - `openstack/compute/v2/extensions/hypervisors` 181 182 Moved to `openstack/compute/v2/hypervisors`. 183 184 - `openstack/compute/v2/extensions/instanceactions` 185 186 Moved to `openstack/compute/v2/instanceactions`. 187 188 - `openstack/compute/v2/extensions/keypairs` 189 190 Moved to `openstack/compute/v2/keypairs`. 191 192 - `openstack/compute/v2/extensions/limits` 193 194 Moved to `openstack/compute/v2/limits`. 195 196 - `openstack/compute/v2/extensions/quotasets` 197 198 Moved to `openstack/compute/v2/quotasets`. 199 200 - `openstack/compute/v2/extensions/remoteconsoles` 201 202 Moved to `openstack/compute/v2/remoteconsoles`. 203 204 - `openstack/compute/v2/extensions/secgroups` 205 206 Moved to `openstack/compute/v2/secgroups`. 207 208 - `openstack/compute/v2/extensions/servergroups` 209 210 Moved to `openstack/compute/v2/servergroups`. 211 212 - `openstack/compute/v2/extensions/services` 213 214 Moved to `openstack/compute/v2/services`. 215 216 - `openstack/compute/v2/extensions/tags` 217 218 Moved to `openstack/compute/v2/tags`. 219 220 - `openstack/compute/v2/extensions/usage` 221 222 Moved to `openstack/compute/v2/usage`. 223 224 - `openstack/compute/v2/extensions/volumeattach` 225 226 Moved to `openstack/compute/v2/volumeattach`. 227 228 - `openstack/identity/v2/extensions/admin/roles` 229 230 Moved to `openstack/identity/v2/roles`. 231 232 - `openstack/identity/v3/extensions/ec2credentials` 233 234 Moved to `openstack/identity/v3/ec2credentials`. 235 236 - `openstack/identity/v3/extensions/ec2tokens` 237 238 Moved to `openstack/identity/v3/ec2tokens`. 239 240 - `openstack/identity/v3/extensions/federation` 241 242 Moved to `openstack/identity/v3/federation` 243 244 - `openstack/identity/v3/extensions/oauth1`. 245 246 Moved to `openstack/identity/v3/oauth1` 247 248 - `openstack/identity/v3/extensions/projectendpoints` 249 250 Moved to `openstack/identity/v3/projectendpoints`. 251 252 For extensions that modified existing APIs, these modifications have been 253 folded into the modified APIs. These are: 254 255 - `openstack/blockstorage/extensions/schedulerhints` 256 257 `SchedulerHints` has been renamed to `SchedulerHintOpts` and moved to 258 `openstack/blockstorage/v2/volumes` and `openstack/blockstorage/v3/volumes`. 259 This is now a required argument of `volumes.Create` for both modules. 260 261 - `openstack/blockstorage/extensions/volumeactions` 262 263 All functions and supporting structs and interfaces have been moved to 264 `openstack/blockstorage/v2/volumes` and `openstack/blockstorage/v3/volumes`. 265 266 - `openstack/blockstorage/extensions/volumehost` 267 268 The `VolumeHostExt` struct has been removed and a `Host` field added to the 269 `Volume` struct in `openstack/blockstorage/v2/volumes` and 270 `openstack/blockstorage/v3/volumes`. 271 272 - `openstack/blockstorage/extensions/volumetenants` 273 274 The `VolumeTenantExt` struct has been removed and a `TenantID` field added to 275 the `Volume` struct in `openstack/blockstorage/v2/volumes` and 276 `openstack/blockstorage/v3/volumes`. 277 278 - `openstack/compute/v2/extensions/bootfromvolume` 279 280 The `CreateOptsExt` struct has been removed and a `BlockDevice` field added 281 to the `CreateOpts` struct in `openstack/compute/v2/servers`. 282 283 - `openstack/compute/v2/extensions/diskconfig` 284 285 The `CreateOptsExt` struct has been removed and a `DiskConfig` field added to 286 the `CreateOpts` struct in `openstack/compute/v2/servers`. 287 288 - `openstack/compute/v2/extensions/evacuate` 289 290 All functions and supporting structs and interfaces have been moved to 291 `openstack/compute/v2/servers`. 292 293 - `openstack/compute/v2/extensions/extendedserverattributes` 294 295 The `ServerAttributesExt` struct has been removed and all fields added to the 296 `Server` struct in `openstack/compute/v2/servers`. 297 298 - `openstack/compute/v2/extensions/extendedstatus` 299 300 The `ServerExtendedStatusExt` struct has been removed and all fields added to 301 the `Server` struct in `openstack/compute/v2/servers`. 302 303 - `openstack/compute/v2/extensions/injectnetworkinfo` 304 305 All functions and supporting structs and interfaces have been moved to 306 `openstack/compute/v2/servers`. 307 308 - `openstack/compute/v2/extensions/lockunlock` 309 310 All functions and supporting structs and interfaces have been moved to 311 `openstack/compute/v2/servers`. 312 313 - `openstack/compute/v2/extensions/migrate` 314 315 All functions and supporting structs and interfaces have been moved to 316 `openstack/compute/v2/servers`. 317 318 - `openstack/compute/v2/extensions/pauseunpause` 319 320 All functions and supporting structs and interfaces have been moved to 321 `openstack/compute/v2/servers`. 322 323 - `openstack/compute/v2/extensions/rescueunrescue` 324 325 All functions and supporting structs and interfaces have been moved to 326 `openstack/compute/v2/servers`. 327 328 - `openstack/compute/v2/extensions/resetnetwork` 329 330 All functions and supporting structs and interfaces have been moved to 331 `openstack/compute/v2/servers`. 332 333 - `openstack/compute/v2/extensions/resetstate` 334 335 All functions and supporting structs and interfaces have been moved to 336 `openstack/compute/v2/servers`. 337 338 - `openstack/compute/v2/extensions/schedulerhints` 339 340 `SchedulerHints` has been moved to `openstack/compute/v2/servers` and 341 renamed to `SchedulerHintOpts`. This is now a required argument of 342 `servers.Create`. 343 344 - `openstack/compute/v2/extensions/serverusage` 345 346 The `serverusage` struct has been removed and all fields added to the 347 `Server` struct in `openstack/compute/v2/servers`. 348 349 - `openstack/compute/v2/extensions/shelveunshelve` 350 351 All functions and supporting structs and interfaces have been moved to 352 `openstack/compute/v2/servers`. 353 354 - `openstack/compute/v2/extensions/startstop` 355 356 All functions and supporting structs and interfaces have been moved to 357 `openstack/compute/v2/servers`. 358 359 - `openstack/compute/v2/extensions/suspendresume` 360 361 All functions and supporting structs and interfaces have been moved to 362 `openstack/compute/v2/servers`. 363 364 For extensions that added new APIs *and* modified existing APIs, the new APIs 365 are moved into the main module of the corresponding service while the 366 modifications are folded into the modified APIs. These are: 367 368 - `openstack/compute/v2/extensions/availabilityzones` 369 370 The `ServerAvailabilityZoneExt` struct has been removed and a 371 `AvailabilityZone` field added to the `Server` struct in 372 `openstack/compute/v2/servers`. Everything else is moved moved to 373 `openstack/compute/v2/availabilityzones`. 374 375 - `openstack/identity/v3/extensions/trusts` 376 377 The `AuthOptsExt` struct has been removed and a `TrustID` field added to the 378 `Scope` struct in `openstack/identity/v3/tokens`. Everything else is moved 379 moved to `openstack/identity/v3/trusts`. 380 381 Finally, for extensions that are deprecated and have been removed in a 382 microversion, the APIs were removed entirely. These are: 383 384 - `openstack/compute/v2/extensions/defsecrules` 385 386 This was a proxy for the Networking service, Neutron. Use 387 `openstack/networking/v2/extensions/security/groups` instead. 388 389 - `openstack/compute/v2/extensions/floatingips` 390 391 This was a proxy for the Networking service, Neutron. Use 392 `openstack/networking/v2/extensions/layer3/floatingips` instead. 393 394 - `openstack/compute/v2/extensions/images` 395 396 This was a proxy for the Image service, Glance. Use 397 `openstack/image/v2/images` instead. 398 399 - `openstack/compute/v2/extensions/networks` 400 401 This was a proxy for the Networking service, Neutron. Use 402 `openstack/networking/v2/networks` instead. 403 404 - `openstack/compute/v2/extensions/tenantnetworks` 405 406 This was a proxy for the Networking service, Neutron. Use 407 `openstack/networking/v2/networks` instead. 408 409 ### Type changes 410 411 `loadbalancer/v2/pools/CreateOpts.Members` is now a slice of `CreateMemberOpts` 412 rather than a slice of `BatchUpdateMemberOpts`. 413 414 `blockstorage/v3/volumes/CreateOpts.Multiattach` is removed. Use a volume type 415 with `multiattach` capability instead. 416 417 The following structs are no longer comparable due to the addition of a non-comparable field: 418 419 - `compute/v2/flavors/Flavor` 420 - `loadbalancer/v2/l7policies/CreateRuleOpts` 421 - `loadbalancer/v2/l7policies/UpdateOpts` 422 - `loadbalancer/v2/l7policies/UpdateRuleOpts` 423 - `loadbalancer/v2/listeners/ListOpts` 424 - `loadbalancer/v2/monitors/ListOpts` 425 - `loadbalancer/v2/monitors/CreateOpts` 426 - `loadbalancer/v2/monitors/UpdateOpts` 427 - `loadbalancer/v2/pools/ListOpts` 428 429 This means that you were previously able to use `==` to compare these objects, 430 this is no longer the case with Gophercloud v2. 431 432 ### Image 433 434 The `imageservice` service is renamed to simply `image` to conform with the other services. 435 436 If you previously imported from 437 `github.com/vnpaycloud-console/gophercloud/v2/openstack/imageservice/`, you now need 438 to import from `github.com/vnpaycloud-console/gophercloud/v2/openstack/image/`. 439 440 Additionally, `NewImageServiceV2()` is renamed `NewImageV2()`. 441 442 ### Baremetal inventory 443 444 The Baremetal inventory types moved from 445 `baremetalintrospection/v1/introspection` to `baremetal/inventory`. This 446 includes `BootInfoType`, `CPUType`, `LLDPTLVType`, `InterfaceType`, 447 `InventoryType`, `MemoryType`, `RootDiskType`, `SystemFirmwareType`, 448 `SystemVendorType`, `ExtraHardwareDataType`, `ExtraHardwareData`, 449 `ExtraHardwareDataSection`, `NUMATopology`, `NUMACPU`, `NUMANIC`, and 450 `NUMARAM`. 451 452 Additionally, a few of these types were renamed in the process: 453 454 - `ExtraHardwareDataType` became `ExtraDataType` 455 - `ExtraHardwareData` became `ExtraDataItem` 456 - `ExtraHardwareDataSection` became `ExtraHardwareDataSection` 457 458 ### Object storage 459 460 Gophercloud now escapes container and object names in all `objects` and 461 `containers` functions. If you were previously escaping names (with, for 462 example, `url.PathEscape` or `url.QueryEscape`), then you should REMOVE that 463 and pass the intended names to Gophercloud directly. 464 465 The `objectstorage/v1/containers.ListOpts#Full` and 466 `objectstorage/v1/objects.ListOpts#Full` properties are removed from the 467 Gophercloud API. Plaintext listing is unfixably wrong and won't handle special 468 characters reliably (i.e. `\n`). Object listing and container listing now 469 always behave like “Full” did. 470 471 Empty container names, container names containing a slash (`/`), and empty 472 object names are now rejected in Gophercloud before any call to Swift. 473 474 The `ErrInvalidContainerName` error has been moved from 475 `objectstorage/v1/containers` to `objectstorage/v1`. In addition, two new name 476 validation errors have been added: `objectstorage.v1.ErrEmptyContainerName` and 477 `objectstorage.v1.ErrEmptyObjectName`. 478 479 The `objectstorage/v1/objects.Copy#Destination` field must be in the form 480 `/container/object`. The function will reject a destination path if it doesn't 481 start with a slash (`/`). 482 483 ### Removed services and extensions 484 485 Support for services that are no longer supported upstream has been removed. 486 Users that still rely on theses old services should continue using Gophercloud v1. 487 488 - Cinder (Blockstorage) v1 (`openstack/blockstorage/v1`) 489 - Neutron (Networking) LBaaS and LBaaS v2 extensions 490 (`openstack/networking/v2/extensions/lbaas`, 491 `openstack/networking/v2/extensions/lbaas_v2`) 492 - Neutron (Networking) FWaaS extension 493 (`openstack/networking/v2/extensions/fwaas`) 494 - Poppy (CDNaaS) service (`openstack/cdn`) 495 - Senlin (Clustering) service (`openstack/clustering`) 496 497 ### Script-assisted migration 498 499 #### Expected outcome 500 501 After running the script, your code may not compile. The idea is that at this point, you're only left with a few changes that can't reasonably be automated. 502 503 #### What it does 504 505 * Add `/v2` to all Gophercloud imports, except to the packages that have been removed without replacement 506 * Adjust the import path of moved packages 507 * Adjust the package identifier in the code where possible 508 * Add `context.TODO()` where required 509 510 #### Limitations 511 512 * it doesn't fix the use of removed extensions. For example, if you used `openstack/blockstorage/extensions/availabilityzones`, you will have to manually put that back into e.g. `servers.CreateOpts` 513 * it will just put `context.TODO()` where a context is required to satisfy the function signature. It's up to you to actually replace that with a variable and provide proper cancellation 514 * it will add `context.TODO()` to `blockstorage/v1` calls, even though that package only exists in Gophercloud v1 515 516 ```bash 517 # Adjust the blockstorage version appropriately 518 blockstorageversion=v3 519 520 openstack='github.com/gophercloud/gophercloud/openstack' 521 openstack_utils='github.com/gophercloud/utils/openstack' 522 find . -type f -name '*.go' -not -path "*/vendor/*" -exec sed -i ' 523 /^import ($/,/^)$/ { 524 525 # 1: These packages have been removed and their functionality moved into the main module for the corresponding service. 526 /\(\/openstack\/blockstorage\/v1\|\/openstack\/networking\/v2\/extensions\/lbaas\|\/openstack\/networking\/v2\/extensions\/lbaas_v2\|\/openstack\/networking\/v2\/extensions\/fwaas\|\/openstack\/cdn\|\/openstack\/clustering\)/! { 527 /\/openstack\/blockstorage\/extensions\/volumehost/d 528 /\/openstack\/blockstorage\/extensions\/volumetenants/d 529 /\/openstack\/compute\/v2\/extensions\/bootfromvolume/d 530 /\/openstack\/compute\/v2\/extensions\/diskconfig/d 531 /\/openstack\/compute\/v2\/extensions\/extendedserverattributes/d 532 /\/openstack\/compute\/v2\/extensions\/extendedstatus/d 533 /\/openstack\/compute\/v2\/extensions\/schedulerhints/d 534 /\/openstack\/compute\/v2\/extensions\/serverusage/d 535 /\/openstack\/compute\/v2\/extensions\/availabilityzones/d 536 /\/openstack\/identity\/v3\/extensions\/trusts/d 537 } 538 539 '" 540 # 2: Functions and supporting structs and interfaces of these packages have been moved to an existing package 541 s|${openstack}/blockstorage/extensions/schedulerhints|${openstack}/blockstorage/${blockstorageversion}/volumes|g 542 s|${openstack}/blockstorage/extensions/volumeactions|${openstack}/blockstorage/${blockstorageversion}/volumes|g 543 s|${openstack}/compute/v2/extensions/evacuate|${openstack}/compute/v2/servers|g 544 s|${openstack}/compute/v2/extensions/injectnetworkinfo|${openstack}/compute/v2/servers|g 545 s|${openstack}/compute/v2/extensions/lockunlock|${openstack}/compute/v2/servers|g 546 s|${openstack}/compute/v2/extensions/migrate|${openstack}/compute/v2/servers|g 547 s|${openstack}/compute/v2/extensions/pauseunpause|${openstack}/compute/v2/servers|g 548 s|${openstack}/compute/v2/extensions/rescueunrescue|${openstack}/compute/v2/servers|g 549 s|${openstack}/compute/v2/extensions/resetnetwork|${openstack}/compute/v2/servers|g 550 s|${openstack}/compute/v2/extensions/resetstate|${openstack}/compute/v2/servers|g 551 s|${openstack}/compute/v2/extensions/shelveunshelve|${openstack}/compute/v2/servers|g 552 s|${openstack}/compute/v2/extensions/startstop|${openstack}/compute/v2/servers|g 553 s|${openstack}/compute/v2/extensions/suspendresume|${openstack}/compute/v2/servers|g 554 555 # 3: These packages have been renamed 556 s|${openstack}/imageservice|${openstack}/image|g 557 s|${openstack_utils}/imageservice|${openstack_utils}/image|g 558 s|${openstack}/blockstorage/extensions/availabilityzones|${openstack}/blockstorage/${blockstorageversion}/availabilityzones|g 559 s|${openstack}/blockstorage/extensions/backups|${openstack}/blockstorage/${blockstorageversion}/backups|g 560 s|${openstack}/blockstorage/extensions/limits|${openstack}/blockstorage/${blockstorageversion}/limits|g 561 s|${openstack}/blockstorage/extensions/quotasets|${openstack}/blockstorage/${blockstorageversion}/quotasets|g 562 s|${openstack}/blockstorage/extensions/schedulerstats|${openstack}/blockstorage/${blockstorageversion}/schedulerstats|g 563 s|${openstack}/blockstorage/extensions/services|${openstack}/blockstorage/${blockstorageversion}/services|g 564 s|${openstack}/blockstorage/extensions/volumetransfers|${openstack}/blockstorage/${blockstorageversion}/transfers|g 565 s|${openstack}/compute/v2/extensions/aggregates|${openstack}/compute/v2/aggregates|g 566 s|${openstack}/compute/v2/extensions/attachinterfaces|${openstack}/compute/v2/attachinterfaces|g 567 s|${openstack}/compute/v2/extensions/diagnostics|${openstack}/compute/v2/diagnostics|g 568 s|${openstack}/compute/v2/extensions/hypervisors|${openstack}/compute/v2/hypervisors|g 569 s|${openstack}/compute/v2/extensions/instanceactions|${openstack}/compute/v2/instanceactions|g 570 s|${openstack}/compute/v2/extensions/keypairs|${openstack}/compute/v2/keypairs|g 571 s|${openstack}/compute/v2/extensions/limits|${openstack}/compute/v2/limits|g 572 s|${openstack}/compute/v2/extensions/quotasets|${openstack}/compute/v2/quotasets|g 573 s|${openstack}/compute/v2/extensions/remoteconsoles|${openstack}/compute/v2/remoteconsoles|g 574 s|${openstack}/compute/v2/extensions/secgroups|${openstack}/compute/v2/secgroups|g 575 s|${openstack}/compute/v2/extensions/servergroups|${openstack}/compute/v2/servergroups|g 576 s|${openstack}/compute/v2/extensions/services|${openstack}/compute/v2/services|g 577 s|${openstack}/compute/v2/extensions/tags|${openstack}/compute/v2/tags|g 578 s|${openstack}/compute/v2/extensions/usage|${openstack}/compute/v2/usage|g 579 s|${openstack}/compute/v2/extensions/volumeattach|${openstack}/compute/v2/volumeattach|g 580 s|${openstack}/identity/v2/extensions/admin/roles|${openstack}/identity/v2/roles|g 581 s|${openstack}/identity/v3/extensions/ec2credentials|${openstack}/identity/v3/ec2credentials|g 582 s|${openstack}/identity/v3/extensions/ec2tokens|${openstack}/identity/v3/ec2tokens|g 583 s|${openstack}/identity/v3/extensions/federation|${openstack}/identity/v3/federation|g 584 s|${openstack}/identity/v3/extensions/oauth1|${openstack}/identity/v3/oauth1|g 585 s|${openstack}/identity/v3/extensions/projectendpoints|${openstack}/identity/v3/projectendpoints|g 586 587 # 4: These removed packages existed as proxies of others 588 s|${openstack}/compute/v2/extensions/defsecrules|${openstack}/networking/v2/extensions/security/groups|g 589 s|${openstack}/compute/v2/extensions/floatingips|${openstack}/networking/v2/extensions/layer3/floatingips|g 590 s|${openstack}/compute/v2/extensions/images|${openstack}/image/v2/images|g 591 s|${openstack}/compute/v2/extensions/networks|${openstack}/networking/v2/networks|g 592 s|${openstack}/compute/v2/extensions/tenantnetworks|${openstack}/networking/v2/networks|g 593 "' 594 595 # 5: Update to v2, except for packages that were removed without replacement 596 s|github.com/gophercloud/utils|github.com/gophercloud/utils/v2|g 597 /\(\/openstack\/blockstorage\/v1\|\/openstack\/networking\/v2\/extensions\/lbaas\|\/openstack\/networking\/v2\/extensions\/lbaas_v2\|\/openstack\/networking\/v2\/extensions\/fwaas\|\/openstack\/cdn\|\/openstack\/clustering\)/! s|github.com/gophercloud/gophercloud|github.com/vnpaycloud-console/gophercloud/v2|g 598 } 599 600 /^)$/,$ { 601 602 # 6: Rename identifiers of items of step 2 above 603 s#\(schedulerhints\|volumeactions\)\.\([A-Z][A-Z_a-z_0-9]*\)#volumes.\2#g 604 s#\(evacuate\|injectnetworkinfo\|lockunlock\|migrate\|pauseunpause\|rescueunrescue\|resetnetwork\|resetstate\|shelveunshelve\|startstop\|suspendresume\)\.\([A-Z][A-Z_a-z_0-9]*\)#servers.\2#g 605 606 # 7: Add context.TODO() 607 s#\(accept\.Create\|accept\.Get\|accounts\.Get\|accounts\.Update\|acls\.DeleteContainerACL\|acls\.DeleteSecretACL\|acls\.GetContainerACL\|acls\.GetSecretACL\|acls\.SetContainerACL\|acls\.SetSecretACL\|acls\.UpdateContainerACL\|acls\.UpdateSecretACL\|addressscopes\.Create\|addressscopes\.Delete\|addressscopes\.Get\|addressscopes\.Update\|agents\.Delete\|agents\.Get\|agents\.ListDHCPNetworks\|agents\.ListL3Routers\|agents\.RemoveBGPSpeaker\|agents\.RemoveDHCPNetwork\|agents\.RemoveL3Router\|agents\.ScheduleBGPSpeaker\|agents\.ScheduleDHCPNetwork\|agents\.ScheduleL3Router\|agents\.Update\|aggregates\.AddHost\|aggregates\.Create\|aggregates\.Delete\|aggregates\.Get\|aggregates\.RemoveHost\|aggregates\.SetMetadata\|aggregates\.Update\|allocations\.Create\|allocations\.Delete\|allocations\.Get\|amphorae\.Failover\|amphorae\.Get\|apiversions\.Get\|apiversions\.List\|applicationcredentials\.Create\|applicationcredentials\.Delete\|applicationcredentials\.DeleteAccessRule\|applicationcredentials\.Get\|applicationcredentials\.GetAccessRule\|attachinterfaces\.Create\|attachinterfaces\.Delete\|attachinterfaces\.Get\|attachments\.Complete\|attachments\.Create\|attachments\.Delete\|attachments\.Get\|attachments\.Update\|attachments\.WaitForStatus\|backups\.Create\|backups\.Delete\|backups\.Export\|backups\.ForceDelete\|backups\.Get\|backups\.Import\|backups\.ResetStatus\|backups\.RestoreFromBackup\|backups\.Update\|bgpvpns\.Create\|bgpvpns\.CreateNetworkAssociation\|bgpvpns\.CreatePortAssociation\|bgpvpns\.CreateRouterAssociation\|bgpvpns\.Delete\|bgpvpns\.DeleteNetworkAssociation\|bgpvpns\.DeletePortAssociation\|bgpvpns\.DeleteRouterAssociation\|bgpvpns\.Get\|bgpvpns\.GetNetworkAssociation\|bgpvpns\.GetPortAssociation\|bgpvpns\.GetRouterAssociation\|bgpvpns\.Update\|bgpvpns\.UpdatePortAssociation\|bgpvpns\.UpdateRouterAssociation\|buildinfo\.Get\|capsules\.Create\|capsules\.Delete\|capsules\.Get\|certificates\.Create\|certificates\.Get\|certificates\.Update\|claims\.Create\|claims\.Delete\|claims\.Get\|claims\.Update\|clusters\.Create\|clusters\.Delete\|clusters\.Get\|clusters\.Resize\|clusters\.Update\|clusters\.Upgrade\|clustertemplates\.Create\|clustertemplates\.Delete\|clustertemplates\.Get\|clustertemplates\.Update\|conductors\.Get\|config\.NewProviderClient\|configurations\.Create\|configurations\.Delete\|configurations\.Get\|configurations\.GetDatastoreParam\|configurations\.GetGlobalParam\|configurations\.Replace\|configurations\.Update\|containers\.BulkDelete\|containers\.Create\|containers\.CreateConsumer\|containers\.CreateSecretRef\|containers\.Delete\|containers\.DeleteConsumer\|containers\.DeleteSecretRef\|containers\.Get\|containers\.Update\|credentials\.Create\|credentials\.Delete\|credentials\.Get\|credentials\.Update\|crontriggers\.Create\|crontriggers\.Delete\|crontriggers\.Get\|databases\.Create\|databases\.Delete\|datastores\.Get\|datastores\.GetVersion\|diagnostics\.Get\|domains\.Create\|domains\.Delete\|domains\.Get\|domains\.Update\|drivers\.GetDriverDetails\|drivers\.GetDriverDiskProperties\|drivers\.GetDriverProperties\|ec2credentials\.Create\|ec2credentials\.Delete\|ec2credentials\.Get\|ec2tokens\.Create\|ec2tokens\.ValidateS3Token\|endpointgroups\.Create\|endpointgroups\.Delete\|endpointgroups\.Get\|endpointgroups\.Update\|endpoints\.Create\|endpoints\.Delete\|endpoints\.Update\|executions\.Create\|executions\.Delete\|executions\.Get\|extensions\.Get\|extraroutes\.Add\|extraroutes\.Remove\|federation\.CreateMapping\|federation\.DeleteMapping\|federation\.GetMapping\|federation\.UpdateMapping\|flavorprofiles\.Create\|flavorprofiles\.Delete\|flavorprofiles\.Get\|flavorprofiles\.Update\|flavors\.AddAccess\|flavors\.Create\|flavors\.CreateExtraSpecs\|flavors\.Delete\|flavors\.DeleteExtraSpec\|flavors\.Get\|flavors\.GetExtraSpec\|flavors\.ListExtraSpecs\|flavors\.RemoveAccess\|flavors\.Update\|flavors\.UpdateExtraSpec\|floatingips\.Create\|floatingips\.Delete\|floatingips\.Get\|floatingips\.Update\|gophercloud\.WaitFor\|groups\.Create\|groups\.Delete\|groups\.Get\|groups\.RemoveEgressPolicy\|groups\.RemoveIngressPolicy\|groups\.Update\|hypervisors\.Get\|hypervisors\.GetStatistics\|hypervisors\.GetUptime\|ikepolicies\.Create\|ikepolicies\.Delete\|ikepolicies\.Get\|ikepolicies\.Update\|imagedata\.Download\|imagedata\.Stage\|imagedata\.Upload\|imageimport\.Create\|imageimport\.Get\|images\.Create\|images\.Delete\|images\.Get\|images\.Update\|instanceactions\.Get\|instances\.AttachConfigurationGroup\|instances\.Create\|instances\.Delete\|instances\.DetachConfigurationGroup\|instances\.EnableRootUser\|instances\.Get\|instances\.IsRootEnabled\|instances\.Resize\|instances\.ResizeVolume\|instances\.Restart\|introspection\.AbortIntrospection\|introspection\.GetIntrospectionData\|introspection\.GetIntrospectionStatus\|introspection\.ReApplyIntrospection\|introspection\.StartIntrospection\|ipsecpolicies\.Create\|ipsecpolicies\.Delete\|ipsecpolicies\.Get\|ipsecpolicies\.Update\|keypairs\.Create\|keypairs\.Delete\|keypairs\.Get\|l7policies\.Create\|l7policies\.CreateRule\|l7policies\.Delete\|l7policies\.DeleteRule\|l7policies\.Get\|l7policies\.GetRule\|l7policies\.Update\|l7policies\.UpdateRule\|limits\.BatchCreate\|limits\.Delete\|limits\.Get\|limits\.GetEnforcementModel\|limits\.Update\|listeners\.Create\|listeners\.Delete\|listeners\.Get\|listeners\.GetStats\|listeners\.Update\|loadbalancers\.Create\|loadbalancers\.Delete\|loadbalancers\.Failover\|loadbalancers\.Get\|loadbalancers\.GetStats\|loadbalancers\.GetStatuses\|loadbalancers\.Update\|members\.Create\|members\.Delete\|members\.Get\|members\.Update\|messages\.Create\|messages\.Delete\|messages\.DeleteMessages\|messages\.Get\|messages\.GetMessages\|messages\.PopMessages\|monitors\.Create\|monitors\.Delete\|monitors\.Get\|monitors\.Update\|networkipavailabilities\.Get\|networks\.Create\|networks\.Delete\|networks\.Get\|networks\.Update\|nodegroups\.Create\|nodegroups\.Delete\|nodegroups\.Get\|nodegroups\.Update\|nodes\.AttachVirtualMedia\|nodes\.ChangePowerState\|nodes\.ChangeProvisionState\|nodes\.Create\|nodes\.CreateSubscription\|nodes\.Delete\|nodes\.DeleteSubscription\|nodes\.DetachVirtualMedia\|nodes\.Get\|nodes\.GetAllSubscriptions\|nodes\.GetBIOSSetting\|nodes\.GetBootDevice\|nodes\.GetInventory\|nodes\.GetSubscription\|nodes\.GetSupportedBootDevices\|nodes\.GetVendorPassthruMethods\|nodes\.InjectNMI\|nodes\.ListBIOSSettings\|nodes\.ListFirmware\|nodes\.SetBootDevice\|nodes\.SetMaintenance\|nodes\.SetRAIDConfig\|nodes\.UnsetMaintenance\|nodes\.Update\|nodes\.Validate\|nodes\.WaitForProvisionState\|oauth1\.AuthorizeToken\|oauth1\.Create\|oauth1\.CreateAccessToken\|oauth1\.CreateConsumer\|oauth1\.DeleteConsumer\|oauth1\.GetAccessToken\|oauth1\.GetAccessTokenRole\|oauth1\.GetConsumer\|oauth1\.RequestToken\|oauth1\.RevokeAccessToken\|oauth1\.UpdateConsumer\|objects\.BulkDelete\|objects\.Copy\|objects\.Create\|objects\.CreateTempURL\|objects\.Delete\|objects\.Download\|objects\.Get\|objects\.Update\|openstack\.Authenticate\|openstack\.AuthenticatedClient\|openstack\.AuthenticateV2\|openstack\.AuthenticateV3\|orders\.Create\|orders\.Delete\|orders\.Get\|osinherit\.Assign\|osinherit\.Unassign\|osinherit\.Validate\|pagination\.Request\|peers\.Create\|peers\.Delete\|peers\.Get\|peers\.Update\|policies\.Create\|policies\.Delete\|policies\.Get\|policies\.InsertRule\|policies\.RemoveRule\|policies\.Update\|pools\.BatchUpdateMembers\|pools\.Create\|pools\.CreateMember\|pools\.Delete\|pools\.DeleteMember\|pools\.Get\|pools\.GetMember\|pools\.Update\|pools\.UpdateMember\|portforwarding\.Create\|portforwarding\.Delete\|portforwarding\.Get\|portforwarding\.Update\|ports\.Create\|ports\.Delete\|ports\.Get\|ports\.Update\|projectendpoints\.Create\|projectendpoints\.Delete\|projects\.Create\|projects\.Delete\|projects\.DeleteTags\|projects\.Get\|projects\.ListTags\|projects\.ModifyTags\|projects\.Update\|qos\.Associate\|qos\.Create\|qos\.Delete\|qos\.DeleteKeys\|qos\.Disassociate\|qos\.DisassociateAll\|qos\.Get\|qos\.Update\|queues\.Create\|queues\.Delete\|queues\.Get\|queues\.GetStats\|queues\.Purge\|queues\.Share\|queues\.Update\|quotas\.Create\|quotasets\.Delete\|quotasets\.Get\|quotasets\.GetDefaults\|quotasets\.GetDetail\|quotasets\.GetUsage\|quotasets\.Update\|quotas\.Get\|quotas\.GetDetail\|quotas\.Update\|rbacpolicies\.Create\|rbacpolicies\.Delete\|rbacpolicies\.Get\|rbacpolicies\.Update\|recordsets\.Create\|recordsets\.Delete\|recordsets\.Get\|recordsets\.Update\|regions\.Create\|regions\.Delete\|regions\.Get\|regions\.Update\|registeredlimits\.BatchCreate\|registeredlimits\.Delete\|registeredlimits\.Get\|registeredlimits\.Update\|remoteconsoles\.Create\|replicas\.Create\|replicas\.Delete\|replicas\.ForceDelete\|replicas\.Get\|replicas\.GetExportLocation\|replicas\.ListExportLocations\|replicas\.Promote\|replicas\.ResetState\|replicas\.ResetStatus\|replicas\.Resync\|request\.Create\|request\.Delete\|request\.Get\|request\.Update\|resourceproviders\.Create\|resourceproviders\.Delete\|resourceproviders\.Get\|resourceproviders\.GetAllocations\|resourceproviders\.GetInventories\|resourceproviders\.GetTraits\|resourceproviders\.GetUsages\|resourceproviders\.Update\|resourcetypes\.GenerateTemplate\|resourcetypes\.GetSchema\|resourcetypes\.List\|roles\.AddUser\|roles\.Assign\|roles\.Create\|roles\.CreateRoleInferenceRule\|roles\.Delete\|roles\.DeleteRoleInferenceRule\|roles\.DeleteUser\|roles\.Get\|roles\.GetRoleInferenceRule\|roles\.ListRoleInferenceRules\|roles\.Unassign\|roles\.Update\|routers\.AddInterface\|routers\.Create\|routers\.Delete\|routers\.Get\|routers\.RemoveInterface\|routers\.Update\|rules\.Create\|rules\.CreateBandwidthLimitRule\|rules\.CreateDSCPMarkingRule\|rules\.CreateMinimumBandwidthRule\|rules\.Delete\|rules\.DeleteBandwidthLimitRule\|rules\.DeleteDSCPMarkingRule\|rules\.DeleteMinimumBandwidthRule\|rules\.Get\|rules\.GetBandwidthLimitRule\|rules\.GetDSCPMarkingRule\|rules\.GetMinimumBandwidthRule\|rules\.Update\|rules\.UpdateBandwidthLimitRule\|rules\.UpdateDSCPMarkingRule\|rules\.UpdateMinimumBandwidthRule\|ruletypes\.GetRuleType\|secgroups\.AddServer\|secgroups\.Create\|secgroups\.CreateRule\|secgroups\.Delete\|secgroups\.DeleteRule\|secgroups\.Get\|secgroups\.RemoveServer\|secgroups\.Update\|secrets\.Create\|secrets\.CreateMetadata\|secrets\.CreateMetadatum\|secrets\.Delete\|secrets\.DeleteMetadatum\|secrets\.Get\|secrets\.GetMetadata\|secrets\.GetMetadatum\|secrets\.GetPayload\|secrets\.Update\|secrets\.UpdateMetadatum\|securityservices\.Create\|securityservices\.Delete\|securityservices\.Get\|securityservices\.Update\|servergroups\.Create\|servergroups\.Delete\|servergroups\.Get\|servers\.ChangeAdminPassword\|servers\.ConfirmResize\|servers\.Create\|servers\.CreateImage\|servers\.CreateMetadatum\|servers\.Delete\|servers\.DeleteMetadatum\|servers\.Evacuate\|servers\.ForceDelete\|servers\.Get\|servers\.GetPassword\|servers\.InjectNetworkInfo\|servers\.LiveMigrate\|servers\.Lock\|servers\.Metadata\|servers\.Metadatum\|servers\.Migrate\|servers\.Pause\|servers\.Reboot\|servers\.Rebuild\|servers\.Rescue\|servers\.ResetMetadata\|servers\.ResetNetwork\|servers\.ResetState\|servers\.Resize\|servers\.Resume\|servers\.RevertResize\|servers\.Shelve\|servers\.ShelveOffload\|servers\.ShowConsoleOutput\|servers\.Start\|servers\.Stop\|servers\.Suspend\|servers\.Unlock\|servers\.Unpause\|servers\.Unrescue\|servers\.Unshelve\|servers\.Update\|servers\.UpdateMetadata\|servers\.WaitForStatus\|services\.Create\|services\.Delete\|services\.Get\|services\.Update\|shareaccessrules\.Get\|shareaccessrules\.List\|sharenetworks\.AddSecurityService\|sharenetworks\.Create\|sharenetworks\.Delete\|sharenetworks\.Get\|sharenetworks\.RemoveSecurityService\|sharenetworks\.Update\|shares\.Create\|shares\.Delete\|shares\.DeleteMetadatum\|shares\.Extend\|shares\.ForceDelete\|shares\.Get\|shares\.GetExportLocation\|shares\.GetMetadata\|shares\.GetMetadatum\|shares\.GrantAccess\|shares\.ListAccessRights\|shares\.ListExportLocations\|shares\.ResetStatus\|shares\.Revert\|shares\.RevokeAccess\|shares\.SetMetadata\|shares\.Shrink\|shares\.Unmanage\|shares\.Update\|shares\.UpdateMetadata\|sharetransfers\.Accept\|sharetransfers\.Create\|sharetransfers\.Delete\|sharetransfers\.Get\|sharetypes\.AddAccess\|sharetypes\.Create\|sharetypes\.Delete\|sharetypes\.GetDefault\|sharetypes\.GetExtraSpecs\|sharetypes\.RemoveAccess\|sharetypes\.SetExtraSpecs\|sharetypes\.ShowAccess\|sharetypes\.UnsetExtraSpecs\|siteconnections\.Create\|siteconnections\.Delete\|siteconnections\.Get\|siteconnections\.Update\|snapshots\.Create\|snapshots\.Delete\|snapshots\.ForceDelete\|snapshots\.Get\|snapshots\.ResetStatus\|snapshots\.Update\|snapshots\.UpdateMetadata\|snapshots\.UpdateStatus\|snapshots\.WaitForStatus\|speakers\.AddBGPPeer\|speakers\.AddGatewayNetwork\|speakers\.Create\|speakers\.Delete\|speakers\.Get\|speakers\.RemoveBGPPeer\|speakers\.RemoveGatewayNetwork\|speakers\.Update\|stackevents\.Find\|stackevents\.Get\|stackresources\.Find\|stackresources\.Get\|stackresources\.MarkUnhealthy\|stackresources\.Metadata\|stackresources\.Schema\|stackresources\.Template\|stacks\.Abandon\|stacks\.Adopt\|stacks\.Create\|stacks\.Delete\|stacks\.Find\|stacks\.Get\|stacks\.Preview\|stacks\.Update\|stacks\.UpdatePatch\|stacktemplates\.Get\|stacktemplates\.Validate\|subnetpools\.Create\|subnetpools\.Delete\|subnetpools\.Get\|subnetpools\.Update\|subnets\.Create\|subnets\.Delete\|subnets\.Get\|subnets\.Update\|swauth\.Auth\|swauth\.NewObjectStorageV1\|tags\.Add\|tags\.Check\|tags\.Delete\|tags\.DeleteAll\|tags\.List\|tags\.ReplaceAll\|tasks\.Create\|tasks\.Get\|tenants\.Create\|tenants\.Delete\|tenants\.Get\|tenants\.Update\|tokens\.Create\|tokens\.Get\|tokens\.Revoke\|tokens\.Validate\|transfers\.Accept\|transfers\.Create\|transfers\.Delete\|transfers\.Get\|trunks\.AddSubports\|trunks\.Create\|trunks\.Delete\|trunks\.Get\|trunks\.GetSubports\|trunks\.RemoveSubports\|trunks\.Update\|trusts\.CheckRole\|trusts\.Create\|trusts\.Delete\|trusts\.Get\|trusts\.GetRole\|users\.AddToGroup\|users\.ChangePassword\|users\.Create\|users\.Delete\|users\.Get\|users\.IsMemberOfGroup\|users\.RemoveFromGroup\|users\.Update\|utils\.ChooseVersion\|utils\.GetSupportedMicroversions\|utils\.RequireMicroversion\|volumeattach\.Create\|volumeattach\.Delete\|volumeattach\.Get\|volumes\.Attach\|volumes\.BeginDetaching\|volumes\.ChangeType\|volumes\.Create\|volumes\.Delete\|volumes\.Detach\|volumes\.ExtendSize\|volumes\.ForceDelete\|volumes\.Get\|volumes\.InitializeConnection\|volumes\.ReImage\|volumes\.Reserve\|volumes\.ResetStatus\|volumes\.SetBootable\|volumes\.SetImageMetadata\|volumes\.TerminateConnection\|volumes\.Unreserve\|volumes\.Update\|volumes\.UploadImage\|volumes\.WaitForStatus\|volumetypes\.AddAccess\|volumetypes\.Create\|volumetypes\.CreateEncryption\|volumetypes\.CreateExtraSpecs\|volumetypes\.Delete\|volumetypes\.DeleteEncryption\|volumetypes\.DeleteExtraSpec\|volumetypes\.Get\|volumetypes\.GetEncryption\|volumetypes\.GetEncryptionSpec\|volumetypes\.GetExtraSpec\|volumetypes\.ListExtraSpecs\|volumetypes\.RemoveAccess\|volumetypes\.Update\|volumetypes\.UpdateEncryption\|volumetypes\.UpdateExtraSpec\|workflows\.Create\|workflows\.Delete\|workflows\.Get\|zones\.Create\|zones\.Delete\|zones\.Get\|zones\.Update\)(#\1(context.TODO(), #g 608 s#\(\.AllPages(\)#\1context.TODO(), #g 609 s#\(\.EachPage(\)\(func(\)#\1context.TODO(), \2ctx context.Context, #g 610 611 # 8: Rename identifiers that were changed in v2 612 s#\(\(volumes\|servers\)\.SchedulerHint\)s#\2.SchedulerHintOpts#g 613 614 # 9: Tentatively replace error handling 615 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault400); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusBadRequest) {#g 616 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault401); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusUnauthorized) {#g 617 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault403); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusForbidden) {#g 618 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault404); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusNotFound) {#g 619 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault405); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusMethodNotAllowed) {#g 620 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault408); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusRequestTimeout) {#g 621 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault409); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusConflict) {#g 622 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault429); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusTooManyRequests) {#g 623 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault500); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusInternalServerError) {#g 624 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault502); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusBadGateway) {#g 625 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault503); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusServiceUnavailable) {#g 626 s#\(\t\+\)if _, ok := err.(gophercloud.ErrDefault504); \(!\?\)ok {#\1if \2gophercloud.ResponseCodeIs(err, http.StatusGatewayTimeout) {#g 627 } 628 ' {} \; 629 630 grep -r -l 'context\.TODO' | xargs -r sed -i ' 631 /^import ($/ a "context" 632 ' 633 634 grep -r -l 'http\.Status' | xargs -r sed -i ' 635 /^import ($/ a "net/http" 636 ' 637 638 goimports -format-only -w . 639 go mod tidy 640 ```