1// Package clients contains functions for creating OpenStack service clients 2// for use in acceptance tests. It also manages the required environment 3// variables to run the tests. 4package clients 5 6import ( 7 "fmt" 8 "net/http" 9 "os" 10 "strings" 11 12 "github.com/gophercloud/gophercloud" 13 "github.com/gophercloud/gophercloud/openstack" 14 baremetalNoAuth "github.com/gophercloud/gophercloud/openstack/baremetal/noauth" 15 blockstorageNoAuth "github.com/gophercloud/gophercloud/openstack/blockstorage/noauth" 16) 17 18// AcceptanceTestChoices contains image and flavor selections for use by the acceptance tests. 19type AcceptanceTestChoices struct { 20 // ImageID contains the ID of a valid image. 21 ImageID string 22 23 // FlavorID contains the ID of a valid flavor. 24 FlavorID string 25 26 // FlavorIDResize contains the ID of a different flavor available on the same OpenStack installation, that is distinct 27 // from FlavorID. 28 FlavorIDResize string 29 30 // FloatingIPPool contains the name of the pool from where to obtain floating IPs. 31 FloatingIPPoolName string 32 33 // MagnumKeypair contains the ID of a valid key pair. 34 MagnumKeypair string 35 36 // MagnumImageID contains the ID of a valid magnum image. 37 MagnumImageID string 38 39 // NetworkName is the name of a network to launch the instance on. 40 NetworkName string 41 42 // NetworkID is the ID of a network to launch the instance on. 43 NetworkID string 44 45 // SubnetID is the ID of a subnet to launch the instance on. 46 SubnetID string 47 48 // ExternalNetworkID is the network ID of the external network. 49 ExternalNetworkID string 50 51 // DBDatastoreType is the datastore type for DB tests. 52 DBDatastoreType string 53 54 // DBDatastoreTypeID is the datastore type version for DB tests. 55 DBDatastoreVersion string 56} 57 58// AcceptanceTestChoicesFromEnv populates a ComputeChoices struct from environment variables. 59// If any required state is missing, an `error` will be returned that enumerates the missing properties. 60func AcceptanceTestChoicesFromEnv() (*AcceptanceTestChoices, error) { 61 imageID := os.Getenv("OS_IMAGE_ID") 62 flavorID := os.Getenv("OS_FLAVOR_ID") 63 flavorIDResize := os.Getenv("OS_FLAVOR_ID_RESIZE") 64 magnumImageID := os.Getenv("OS_MAGNUM_IMAGE_ID") 65 magnumKeypair := os.Getenv("OS_MAGNUM_KEYPAIR") 66 networkName := os.Getenv("OS_NETWORK_NAME") 67 networkID := os.Getenv("OS_NETWORK_ID") 68 subnetID := os.Getenv("OS_SUBNET_ID") 69 floatingIPPoolName := os.Getenv("OS_POOL_NAME") 70 externalNetworkID := os.Getenv("OS_EXTGW_ID") 71 dbDatastoreType := os.Getenv("OS_DB_DATASTORE_TYPE") 72 dbDatastoreVersion := os.Getenv("OS_DB_DATASTORE_VERSION") 73 74 missing := make([]string, 0, 3) 75 if imageID == "" { 76 missing = append(missing, "OS_IMAGE_ID") 77 } 78 if flavorID == "" { 79 missing = append(missing, "OS_FLAVOR_ID") 80 } 81 if flavorIDResize == "" { 82 missing = append(missing, "OS_FLAVOR_ID_RESIZE") 83 } 84 if floatingIPPoolName == "" { 85 missing = append(missing, "OS_POOL_NAME") 86 } 87 if externalNetworkID == "" { 88 missing = append(missing, "OS_EXTGW_ID") 89 } 90 91 /* // Temporarily disabled, see https://github.com/gophercloud/gophercloud/issues/1345 92 if networkID == "" { 93 missing = append(missing, "OS_NETWORK_ID") 94 } 95 if subnetID == "" { 96 missing = append(missing, "OS_SUBNET_ID") 97 } 98 */ 99 100 if networkName == "" { 101 networkName = "private" 102 } 103 notDistinct := "" 104 if flavorID == flavorIDResize { 105 notDistinct = "OS_FLAVOR_ID and OS_FLAVOR_ID_RESIZE must be distinct." 106 } 107 108 if len(missing) > 0 || notDistinct != "" { 109 text := "You're missing some important setup:\n" 110 if len(missing) > 0 { 111 text += " * These environment variables must be provided: " + strings.Join(missing, ", ") + "\n" 112 } 113 if notDistinct != "" { 114 text += " * " + notDistinct + "\n" 115 } 116 117 return nil, fmt.Errorf(text) 118 } 119 120 return &AcceptanceTestChoices{ 121 ImageID: imageID, 122 FlavorID: flavorID, 123 FlavorIDResize: flavorIDResize, 124 FloatingIPPoolName: floatingIPPoolName, 125 MagnumImageID: magnumImageID, 126 MagnumKeypair: magnumKeypair, 127 NetworkName: networkName, 128 NetworkID: networkID, 129 SubnetID: subnetID, 130 ExternalNetworkID: externalNetworkID, 131 DBDatastoreType: dbDatastoreType, 132 DBDatastoreVersion: dbDatastoreVersion, 133 }, nil 134} 135 136// NewBlockStorageV1Client returns a *ServiceClient for making calls 137// to the OpenStack Block Storage v1 API. An error will be returned 138// if authentication or client creation was not possible. 139func NewBlockStorageV1Client() (*gophercloud.ServiceClient, error) { 140 ao, err := openstack.AuthOptionsFromEnv() 141 if err != nil { 142 return nil, err 143 } 144 145 client, err := openstack.AuthenticatedClient(ao) 146 if err != nil { 147 return nil, err 148 } 149 150 client = configureDebug(client) 151 152 return openstack.NewBlockStorageV1(client, gophercloud.EndpointOpts{ 153 Region: os.Getenv("OS_REGION_NAME"), 154 }) 155} 156 157// NewBlockStorageV2Client returns a *ServiceClient for making calls 158// to the OpenStack Block Storage v2 API. An error will be returned 159// if authentication or client creation was not possible. 160func NewBlockStorageV2Client() (*gophercloud.ServiceClient, error) { 161 ao, err := openstack.AuthOptionsFromEnv() 162 if err != nil { 163 return nil, err 164 } 165 166 client, err := openstack.AuthenticatedClient(ao) 167 if err != nil { 168 return nil, err 169 } 170 171 client = configureDebug(client) 172 173 return openstack.NewBlockStorageV2(client, gophercloud.EndpointOpts{ 174 Region: os.Getenv("OS_REGION_NAME"), 175 }) 176} 177 178// NewBlockStorageV3Client returns a *ServiceClient for making calls 179// to the OpenStack Block Storage v3 API. An error will be returned 180// if authentication or client creation was not possible. 181func NewBlockStorageV3Client() (*gophercloud.ServiceClient, error) { 182 ao, err := openstack.AuthOptionsFromEnv() 183 if err != nil { 184 return nil, err 185 } 186 187 client, err := openstack.AuthenticatedClient(ao) 188 if err != nil { 189 return nil, err 190 } 191 192 client = configureDebug(client) 193 194 return openstack.NewBlockStorageV3(client, gophercloud.EndpointOpts{ 195 Region: os.Getenv("OS_REGION_NAME"), 196 }) 197} 198 199// NewBlockStorageV2NoAuthClient returns a noauth *ServiceClient for 200// making calls to the OpenStack Block Storage v2 API. An error will be 201// returned if client creation was not possible. 202func NewBlockStorageV2NoAuthClient() (*gophercloud.ServiceClient, error) { 203 client, err := blockstorageNoAuth.NewClient(gophercloud.AuthOptions{ 204 Username: os.Getenv("OS_USERNAME"), 205 TenantName: os.Getenv("OS_TENANT_NAME"), 206 }) 207 if err != nil { 208 return nil, err 209 } 210 211 client = configureDebug(client) 212 213 return blockstorageNoAuth.NewBlockStorageNoAuth(client, blockstorageNoAuth.EndpointOpts{ 214 CinderEndpoint: os.Getenv("CINDER_ENDPOINT"), 215 }) 216} 217 218// NewBlockStorageV3NoAuthClient returns a noauth *ServiceClient for 219// making calls to the OpenStack Block Storage v2 API. An error will be 220// returned if client creation was not possible. 221func NewBlockStorageV3NoAuthClient() (*gophercloud.ServiceClient, error) { 222 client, err := blockstorageNoAuth.NewClient(gophercloud.AuthOptions{ 223 Username: os.Getenv("OS_USERNAME"), 224 TenantName: os.Getenv("OS_TENANT_NAME"), 225 }) 226 if err != nil { 227 return nil, err 228 } 229 230 client = configureDebug(client) 231 232 return blockstorageNoAuth.NewBlockStorageNoAuth(client, blockstorageNoAuth.EndpointOpts{ 233 CinderEndpoint: os.Getenv("CINDER_ENDPOINT"), 234 }) 235} 236 237// NewComputeV2Client returns a *ServiceClient for making calls 238// to the OpenStack Compute v2 API. An error will be returned 239// if authentication or client creation was not possible. 240func NewComputeV2Client() (*gophercloud.ServiceClient, error) { 241 ao, err := openstack.AuthOptionsFromEnv() 242 if err != nil { 243 return nil, err 244 } 245 246 client, err := openstack.AuthenticatedClient(ao) 247 if err != nil { 248 return nil, err 249 } 250 251 client = configureDebug(client) 252 253 return openstack.NewComputeV2(client, gophercloud.EndpointOpts{ 254 Region: os.Getenv("OS_REGION_NAME"), 255 }) 256} 257 258// NewBareMetalV1Client returns a *ServiceClient for making calls 259// to the OpenStack Bare Metal v1 API. An error will be returned 260// if authentication or client creation was not possible. 261func NewBareMetalV1Client() (*gophercloud.ServiceClient, error) { 262 ao, err := openstack.AuthOptionsFromEnv() 263 if err != nil { 264 return nil, err 265 } 266 267 client, err := openstack.AuthenticatedClient(ao) 268 if err != nil { 269 return nil, err 270 } 271 272 client = configureDebug(client) 273 274 return openstack.NewBareMetalV1(client, gophercloud.EndpointOpts{ 275 Region: os.Getenv("OS_REGION_NAME"), 276 }) 277} 278 279// NewBareMetalV1NoAuthClient returns a *ServiceClient for making calls 280// to the OpenStack Bare Metal v1 API. An error will be returned 281// if authentication or client creation was not possible. 282func NewBareMetalV1NoAuthClient() (*gophercloud.ServiceClient, error) { 283 return baremetalNoAuth.NewBareMetalNoAuth(baremetalNoAuth.EndpointOpts{ 284 IronicEndpoint: os.Getenv("IRONIC_ENDPOINT"), 285 }) 286} 287 288// NewBareMetalIntrospectionV1Client returns a *ServiceClient for making calls 289// to the OpenStack Bare Metal Introspection v1 API. An error will be returned 290// if authentication or client creation was not possible. 291func NewBareMetalIntrospectionV1Client() (*gophercloud.ServiceClient, error) { 292 ao, err := openstack.AuthOptionsFromEnv() 293 if err != nil { 294 return nil, err 295 } 296 297 client, err := openstack.AuthenticatedClient(ao) 298 if err != nil { 299 return nil, err 300 } 301 302 client = configureDebug(client) 303 304 return openstack.NewBareMetalIntrospectionV1(client, gophercloud.EndpointOpts{ 305 Region: os.Getenv("OS_REGION_NAME"), 306 }) 307} 308 309// NewDBV1Client returns a *ServiceClient for making calls 310// to the OpenStack Database v1 API. An error will be returned 311// if authentication or client creation was not possible. 312func NewDBV1Client() (*gophercloud.ServiceClient, error) { 313 ao, err := openstack.AuthOptionsFromEnv() 314 if err != nil { 315 return nil, err 316 } 317 318 client, err := openstack.AuthenticatedClient(ao) 319 if err != nil { 320 return nil, err 321 } 322 323 client = configureDebug(client) 324 325 return openstack.NewDBV1(client, gophercloud.EndpointOpts{ 326 Region: os.Getenv("OS_REGION_NAME"), 327 }) 328} 329 330// NewDNSV2Client returns a *ServiceClient for making calls 331// to the OpenStack Compute v2 API. An error will be returned 332// if authentication or client creation was not possible. 333func NewDNSV2Client() (*gophercloud.ServiceClient, error) { 334 ao, err := openstack.AuthOptionsFromEnv() 335 if err != nil { 336 return nil, err 337 } 338 339 client, err := openstack.AuthenticatedClient(ao) 340 if err != nil { 341 return nil, err 342 } 343 344 client = configureDebug(client) 345 346 return openstack.NewDNSV2(client, gophercloud.EndpointOpts{ 347 Region: os.Getenv("OS_REGION_NAME"), 348 }) 349} 350 351// NewIdentityV2Client returns a *ServiceClient for making calls 352// to the OpenStack Identity v2 API. An error will be returned 353// if authentication or client creation was not possible. 354func NewIdentityV2Client() (*gophercloud.ServiceClient, error) { 355 ao, err := openstack.AuthOptionsFromEnv() 356 if err != nil { 357 return nil, err 358 } 359 360 client, err := openstack.AuthenticatedClient(ao) 361 if err != nil { 362 return nil, err 363 } 364 365 client = configureDebug(client) 366 367 return openstack.NewIdentityV2(client, gophercloud.EndpointOpts{ 368 Region: os.Getenv("OS_REGION_NAME"), 369 }) 370} 371 372// NewIdentityV2AdminClient returns a *ServiceClient for making calls 373// to the Admin Endpoint of the OpenStack Identity v2 API. An error 374// will be returned if authentication or client creation was not possible. 375func NewIdentityV2AdminClient() (*gophercloud.ServiceClient, error) { 376 ao, err := openstack.AuthOptionsFromEnv() 377 if err != nil { 378 return nil, err 379 } 380 381 client, err := openstack.AuthenticatedClient(ao) 382 if err != nil { 383 return nil, err 384 } 385 386 client = configureDebug(client) 387 388 return openstack.NewIdentityV2(client, gophercloud.EndpointOpts{ 389 Region: os.Getenv("OS_REGION_NAME"), 390 Availability: gophercloud.AvailabilityAdmin, 391 }) 392} 393 394// NewIdentityV2UnauthenticatedClient returns an unauthenticated *ServiceClient 395// for the OpenStack Identity v2 API. An error will be returned if 396// authentication or client creation was not possible. 397func NewIdentityV2UnauthenticatedClient() (*gophercloud.ServiceClient, error) { 398 ao, err := openstack.AuthOptionsFromEnv() 399 if err != nil { 400 return nil, err 401 } 402 403 client, err := openstack.NewClient(ao.IdentityEndpoint) 404 if err != nil { 405 return nil, err 406 } 407 408 client = configureDebug(client) 409 410 return openstack.NewIdentityV2(client, gophercloud.EndpointOpts{}) 411} 412 413// NewIdentityV3Client returns a *ServiceClient for making calls 414// to the OpenStack Identity v3 API. An error will be returned 415// if authentication or client creation was not possible. 416func NewIdentityV3Client() (*gophercloud.ServiceClient, error) { 417 ao, err := openstack.AuthOptionsFromEnv() 418 if err != nil { 419 return nil, err 420 } 421 422 client, err := openstack.AuthenticatedClient(ao) 423 if err != nil { 424 return nil, err 425 } 426 427 client = configureDebug(client) 428 429 return openstack.NewIdentityV3(client, gophercloud.EndpointOpts{ 430 Region: os.Getenv("OS_REGION_NAME"), 431 }) 432} 433 434// NewIdentityV3UnauthenticatedClient returns an unauthenticated *ServiceClient 435// for the OpenStack Identity v3 API. An error will be returned if 436// authentication or client creation was not possible. 437func NewIdentityV3UnauthenticatedClient() (*gophercloud.ServiceClient, error) { 438 ao, err := openstack.AuthOptionsFromEnv() 439 if err != nil { 440 return nil, err 441 } 442 443 client, err := openstack.NewClient(ao.IdentityEndpoint) 444 if err != nil { 445 return nil, err 446 } 447 448 client = configureDebug(client) 449 450 return openstack.NewIdentityV3(client, gophercloud.EndpointOpts{}) 451} 452 453// NewImageServiceV2Client returns a *ServiceClient for making calls to the 454// OpenStack Image v2 API. An error will be returned if authentication or 455// client creation was not possible. 456func NewImageServiceV2Client() (*gophercloud.ServiceClient, error) { 457 ao, err := openstack.AuthOptionsFromEnv() 458 if err != nil { 459 return nil, err 460 } 461 462 client, err := openstack.AuthenticatedClient(ao) 463 if err != nil { 464 return nil, err 465 } 466 467 client = configureDebug(client) 468 469 return openstack.NewImageServiceV2(client, gophercloud.EndpointOpts{ 470 Region: os.Getenv("OS_REGION_NAME"), 471 }) 472} 473 474// NewNetworkV2Client returns a *ServiceClient for making calls to the 475// OpenStack Networking v2 API. An error will be returned if authentication 476// or client creation was not possible. 477func NewNetworkV2Client() (*gophercloud.ServiceClient, error) { 478 ao, err := openstack.AuthOptionsFromEnv() 479 if err != nil { 480 return nil, err 481 } 482 483 client, err := openstack.AuthenticatedClient(ao) 484 if err != nil { 485 return nil, err 486 } 487 488 client = configureDebug(client) 489 490 return openstack.NewNetworkV2(client, gophercloud.EndpointOpts{ 491 Region: os.Getenv("OS_REGION_NAME"), 492 }) 493} 494 495// NewObjectStorageV1Client returns a *ServiceClient for making calls to the 496// OpenStack Object Storage v1 API. An error will be returned if authentication 497// or client creation was not possible. 498func NewObjectStorageV1Client() (*gophercloud.ServiceClient, error) { 499 ao, err := openstack.AuthOptionsFromEnv() 500 if err != nil { 501 return nil, err 502 } 503 504 client, err := openstack.AuthenticatedClient(ao) 505 if err != nil { 506 return nil, err 507 } 508 509 client = configureDebug(client) 510 511 return openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{ 512 Region: os.Getenv("OS_REGION_NAME"), 513 }) 514} 515 516// NewSharedFileSystemV2Client returns a *ServiceClient for making calls 517// to the OpenStack Shared File System v2 API. An error will be returned 518// if authentication or client creation was not possible. 519func NewSharedFileSystemV2Client() (*gophercloud.ServiceClient, error) { 520 ao, err := openstack.AuthOptionsFromEnv() 521 if err != nil { 522 return nil, err 523 } 524 525 client, err := openstack.AuthenticatedClient(ao) 526 if err != nil { 527 return nil, err 528 } 529 530 client = configureDebug(client) 531 532 return openstack.NewSharedFileSystemV2(client, gophercloud.EndpointOpts{ 533 Region: os.Getenv("OS_REGION_NAME"), 534 }) 535} 536 537// NewLoadBalancerV2Client returns a *ServiceClient for making calls to the 538// OpenStack Octavia v2 API. An error will be returned if authentication 539// or client creation was not possible. 540func NewLoadBalancerV2Client() (*gophercloud.ServiceClient, error) { 541 ao, err := openstack.AuthOptionsFromEnv() 542 if err != nil { 543 return nil, err 544 } 545 546 client, err := openstack.AuthenticatedClient(ao) 547 if err != nil { 548 return nil, err 549 } 550 551 client = configureDebug(client) 552 553 return openstack.NewLoadBalancerV2(client, gophercloud.EndpointOpts{ 554 Region: os.Getenv("OS_REGION_NAME"), 555 }) 556} 557 558// NewClusteringV1Client returns a *ServiceClient for making calls 559// to the OpenStack Clustering v1 API. An error will be returned 560// if authentication or client creation was not possible. 561func NewClusteringV1Client() (*gophercloud.ServiceClient, error) { 562 ao, err := openstack.AuthOptionsFromEnv() 563 if err != nil { 564 return nil, err 565 } 566 567 client, err := openstack.AuthenticatedClient(ao) 568 if err != nil { 569 return nil, err 570 } 571 572 client = configureDebug(client) 573 574 return openstack.NewClusteringV1(client, gophercloud.EndpointOpts{ 575 Region: os.Getenv("OS_REGION_NAME"), 576 }) 577} 578 579// NewMessagingV2Client returns a *ServiceClient for making calls 580// to the OpenStack Messaging (Zaqar) v2 API. An error will be returned 581// if authentication or client creation was not possible. 582func NewMessagingV2Client(clientID string) (*gophercloud.ServiceClient, error) { 583 ao, err := openstack.AuthOptionsFromEnv() 584 if err != nil { 585 return nil, err 586 } 587 588 client, err := openstack.AuthenticatedClient(ao) 589 if err != nil { 590 return nil, err 591 } 592 593 client = configureDebug(client) 594 595 return openstack.NewMessagingV2(client, clientID, gophercloud.EndpointOpts{ 596 Region: os.Getenv("OS_REGION_NAME"), 597 }) 598} 599 600// NewContainerV1Client returns a *ServiceClient for making calls 601// to the OpenStack Container V1 API. An error will be returned 602// if authentication or client creation was not possible. 603func NewContainerV1Client() (*gophercloud.ServiceClient, error) { 604 ao, err := openstack.AuthOptionsFromEnv() 605 if err != nil { 606 return nil, err 607 } 608 609 client, err := openstack.AuthenticatedClient(ao) 610 if err != nil { 611 return nil, err 612 } 613 614 client = configureDebug(client) 615 616 return openstack.NewContainerV1(client, gophercloud.EndpointOpts{ 617 Region: os.Getenv("OS_REGION_NAME"), 618 }) 619} 620 621// NewKeyManagerV1Client returns a *ServiceClient for making calls 622// to the OpenStack Key Manager (Barbican) v1 API. An error will be 623// returned if authentication or client creation was not possible. 624func NewKeyManagerV1Client() (*gophercloud.ServiceClient, error) { 625 ao, err := openstack.AuthOptionsFromEnv() 626 if err != nil { 627 return nil, err 628 } 629 630 client, err := openstack.AuthenticatedClient(ao) 631 if err != nil { 632 return nil, err 633 } 634 635 client = configureDebug(client) 636 637 return openstack.NewKeyManagerV1(client, gophercloud.EndpointOpts{ 638 Region: os.Getenv("OS_REGION_NAME"), 639 }) 640} 641 642// configureDebug will configure the provider client to print the API 643// requests and responses if OS_DEBUG is enabled. 644func configureDebug(client *gophercloud.ProviderClient) *gophercloud.ProviderClient { 645 if os.Getenv("OS_DEBUG") != "" { 646 client.HTTPClient = http.Client{ 647 Transport: &LogRoundTripper{ 648 Rt: &http.Transport{}, 649 }, 650 } 651 } 652 653 return client 654} 655 656// NewContainerInfraV1Client returns a *ServiceClient for making calls 657// to the OpenStack Container Infra Management v1 API. An error will be returned 658// if authentication or client creation was not possible. 659func NewContainerInfraV1Client() (*gophercloud.ServiceClient, error) { 660 ao, err := openstack.AuthOptionsFromEnv() 661 if err != nil { 662 return nil, err 663 } 664 665 client, err := openstack.AuthenticatedClient(ao) 666 if err != nil { 667 return nil, err 668 } 669 670 client = configureDebug(client) 671 672 return openstack.NewContainerInfraV1(client, gophercloud.EndpointOpts{ 673 Region: os.Getenv("OS_REGION_NAME"), 674 }) 675} 676 677// NewWorkflowV2Client returns a *ServiceClient for making calls 678// to the OpenStack Workflow v2 API (Mistral). An error will be returned if 679// authentication or client creation failed. 680func NewWorkflowV2Client() (*gophercloud.ServiceClient, error) { 681 ao, err := openstack.AuthOptionsFromEnv() 682 if err != nil { 683 return nil, err 684 } 685 686 client, err := openstack.AuthenticatedClient(ao) 687 if err != nil { 688 return nil, err 689 } 690 691 client = configureDebug(client) 692 693 return openstack.NewWorkflowV2(client, gophercloud.EndpointOpts{ 694 Region: os.Getenv("OS_REGION_NAME"), 695 }) 696} 697 698// NewOrchestrationV1Client returns a *ServiceClient for making calls 699// to the OpenStack Orchestration v1 API. An error will be returned 700// if authentication or client creation was not possible. 701func NewOrchestrationV1Client() (*gophercloud.ServiceClient, error) { 702 ao, err := openstack.AuthOptionsFromEnv() 703 if err != nil { 704 return nil, err 705 } 706 707 client, err := openstack.AuthenticatedClient(ao) 708 if err != nil { 709 return nil, err 710 } 711 712 client = configureDebug(client) 713 714 return openstack.NewOrchestrationV1(client, gophercloud.EndpointOpts{ 715 Region: os.Getenv("OS_REGION_NAME"), 716 }) 717} 718 719// NewPlacementV1Client returns a *ServiceClient for making calls 720// to the OpenStack Placement API. An error will be returned 721// if authentication or client creation was not possible. 722func NewPlacementV1Client() (*gophercloud.ServiceClient, error) { 723 ao, err := openstack.AuthOptionsFromEnv() 724 if err != nil { 725 return nil, err 726 } 727 728 client, err := openstack.AuthenticatedClient(ao) 729 if err != nil { 730 return nil, err 731 } 732 733 client = configureDebug(client) 734 735 return openstack.NewPlacementV1(client, gophercloud.EndpointOpts{ 736 Region: os.Getenv("OS_REGION_NAME"), 737 }) 738} 739