From 406ef92623ea3c81e1101f11c5ffae59ab32f688 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Fri, 22 Dec 2017 17:12:51 -0500 Subject: [PATCH] Update to latest gophercloud Catch up with all the latest stuff from gophercloud 4b7db606 - only try to reauth once d13755e6 - BlockStorage v3: Rename VolumeType PublicAccess to IsPublic 614da04d - Add UPDATE support in V3 volume types (#656) be3fd784 - Flavor Extra Specs Create c2cafb46 - Flavor Extra Specs: List / Get 7b1b8775 - Compute v2: Flavor Access Add cf81d92c - Add DELETE support in V3 volume types a879b375 - Fix incorrect variable name 2997913a - Add pagination support in snapshots a5c71868 - Support pagination in volume resources 1db0312e - TrivialFix incorrect variable name 69194d93 - Add basic CRUD acceptance testcases in snapshot V3 22c7abce - Add CREATE support in V3 volume types aed60e9f - Add basic CRUD acceptance in volume V3 7cbf4661 - BlockStorage v3: volumetype get/list acc test bcab0f79 - Update README with Thank Yous f85e7c0f - Docs: Updating Contributing and Style Guides be1b616c - Fix a small syntax error of TestShareTypeExtraSpecs test 3f38a1ee - Add List/Get support for volume type in volume V3 48a40399 - Support for setting availability_zone_hints to a router 747776a7 - Fix the undefined function error of TestPortsbindingCRUD test a7ec61ea - Fix the undefined function error of TestNetworksProviderCRUD test 25e18920 - Compute v2: Add the extended status information API b63d2fd3 - availability_zone_hints for network(s) 157d7511 - Add support for ipv6_address_mode and ipv6_ra_mode in subnets ed468967 - DBv1: configurations acceptance test 578e2aab - Configuration group time parsing error 669959f8 - Compute v2: attachinterfaces acceptance test 8113f0cb - Add Nova interface-detach support d6484abc - Add Nova interface-attach support 7883fd95 - fix reauth deadlock by not calling Token() during reauth 4d0f8253 - Add support to get interface of a server 7dc13e0d - AccTests: BlockStorage v2 ForceDelete 1e86e54d - Refactor blockstorage actionURL e30da231 - Feature/support force delete e193578c - add UseTokenLock method in ProviderClient to allow safe concurrent access e6a5f874 - ObjectStorage v1: Rename ExtractLastMarker to extractLastMarker c47bb004 - BlockStorage v2/v3: Reorder snapshot/volume ListOpts and update godoc 2c05d0e4 - Add 'tenant' support in volume&snapshot API 639d71fd - Networking v2: Port Security Extension 755794a7 - ObjectStorage v1: Subdir and Marker detection a043441f - fixed bug with endless loop when using delimiter on folded directory a4799293 - OpenStack: support OS_PROJECT_* variables --- Godeps/Godeps.json | 60 +++++++------- .../src/k8s.io/apiserver/Godeps/Godeps.json | 14 ++-- .../src/k8s.io/client-go/Godeps/Godeps.json | 14 ++-- .../gophercloud/gophercloud/README.md | 16 ++++ .../gophercloud/gophercloud/STYLEGUIDE.md | 5 ++ .../gophercloud/openstack/auth_env.go | 17 +++- .../extensions/volumeactions/requests.go | 24 +++--- .../extensions/volumeactions/results.go | 5 ++ .../extensions/volumeactions/urls.go | 34 +------- .../blockstorage/v2/volumes/requests.go | 15 +++- .../blockstorage/v3/volumes/requests.go | 30 +++++-- .../blockstorage/v3/volumes/results.go | 13 +++- .../gophercloud/openstack/client.go | 52 +++++++++++-- .../v2/extensions/attachinterfaces/doc.go | 30 +++++++ .../extensions/attachinterfaces/requests.go | 59 ++++++++++++++ .../v2/extensions/attachinterfaces/results.go | 32 ++++++++ .../v2/extensions/attachinterfaces/urls.go | 11 +++ .../openstack/compute/v2/flavors/doc.go | 40 ++++++++++ .../openstack/compute/v2/flavors/requests.go | 69 ++++++++++++++++ .../openstack/compute/v2/flavors/results.go | 67 ++++++++++++++++ .../openstack/compute/v2/flavors/urls.go | 16 ++++ .../v2/extensions/layer3/routers/requests.go | 11 +-- .../v2/extensions/layer3/routers/results.go | 4 + .../networking/v2/networks/requests.go | 9 ++- .../networking/v2/networks/results.go | 4 + .../gophercloud/provider_client.go | 78 ++++++++++++++++--- 26 files changed, 605 insertions(+), 124 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 691bd76f46e..9a9d3aa2c2a 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1633,123 +1633,123 @@ }, { "ImportPath": "github.com/gophercloud/gophercloud", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/pagination", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gorilla/context", diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json index 83c6b74dbaa..49ef5aaa071 100644 --- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json @@ -408,31 +408,31 @@ }, { "ImportPath": "github.com/gophercloud/gophercloud", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/pagination", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gregjones/httpcache", diff --git a/staging/src/k8s.io/client-go/Godeps/Godeps.json b/staging/src/k8s.io/client-go/Godeps/Godeps.json index d9c1c4f0410..c3d9ca80a46 100644 --- a/staging/src/k8s.io/client-go/Godeps/Godeps.json +++ b/staging/src/k8s.io/client-go/Godeps/Godeps.json @@ -172,31 +172,31 @@ }, { "ImportPath": "github.com/gophercloud/gophercloud", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/openstack/utils", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gophercloud/gophercloud/pagination", - "Rev": "8183543f90d1aef267a5ecc209f2e0715b355acb" + "Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97" }, { "ImportPath": "github.com/gregjones/httpcache", diff --git a/vendor/github.com/gophercloud/gophercloud/README.md b/vendor/github.com/gophercloud/gophercloud/README.md index 60ca479de89..bb218c3fe9e 100644 --- a/vendor/github.com/gophercloud/gophercloud/README.md +++ b/vendor/github.com/gophercloud/gophercloud/README.md @@ -141,3 +141,19 @@ See the [contributing guide](./.github/CONTRIBUTING.md). If you're struggling with something or have spotted a potential bug, feel free to submit an issue to our [bug tracker](/issues). + +## Thank You + +We'd like to extend special thanks and appreciation to the following: + +### OpenLab + + + +OpenLab is providing a full CI environment to test each PR and merge for a variety of OpenStack releases. + +### VEXXHOST + + + +VEXXHOST is providing their services to assist with the development and testing of Gophercloud. diff --git a/vendor/github.com/gophercloud/gophercloud/STYLEGUIDE.md b/vendor/github.com/gophercloud/gophercloud/STYLEGUIDE.md index e7531a83d9d..22a29009412 100644 --- a/vendor/github.com/gophercloud/gophercloud/STYLEGUIDE.md +++ b/vendor/github.com/gophercloud/gophercloud/STYLEGUIDE.md @@ -1,6 +1,8 @@ ## On Pull Requests +- Please make sure to read our [contributing guide](/.github/CONTRIBUTING.md). + - Before you start a PR there needs to be a Github issue and a discussion about it on that issue with a core contributor, even if it's just a 'SGTM'. @@ -34,6 +36,9 @@ append. It makes it difficult for the reviewer to see what's changed from one review to the next. +- See [#583](https://github.com/gophercloud/gophercloud/issues/583) as an example of a + well-formatted issue which contains all relevant information we need to review and approve. + ## On Code - In re design: follow as closely as is reasonable the code already in the library. diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go index 95286041d66..b5482ba8c9f 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go @@ -16,7 +16,12 @@ The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME, OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME. Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must have settings, -or an error will result. OS_TENANT_ID and OS_TENANT_NAME are optional. +or an error will result. OS_TENANT_ID, OS_TENANT_NAME, OS_PROJECT_ID, and +OS_PROJECT_NAME are optional. + +OS_TENANT_ID and OS_TENANT_NAME are mutually exclusive to OS_PROJECT_ID and +OS_PROJECT_NAME. If OS_PROJECT_ID and OS_PROJECT_NAME are set, they will +still be referred as "tenant" in Gophercloud. To use this function, first set the OS_* environment variables (for example, by sourcing an `openrc` file), then: @@ -34,6 +39,16 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) { domainID := os.Getenv("OS_DOMAIN_ID") domainName := os.Getenv("OS_DOMAIN_NAME") + // If OS_PROJECT_ID is set, overwrite tenantID with the value. + if v := os.Getenv("OS_PROJECT_ID"); v != "" { + tenantID = v + } + + // If OS_PROJECT_NAME is set, overwrite tenantName with the value. + if v := os.Getenv("OS_PROJECT_NAME"); v != "" { + tenantName = v + } + if authURL == "" { err := gophercloud.ErrMissingInput{Argument: "authURL"} return nilOptions, err diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go index a3916c77c16..d18bff555b5 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go @@ -47,7 +47,7 @@ func Attach(client *gophercloud.ServiceClient, id string, opts AttachOptsBuilder r.Err = err return } - _, r.Err = client.Post(attachURL(client, id), b, nil, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{202}, }) return @@ -56,7 +56,7 @@ func Attach(client *gophercloud.ServiceClient, id string, opts AttachOptsBuilder // BeginDetach will mark the volume as detaching. func BeginDetaching(client *gophercloud.ServiceClient, id string) (r BeginDetachingResult) { b := map[string]interface{}{"os-begin_detaching": make(map[string]interface{})} - _, r.Err = client.Post(beginDetachingURL(client, id), b, nil, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{202}, }) return @@ -87,7 +87,7 @@ func Detach(client *gophercloud.ServiceClient, id string, opts DetachOptsBuilder r.Err = err return } - _, r.Err = client.Post(detachURL(client, id), b, nil, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{202}, }) return @@ -96,7 +96,7 @@ func Detach(client *gophercloud.ServiceClient, id string, opts DetachOptsBuilder // Reserve will reserve a volume based on volume ID. func Reserve(client *gophercloud.ServiceClient, id string) (r ReserveResult) { b := map[string]interface{}{"os-reserve": make(map[string]interface{})} - _, r.Err = client.Post(reserveURL(client, id), b, nil, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{200, 201, 202}, }) return @@ -105,7 +105,7 @@ func Reserve(client *gophercloud.ServiceClient, id string) (r ReserveResult) { // Unreserve will unreserve a volume based on volume ID. func Unreserve(client *gophercloud.ServiceClient, id string) (r UnreserveResult) { b := map[string]interface{}{"os-unreserve": make(map[string]interface{})} - _, r.Err = client.Post(unreserveURL(client, id), b, nil, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{200, 201, 202}, }) return @@ -145,7 +145,7 @@ func InitializeConnection(client *gophercloud.ServiceClient, id string, opts Ini r.Err = err return } - _, r.Err = client.Post(initializeConnectionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{200, 201, 202}, }) return @@ -183,7 +183,7 @@ func TerminateConnection(client *gophercloud.ServiceClient, id string, opts Term r.Err = err return } - _, r.Err = client.Post(teminateConnectionURL(client, id), b, nil, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{202}, }) return @@ -216,7 +216,7 @@ func ExtendSize(client *gophercloud.ServiceClient, id string, opts ExtendSizeOpt r.Err = err return } - _, r.Err = client.Post(extendSizeURL(client, id), b, nil, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ OkCodes: []int{202}, }) return @@ -256,8 +256,14 @@ func UploadImage(client *gophercloud.ServiceClient, id string, opts UploadImageO r.Err = err return } - _, r.Err = client.Post(uploadURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ + _, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ OkCodes: []int{202}, }) return } + +// ForceDelete will delete the volume regardless of state. +func ForceDelete(client *gophercloud.ServiceClient, id string) (r ForceDeleteResult) { + _, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-force_delete": ""}, nil, nil) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go index 9815f0c26ac..5cadd360f20 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go @@ -184,3 +184,8 @@ func (r UploadImageResult) Extract() (VolumeImage, error) { err := r.ExtractInto(&s) return s.VolumeImage, err } + +// ForceDeleteResult contains the response body and error from a ForceDelete request. +type ForceDeleteResult struct { + gophercloud.ErrResult +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go index 5efd2b25c05..20486ed7194 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go @@ -2,38 +2,6 @@ package volumeactions import "github.com/gophercloud/gophercloud" -func attachURL(c *gophercloud.ServiceClient, id string) string { +func actionURL(c *gophercloud.ServiceClient, id string) string { return c.ServiceURL("volumes", id, "action") } - -func beginDetachingURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} - -func detachURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} - -func uploadURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} - -func reserveURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} - -func unreserveURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} - -func initializeConnectionURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} - -func teminateConnectionURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} - -func extendSizeURL(c *gophercloud.ServiceClient, id string) string { - return attachURL(c, id) -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go index 18c9cb272ec..2ec10ad55ed 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go @@ -83,14 +83,21 @@ type ListOptsBuilder interface { // ListOpts holds options for listing Volumes. It is passed to the volumes.List // function. type ListOpts struct { - // admin-only option. Set it to true to see all tenant volumes. + // AllTenants will retrieve volumes of all tenants/projects. AllTenants bool `q:"all_tenants"` - // List only volumes that contain Metadata. + + // Metadata will filter results based on specified metadata. Metadata map[string]string `q:"metadata"` - // List only volumes that have Name as the display name. + + // Name will filter by the specified volume name. Name string `q:"name"` - // List only volumes that have a status of Status. + + // Status will filter by the specified status. Status string `q:"status"` + + // TenantID will filter by a specific tenant/project ID. + // Setting AllTenants is required for this. + TenantID string `q:"project_id"` } // ToVolumeListQuery formats a ListOpts into a query string. diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go index 18c9cb272ec..43727409dd9 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go @@ -83,14 +83,34 @@ type ListOptsBuilder interface { // ListOpts holds options for listing Volumes. It is passed to the volumes.List // function. type ListOpts struct { - // admin-only option. Set it to true to see all tenant volumes. + // AllTenants will retrieve volumes of all tenants/projects. AllTenants bool `q:"all_tenants"` - // List only volumes that contain Metadata. + + // Metadata will filter results based on specified metadata. Metadata map[string]string `q:"metadata"` - // List only volumes that have Name as the display name. + + // Name will filter by the specified volume name. Name string `q:"name"` - // List only volumes that have a status of Status. + + // Status will filter by the specified status. Status string `q:"status"` + + // TenantID will filter by a specific tenant/project ID. + // Setting AllTenants is required for this. + TenantID string `q:"project_id"` + + // Comma-separated list of sort keys and optional sort directions in the + // form of [:]. + Sort string `q:"sort"` + + // Requests a page size of items. + Limit int `q:"limit"` + + // Used in conjunction with limit to return a slice of items. + Offset int `q:"offset"` + + // The ID of the last-seen item. + Marker string `q:"marker"` } // ToVolumeListQuery formats a ListOpts into a query string. @@ -111,7 +131,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa } return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return VolumePage{pagination.SinglePageBase(r)} + return VolumePage{pagination.LinkedPageBase{PageResult: r}} }) } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go index 5ebe36a3385..87f71262c1d 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go @@ -101,7 +101,7 @@ func (r *Volume) UnmarshalJSON(b []byte) error { // VolumePage is a pagination.pager that is returned from a call to the List function. type VolumePage struct { - pagination.SinglePageBase + pagination.LinkedPageBase } // IsEmpty returns true if a ListResult contains no Volumes. @@ -110,6 +110,17 @@ func (r VolumePage) IsEmpty() (bool, error) { return len(volumes) == 0, err } +func (page VolumePage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"volumes_links"` + } + err := page.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + // ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call. func ExtractVolumes(r pagination.Page) ([]Volume, error) { var s []Volume diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/client.go b/vendor/github.com/gophercloud/gophercloud/openstack/client.go index c796795b8ee..5a52e579148 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/client.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/client.go @@ -56,11 +56,12 @@ func NewClient(endpoint string) (*gophercloud.ProviderClient, error) { endpoint = gophercloud.NormalizeURL(endpoint) base = gophercloud.NormalizeURL(base) - return &gophercloud.ProviderClient{ - IdentityBase: base, - IdentityEndpoint: endpoint, - }, nil + p := new(gophercloud.ProviderClient) + p.IdentityBase = base + p.IdentityEndpoint = endpoint + p.UseTokenLock() + return p, nil } /* @@ -158,9 +159,21 @@ func v2auth(client *gophercloud.ProviderClient, endpoint string, options gopherc } if options.AllowReauth { + // here we're creating a throw-away client (tac). it's a copy of the user's provider client, but + // with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`, + // this should retry authentication only once + tac := *client + tac.ReauthFunc = nil + tac.TokenID = "" + tao := options + tao.AllowReauth = false client.ReauthFunc = func() error { - client.TokenID = "" - return v2auth(client, endpoint, options, eo) + err := v2auth(&tac, endpoint, tao, eo) + if err != nil { + return err + } + client.TokenID = tac.TokenID + return nil } } client.TokenID = token.ID @@ -202,9 +215,32 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au client.TokenID = token.ID if opts.CanReauth() { + // here we're creating a throw-away client (tac). it's a copy of the user's provider client, but + // with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`, + // this should retry authentication only once + tac := *client + tac.ReauthFunc = nil + tac.TokenID = "" + var tao tokens3.AuthOptionsBuilder + switch ot := opts.(type) { + case *gophercloud.AuthOptions: + o := *ot + o.AllowReauth = false + tao = &o + case *tokens3.AuthOptions: + o := *ot + o.AllowReauth = false + tao = &o + default: + tao = opts + } client.ReauthFunc = func() error { - client.TokenID = "" - return v3auth(client, endpoint, opts, eo) + err := v3auth(&tac, endpoint, tao, eo) + if err != nil { + return err + } + client.TokenID = tac.TokenID + return nil } } client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go index a9960137117..3653122bf30 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go @@ -18,5 +18,35 @@ Example of Listing a Server's Interfaces for _, interface := range allInterfaces { fmt.Printf("%+v\n", interface) } + +Example to Get a Server's Interface + + portID = "0dde1598-b374-474e-986f-5b8dd1df1d4e" + serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" + interface, err := attachinterfaces.Get(computeClient, serverID, portID).Extract() + if err != nil { + panic(err) + } + +Example to Create a new Interface attachment on the Server + + networkID := "8a5fe506-7e9f-4091-899b-96336909d93c" + serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" + attachOpts := attachinterfaces.CreateOpts{ + NetworkID: networkID, + } + interface, err := attachinterfaces.Create(computeClient, serverID, attachOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete an Interface attachment from the Server + + portID = "0dde1598-b374-474e-986f-5b8dd1df1d4e" + serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" + err := attachinterfaces.Delete(computeClient, serverID, portID).ExtractErr() + if err != nil { + panic(err) + } */ package attachinterfaces diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go index faf2747246a..18dade837c1 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go @@ -11,3 +11,62 @@ func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager { return InterfacePage{pagination.SinglePageBase(r)} }) } + +// Get requests details on a single interface attachment by the server and port IDs. +func Get(client *gophercloud.ServiceClient, serverID, portID string) (r GetResult) { + _, r.Err = client.Get(getInterfaceURL(client, serverID, portID), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToAttachInterfacesCreateMap() (map[string]interface{}, error) +} + +// CreateOpts specifies parameters of a new interface attachment. +type CreateOpts struct { + + // PortID is the ID of the port for which you want to create an interface. + // The NetworkID and PortID parameters are mutually exclusive. + // If you do not specify the PortID parameter, the OpenStack Networking API + // v2.0 allocates a port and creates an interface for it on the network. + PortID string `json:"port_id,omitempty"` + + // NetworkID is the ID of the network for which you want to create an interface. + // The NetworkID and PortID parameters are mutually exclusive. + // If you do not specify the NetworkID parameter, the OpenStack Networking + // API v2.0 uses the network information cache that is associated with the instance. + NetworkID string `json:"net_id,omitempty"` + + // Slice of FixedIPs. If you request a specific FixedIP address without a + // NetworkID, the request returns a Bad Request (400) response code. + FixedIPs []FixedIP `json:"fixed_ips,omitempty"` +} + +// ToAttachInterfacesCreateMap constructs a request body from CreateOpts. +func (opts CreateOpts) ToAttachInterfacesCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "interfaceAttachment") +} + +// Create requests the creation of a new interface attachment on the server. +func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToAttachInterfacesCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createInterfaceURL(client, serverID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete makes a request against the nova API to detach a single interface from the server. +// It needs server and port IDs to make a such request. +func Delete(client *gophercloud.ServiceClient, serverID, portID string) (r DeleteResult) { + _, r.Err = client.Delete(deleteInterfaceURL(client, serverID, portID), nil) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go index e3987eaca84..a16fa14f759 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go @@ -1,9 +1,41 @@ package attachinterfaces import ( + "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/pagination" ) +type attachInterfaceResult struct { + gophercloud.Result +} + +// Extract interprets any attachInterfaceResult as an Interface, if possible. +func (r attachInterfaceResult) Extract() (*Interface, error) { + var s struct { + Interface *Interface `json:"interfaceAttachment"` + } + err := r.ExtractInto(&s) + return s.Interface, err +} + +// GetResult is the response from a Get operation. Call its Extract +// method to interpret it as an Interface. +type GetResult struct { + attachInterfaceResult +} + +// CreateResult is the response from a Create operation. Call its Extract +// method to interpret it as an Interface. +type CreateResult struct { + attachInterfaceResult +} + +// DeleteResult is the response from a Delete operation. Call its ExtractErr +// method to determine if the call succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + // FixedIP represents a Fixed IP Address. type FixedIP struct { SubnetID string `json:"subnet_id"` diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go index 7d376f99bb5..50292e8b5a5 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go @@ -5,3 +5,14 @@ import "github.com/gophercloud/gophercloud" func listInterfaceURL(client *gophercloud.ServiceClient, serverID string) string { return client.ServiceURL("servers", serverID, "os-interface") } + +func getInterfaceURL(client *gophercloud.ServiceClient, serverID, portID string) string { + return client.ServiceURL("servers", serverID, "os-interface", portID) +} + +func createInterfaceURL(client *gophercloud.ServiceClient, serverID string) string { + return client.ServiceURL("servers", serverID, "os-interface") +} +func deleteInterfaceURL(client *gophercloud.ServiceClient, serverID, portID string) string { + return client.ServiceURL("servers", serverID, "os-interface", portID) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go index a7bc15c3e5c..867d53a8190 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go @@ -59,5 +59,45 @@ Example to List Flavor Access for _, access := range allAccesses { fmt.Printf("%+v", access) } + +Example to Grant Access to a Flavor + + flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" + + accessOpts := flavors.AddAccessOpts{ + Tenant: "15153a0979884b59b0592248ef947921", + } + + accessList, err := flavors.AddAccess(computeClient, flavor.ID, accessOpts).Extract() + if err != nil { + panic(err) + } + +Example to Create Extra Specs for a Flavor + + flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" + + createOpts := flavors.ExtraSpecsOpts{ + "hw:cpu_policy": "CPU-POLICY", + "hw:cpu_thread_policy": "CPU-THREAD-POLICY", + } + createdExtraSpecs, err := flavors.CreateExtraSpecs(computeClient, flavorID, createOpts).Extract() + if err != nil { + panic(err) + } + + fmt.Printf("%+v", createdExtraSpecs) + +Example to Get Extra Specs for a Flavor + + flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" + + extraSpecs, err := flavors.ListExtraSpecs(computeClient, flavorID).Extract() + if err != nil { + panic(err) + } + + fmt.Printf("%+v", extraSpecs) + */ package flavors diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go index 6eb3678b2bd..965d271d1d3 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go @@ -162,6 +162,75 @@ func ListAccesses(client *gophercloud.ServiceClient, id string) pagination.Pager }) } +// AddAccessOptsBuilder allows extensions to add additional parameters to the +// AddAccess requests. +type AddAccessOptsBuilder interface { + ToAddAccessMap() (map[string]interface{}, error) +} + +// AddAccessOpts represents options for adding access to a flavor. +type AddAccessOpts struct { + // Tenant is the project/tenant ID to grant access. + Tenant string `json:"tenant"` +} + +// ToAddAccessMap constructs a request body from AddAccessOpts. +func (opts AddAccessOpts) ToAddAccessMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "addTenantAccess") +} + +// AddAccess grants a tenant/project access to a flavor. +func AddAccess(client *gophercloud.ServiceClient, id string, opts AddAccessOptsBuilder) (r AddAccessResult) { + b, err := opts.ToAddAccessMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// ExtraSpecs requests all the extra-specs for the given flavor ID. +func ListExtraSpecs(client *gophercloud.ServiceClient, flavorID string) (r ListExtraSpecsResult) { + _, r.Err = client.Get(extraSpecsListURL(client, flavorID), &r.Body, nil) + return +} + +func GetExtraSpec(client *gophercloud.ServiceClient, flavorID string, key string) (r GetExtraSpecResult) { + _, r.Err = client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil) + return +} + +// CreateExtraSpecsOptsBuilder allows extensions to add additional parameters to the +// CreateExtraSpecs requests. +type CreateExtraSpecsOptsBuilder interface { + ToExtraSpecsCreateMap() (map[string]interface{}, error) +} + +// ExtraSpecsOpts is a map that contains key-value pairs. +type ExtraSpecsOpts map[string]string + +// ToExtraSpecsCreateMap assembles a body for a Create request based on the +// contents of a ExtraSpecsOpts +func (opts ExtraSpecsOpts) ToExtraSpecsCreateMap() (map[string]interface{}, error) { + return map[string]interface{}{"extra_specs": opts}, nil +} + +// CreateExtraSpecs will create or update the extra-specs key-value pairs for the specified Flavor +func CreateExtraSpecs(client *gophercloud.ServiceClient, flavorID string, opts CreateExtraSpecsOptsBuilder) (r CreateExtraSpecsResult) { + b, err := opts.ToExtraSpecsCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(extraSpecsCreateURL(client, flavorID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + // IDFromName is a convienience function that returns a flavor's ID given its // name. func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go index fb5c335b8ea..4451be38c92 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go @@ -154,6 +154,26 @@ func ExtractAccesses(r pagination.Page) ([]FlavorAccess, error) { return s.FlavorAccesses, err } +type accessResult struct { + gophercloud.Result +} + +// AddAccessResult is the response of an AddAccess operations. Call its +// Extract method to interpret it as a slice of FlavorAccess. +type AddAccessResult struct { + accessResult +} + +// Extract provides access to the result of an access create or delete. +// The result will be all accesses that the flavor has. +func (r accessResult) Extract() ([]FlavorAccess, error) { + var s struct { + FlavorAccesses []FlavorAccess `json:"flavor_access"` + } + err := r.ExtractInto(&s) + return s.FlavorAccesses, err +} + // FlavorAccess represents an ACL of tenant access to a specific Flavor. type FlavorAccess struct { // FlavorID is the unique ID of the flavor. @@ -162,3 +182,50 @@ type FlavorAccess struct { // TenantID is the unique ID of the tenant. TenantID string `json:"tenant_id"` } + +// Extract interprets any extraSpecsResult as ExtraSpecs, if possible. +func (r extraSpecsResult) Extract() (map[string]string, error) { + var s struct { + ExtraSpecs map[string]string `json:"extra_specs"` + } + err := r.ExtractInto(&s) + return s.ExtraSpecs, err +} + +// extraSpecsResult contains the result of a call for (potentially) multiple +// key-value pairs. Call its Extract method to interpret it as a +// map[string]interface. +type extraSpecsResult struct { + gophercloud.Result +} + +// ListExtraSpecsResult contains the result of a Get operation. Call its Extract +// method to interpret it as a map[string]interface. +type ListExtraSpecsResult struct { + extraSpecsResult +} + +// CreateExtraSpecResult contains the result of a Create operation. Call its +// Extract method to interpret it as a map[string]interface. +type CreateExtraSpecsResult struct { + extraSpecsResult +} + +// extraSpecResult contains the result of a call for individual a single +// key-value pair. +type extraSpecResult struct { + gophercloud.Result +} + +// GetExtraSpecResult contains the result of a Get operation. Call its Extract +// method to interpret it as a map[string]interface. +type GetExtraSpecResult struct { + extraSpecResult +} + +// Extract interprets any extraSpecResult as an ExtraSpec, if possible. +func (r extraSpecResult) Extract() (map[string]string, error) { + var s map[string]string + err := r.ExtractInto(&s) + return s, err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go index 04d33bf1279..b74f81625d8 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go @@ -23,3 +23,19 @@ func deleteURL(client *gophercloud.ServiceClient, id string) string { func accessURL(client *gophercloud.ServiceClient, id string) string { return client.ServiceURL("flavors", id, "os-flavor-access") } + +func accessActionURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("flavors", id, "action") +} + +func extraSpecsListURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("flavors", id, "os-extra_specs") +} + +func extraSpecsGetURL(client *gophercloud.ServiceClient, id, key string) string { + return client.ServiceURL("flavors", id, "os-extra_specs", key) +} + +func extraSpecsCreateURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("flavors", id, "os-extra_specs") +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go index 6799d200b7a..fa346c8555f 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go @@ -49,11 +49,12 @@ type CreateOptsBuilder interface { // CreateOpts contains all the values needed to create a new router. There are // no required values. type CreateOpts struct { - Name string `json:"name,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Distributed *bool `json:"distributed,omitempty"` - TenantID string `json:"tenant_id,omitempty"` - GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` + Name string `json:"name,omitempty"` + AdminStateUp *bool `json:"admin_state_up,omitempty"` + Distributed *bool `json:"distributed,omitempty"` + TenantID string `json:"tenant_id,omitempty"` + GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` + AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"` } // ToRouterCreateMap builds a create request body from CreateOpts. diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go index e19c8e74c47..da1b9e4bdfa 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go @@ -60,6 +60,10 @@ type Router struct { // Routes are a collection of static routes that the router will host. Routes []Route `json:"routes"` + + // Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others. + // Used to make network resources highly available. + AvailabilityZoneHints []string `json:"availability_zone_hints"` } // RouterPage is the page returned by a pager when traversing over a diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go index 5b61b247192..040f32183b4 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go @@ -66,10 +66,11 @@ type CreateOptsBuilder interface { // CreateOpts represents options used to create a network. type CreateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Name string `json:"name,omitempty"` - Shared *bool `json:"shared,omitempty"` - TenantID string `json:"tenant_id,omitempty"` + AdminStateUp *bool `json:"admin_state_up,omitempty"` + Name string `json:"name,omitempty"` + Shared *bool `json:"shared,omitempty"` + TenantID string `json:"tenant_id,omitempty"` + AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"` } // ToNetworkCreateMap builds a request body from CreateOpts. diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go index ffd0259f1d2..c73f9e1a63f 100644 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go @@ -69,6 +69,10 @@ type Network struct { // Specifies whether the network resource can be accessed by any tenant. Shared bool `json:"shared"` + + // Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others. + // Used to make network resources highly available. + AvailabilityZoneHints []string `json:"availability_zone_hints"` } // NetworkPage is the page returned by a pager when traversing over a diff --git a/vendor/github.com/gophercloud/gophercloud/provider_client.go b/vendor/github.com/gophercloud/gophercloud/provider_client.go index 01b3010739a..72daeb0a3eb 100644 --- a/vendor/github.com/gophercloud/gophercloud/provider_client.go +++ b/vendor/github.com/gophercloud/gophercloud/provider_client.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net/http" "strings" + "sync" ) // DefaultUserAgent is the default User-Agent string set in the request header. @@ -51,6 +52,8 @@ type ProviderClient struct { IdentityEndpoint string // TokenID is the ID of the most recently issued valid token. + // NOTE: Aside from within a custom ReauthFunc, this field shouldn't be set by an application. + // To safely read or write this value, call `Token` or `SetToken`, respectively TokenID string // EndpointLocator describes how this provider discovers the endpoints for @@ -68,16 +71,59 @@ type ProviderClient struct { // authentication functions for different Identity service versions. ReauthFunc func() error - Debug bool + mut *sync.RWMutex + + reauthmut *reauthlock +} + +type reauthlock struct { + sync.RWMutex + reauthing bool } // AuthenticatedHeaders returns a map of HTTP headers that are common for all // authenticated service requests. -func (client *ProviderClient) AuthenticatedHeaders() map[string]string { - if client.TokenID == "" { - return map[string]string{} +func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) { + if client.reauthmut != nil { + client.reauthmut.RLock() + if client.reauthmut.reauthing { + client.reauthmut.RUnlock() + return + } + client.reauthmut.RUnlock() } - return map[string]string{"X-Auth-Token": client.TokenID} + t := client.Token() + if t == "" { + return + } + return map[string]string{"X-Auth-Token": t} +} + +// UseTokenLock creates a mutex that is used to allow safe concurrent access to the auth token. +// If the application's ProviderClient is not used concurrently, this doesn't need to be called. +func (client *ProviderClient) UseTokenLock() { + client.mut = new(sync.RWMutex) + client.reauthmut = new(reauthlock) +} + +// Token safely reads the value of the auth token from the ProviderClient. Applications should +// call this method to access the token instead of the TokenID field +func (client *ProviderClient) Token() string { + if client.mut != nil { + client.mut.RLock() + defer client.mut.RUnlock() + } + return client.TokenID +} + +// SetToken safely sets the value of the auth token in the ProviderClient. Applications may +// use this method in a custom ReauthFunc +func (client *ProviderClient) SetToken(t string) { + if client.mut != nil { + client.mut.Lock() + defer client.mut.Unlock() + } + client.TokenID = t } // RequestOpts customizes the behavior of the provider.Request() method. @@ -166,6 +212,8 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts) // Set connection parameter to close the connection immediately when we've got the response req.Close = true + prereqtok := req.Header.Get("X-Auth-Token") + // Issue the request. resp, err := client.HTTPClient.Do(req) if err != nil { @@ -189,9 +237,6 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts) if !ok { body, _ := ioutil.ReadAll(resp.Body) resp.Body.Close() - //pc := make([]uintptr, 1) - //runtime.Callers(2, pc) - //f := runtime.FuncForPC(pc[0]) respErr := ErrUnexpectedResponseCode{ URL: url, Method: method, @@ -199,7 +244,6 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts) Actual: resp.StatusCode, Body: body, } - //respErr.Function = "gophercloud.ProviderClient.Request" errType := options.ErrorContext switch resp.StatusCode { @@ -210,7 +254,21 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts) } case http.StatusUnauthorized: if client.ReauthFunc != nil { - err = client.ReauthFunc() + if client.mut != nil { + client.mut.Lock() + client.reauthmut.Lock() + client.reauthmut.reauthing = true + client.reauthmut.Unlock() + if curtok := client.TokenID; curtok == prereqtok { + err = client.ReauthFunc() + } + client.reauthmut.Lock() + client.reauthmut.reauthing = false + client.reauthmut.Unlock() + client.mut.Unlock() + } else { + err = client.ReauthFunc() + } if err != nil { e := &ErrUnableToReauthenticate{} e.ErrOriginal = respErr