Merge pull request #63405 from dims/update-to-latest-gophercloud-may-3-2018

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Update to latest Gophercloud

**What this PR does / why we need it**:

periodic update to latest gophercloud. The changes are as follows:
6da026c32e...781450b3c4

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```
pull/8/head
Kubernetes Submit Queue 2018-05-04 09:03:44 -07:00 committed by GitHub
commit bc56947e8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 219 additions and 99 deletions

60
Godeps/Godeps.json generated
View File

@ -1761,123 +1761,123 @@
},
{
"ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/common/extensions",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gorilla/websocket",

View File

@ -104,31 +104,31 @@
},
{
"ImportPath": "github.com/gophercloud/gophercloud",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
},
{
"ImportPath": "github.com/hashicorp/golang-lru",

View File

@ -72,6 +72,11 @@ type ErrDefault401 struct {
ErrUnexpectedResponseCode
}
// ErrDefault403 is the default error type returned on a 403 HTTP response code.
type ErrDefault403 struct {
ErrUnexpectedResponseCode
}
// ErrDefault404 is the default error type returned on a 404 HTTP response code.
type ErrDefault404 struct {
ErrUnexpectedResponseCode
@ -108,6 +113,13 @@ func (e ErrDefault400) Error() string {
func (e ErrDefault401) Error() string {
return "Authentication failed"
}
func (e ErrDefault403) Error() string {
e.DefaultErrString = fmt.Sprintf(
"Request forbidden: [%s %s], error message: %s",
e.Method, e.URL, e.Body,
)
return e.choseErrString()
}
func (e ErrDefault404) Error() string {
return "Resource not found"
}
@ -141,6 +153,12 @@ type Err401er interface {
Error401(ErrUnexpectedResponseCode) error
}
// Err403er is the interface resource error types implement to override the error message
// from a 403 error.
type Err403er interface {
Error403(ErrUnexpectedResponseCode) error
}
// Err404er is the interface resource error types implement to override the error message
// from a 404 error.
type Err404er interface {

View File

@ -394,3 +394,9 @@ func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi
sc.ResourceBase = sc.Endpoint + "v2.0/"
return sc, err
}
// NewClusteringV1 creates a ServiceClient that may be used with the v1 clustering
// package.
func NewClusteringV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "clustering")
}

View File

@ -236,21 +236,22 @@ func GetExtraSpec(client *gophercloud.ServiceClient, flavorID string, key string
// CreateExtraSpecsOptsBuilder allows extensions to add additional parameters to the
// CreateExtraSpecs requests.
type CreateExtraSpecsOptsBuilder interface {
ToExtraSpecsCreateMap() (map[string]interface{}, error)
ToFlavorExtraSpecsCreateMap() (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) {
// ToFlavorExtraSpecsCreateMap assembles a body for a Create request based on
// the contents of ExtraSpecsOpts.
func (opts ExtraSpecsOpts) ToFlavorExtraSpecsCreateMap() (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
// 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()
b, err := opts.ToFlavorExtraSpecsCreateMap()
if err != nil {
r.Err = err
return
@ -261,15 +262,15 @@ func CreateExtraSpecs(client *gophercloud.ServiceClient, flavorID string, opts C
return
}
// UpdateExtraSpecOptsBuilder allows extensions to add additional parameters to the
// Update request.
// UpdateExtraSpecOptsBuilder allows extensions to add additional parameters to
// the Update request.
type UpdateExtraSpecOptsBuilder interface {
ToExtraSpecUpdateMap() (map[string]string, string, error)
ToFlavorExtraSpecUpdateMap() (map[string]string, string, error)
}
// ToExtraSpecUpdateMap assembles a body for an Update request based on the
// contents of a ExtraSpecOpts.
func (opts ExtraSpecsOpts) ToExtraSpecUpdateMap() (map[string]string, string, error) {
// ToFlavorExtraSpecUpdateMap assembles a body for an Update request based on
// the contents of a ExtraSpecOpts.
func (opts ExtraSpecsOpts) ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) {
if len(opts) != 1 {
err := gophercloud.ErrInvalidInput{}
err.Argument = "flavors.ExtraSpecOpts"
@ -285,9 +286,10 @@ func (opts ExtraSpecsOpts) ToExtraSpecUpdateMap() (map[string]string, string, er
return opts, key, nil
}
// UpdateExtraSpec will updates the value of the specified flavor's extra spec for the key in opts.
// UpdateExtraSpec will updates the value of the specified flavor's extra spec
// for the key in opts.
func UpdateExtraSpec(client *gophercloud.ServiceClient, flavorID string, opts UpdateExtraSpecOptsBuilder) (r UpdateExtraSpecResult) {
b, key, err := opts.ToExtraSpecUpdateMap()
b, key, err := opts.ToFlavorExtraSpecUpdateMap()
if err != nil {
r.Err = err
return

View File

@ -84,7 +84,7 @@ func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpt
return "", err
}
if (opts.Availability == gophercloud.Availability(endpoint.Interface)) &&
(opts.Region == "" || endpoint.Region == opts.Region) {
(opts.Region == "" || endpoint.Region == opts.Region || endpoint.RegionID == opts.Region) {
endpoints = append(endpoints, endpoint)
}
}

View File

@ -13,6 +13,7 @@ import (
type Endpoint struct {
ID string `json:"id"`
Region string `json:"region"`
RegionID string `json:"region_id"`
Interface string `json:"interface"`
URL string `json:"url"`
}

View File

@ -17,6 +17,7 @@ type ListOpts struct {
FixedIP string `q:"fixed_ip_address"`
FloatingIP string `q:"floating_ip_address"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
Limit int `q:"limit"`
Marker string `q:"marker"`
SortKey string `q:"sort_key"`
@ -55,6 +56,7 @@ type CreateOpts struct {
FixedIP string `json:"fixed_ip_address,omitempty"`
SubnetID string `json:"subnet_id,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
ProjectID string `json:"project_id,omitempty"`
}
// ToFloatingIPCreateMap allows CreateOpts to satisfy the CreateOptsBuilder

View File

@ -30,10 +30,13 @@ type FloatingIP struct {
// associated with the floating IP.
FixedIP string `json:"fixed_ip_address"`
// TenantID is the Owner of the floating IP. Only admin users can specify a
// tenant identifier other than its own.
// TenantID is the project owner of the floating IP. Only admin users can
// specify a project identifier other than its own.
TenantID string `json:"tenant_id"`
// ProjectID is the project owner of the floating IP.
ProjectID string `json:"project_id"`
// Status is the condition of the API resource.
Status string `json:"status"`

View File

@ -17,6 +17,7 @@ type ListOpts struct {
Distributed *bool `q:"distributed"`
Status string `q:"status"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
Limit int `q:"limit"`
Marker string `q:"marker"`
SortKey string `q:"sort_key"`
@ -53,6 +54,7 @@ type CreateOpts struct {
AdminStateUp *bool `json:"admin_state_up,omitempty"`
Distributed *bool `json:"distributed,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
ProjectID string `json:"project_id,omitempty"`
GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"`
AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"`
}

View File

@ -54,10 +54,13 @@ type Router struct {
// ID is the unique identifier for the router.
ID string `json:"id"`
// TenantID is the owner of the router. Only admin users can specify a tenant
// identifier other than its own.
// TenantID is the project owner of the router. Only admin users can
// specify a project identifier other than its own.
TenantID string `json:"tenant_id"`
// ProjectID is the project owner of the router.
ProjectID string `json:"project_id"`
// Routes are a collection of static routes that the router will host.
Routes []Route `json:"routes"`

View File

@ -31,6 +31,7 @@ type ListOpts struct {
Name string `q:"name"`
AdminStateUp *bool `q:"admin_state_up"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
LoadbalancerID string `q:"loadbalancer_id"`
DefaultPoolID string `q:"default_pool_id"`
Protocol string `q:"protocol"`
@ -86,9 +87,13 @@ type CreateOpts struct {
ProtocolPort int `json:"protocol_port" required:"true"`
// TenantID is only required if the caller has an admin role and wants
// to create a pool for another tenant.
// to create a pool for another project.
TenantID string `json:"tenant_id,omitempty"`
// ProjectID is only required if the caller has an admin role and wants
// to create a pool for another project.
ProjectID string `json:"project_id,omitempty"`
// Human-readable name for the Listener. Does not have to be unique.
Name string `json:"name,omitempty"`

View File

@ -1,6 +1,8 @@
package loadbalancers
import (
"fmt"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@ -20,6 +22,7 @@ type ListOpts struct {
Description string `q:"description"`
AdminStateUp *bool `q:"admin_state_up"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
ProvisioningStatus string `q:"provisioning_status"`
VipAddress string `q:"vip_address"`
VipPortID string `q:"vip_port_id"`
@ -35,7 +38,7 @@ type ListOpts struct {
SortDir string `q:"sort_dir"`
}
// ToLoadbalancerListQuery formats a ListOpts into a query string.
// ToLoadBalancerListQuery formats a ListOpts into a query string.
func (opts ListOpts) ToLoadBalancerListQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
@ -81,10 +84,14 @@ type CreateOpts struct {
// that belong to them or networks that are shared).
VipSubnetID string `json:"vip_subnet_id" required:"true"`
// The UUID of the tenant who owns the Loadbalancer. Only administrative users
// can specify a tenant UUID other than their own.
// TenantID is the UUID of the project who owns the Loadbalancer.
// Only administrative users can specify a project UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// ProjectID is the UUID of the project who owns the Loadbalancer.
// Only administrative users can specify a project UUID other than their own.
ProjectID string `json:"project_id,omitempty"`
// The IP address of the Loadbalancer.
VipAddress string `json:"vip_address,omitempty"`
@ -170,6 +177,20 @@ func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
return
}
// CascadingDelete is like `Delete`, but will also delete any of the load balancer's
// children (listener, monitor, etc).
// NOTE: This function will only work with Octavia load balancers; Neutron does not
// support this.
func CascadingDelete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
if c.Type != "load-balancer" {
r.Err = fmt.Errorf("error prior to running cascade delete: only Octavia LBs supported")
return
}
u := fmt.Sprintf("%s?cascade=true", resourceURL(c, id))
_, r.Err = c.Delete(u, nil)
return
}
// GetStatuses will return the status of a particular LoadBalancer.
func GetStatuses(c *gophercloud.ServiceClient, id string) (r GetStatusesResult) {
_, r.Err = c.Get(statusRootURL(c, id), &r.Body, nil)

View File

@ -79,8 +79,8 @@ func (r LoadBalancerPage) NextPageURL() (string, error) {
}
// IsEmpty checks whether a LoadBalancerPage struct is empty.
func (p LoadBalancerPage) IsEmpty() (bool, error) {
is, err := ExtractLoadBalancers(p)
func (r LoadBalancerPage) IsEmpty() (bool, error) {
is, err := ExtractLoadBalancers(r)
return len(is) == 0, err
}

View File

@ -22,6 +22,7 @@ type ListOpts struct {
ID string `q:"id"`
Name string `q:"name"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
PoolID string `q:"pool_id"`
Type string `q:"type"`
Delay int `q:"delay"`
@ -119,10 +120,14 @@ type CreateOpts struct {
// types.
ExpectedCodes string `json:"expected_codes,omitempty"`
// The UUID of the tenant who owns the Monitor. Only administrative users
// can specify a tenant UUID other than their own.
// TenantID is the UUID of the project who owns the Monitor.
// Only administrative users can specify a project UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// ProjectID is the UUID of the project who owns the Monitor.
// Only administrative users can specify a project UUID other than their own.
ProjectID string `json:"project_id,omitempty"`
// The Name of the Monitor.
Name string `json:"name,omitempty"`

View File

@ -20,6 +20,7 @@ type ListOpts struct {
LBMethod string `q:"lb_algorithm"`
Protocol string `q:"protocol"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
AdminStateUp *bool `q:"admin_state_up"`
Name string `q:"name"`
ID string `q:"id"`
@ -97,10 +98,14 @@ type CreateOpts struct {
// Note: one of LoadbalancerID or ListenerID must be provided.
ListenerID string `json:"listener_id,omitempty" xor:"LoadbalancerID"`
// The UUID of the tenant who owns the Pool. Only administrative users
// can specify a tenant UUID other than their own.
// TenantID is the UUID of the project who owns the Pool.
// Only administrative users can specify a project UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// ProjectID is the UUID of the project who owns the Pool.
// Only administrative users can specify a project UUID other than their own.
ProjectID string `json:"project_id,omitempty"`
// Name of the pool.
Name string `json:"name,omitempty"`
@ -257,10 +262,14 @@ type CreateMemberOpts struct {
// Name of the Member.
Name string `json:"name,omitempty"`
// The UUID of the tenant who owns the Member. Only administrative users
// can specify a tenant UUID other than their own.
// TenantID is the UUID of the project who owns the Member.
// Only administrative users can specify a project UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// ProjectID is the UUID of the project who owns the Member.
// Only administrative users can specify a project UUID other than their own.
ProjectID string `json:"project_id,omitempty"`
// A positive integer value that indicates the relative portion of traffic
// that this member should receive from the pool. For example, a member with
// a weight of 10 receives five times as much traffic as a member with a

View File

@ -11,13 +11,14 @@ import (
// sort by a particular network attribute. SortDir sets the direction, and is
// either `asc' or `desc'. Marker and Limit are used for pagination.
type ListOpts struct {
ID string `q:"id"`
Name string `q:"name"`
TenantID string `q:"tenant_id"`
Limit int `q:"limit"`
Marker string `q:"marker"`
SortKey string `q:"sort_key"`
SortDir string `q:"sort_dir"`
ID string `q:"id"`
Name string `q:"name"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
Limit int `q:"limit"`
Marker string `q:"marker"`
SortKey string `q:"sort_key"`
SortDir string `q:"sort_dir"`
}
// List returns a Pager which allows you to iterate over a collection of
@ -45,10 +46,14 @@ type CreateOpts struct {
// Human-readable name for the Security Group. Does not have to be unique.
Name string `json:"name" required:"true"`
// The UUID of the tenant who owns the Group. Only administrative users
// can specify a tenant UUID other than their own.
// TenantID is the UUID of the project who owns the Group.
// Only administrative users can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// ProjectID is the UUID of the project who owns the Group.
// Only administrative users can specify a tenant UUID other than their own.
ProjectID string `json:"project_id,omitempty"`
// Describes the security group.
Description string `json:"description,omitempty"`
}

View File

@ -22,8 +22,11 @@ type SecGroup struct {
// traffic entering and leaving the group.
Rules []rules.SecGroupRule `json:"security_group_rules"`
// Owner of the security group.
// TenantID is the project owner of the security group.
TenantID string `json:"tenant_id"`
// ProjectID is the project owner of the security group.
ProjectID string `json:"project_id"`
}
// SecGroupPage is the page returned by a pager when traversing over a

View File

@ -21,6 +21,7 @@ type ListOpts struct {
RemoteIPPrefix string `q:"remote_ip_prefix"`
SecGroupID string `q:"security_group_id"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
Limit int `q:"limit"`
Marker string `q:"marker"`
SortKey string `q:"sort_key"`
@ -118,9 +119,9 @@ type CreateOpts struct {
// specified IP prefix as the source IP address of the IP packet.
RemoteIPPrefix string `json:"remote_ip_prefix,omitempty"`
// The UUID of the tenant who owns the Rule. Only administrative users
// can specify a tenant UUID other than their own.
TenantID string `json:"tenant_id,omitempty"`
// TenantID is the UUID of the project who owns the Rule.
// Only administrative users can specify a project UUID other than their own.
ProjectID string `json:"project_id,omitempty"`
}
// ToSecGroupRuleCreateMap builds a request body from CreateOpts.

View File

@ -48,8 +48,11 @@ type SecGroupRule struct {
// matches the specified IP prefix as the source IP address of the IP packet.
RemoteIPPrefix string `json:"remote_ip_prefix"`
// The owner of this security group rule.
// TenantID is the project owner of this security group rule.
TenantID string `json:"tenant_id"`
// ProjectID is the project owner of this security group rule.
ProjectID string `json:"project_id"`
}
// SecGroupRulePage is the page returned by a pager when traversing over a

View File

@ -21,6 +21,7 @@ type ListOpts struct {
Name string `q:"name"`
AdminStateUp *bool `q:"admin_state_up"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
Shared *bool `q:"shared"`
ID string `q:"id"`
Marker string `q:"marker"`
@ -70,6 +71,7 @@ type CreateOpts struct {
Name string `json:"name,omitempty"`
Shared *bool `json:"shared,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
ProjectID string `json:"project_id,omitempty"`
AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"`
}

View File

@ -64,9 +64,12 @@ type Network struct {
// Subnets associated with this network.
Subnets []string `json:"subnets"`
// Owner of network.
// TenantID is the project owner of the network.
TenantID string `json:"tenant_id"`
// ProjectID is the project owner of the network.
ProjectID string `json:"project_id"`
// Specifies whether the network resource can be accessed by any tenant.
Shared bool `json:"shared"`

View File

@ -22,6 +22,7 @@ type ListOpts struct {
AdminStateUp *bool `q:"admin_state_up"`
NetworkID string `q:"network_id"`
TenantID string `q:"tenant_id"`
ProjectID string `q:"project_id"`
DeviceOwner string `q:"device_owner"`
MACAddress string `q:"mac_address"`
ID string `q:"id"`
@ -81,6 +82,7 @@ type CreateOpts struct {
DeviceID string `json:"device_id,omitempty"`
DeviceOwner string `json:"device_owner,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
ProjectID string `json:"project_id,omitempty"`
SecurityGroups *[]string `json:"security_groups,omitempty"`
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
}

View File

@ -84,9 +84,12 @@ type Port struct {
// the subnets where the IP addresses are picked from
FixedIPs []IP `json:"fixed_ips"`
// Owner of network.
// TenantID is the project owner of the port.
TenantID string `json:"tenant_id"`
// ProjectID is the project owner of the port.
ProjectID string `json:"project_id"`
// Identifies the entity (e.g.: dhcp agent) using this port.
DeviceOwner string `json:"device_owner"`

View File

@ -126,6 +126,36 @@ func (client *ProviderClient) SetToken(t string) {
client.TokenID = t
}
//Reauthenticate calls client.ReauthFunc in a thread-safe way. If this is
//called because of a 401 response, the caller may pass the previous token. In
//this case, the reauthentication can be skipped if another thread has already
//reauthenticated in the meantime. If no previous token is known, an empty
//string should be passed instead to force unconditional reauthentication.
func (client *ProviderClient) Reauthenticate(previousToken string) (err error) {
if client.ReauthFunc == nil {
return nil
}
if client.mut == nil {
return client.ReauthFunc()
}
client.mut.Lock()
defer client.mut.Unlock()
client.reauthmut.Lock()
client.reauthmut.reauthing = true
client.reauthmut.Unlock()
if previousToken == "" || client.TokenID == previousToken {
err = client.ReauthFunc()
}
client.reauthmut.Lock()
client.reauthmut.reauthing = false
client.reauthmut.Unlock()
return
}
// RequestOpts customizes the behavior of the provider.Request() method.
type RequestOpts struct {
// JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The
@ -254,21 +284,7 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts)
}
case http.StatusUnauthorized:
if client.ReauthFunc != nil {
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()
}
err = client.Reauthenticate(prereqtok)
if err != nil {
e := &ErrUnableToReauthenticate{}
e.ErrOriginal = respErr
@ -298,6 +314,11 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts)
if error401er, ok := errType.(Err401er); ok {
err = error401er.Error401(respErr)
}
case http.StatusForbidden:
err = ErrDefault403{respErr}
if error403er, ok := errType.(Err403er); ok {
err = error403er.Error403(respErr)
}
case http.StatusNotFound:
err = ErrDefault404{respErr}
if error404er, ok := errType.(Err404er); ok {