mirror of https://github.com/kubernetes/kops.git
Upgrade gophercloud to v1.11.0
Update upup/pkg/fi/cloudup/openstacktasks/instance.go Co-authored-by: Peter Rifel <rifelpet@users.noreply.github.com>
This commit is contained in:
parent
40662d04dd
commit
8c70787bab
4
go.mod
4
go.mod
|
@ -46,7 +46,7 @@ replace k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.18.6
|
|||
|
||||
replace k8s.io/code-generator => k8s.io/code-generator v0.18.6
|
||||
|
||||
replace github.com/gophercloud/gophercloud => github.com/gophercloud/gophercloud v0.9.0
|
||||
replace github.com/gophercloud/gophercloud => github.com/gophercloud/gophercloud v0.11.0
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.38.0
|
||||
|
@ -76,7 +76,7 @@ require (
|
|||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/golang/protobuf v1.4.2 // indirect
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gophercloud/gophercloud v0.7.1-0.20200116011225-46fdd1830e9a
|
||||
github.com/gophercloud/gophercloud v0.11.0
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/hashicorp/hcl v1.0.0
|
||||
github.com/hashicorp/hcl/v2 v2.3.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -409,8 +409,8 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC
|
|||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
|
||||
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/gophercloud/gophercloud v0.9.0 h1:eJHQQFguQRv2FatH2d2VXH2ueTe2XzjgjwFjFS7SGcs=
|
||||
github.com/gophercloud/gophercloud v0.9.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
|
||||
github.com/gophercloud/gophercloud v0.11.0 h1:pYMP9UZBdQa3lsfIZ1tZor4EbtxiuB6BHhocenkiH/E=
|
||||
github.com/gophercloud/gophercloud v0.11.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
|
||||
github.com/gophercloud/utils v0.0.0-20191020172814-bd86af96d544/go.mod h1:SZ9FTKibIotDtCrxAU/evccoyu1yhKST6hgBvwTB5Eg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
os "github.com/gophercloud/gophercloud/openstack"
|
||||
cinder "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
|
||||
|
@ -291,6 +293,8 @@ type OpenstackCloud interface {
|
|||
|
||||
GetImage(name string) (i *images.Image, err error)
|
||||
|
||||
GetFlavor(name string) (f *flavors.Flavor, err error)
|
||||
|
||||
AssociateFloatingIPToInstance(serverID string, opts floatingips.AssociateOpts) (err error)
|
||||
|
||||
ListServerFloatingIPs(id string) ([]*string, error)
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
@ -189,3 +191,29 @@ func listInstances(c OpenstackCloud, opt servers.ListOptsBuilder) ([]servers.Ser
|
|||
return instances, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) GetFlavor(name string) (*flavors.Flavor, error) {
|
||||
return getFlavor(c, name)
|
||||
}
|
||||
|
||||
func getFlavor(c OpenstackCloud, name string) (*flavors.Flavor, error) {
|
||||
opts := flavors.ListOpts{}
|
||||
pager := flavors.ListDetail(c.ComputeClient(), opts)
|
||||
page, err := pager.AllPages()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list flavors: %v", err)
|
||||
}
|
||||
|
||||
fs, err := flavors.ExtractFlavors(page)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract flavors: %v", err)
|
||||
}
|
||||
for _, f := range fs {
|
||||
if f.Name == name {
|
||||
return &f, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("could not find flavor with name %v", name)
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ package openstack
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
cinder "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
|
||||
az "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones"
|
||||
|
@ -331,6 +333,10 @@ func (c *MockCloud) GetImage(name string) (*images.Image, error) {
|
|||
return getImage(c, name)
|
||||
}
|
||||
|
||||
func (c *MockCloud) GetFlavor(name string) (*flavors.Flavor, error) {
|
||||
return getFlavor(c, name)
|
||||
}
|
||||
|
||||
func (c *MockCloud) GetInstance(id string) (*servers.Server, error) {
|
||||
return getInstance(c, id)
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ go_library(
|
|||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/listeners:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools:go_default_library",
|
||||
|
|
|
@ -20,8 +20,6 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs"
|
||||
|
@ -181,15 +179,21 @@ func (_ *Instance) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, change
|
|||
cloud := t.Cloud.(openstack.OpenstackCloud)
|
||||
|
||||
imageName := fi.StringValue(e.Image)
|
||||
imageRef, err := images.IDFromName(cloud.ImageClient(), imageName)
|
||||
image, err := cloud.GetImage(imageName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find image %v: %v", imageName, err)
|
||||
}
|
||||
|
||||
flavorName := fi.StringValue(e.Flavor)
|
||||
flavor, err := cloud.GetFlavor(flavorName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find flavor %v: %v", flavorName, err)
|
||||
}
|
||||
|
||||
opt := servers.CreateOpts{
|
||||
Name: fi.StringValue(e.Name),
|
||||
ImageRef: imageRef,
|
||||
FlavorName: fi.StringValue(e.Flavor),
|
||||
Name: fi.StringValue(e.Name),
|
||||
ImageRef: image.ID,
|
||||
FlavorRef: flavor.ID,
|
||||
Networks: []servers.Network{
|
||||
{
|
||||
Port: fi.StringValue(e.Port.ID),
|
||||
|
|
|
@ -1,4 +1,100 @@
|
|||
## 0.10.0 (Unreleased)
|
||||
## 0.12.0 (Unreleased)
|
||||
|
||||
## 0.11.0 (May 14, 2020)
|
||||
|
||||
UPGRADE NOTES
|
||||
|
||||
* Object storage container and object names are now URL encoded [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
|
||||
* All responses now have access to the returned headers. Please report any issues this has caused [GH-1942](https://github.com/gophercloud/gophercloud/pull/1942)
|
||||
* Changes have been made to the internal HTTP client to ensure response bodies are handled in a way that enables connections to be re-used more efficiently [GH-1952](https://github.com/gophercloud/gophercloud/pull/1952)
|
||||
|
||||
IMPROVEMENTS
|
||||
|
||||
* Added `objectstorage/v1/containers.BulkDelete` [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
|
||||
* Added `objectstorage/v1/objects.BulkDelete` [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
|
||||
* Object storage container and object names are now URL encoded [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
|
||||
* All responses now have access to the returned headers [GH-1942](https://github.com/gophercloud/gophercloud/pull/1942)
|
||||
* Added `compute/v2/extensions/injectnetworkinfo.InjectNetworkInfo` [GH-1941](https://github.com/gophercloud/gophercloud/pull/1941)
|
||||
* Added `compute/v2/extensions/resetnetwork.ResetNetwork` [GH-1941](https://github.com/gophercloud/gophercloud/pull/1941)
|
||||
* Added `identity/v3/extensions/trusts.ListRoles` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
|
||||
* Added `identity/v3/extensions/trusts.GetRole` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
|
||||
* Added `identity/v3/extensions/trusts.CheckRole` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
|
||||
* Added `identity/v3/extensions/oauth1.Create` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.CreateConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.DeleteConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.ListConsumers` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.GetConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.UpdateConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.RequestToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.AuthorizeToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.CreateAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.GetAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.RevokeAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.ListAccessTokens` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.ListAccessTokenRoles` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `identity/v3/extensions/oauth1.GetAccessTokenRole` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
|
||||
* Added `networking/v2/extensions/agents.Update` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
|
||||
* Added `networking/v2/extensions/agents.Delete` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
|
||||
* Added `networking/v2/extensions/agents.ScheduleDHCPNetwork` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
|
||||
* Added `networking/v2/extensions/agents.RemoveDHCPNetwork` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
|
||||
* Added `identity/v3/projects.CreateOpts.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
|
||||
* Added `identity/v3/projects.CreateOpts.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
|
||||
* Added `identity/v3/projects.UpdateOpts.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
|
||||
* Added `identity/v3/projects.UpdateOpts.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
|
||||
* Added `identity/v3/projects.Project.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
|
||||
* Added `identity/v3/projects.Options.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
|
||||
* Added `imageservice/v2/images.Image.OpenStackImageImportMethods` [GH-1962](https://github.com/gophercloud/gophercloud/pull/1962)
|
||||
* Added `imageservice/v2/images.Image.OpenStackImageStoreIDs` [GH-1962](https://github.com/gophercloud/gophercloud/pull/1962)
|
||||
|
||||
BUG FIXES
|
||||
|
||||
* Changed`identity/v3/extensions/trusts.Trust.RemainingUses` from `bool` to `int` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
|
||||
* Changed `identity/v3/applicationcredentials.CreateOpts.ExpiresAt` from `string` to `*time.Time` [GH-1937](https://github.com/gophercloud/gophercloud/pull/1937)
|
||||
* Fixed issue with unmarshalling/decoding slices of composed structs [GH-1964](https://github.com/gophercloud/gophercloud/pull/1964)
|
||||
|
||||
## 0.10.0 (April 12, 2020)
|
||||
|
||||
UPGRADE NOTES
|
||||
|
||||
* The various `IDFromName` convenience functions have been moved to https://github.com/gophercloud/utils [GH-1897](https://github.com/gophercloud/gophercloud/pull/1897)
|
||||
* `sharedfilesystems/v2/shares.GetExportLocations` was renamed to `sharedfilesystems/v2/shares.ListExportLocations` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932)
|
||||
|
||||
IMPROVEMENTS
|
||||
|
||||
* Added `blockstorage/extensions/volumeactions.SetBootable` [GH-1891](https://github.com/gophercloud/gophercloud/pull/1891)
|
||||
* Added `blockstorage/extensions/backups.Export` [GH-1894](https://github.com/gophercloud/gophercloud/pull/1894)
|
||||
* Added `blockstorage/extensions/backups.Import` [GH-1894](https://github.com/gophercloud/gophercloud/pull/1894)
|
||||
* Added `placement/v1/resourceproviders.GetTraits` [GH-1899](https://github.com/gophercloud/gophercloud/pull/1899)
|
||||
* Added the ability to authenticate with Amazon EC2 Credentials [GH-1900](https://github.com/gophercloud/gophercloud/pull/1900)
|
||||
* Added ability to list Nova services by binary and host [GH-1904](https://github.com/gophercloud/gophercloud/pull/1904)
|
||||
* Added `compute/v2/extensions/services.Update` [GH-1902](https://github.com/gophercloud/gophercloud/pull/1902)
|
||||
* Added system scope to v3 authentication [GH-1908](https://github.com/gophercloud/gophercloud/pull/1908)
|
||||
* Added `identity/v3/extensions/ec2tokens.ValidateS3Token` [GH-1906](https://github.com/gophercloud/gophercloud/pull/1906)
|
||||
* Added `containerinfra/v1/clusters.Cluster.HealthStatus` [GH-1910](https://github.com/gophercloud/gophercloud/pull/1910)
|
||||
* Added `containerinfra/v1/clusters.Cluster.HealthStatusReason` [GH-1910](https://github.com/gophercloud/gophercloud/pull/1910)
|
||||
* Added `loadbalancer/v2/amphorae.Failover` [GH-1912](https://github.com/gophercloud/gophercloud/pull/1912)
|
||||
* Added `identity/v3/extensions/ec2credentials.List` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
|
||||
* Added `identity/v3/extensions/ec2credentials.Get` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
|
||||
* Added `identity/v3/extensions/ec2credentials.Create` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
|
||||
* Added `identity/v3/extensions/ec2credentials.Delete` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
|
||||
* Added `ErrUnexpectedResponseCode.ResponseHeader` [GH-1919](https://github.com/gophercloud/gophercloud/pull/1919)
|
||||
* Added support for TOTP authentication [GH-1922](https://github.com/gophercloud/gophercloud/pull/1922)
|
||||
* `sharedfilesystems/v2/shares.GetExportLocations` was renamed to `sharedfilesystems/v2/shares.ListExportLocations` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932)
|
||||
* Added `sharedfilesystems/v2/shares.GetExportLocation` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932)
|
||||
* Added `sharedfilesystems/v2/shares.Revert` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
|
||||
* Added `sharedfilesystems/v2/shares.ResetStatus` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
|
||||
* Added `sharedfilesystems/v2/shares.ForceDelete` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
|
||||
* Added `sharedfilesystems/v2/shares.Unmanage` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
|
||||
* Added `blockstorage/v3/attachments.Create` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
|
||||
* Added `blockstorage/v3/attachments.List` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
|
||||
* Added `blockstorage/v3/attachments.Get` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
|
||||
* Added `blockstorage/v3/attachments.Update` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
|
||||
* Added `blockstorage/v3/attachments.Delete` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
|
||||
* Added `blockstorage/v3/attachments.Complete` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
|
||||
|
||||
BUG FIXES
|
||||
|
||||
* Fixed issue with Orchestration `get_file` only being able to read JSON and YAML files [GH-1915](https://github.com/gophercloud/gophercloud/pull/1915)
|
||||
|
||||
## 0.9.0 (March 10, 2020)
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ type AuthOptions struct {
|
|||
|
||||
Password string `json:"password,omitempty"`
|
||||
|
||||
// Passcode is used in TOTP authentication method
|
||||
Passcode string `json:"passcode,omitempty"`
|
||||
|
||||
// At most one of DomainID and DomainName must be provided if using Username
|
||||
// with Identity V3. Otherwise, either are optional.
|
||||
DomainID string `json:"-"`
|
||||
|
@ -98,6 +101,7 @@ type AuthScope struct {
|
|||
ProjectName string
|
||||
DomainID string
|
||||
DomainName string
|
||||
System bool
|
||||
}
|
||||
|
||||
// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||
|
@ -133,6 +137,8 @@ func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) {
|
|||
return map[string]interface{}{"auth": authMap}, nil
|
||||
}
|
||||
|
||||
// ToTokenV3CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||
// interface in the v3 tokens package
|
||||
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
|
||||
type domainReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
|
@ -148,7 +154,8 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
type userReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Password *string `json:"password,omitempty"`
|
||||
Passcode *string `json:"passcode,omitempty"`
|
||||
Domain *domainReq `json:"domain,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -167,11 +174,16 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
Secret *string `json:"secret,omitempty"`
|
||||
}
|
||||
|
||||
type totpReq struct {
|
||||
User *userReq `json:"user,omitempty"`
|
||||
}
|
||||
|
||||
type identityReq struct {
|
||||
Methods []string `json:"methods"`
|
||||
Password *passwordReq `json:"password,omitempty"`
|
||||
Token *tokenReq `json:"token,omitempty"`
|
||||
ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"`
|
||||
TOTP *totpReq `json:"totp,omitempty"`
|
||||
}
|
||||
|
||||
type authReq struct {
|
||||
|
@ -186,7 +198,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
// if insufficient or incompatible information is present.
|
||||
var req request
|
||||
|
||||
if opts.Password == "" {
|
||||
if opts.Password == "" && opts.Passcode == "" {
|
||||
if opts.TokenID != "" {
|
||||
// Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
|
||||
// parameters.
|
||||
|
@ -274,7 +286,14 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
}
|
||||
} else {
|
||||
// Password authentication.
|
||||
req.Auth.Identity.Methods = []string{"password"}
|
||||
if opts.Password != "" {
|
||||
req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "password")
|
||||
}
|
||||
|
||||
// TOTP authentication.
|
||||
if opts.Passcode != "" {
|
||||
req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "totp")
|
||||
}
|
||||
|
||||
// At least one of Username and UserID must be specified.
|
||||
if opts.Username == "" && opts.UserID == "" {
|
||||
|
@ -298,23 +317,46 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
}
|
||||
|
||||
// Configure the request for Username and Password authentication with a DomainID.
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{
|
||||
Name: &opts.Username,
|
||||
Password: opts.Password,
|
||||
Domain: &domainReq{ID: &opts.DomainID},
|
||||
},
|
||||
if opts.Password != "" {
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{
|
||||
Name: &opts.Username,
|
||||
Password: &opts.Password,
|
||||
Domain: &domainReq{ID: &opts.DomainID},
|
||||
},
|
||||
}
|
||||
}
|
||||
if opts.Passcode != "" {
|
||||
req.Auth.Identity.TOTP = &totpReq{
|
||||
User: &userReq{
|
||||
Name: &opts.Username,
|
||||
Passcode: &opts.Passcode,
|
||||
Domain: &domainReq{ID: &opts.DomainID},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if opts.DomainName != "" {
|
||||
// Configure the request for Username and Password authentication with a DomainName.
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{
|
||||
Name: &opts.Username,
|
||||
Password: opts.Password,
|
||||
Domain: &domainReq{Name: &opts.DomainName},
|
||||
},
|
||||
if opts.Password != "" {
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{
|
||||
Name: &opts.Username,
|
||||
Password: &opts.Password,
|
||||
Domain: &domainReq{Name: &opts.DomainName},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Passcode != "" {
|
||||
req.Auth.Identity.TOTP = &totpReq{
|
||||
User: &userReq{
|
||||
Name: &opts.Username,
|
||||
Passcode: &opts.Passcode,
|
||||
Domain: &domainReq{Name: &opts.DomainName},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -329,8 +371,22 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
}
|
||||
|
||||
// Configure the request for UserID and Password authentication.
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{ID: &opts.UserID, Password: opts.Password},
|
||||
if opts.Password != "" {
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{
|
||||
ID: &opts.UserID,
|
||||
Password: &opts.Password,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Passcode != "" {
|
||||
req.Auth.Identity.TOTP = &totpReq{
|
||||
User: &userReq{
|
||||
ID: &opts.UserID,
|
||||
Passcode: &opts.Passcode,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -347,6 +403,8 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
return b, nil
|
||||
}
|
||||
|
||||
// ToTokenV3ScopeMap builds a scope from AuthOptions and satisfies interface in
|
||||
// the v3 tokens package.
|
||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||
// For backwards compatibility.
|
||||
// If AuthOptions.Scope was not set, try to determine it.
|
||||
|
@ -364,6 +422,14 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if opts.Scope.System {
|
||||
return map[string]interface{}{
|
||||
"system": map[string]interface{}{
|
||||
"all": true,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if opts.Scope.ProjectName != "" {
|
||||
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
||||
// ProjectID may not be supplied.
|
||||
|
@ -433,5 +499,16 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
|||
}
|
||||
|
||||
func (opts AuthOptions) CanReauth() bool {
|
||||
if opts.Passcode != "" {
|
||||
// cannot reauth using TOTP passcode
|
||||
return false
|
||||
}
|
||||
|
||||
return opts.AllowReauth
|
||||
}
|
||||
|
||||
// ToTokenV3HeadersMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||
// interface in the v3 tokens package.
|
||||
func (opts *AuthOptions) ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package gophercloud
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -77,11 +78,12 @@ func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string {
|
|||
// those listed in OkCodes is encountered.
|
||||
type ErrUnexpectedResponseCode struct {
|
||||
BaseError
|
||||
URL string
|
||||
Method string
|
||||
Expected []int
|
||||
Actual int
|
||||
Body []byte
|
||||
URL string
|
||||
Method string
|
||||
Expected []int
|
||||
Actual int
|
||||
Body []byte
|
||||
ResponseHeader http.Header
|
||||
}
|
||||
|
||||
func (e ErrUnexpectedResponseCode) Error() string {
|
||||
|
|
|
@ -15,6 +15,8 @@ go_library(
|
|||
deps = [
|
||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/utils:go_default_library",
|
||||
],
|
||||
|
|
|
@ -38,6 +38,7 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
|||
username := os.Getenv("OS_USERNAME")
|
||||
userID := os.Getenv("OS_USERID")
|
||||
password := os.Getenv("OS_PASSWORD")
|
||||
passcode := os.Getenv("OS_PASSCODE")
|
||||
tenantID := os.Getenv("OS_TENANT_ID")
|
||||
tenantName := os.Getenv("OS_TENANT_NAME")
|
||||
domainID := os.Getenv("OS_DOMAIN_ID")
|
||||
|
@ -73,8 +74,9 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if password == "" && applicationCredentialID == "" && applicationCredentialName == "" {
|
||||
if password == "" && passcode == "" && applicationCredentialID == "" && applicationCredentialName == "" {
|
||||
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||
// silently ignore TOTP passcode warning, since it is not a common auth method
|
||||
EnvironmentVariable: "OS_PASSWORD",
|
||||
}
|
||||
return nilOptions, err
|
||||
|
@ -112,6 +114,7 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
|||
UserID: userID,
|
||||
Username: username,
|
||||
Password: password,
|
||||
Passcode: passcode,
|
||||
TenantID: tenantID,
|
||||
TenantName: tenantName,
|
||||
DomainID: domainID,
|
||||
|
|
48
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go
generated
vendored
48
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go
generated
vendored
|
@ -60,9 +60,10 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -96,14 +97,16 @@ func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder
|
|||
}
|
||||
url += query
|
||||
}
|
||||
_, r.Err = client.Delete(url, nil)
|
||||
resp, err := client.Delete(url, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves the Volume with the provided ID. To extract the Volume object
|
||||
// from the response, call the Extract method on the GetResult.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -197,44 +200,9 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convienience function that returns a volume's ID given its name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
pages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractVolumes(pages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, s := range all {
|
||||
if s.Name == name {
|
||||
count++
|
||||
id = s.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "volume"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "volume"}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens"
|
||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1"
|
||||
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
"github.com/gophercloud/gophercloud/openstack/utils"
|
||||
)
|
||||
|
@ -68,7 +70,7 @@ Example:
|
|||
|
||||
ao, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(ao)
|
||||
client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
|
||||
client, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
|
||||
Region: os.Getenv("OS_REGION_NAME"),
|
||||
})
|
||||
*/
|
||||
|
@ -224,7 +226,15 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
result := tokens3.Create(v3Client, opts)
|
||||
var result tokens3.CreateResult
|
||||
switch opts.(type) {
|
||||
case *ec2tokens.AuthOptions:
|
||||
result = ec2tokens.Create(v3Client, opts)
|
||||
case *oauth1.AuthOptions:
|
||||
result = oauth1.Create(v3Client, opts)
|
||||
default:
|
||||
result = tokens3.Create(v3Client, opts)
|
||||
}
|
||||
|
||||
err = client.SetTokenAndAuthResult(result)
|
||||
if err != nil {
|
||||
|
@ -255,6 +265,14 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
|
|||
o := *ot
|
||||
o.AllowReauth = false
|
||||
tao = &o
|
||||
case *ec2tokens.AuthOptions:
|
||||
o := *ot
|
||||
o.AllowReauth = false
|
||||
tao = &o
|
||||
case *oauth1.AuthOptions:
|
||||
o := *ot
|
||||
o.AllowReauth = false
|
||||
tao = &o
|
||||
default:
|
||||
tao = opts
|
||||
}
|
||||
|
|
|
@ -125,8 +125,9 @@ func Create(client *gophercloud.ServiceClient, opts servers.CreateOptsBuilder) (
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -36,21 +36,24 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns data about a previously created Floating IP.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete requests the deletion of a previous allocated Floating IP.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
resp, err := client.Delete(deleteURL(client, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -81,7 +84,8 @@ func AssociateInstance(client *gophercloud.ServiceClient, serverID string, opts
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(associateURL(client, serverID), b, nil, nil)
|
||||
resp, err := client.Post(associateURL(client, serverID), b, nil, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -109,6 +113,7 @@ func DisassociateInstance(client *gophercloud.ServiceClient, serverID string, op
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(disassociateURL(client, serverID), b, nil, nil)
|
||||
resp, err := client.Post(disassociateURL(client, serverID), b, nil, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -67,20 +67,23 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns public data about a previously uploaded KeyPair.
|
||||
func Get(client *gophercloud.ServiceClient, name string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, name), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, name), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete requests the deletion of a previous stored KeyPair from the server.
|
||||
func Delete(client *gophercloud.ServiceClient, name string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, name), nil)
|
||||
resp, err := client.Delete(deleteURL(client, name), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -48,20 +48,23 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns data about a previously created ServerGroup.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete requests the deletion of a previously allocated ServerGroup.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
resp, err := client.Delete(deleteURL(client, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -40,21 +40,24 @@ func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsB
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client, serverID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client, serverID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns public data about a previously created VolumeAttachment.
|
||||
func Get(client *gophercloud.ServiceClient, serverID, attachmentID string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, serverID, attachmentID), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, serverID, attachmentID), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete requests the deletion of a previous stored VolumeAttachment from
|
||||
// the server.
|
||||
func Delete(client *gophercloud.ServiceClient, serverID, attachmentID string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, serverID, attachmentID), nil)
|
||||
resp, err := client.Delete(deleteURL(client, serverID, attachmentID), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
69
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
69
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
|
@ -142,22 +142,25 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves details of a single flavor. Use Extract to convert its
|
||||
// result into a Flavor.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes the specified flavor ID.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
resp, err := client.Delete(deleteURL(client, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -194,9 +197,10 @@ func AddAccess(client *gophercloud.ServiceClient, id string, opts AddAccessOptsB
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(accessActionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -224,20 +228,23 @@ func RemoveAccess(client *gophercloud.ServiceClient, id string, opts RemoveAcces
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(accessActionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
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)
|
||||
resp, err := client.Get(extraSpecsListURL(client, flavorID), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
func GetExtraSpec(client *gophercloud.ServiceClient, flavorID string, key string) (r GetExtraSpecResult) {
|
||||
_, r.Err = client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil)
|
||||
resp, err := client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -264,9 +271,10 @@ func CreateExtraSpecs(client *gophercloud.ServiceClient, flavorID string, opts C
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(extraSpecsCreateURL(client, flavorID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(extraSpecsCreateURL(client, flavorID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -302,56 +310,19 @@ func UpdateExtraSpec(client *gophercloud.ServiceClient, flavorID string, opts Up
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(extraSpecUpdateURL(client, flavorID, key), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(extraSpecUpdateURL(client, flavorID, key), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteExtraSpec will delete the key-value pair with the given key for the given
|
||||
// flavor ID.
|
||||
func DeleteExtraSpec(client *gophercloud.ServiceClient, flavorID, key string) (r DeleteExtraSpecResult) {
|
||||
_, r.Err = client.Delete(extraSpecDeleteURL(client, flavorID, key), &gophercloud.RequestOpts{
|
||||
resp, err := client.Delete(extraSpecDeleteURL(client, flavorID, key), &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convienience function that returns a flavor's ID given its
|
||||
// name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
allPages, err := ListDetail(client, nil).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractFlavors(allPages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, f := range all {
|
||||
if f.Name == name {
|
||||
count++
|
||||
id = f.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
err := &gophercloud.ErrResourceNotFound{}
|
||||
err.ResourceType = "flavor"
|
||||
err.Name = name
|
||||
return "", err
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
err := &gophercloud.ErrMultipleResourcesFound{}
|
||||
err.ResourceType = "flavor"
|
||||
err.Name = name
|
||||
err.Count = count
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
Package images provides information and interaction with the images through
|
||||
the OpenStack Compute service.
|
||||
|
||||
This API is deprecated and will be removed from a future version of the Nova
|
||||
API service.
|
||||
|
||||
An image is a collection of files used to create or rebuild a server.
|
||||
Operators provide a number of pre-built OS images by default. You may also
|
||||
create custom images from cloud servers you have launched.
|
||||
|
||||
Example to List Images
|
||||
|
||||
listOpts := images.ListOpts{
|
||||
Limit: 2,
|
||||
}
|
||||
|
||||
allPages, err := images.ListDetail(computeClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allImages, err := images.ExtractImages(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, image := range allImages {
|
||||
fmt.Printf("%+v\n", image)
|
||||
}
|
||||
*/
|
||||
package images
|
109
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/requests.go
generated
vendored
109
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/requests.go
generated
vendored
|
@ -1,109 +0,0 @@
|
|||
package images
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||
// ListDetail request.
|
||||
type ListOptsBuilder interface {
|
||||
ToImageListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts contain options filtering Images returned from a call to ListDetail.
|
||||
type ListOpts struct {
|
||||
// ChangesSince filters Images based on the last changed status (in date-time
|
||||
// format).
|
||||
ChangesSince string `q:"changes-since"`
|
||||
|
||||
// Limit limits the number of Images to return.
|
||||
Limit int `q:"limit"`
|
||||
|
||||
// Mark is an Image UUID at which to set a marker.
|
||||
Marker string `q:"marker"`
|
||||
|
||||
// Name is the name of the Image.
|
||||
Name string `q:"name"`
|
||||
|
||||
// Server is the name of the Server (in URL format).
|
||||
Server string `q:"server"`
|
||||
|
||||
// Status is the current status of the Image.
|
||||
Status string `q:"status"`
|
||||
|
||||
// Type is the type of image (e.g. BASE, SERVER, ALL).
|
||||
Type string `q:"type"`
|
||||
}
|
||||
|
||||
// ToImageListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToImageListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// ListDetail enumerates the available images.
|
||||
func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := listDetailURL(client)
|
||||
if opts != nil {
|
||||
query, err := opts.ToImageListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return ImagePage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// Get returns data about a specific image by its ID.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes the specified image ID.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convienience function that returns an image's ID given its
|
||||
// name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
allPages, err := ListDetail(client, nil).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractImages(allPages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, f := range all {
|
||||
if f.Name == name {
|
||||
count++
|
||||
id = f.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
err := &gophercloud.ErrResourceNotFound{}
|
||||
err.ResourceType = "image"
|
||||
err.Name = name
|
||||
return "", err
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
err := &gophercloud.ErrMultipleResourcesFound{}
|
||||
err.ResourceType = "image"
|
||||
err.Name = name
|
||||
err.Count = count
|
||||
return "", err
|
||||
}
|
||||
}
|
95
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/results.go
generated
vendored
95
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/results.go
generated
vendored
|
@ -1,95 +0,0 @@
|
|||
package images
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// GetResult is the response from a Get operation. Call its Extract method to
|
||||
// interpret it as an Image.
|
||||
type GetResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// DeleteResult is the result from a Delete operation. Call its ExtractErr
|
||||
// method to determine if the call succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// Extract interprets a GetResult as an Image.
|
||||
func (r GetResult) Extract() (*Image, error) {
|
||||
var s struct {
|
||||
Image *Image `json:"image"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Image, err
|
||||
}
|
||||
|
||||
// Image represents an Image returned by the Compute API.
|
||||
type Image struct {
|
||||
// ID is the unique ID of an image.
|
||||
ID string
|
||||
|
||||
// Created is the date when the image was created.
|
||||
Created string
|
||||
|
||||
// MinDisk is the minimum amount of disk a flavor must have to be able
|
||||
// to create a server based on the image, measured in GB.
|
||||
MinDisk int
|
||||
|
||||
// MinRAM is the minimum amount of RAM a flavor must have to be able
|
||||
// to create a server based on the image, measured in MB.
|
||||
MinRAM int
|
||||
|
||||
// Name provides a human-readable moniker for the OS image.
|
||||
Name string
|
||||
|
||||
// The Progress and Status fields indicate image-creation status.
|
||||
Progress int
|
||||
|
||||
// Status is the current status of the image.
|
||||
Status string
|
||||
|
||||
// Update is the date when the image was updated.
|
||||
Updated string
|
||||
|
||||
// Metadata provides free-form key/value pairs that further describe the
|
||||
// image.
|
||||
Metadata map[string]interface{}
|
||||
}
|
||||
|
||||
// ImagePage contains a single page of all Images returne from a ListDetail
|
||||
// operation. Use ExtractImages to convert it into a slice of usable structs.
|
||||
type ImagePage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if an ImagePage contains no Image results.
|
||||
func (page ImagePage) IsEmpty() (bool, error) {
|
||||
images, err := ExtractImages(page)
|
||||
return len(images) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||
// next page of results.
|
||||
func (page ImagePage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"images_links"`
|
||||
}
|
||||
err := page.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// ExtractImages converts a page of List results into a slice of usable Image
|
||||
// structs.
|
||||
func ExtractImages(r pagination.Page) ([]Image, error) {
|
||||
var s struct {
|
||||
Images []Image `json:"images"`
|
||||
}
|
||||
err := (r.(ImagePage)).ExtractInto(&s)
|
||||
return s.Images, err
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package images
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func listDetailURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("images", "detail")
|
||||
}
|
||||
|
||||
func getURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("images", id)
|
||||
}
|
||||
|
||||
func deleteURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("images", id)
|
||||
}
|
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/BUILD.bazel
generated
vendored
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/BUILD.bazel
generated
vendored
|
@ -15,8 +15,6 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
178
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
178
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
|
@ -6,8 +6,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/images"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
|
@ -148,24 +146,14 @@ type CreateOpts struct {
|
|||
// Name is the name to assign to the newly launched server.
|
||||
Name string `json:"name" required:"true"`
|
||||
|
||||
// ImageRef [optional; required if ImageName is not provided] is the ID or
|
||||
// full URL to the image that contains the server's OS and initial state.
|
||||
// ImageRef is the ID or full URL to the image that contains the
|
||||
// server's OS and initial state.
|
||||
// Also optional if using the boot-from-volume extension.
|
||||
ImageRef string `json:"imageRef"`
|
||||
|
||||
// ImageName [optional; required if ImageRef is not provided] is the name of
|
||||
// the image that contains the server's OS and initial state.
|
||||
// Also optional if using the boot-from-volume extension.
|
||||
ImageName string `json:"-"`
|
||||
|
||||
// FlavorRef [optional; required if FlavorName is not provided] is the ID or
|
||||
// full URL to the flavor that describes the server's specs.
|
||||
// FlavorRef is the ID or full URL to the flavor that describes the server's specs.
|
||||
FlavorRef string `json:"flavorRef"`
|
||||
|
||||
// FlavorName [optional; required if FlavorRef is not provided] is the name of
|
||||
// the flavor that describes the server's specs.
|
||||
FlavorName string `json:"-"`
|
||||
|
||||
// SecurityGroups lists the names of the security groups to which this server
|
||||
// should belong.
|
||||
SecurityGroups []string `json:"-"`
|
||||
|
@ -223,7 +211,6 @@ type CreateOpts struct {
|
|||
// ToServerCreateMap assembles a request body based on the contents of a
|
||||
// CreateOpts.
|
||||
func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
|
||||
sc := opts.ServiceClient
|
||||
opts.ServiceClient = nil
|
||||
b, err := gophercloud.BuildRequestBody(opts, "")
|
||||
if err != nil {
|
||||
|
@ -274,42 +261,6 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// If ImageRef isn't provided, check if ImageName was provided to ascertain
|
||||
// the image ID.
|
||||
if opts.ImageRef == "" {
|
||||
if opts.ImageName != "" {
|
||||
if sc == nil {
|
||||
err := ErrNoClientProvidedForIDByName{}
|
||||
err.Argument = "ServiceClient"
|
||||
return nil, err
|
||||
}
|
||||
imageID, err := images.IDFromName(sc, opts.ImageName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b["imageRef"] = imageID
|
||||
}
|
||||
}
|
||||
|
||||
// If FlavorRef isn't provided, use FlavorName to ascertain the flavor ID.
|
||||
if opts.FlavorRef == "" {
|
||||
if opts.FlavorName == "" {
|
||||
err := ErrNeitherFlavorIDNorFlavorNameProvided{}
|
||||
err.Argument = "FlavorRef/FlavorName"
|
||||
return nil, err
|
||||
}
|
||||
if sc == nil {
|
||||
err := ErrNoClientProvidedForIDByName{}
|
||||
err.Argument = "ServiceClient"
|
||||
return nil, err
|
||||
}
|
||||
flavorID, err := flavors.IDFromName(sc, opts.FlavorName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b["flavorRef"] = flavorID
|
||||
}
|
||||
|
||||
if opts.Min != 0 {
|
||||
b["min_count"] = opts.Min
|
||||
}
|
||||
|
@ -328,28 +279,32 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(listURL(client), reqBody, &r.Body, nil)
|
||||
resp, err := client.Post(listURL(client), reqBody, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete requests that a server previously provisioned be removed from your
|
||||
// account.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
resp, err := client.Delete(deleteURL(client, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// ForceDelete forces the deletion of a server.
|
||||
func ForceDelete(client *gophercloud.ServiceClient, id string) (r ActionResult) {
|
||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"forceDelete": ""}, nil, nil)
|
||||
resp, err := client.Post(actionURL(client, id), map[string]interface{}{"forceDelete": ""}, nil, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get requests details on a single server, by ID.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Get(getURL(client, id), &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -386,9 +341,10 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -400,7 +356,8 @@ func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword stri
|
|||
"adminPass": newPassword,
|
||||
},
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
|
||||
resp, err := client.Post(actionURL(client, id), b, nil, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -441,7 +398,7 @@ func (opts RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
|
|||
HardReboot (aka PowerCycle) starts the server instance by physically cutting
|
||||
power to the machine, or if a VM, terminating it at the hypervisor level.
|
||||
It's done. Caput. Full stop.
|
||||
Then, after a brief while, power is rtored or the VM instance restarted.
|
||||
Then, after a brief while, power is restored or the VM instance restarted.
|
||||
|
||||
SoftReboot (aka OSReboot) simply tells the OS to restart under its own
|
||||
procedure.
|
||||
|
@ -454,7 +411,8 @@ func Reboot(client *gophercloud.ServiceClient, id string, opts RebootOptsBuilder
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
|
||||
resp, err := client.Post(actionURL(client, id), b, nil, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -470,11 +428,8 @@ type RebuildOpts struct {
|
|||
// AdminPass is the server's admin password
|
||||
AdminPass string `json:"adminPass,omitempty"`
|
||||
|
||||
// ImageID is the ID of the image you want your server to be provisioned on.
|
||||
ImageID string `json:"imageRef"`
|
||||
|
||||
// ImageName is readable name of an image.
|
||||
ImageName string `json:"-"`
|
||||
// ImageRef is the ID of the image you want your server to be provisioned on.
|
||||
ImageRef string `json:"imageRef"`
|
||||
|
||||
// Name to set the server to
|
||||
Name string `json:"name,omitempty"`
|
||||
|
@ -505,23 +460,6 @@ func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// If ImageRef isn't provided, check if ImageName was provided to ascertain
|
||||
// the image ID.
|
||||
if opts.ImageID == "" {
|
||||
if opts.ImageName != "" {
|
||||
if opts.ServiceClient == nil {
|
||||
err := ErrNoClientProvidedForIDByName{}
|
||||
err.Argument = "ServiceClient"
|
||||
return nil, err
|
||||
}
|
||||
imageID, err := images.IDFromName(opts.ServiceClient, opts.ImageName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b["imageRef"] = imageID
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]interface{}{"rebuild": b}, nil
|
||||
}
|
||||
|
||||
|
@ -533,7 +471,8 @@ func Rebuild(client *gophercloud.ServiceClient, id string, opts RebuildOptsBuild
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, nil)
|
||||
resp, err := client.Post(actionURL(client, id), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -571,23 +510,26 @@ func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
|
||||
resp, err := client.Post(actionURL(client, id), b, nil, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// ConfirmResize confirms a previous resize operation on a server.
|
||||
// See Resize() for more details.
|
||||
func ConfirmResize(client *gophercloud.ServiceClient, id string) (r ActionResult) {
|
||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"confirmResize": nil}, nil, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(actionURL(client, id), map[string]interface{}{"confirmResize": nil}, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{201, 202, 204},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// RevertResize cancels a previous resize operation on a server.
|
||||
// See Resize() for more details.
|
||||
func RevertResize(client *gophercloud.ServiceClient, id string) (r ActionResult) {
|
||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"revertResize": nil}, nil, nil)
|
||||
resp, err := client.Post(actionURL(client, id), map[string]interface{}{"revertResize": nil}, nil, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -623,15 +565,17 @@ func ResetMetadata(client *gophercloud.ServiceClient, id string, opts ResetMetad
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(metadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(metadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Metadata requests all the metadata for the given server ID.
|
||||
func Metadata(client *gophercloud.ServiceClient, id string) (r GetMetadataResult) {
|
||||
_, r.Err = client.Get(metadataURL(client, id), &r.Body, nil)
|
||||
resp, err := client.Get(metadataURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -650,9 +594,10 @@ func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMet
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(metadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(metadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -690,23 +635,26 @@ func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts Metadatu
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(metadatumURL(client, id, key), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(metadatumURL(client, id, key), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Metadatum requests the key-value pair with the given key for the given
|
||||
// server ID.
|
||||
func Metadatum(client *gophercloud.ServiceClient, id, key string) (r GetMetadatumResult) {
|
||||
_, r.Err = client.Get(metadatumURL(client, id, key), &r.Body, nil)
|
||||
resp, err := client.Get(metadatumURL(client, id, key), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteMetadatum will delete the key-value pair with the given key for the
|
||||
// given server ID.
|
||||
func DeleteMetadatum(client *gophercloud.ServiceClient, id, key string) (r DeleteMetadatumResult) {
|
||||
_, r.Err = client.Delete(metadatumURL(client, id, key), nil)
|
||||
resp, err := client.Delete(metadatumURL(client, id, key), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -759,52 +707,15 @@ func CreateImage(client *gophercloud.ServiceClient, id string, opts CreateImageO
|
|||
resp, err := client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
r.Err = err
|
||||
r.Header = resp.Header
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convienience function that returns a server's ID given its
|
||||
// name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
allPages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractServers(allPages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, f := range all {
|
||||
if f.Name == name {
|
||||
count++
|
||||
id = f.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "server"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "server"}
|
||||
}
|
||||
}
|
||||
|
||||
// GetPassword makes a request against the nova API to get the encrypted
|
||||
// administrative password.
|
||||
func GetPassword(client *gophercloud.ServiceClient, serverId string) (r GetPasswordResult) {
|
||||
_, r.Err = client.Get(passwordURL(client, serverId), &r.Body, nil)
|
||||
resp, err := client.Get(passwordURL(client, serverId), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -833,8 +744,9 @@ func ShowConsoleOutput(client *gophercloud.ServiceClient, id string, opts ShowCo
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
12
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/requests.go
generated
vendored
12
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/requests.go
generated
vendored
|
@ -57,7 +57,8 @@ func ListByZone(client *gophercloud.ServiceClient, zoneID string, opts ListOptsB
|
|||
|
||||
// Get implements the recordset Get request.
|
||||
func Get(client *gophercloud.ServiceClient, zoneID string, rrsetID string) (r GetResult) {
|
||||
_, r.Err = client.Get(rrsetURL(client, zoneID, rrsetID), &r.Body, nil)
|
||||
resp, err := client.Get(rrsetURL(client, zoneID, rrsetID), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -103,9 +104,10 @@ func Create(client *gophercloud.ServiceClient, zoneID string, opts CreateOptsBui
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(baseURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(baseURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{201, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -158,16 +160,18 @@ func Update(client *gophercloud.ServiceClient, zoneID string, rrsetID string, op
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(rrsetURL(client, zoneID, rrsetID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(rrsetURL(client, zoneID, rrsetID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete removes an existing RecordSet.
|
||||
func Delete(client *gophercloud.ServiceClient, zoneID string, rrsetID string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(rrsetURL(client, zoneID, rrsetID), &gophercloud.RequestOpts{
|
||||
resp, err := client.Delete(rrsetURL(client, zoneID, rrsetID), &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -55,7 +55,8 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa
|
|||
|
||||
// Get returns information about a zone, given its ID.
|
||||
func Get(client *gophercloud.ServiceClient, zoneID string) (r GetResult) {
|
||||
_, r.Err = client.Get(zoneURL(client, zoneID), &r.Body, nil)
|
||||
resp, err := client.Get(zoneURL(client, zoneID), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -110,9 +111,10 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{201, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -158,17 +160,19 @@ func Update(client *gophercloud.ServiceClient, zoneID string, opts UpdateOptsBui
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Patch(zoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Patch(zoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete implements a zone delete request.
|
||||
func Delete(client *gophercloud.ServiceClient, zoneID string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(zoneURL(client, zoneID), &gophercloud.RequestOpts{
|
||||
resp, err := client.Delete(zoneURL(client, zoneID), &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
JSONResponse: &r.Body,
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example of Creating a Service Client
|
|||
|
||||
ao, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(ao)
|
||||
client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
|
||||
client, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
|
||||
Region: os.Getenv("OS_REGION_NAME"),
|
||||
})
|
||||
*/
|
||||
|
|
12
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
12
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
|
@ -60,15 +60,17 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get requests details on a single tenant by ID.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -103,14 +105,16 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(updateURL(client, id), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete is the operation responsible for permanently deleting a tenant.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
resp, err := client.Delete(deleteURL(client, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
6
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
generated
vendored
6
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
generated
vendored
|
@ -87,17 +87,19 @@ func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) (r Creat
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(CreateURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Post(CreateURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 203},
|
||||
MoreHeaders: map[string]string{"X-Auth-Token": ""},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get validates and retrieves information for user's token.
|
||||
func Get(client *gophercloud.ServiceClient, token string) (r GetResult) {
|
||||
_, r.Err = client.Get(GetURL(client, token), &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Get(GetURL(client, token), &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
17
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/BUILD.bazel
generated
vendored
Normal file
17
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/BUILD.bazel
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"requests.go",
|
||||
"urls.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens",
|
||||
importpath = "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens:go_default_library",
|
||||
],
|
||||
)
|
41
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/doc.go
generated
vendored
Normal file
41
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Package tokens provides information and interaction with the EC2 token API
|
||||
resource for the OpenStack Identity service.
|
||||
|
||||
For more information, see:
|
||||
https://docs.openstack.org/api-ref/identity/v2-ext/
|
||||
|
||||
Example to Create a Token From an EC2 access and secret keys
|
||||
|
||||
var authOptions tokens.AuthOptionsBuilder
|
||||
authOptions = &ec2tokens.AuthOptions{
|
||||
Access: "a7f1e798b7c2417cba4a02de97dc3cdc",
|
||||
Secret: "18f4f6761ada4e3795fa5273c30349b9",
|
||||
}
|
||||
|
||||
token, err := ec2tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to auth a client using EC2 access and secret keys
|
||||
|
||||
client, err := openstack.NewClient("http://localhost:5000/v3")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var authOptions tokens.AuthOptionsBuilder
|
||||
authOptions = &ec2tokens.AuthOptions{
|
||||
Access: "a7f1e798b7c2417cba4a02de97dc3cdc",
|
||||
Secret: "18f4f6761ada4e3795fa5273c30349b9",
|
||||
AllowReauth: true,
|
||||
}
|
||||
|
||||
err = openstack.AuthenticateV3(client, authOptions, gophercloud.EndpointOpts{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
*/
|
||||
package ec2tokens
|
377
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/requests.go
generated
vendored
Normal file
377
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,377 @@
|
|||
package ec2tokens
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
)
|
||||
|
||||
const (
|
||||
// EC2CredentialsAwsRequestV4 is a constant, used to generate AWS
|
||||
// Credential V4.
|
||||
EC2CredentialsAwsRequestV4 = "aws4_request"
|
||||
// EC2CredentialsHmacSha1V2 is a HMAC SHA1 signature method. Used to
|
||||
// generate AWS Credential V2.
|
||||
EC2CredentialsHmacSha1V2 = "HmacSHA1"
|
||||
// EC2CredentialsHmacSha256V2 is a HMAC SHA256 signature method. Used
|
||||
// to generate AWS Credential V2.
|
||||
EC2CredentialsHmacSha256V2 = "HmacSHA256"
|
||||
// EC2CredentialsAwsHmacV4 is an AWS signature V4 signing method.
|
||||
// More details:
|
||||
// https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
|
||||
EC2CredentialsAwsHmacV4 = "AWS4-HMAC-SHA256"
|
||||
// EC2CredentialsTimestampFormatV4 is an AWS signature V4 timestamp
|
||||
// format.
|
||||
EC2CredentialsTimestampFormatV4 = "20060102T150405Z"
|
||||
// EC2CredentialsDateFormatV4 is an AWS signature V4 date format.
|
||||
EC2CredentialsDateFormatV4 = "20060102"
|
||||
)
|
||||
|
||||
// AuthOptions represents options for authenticating a user using EC2 credentials.
|
||||
type AuthOptions struct {
|
||||
// Access is the EC2 Credential Access ID.
|
||||
Access string `json:"access" required:"true"`
|
||||
// Secret is the EC2 Credential Secret, used to calculate signature.
|
||||
// Not used, when a Signature is is.
|
||||
Secret string `json:"-"`
|
||||
// Host is a HTTP request Host header. Used to calculate an AWS
|
||||
// signature V2. For signature V4 set the Host inside Headers map.
|
||||
// Optional.
|
||||
Host string `json:"host"`
|
||||
// Path is a HTTP request path. Optional.
|
||||
Path string `json:"path"`
|
||||
// Verb is a HTTP request method. Optional.
|
||||
Verb string `json:"verb"`
|
||||
// Headers is a map of HTTP request headers. Optional.
|
||||
Headers map[string]string `json:"headers"`
|
||||
// Region is a region name to calculate an AWS signature V4. Optional.
|
||||
Region string `json:"-"`
|
||||
// Service is a service name to calculate an AWS signature V4. Optional.
|
||||
Service string `json:"-"`
|
||||
// Params is a map of GET method parameters. Optional.
|
||||
Params map[string]string `json:"params"`
|
||||
// AllowReauth allows Gophercloud to re-authenticate automatically
|
||||
// if/when your token expires.
|
||||
AllowReauth bool `json:"-"`
|
||||
// Signature can be either a []byte (encoded to base64 automatically) or
|
||||
// a string. You can set the singature explicitly, when you already know
|
||||
// it. In this case default Params won't be automatically set. Optional.
|
||||
Signature interface{} `json:"signature"`
|
||||
// BodyHash is a HTTP request body sha256 hash. When nil and Signature
|
||||
// is not set, a random hash is generated. Optional.
|
||||
BodyHash *string `json:"body_hash"`
|
||||
// Timestamp is a timestamp to calculate a V4 signature. Optional.
|
||||
Timestamp *time.Time `json:"-"`
|
||||
// Token is a []byte string (encoded to base64 automatically) which was
|
||||
// signed by an EC2 secret key. Used by S3 tokens for validation only.
|
||||
// Token must be set with a Signature. If a Signature is not provided,
|
||||
// a Token will be generated automatically along with a Signature.
|
||||
Token []byte `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildCanonicalQueryStringV2 builds a canonical query string
|
||||
// for an AWS signature V2.
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L133
|
||||
func EC2CredentialsBuildCanonicalQueryStringV2(params map[string]string) string {
|
||||
var keys []string
|
||||
for k := range params {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
var pairs []string
|
||||
for _, k := range keys {
|
||||
pairs = append(pairs, fmt.Sprintf("%s=%s", k, url.QueryEscape(params[k])))
|
||||
}
|
||||
|
||||
return strings.Join(pairs, "&")
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildStringToSignV2 builds a string to sign an AWS signature
|
||||
// V2.
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L148
|
||||
func EC2CredentialsBuildStringToSignV2(opts AuthOptions) []byte {
|
||||
stringToSign := strings.Join([]string{
|
||||
opts.Verb,
|
||||
opts.Host,
|
||||
opts.Path,
|
||||
}, "\n")
|
||||
|
||||
return []byte(strings.Join([]string{
|
||||
stringToSign,
|
||||
EC2CredentialsBuildCanonicalQueryStringV2(opts.Params),
|
||||
}, "\n"))
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildCanonicalQueryStringV2 builds a canonical query string
|
||||
// for an AWS signature V4.
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L244
|
||||
func EC2CredentialsBuildCanonicalQueryStringV4(verb string, params map[string]string) string {
|
||||
if verb == "POST" {
|
||||
return ""
|
||||
}
|
||||
return EC2CredentialsBuildCanonicalQueryStringV2(params)
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildCanonicalHeadersV4 builds a canonical string based on
|
||||
// "headers" map and "signedHeaders" string parameters.
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L216
|
||||
func EC2CredentialsBuildCanonicalHeadersV4(headers map[string]string, signedHeaders string) string {
|
||||
headersLower := make(map[string]string, len(headers))
|
||||
for k, v := range headers {
|
||||
headersLower[strings.ToLower(k)] = v
|
||||
}
|
||||
|
||||
var headersList []string
|
||||
for _, h := range strings.Split(signedHeaders, ";") {
|
||||
if v, ok := headersLower[h]; ok {
|
||||
headersList = append(headersList, h+":"+v)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(headersList, "\n") + "\n"
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildSignatureKeyV4 builds a HMAC 256 signature key based on
|
||||
// input parameters.
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L169
|
||||
func EC2CredentialsBuildSignatureKeyV4(secret, region, service string, date time.Time) []byte {
|
||||
kDate := sumHMAC256([]byte("AWS4"+secret), []byte(date.Format(EC2CredentialsDateFormatV4)))
|
||||
kRegion := sumHMAC256(kDate, []byte(region))
|
||||
kService := sumHMAC256(kRegion, []byte(service))
|
||||
return sumHMAC256(kService, []byte(EC2CredentialsAwsRequestV4))
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildStringToSignV4 builds an AWS v4 signature string to sign
|
||||
// based on input parameters.
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L251
|
||||
func EC2CredentialsBuildStringToSignV4(opts AuthOptions, signedHeaders string, bodyHash string, date time.Time) []byte {
|
||||
scope := strings.Join([]string{
|
||||
date.Format(EC2CredentialsDateFormatV4),
|
||||
opts.Region,
|
||||
opts.Service,
|
||||
EC2CredentialsAwsRequestV4,
|
||||
}, "/")
|
||||
|
||||
canonicalRequest := strings.Join([]string{
|
||||
opts.Verb,
|
||||
opts.Path,
|
||||
EC2CredentialsBuildCanonicalQueryStringV4(opts.Verb, opts.Params),
|
||||
EC2CredentialsBuildCanonicalHeadersV4(opts.Headers, signedHeaders),
|
||||
signedHeaders,
|
||||
bodyHash,
|
||||
}, "\n")
|
||||
hash := sha256.Sum256([]byte(canonicalRequest))
|
||||
|
||||
return []byte(strings.Join([]string{
|
||||
EC2CredentialsAwsHmacV4,
|
||||
date.Format(EC2CredentialsTimestampFormatV4),
|
||||
scope,
|
||||
hex.EncodeToString(hash[:]),
|
||||
}, "\n"))
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildSignatureV4 builds an AWS v4 signature based on input
|
||||
// parameters.
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L285..L286
|
||||
func EC2CredentialsBuildSignatureV4(key []byte, stringToSign []byte) string {
|
||||
return hex.EncodeToString(sumHMAC256(key, stringToSign))
|
||||
}
|
||||
|
||||
// EC2CredentialsBuildAuthorizationHeaderV4 builds an AWS v4 Authorization
|
||||
// header based on auth parameters, date and signature
|
||||
func EC2CredentialsBuildAuthorizationHeaderV4(opts AuthOptions, signedHeaders string, signature string, date time.Time) string {
|
||||
return fmt.Sprintf("%s Credential=%s/%s/%s/%s/%s, SignedHeaders=%s, Signature=%s",
|
||||
EC2CredentialsAwsHmacV4,
|
||||
opts.Access,
|
||||
date.Format(EC2CredentialsDateFormatV4),
|
||||
opts.Region,
|
||||
opts.Service,
|
||||
EC2CredentialsAwsRequestV4,
|
||||
signedHeaders,
|
||||
signature)
|
||||
}
|
||||
|
||||
// ToTokenV3ScopeMap is a dummy method to satisfy tokens.AuthOptionsBuilder
|
||||
// interface.
|
||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ToTokenV3HeadersMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||
// interface in the v3 tokens package.
|
||||
func (opts *AuthOptions) ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// CanReauth is a method method to satisfy tokens.AuthOptionsBuilder interface
|
||||
func (opts *AuthOptions) CanReauth() bool {
|
||||
return opts.AllowReauth
|
||||
}
|
||||
|
||||
// ToTokenV3CreateMap formats an AuthOptions into a create request.
|
||||
func (opts *AuthOptions) ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "credentials")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.Signature != nil {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// calculate signature, when it is not set
|
||||
c, _ := b["credentials"].(map[string]interface{})
|
||||
h := interfaceToMap(c, "headers")
|
||||
p := interfaceToMap(c, "params")
|
||||
|
||||
// detect and process a signature v2
|
||||
if v, ok := p["SignatureVersion"]; ok && v == "2" {
|
||||
if _, ok := c["body_hash"]; ok {
|
||||
delete(c, "body_hash")
|
||||
}
|
||||
if _, ok := c["headers"]; ok {
|
||||
delete(c, "headers")
|
||||
}
|
||||
if v, ok := p["SignatureMethod"]; ok {
|
||||
// params is a map of strings
|
||||
strToSign := EC2CredentialsBuildStringToSignV2(*opts)
|
||||
switch v {
|
||||
case EC2CredentialsHmacSha1V2:
|
||||
// keystone uses this method only when HmacSHA256 is not available on the server side
|
||||
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L151..L156
|
||||
c["signature"] = sumHMAC1([]byte(opts.Secret), strToSign)
|
||||
return b, nil
|
||||
case EC2CredentialsHmacSha256V2:
|
||||
c["signature"] = sumHMAC256([]byte(opts.Secret), strToSign)
|
||||
return b, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported signature method: %s", v)
|
||||
}
|
||||
return nil, fmt.Errorf("signature method must be provided")
|
||||
} else if ok {
|
||||
return nil, fmt.Errorf("unsupported signature version: %s", v)
|
||||
}
|
||||
|
||||
// it is not a signature v2, but a signature v4
|
||||
date := time.Now().UTC()
|
||||
if opts.Timestamp != nil {
|
||||
date = *opts.Timestamp
|
||||
}
|
||||
if v, _ := c["body_hash"]; v == nil {
|
||||
// when body_hash is not set, generate a random one
|
||||
c["body_hash"] = randomBodyHash()
|
||||
}
|
||||
|
||||
signedHeaders, _ := h["X-Amz-SignedHeaders"]
|
||||
|
||||
stringToSign := EC2CredentialsBuildStringToSignV4(*opts, signedHeaders, c["body_hash"].(string), date)
|
||||
key := EC2CredentialsBuildSignatureKeyV4(opts.Secret, opts.Region, opts.Service, date)
|
||||
c["signature"] = EC2CredentialsBuildSignatureV4(key, stringToSign)
|
||||
h["X-Amz-Date"] = date.Format(EC2CredentialsTimestampFormatV4)
|
||||
h["Authorization"] = EC2CredentialsBuildAuthorizationHeaderV4(*opts, signedHeaders, c["signature"].(string), date)
|
||||
|
||||
// token is only used for S3 tokens validation and will be removed when using EC2 validation
|
||||
c["token"] = stringToSign
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Create authenticates and either generates a new token from EC2 credentials
|
||||
func Create(c *gophercloud.ServiceClient, opts tokens.AuthOptionsBuilder) (r tokens.CreateResult) {
|
||||
b, err := opts.ToTokenV3CreateMap(nil)
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
// delete "token" element, since it is used in s3tokens
|
||||
deleteBodyElements(b, "token")
|
||||
|
||||
resp, err := c.Post(ec2tokensURL(c), b, &r.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: map[string]string{"X-Auth-Token": ""},
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// ValidateS3Token authenticates an S3 request using EC2 credentials. Doesn't
|
||||
// generate a new token ID, but returns a tokens.CreateResult.
|
||||
func ValidateS3Token(c *gophercloud.ServiceClient, opts tokens.AuthOptionsBuilder) (r tokens.CreateResult) {
|
||||
b, err := opts.ToTokenV3CreateMap(nil)
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
// delete unused element, since it is used in ec2tokens only
|
||||
deleteBodyElements(b, "body_hash", "headers", "host", "params", "path", "verb")
|
||||
|
||||
resp, err := c.Post(s3tokensURL(c), b, &r.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: map[string]string{"X-Auth-Token": ""},
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// The following are small helper functions used to help build the signature.
|
||||
|
||||
// sumHMAC1 is a func to implement the HMAC SHA1 signature method.
|
||||
func sumHMAC1(key []byte, data []byte) []byte {
|
||||
hash := hmac.New(sha1.New, key)
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
// sumHMAC256 is a func to implement the HMAC SHA256 signature method.
|
||||
func sumHMAC256(key []byte, data []byte) []byte {
|
||||
hash := hmac.New(sha256.New, key)
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
// randomBodyHash is a func to generate a random sha256 hexdigest.
|
||||
func randomBodyHash() string {
|
||||
h := make([]byte, 64)
|
||||
rand.Read(h)
|
||||
return hex.EncodeToString(h)
|
||||
}
|
||||
|
||||
// interfaceToMap is a func used to represent a "credentials" map element as a
|
||||
// "map[string]string"
|
||||
func interfaceToMap(c map[string]interface{}, key string) map[string]string {
|
||||
// convert map[string]interface{} to map[string]string
|
||||
m := make(map[string]string)
|
||||
if v, _ := c[key].(map[string]interface{}); v != nil {
|
||||
for k, v := range v {
|
||||
m[k] = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
c[key] = m
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// deleteBodyElements deletes map body elements
|
||||
func deleteBodyElements(b map[string]interface{}, elements ...string) {
|
||||
if c, ok := b["credentials"].(map[string]interface{}); ok {
|
||||
for _, k := range elements {
|
||||
if _, ok := c[k]; ok {
|
||||
delete(c, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/urls.go
generated
vendored
Normal file
11
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package ec2tokens
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func ec2tokensURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("ec2tokens")
|
||||
}
|
||||
|
||||
func s3tokensURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("s3tokens")
|
||||
}
|
|
@ -8,11 +8,12 @@ go_library(
|
|||
"results.go",
|
||||
"urls.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images",
|
||||
importpath = "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
|
||||
importmap = "k8s.io/kops/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1",
|
||||
importpath = "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
||||
],
|
||||
)
|
123
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/doc.go
generated
vendored
Normal file
123
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
Package oauth1 enables management of OpenStack OAuth1 tokens and Authentication.
|
||||
|
||||
Example to Create an OAuth1 Consumer
|
||||
|
||||
createConsumerOpts := oauth1.CreateConsumerOpts{
|
||||
Description: "My consumer",
|
||||
}
|
||||
consumer, err := oauth1.CreateConsumer(identityClient, createConsumerOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// NOTE: Consumer secret is available only on create response
|
||||
fmt.Printf("Consumer: %+v\n", consumer)
|
||||
|
||||
Example to Request an unauthorized OAuth1 token
|
||||
|
||||
requestTokenOpts := oauth1.RequestTokenOpts{
|
||||
OAuthConsumerKey: consumer.ID,
|
||||
OAuthConsumerSecret: consumer.Secret,
|
||||
OAuthSignatureMethod: oauth1.HMACSHA1,
|
||||
RequestedProjectID: projectID,
|
||||
}
|
||||
requestToken, err := oauth1.RequestToken(identityClient, requestTokenOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// NOTE: Request token secret is available only on request response
|
||||
fmt.Printf("Request token: %+v\n", requestToken)
|
||||
|
||||
Example to Authorize an unauthorized OAuth1 token
|
||||
|
||||
authorizeTokenOpts := oauth1.AuthorizeTokenOpts{
|
||||
Roles: []oauth1.Role{
|
||||
{Name: "member"},
|
||||
},
|
||||
}
|
||||
authToken, err := oauth1.AuthorizeToken(identityClient, requestToken.OAuthToken, authorizeTokenOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Verifier ID of the unauthorized Token: %+v\n", authToken.OAuthVerifier)
|
||||
|
||||
Example to Create an OAuth1 Access Token
|
||||
|
||||
accessTokenOpts := oauth1.CreateAccessTokenOpts{
|
||||
OAuthConsumerKey: consumer.ID,
|
||||
OAuthConsumerSecret: consumer.Secret,
|
||||
OAuthToken: requestToken.OAuthToken,
|
||||
OAuthTokenSecret: requestToken.OAuthTokenSecret,
|
||||
OAuthVerifier: authToken.OAuthVerifier,
|
||||
OAuthSignatureMethod: oauth1.HMACSHA1,
|
||||
}
|
||||
accessToken, err := oauth1.CreateAccessToken(identityClient, accessTokenOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// NOTE: Access token secret is available only on create response
|
||||
fmt.Printf("OAuth1 Access Token: %+v\n", accessToken)
|
||||
|
||||
Example to List User's OAuth1 Access Tokens
|
||||
|
||||
allPages, err := oauth1.ListAccessTokens(identityClient, userID).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
accessTokens, err := oauth1.ExtractAccessTokens(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, accessToken := range accessTokens {
|
||||
fmt.Printf("Access Token: %+v\n", accessToken)
|
||||
}
|
||||
|
||||
Example to Authenticate a client using OAuth1 method
|
||||
|
||||
client, err := openstack.NewClient("http://localhost:5000/v3")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
authOptions := &oauth1.AuthOptions{
|
||||
// consumer token, created earlier
|
||||
OAuthConsumerKey: consumer.ID,
|
||||
OAuthConsumerSecret: consumer.Secret,
|
||||
// access token, created earlier
|
||||
OAuthToken: accessToken.OAuthToken,
|
||||
OAuthTokenSecret: accessToken.OAuthTokenSecret,
|
||||
OAuthSignatureMethod: oauth1.HMACSHA1,
|
||||
}
|
||||
err = openstack.AuthenticateV3(client, authOptions, gophercloud.EndpointOpts{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token using OAuth1 method
|
||||
|
||||
var oauth1Token struct {
|
||||
tokens.Token
|
||||
oauth1.TokenExt
|
||||
}
|
||||
|
||||
createOpts := &oauth1.AuthOptions{
|
||||
// consumer token, created earlier
|
||||
OAuthConsumerKey: consumer.ID,
|
||||
OAuthConsumerSecret: consumer.Secret,
|
||||
// access token, created earlier
|
||||
OAuthToken: accessToken.OAuthToken,
|
||||
OAuthTokenSecret: accessToken.OAuthTokenSecret,
|
||||
OAuthSignatureMethod: oauth1.HMACSHA1,
|
||||
}
|
||||
err := tokens.Create(identityClient, createOpts).ExtractInto(&oauth1Token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
*/
|
||||
package oauth1
|
587
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/requests.go
generated
vendored
Normal file
587
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,587 @@
|
|||
package oauth1
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Type SignatureMethod is a OAuth1 SignatureMethod type.
|
||||
type SignatureMethod string
|
||||
|
||||
const (
|
||||
// HMACSHA1 is a recommended OAuth1 signature method.
|
||||
HMACSHA1 SignatureMethod = "HMAC-SHA1"
|
||||
|
||||
// PLAINTEXT signature method is not recommended to be used in
|
||||
// production environment.
|
||||
PLAINTEXT SignatureMethod = "PLAINTEXT"
|
||||
|
||||
// OAuth1TokenContentType is a supported content type for an OAuth1
|
||||
// token.
|
||||
OAuth1TokenContentType = "application/x-www-form-urlencoded"
|
||||
)
|
||||
|
||||
// AuthOptions represents options for authenticating a user using OAuth1 tokens.
|
||||
type AuthOptions struct {
|
||||
// OAuthConsumerKey is the OAuth1 Consumer Key.
|
||||
OAuthConsumerKey string `q:"oauth_consumer_key" required:"true"`
|
||||
|
||||
// OAuthConsumerSecret is the OAuth1 Consumer Secret. Used to generate
|
||||
// an OAuth1 request signature.
|
||||
OAuthConsumerSecret string `required:"true"`
|
||||
|
||||
// OAuthToken is the OAuth1 Request Token.
|
||||
OAuthToken string `q:"oauth_token" required:"true"`
|
||||
|
||||
// OAuthTokenSecret is the OAuth1 Request Token Secret. Used to generate
|
||||
// an OAuth1 request signature.
|
||||
OAuthTokenSecret string `required:"true"`
|
||||
|
||||
// OAuthSignatureMethod is the OAuth1 signature method the Consumer used
|
||||
// to sign the request. Supported values are "HMAC-SHA1" or "PLAINTEXT".
|
||||
// "PLAINTEXT" is not recommended for production usage.
|
||||
OAuthSignatureMethod SignatureMethod `q:"oauth_signature_method" required:"true"`
|
||||
|
||||
// OAuthTimestamp is an OAuth1 request timestamp. If nil, current Unix
|
||||
// timestamp will be used.
|
||||
OAuthTimestamp *time.Time
|
||||
|
||||
// OAuthNonce is an OAuth1 request nonce. Nonce must be a random string,
|
||||
// uniquely generated for each request. Will be generated automatically
|
||||
// when it is not set.
|
||||
OAuthNonce string `q:"oauth_nonce"`
|
||||
|
||||
// AllowReauth allows Gophercloud to re-authenticate automatically
|
||||
// if/when your token expires.
|
||||
AllowReauth bool
|
||||
}
|
||||
|
||||
// ToTokenV3HeadersMap builds the headers required for an OAuth1-based create
|
||||
// request.
|
||||
func (opts AuthOptions) ToTokenV3HeadersMap(headerOpts map[string]interface{}) (map[string]string, error) {
|
||||
q, err := buildOAuth1QueryString(opts, opts.OAuthTimestamp, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signatureKeys := []string{opts.OAuthConsumerSecret, opts.OAuthTokenSecret}
|
||||
|
||||
method := headerOpts["method"].(string)
|
||||
u := headerOpts["url"].(string)
|
||||
stringToSign := buildStringToSign(method, u, q.Query())
|
||||
signature := url.QueryEscape(signString(opts.OAuthSignatureMethod, stringToSign, signatureKeys))
|
||||
|
||||
authHeader := buildAuthHeader(q.Query(), signature)
|
||||
|
||||
headers := map[string]string{
|
||||
"Authorization": authHeader,
|
||||
"X-Auth-Token": "",
|
||||
}
|
||||
|
||||
return headers, nil
|
||||
}
|
||||
|
||||
// ToTokenV3ScopeMap allows AuthOptions to satisfy the tokens.AuthOptionsBuilder
|
||||
// interface.
|
||||
func (opts AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// CanReauth allows AuthOptions to satisfy the tokens.AuthOptionsBuilder
|
||||
// interface.
|
||||
func (opts AuthOptions) CanReauth() bool {
|
||||
return opts.AllowReauth
|
||||
}
|
||||
|
||||
// ToTokenV3CreateMap builds a create request body.
|
||||
func (opts AuthOptions) ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error) {
|
||||
// identityReq defines the "identity" portion of an OAuth1-based authentication
|
||||
// create request body.
|
||||
type identityReq struct {
|
||||
Methods []string `json:"methods"`
|
||||
OAuth1 struct{} `json:"oauth1"`
|
||||
}
|
||||
|
||||
// authReq defines the "auth" portion of an OAuth1-based authentication
|
||||
// create request body.
|
||||
type authReq struct {
|
||||
Identity identityReq `json:"identity"`
|
||||
}
|
||||
|
||||
// oauth1Request defines how an OAuth1-based authentication create
|
||||
// request body looks.
|
||||
type oauth1Request struct {
|
||||
Auth authReq `json:"auth"`
|
||||
}
|
||||
|
||||
var req oauth1Request
|
||||
|
||||
req.Auth.Identity.Methods = []string{"oauth1"}
|
||||
return gophercloud.BuildRequestBody(req, "")
|
||||
}
|
||||
|
||||
// Create authenticates and either generates a new OpenStack token from an
|
||||
// OAuth1 token.
|
||||
func Create(client *gophercloud.ServiceClient, opts tokens.AuthOptionsBuilder) (r tokens.CreateResult) {
|
||||
b, err := opts.ToTokenV3CreateMap(nil)
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
headerOpts := map[string]interface{}{
|
||||
"method": "POST",
|
||||
"url": authURL(client),
|
||||
}
|
||||
|
||||
h, err := opts.ToTokenV3HeadersMap(headerOpts)
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.Post(authURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// CreateConsumerOptsBuilder allows extensions to add additional parameters to
|
||||
// the CreateConsumer request.
|
||||
type CreateConsumerOptsBuilder interface {
|
||||
ToOAuth1CreateConsumerMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateConsumerOpts provides options used to create a new Consumer.
|
||||
type CreateConsumerOpts struct {
|
||||
// Description is the consumer description.
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ToOAuth1CreateConsumerMap formats a CreateConsumerOpts into a create request.
|
||||
func (opts CreateConsumerOpts) ToOAuth1CreateConsumerMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "consumer")
|
||||
}
|
||||
|
||||
// Create creates a new Consumer.
|
||||
func CreateConsumer(client *gophercloud.ServiceClient, opts CreateConsumerOptsBuilder) (r CreateConsumerResult) {
|
||||
b, err := opts.ToOAuth1CreateConsumerMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
resp, err := client.Post(consumersURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes a Consumer.
|
||||
func DeleteConsumer(client *gophercloud.ServiceClient, id string) (r DeleteConsumerResult) {
|
||||
resp, err := client.Delete(consumerURL(client, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// List enumerates Consumers.
|
||||
func ListConsumers(client *gophercloud.ServiceClient) pagination.Pager {
|
||||
return pagination.NewPager(client, consumersURL(client), func(r pagination.PageResult) pagination.Page {
|
||||
return ConsumersPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// GetConsumer retrieves details on a single Consumer by ID.
|
||||
func GetConsumer(client *gophercloud.ServiceClient, id string) (r GetConsumerResult) {
|
||||
resp, err := client.Get(consumerURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateConsumerOpts provides options used to update a consumer.
|
||||
type UpdateConsumerOpts struct {
|
||||
// Description is the consumer description.
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ToOAuth1UpdateConsumerMap formats an UpdateConsumerOpts into a consumer update
|
||||
// request.
|
||||
func (opts UpdateConsumerOpts) ToOAuth1UpdateConsumerMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "consumer")
|
||||
}
|
||||
|
||||
// UpdateConsumer updates an existing Consumer.
|
||||
func UpdateConsumer(client *gophercloud.ServiceClient, id string, opts UpdateConsumerOpts) (r UpdateConsumerResult) {
|
||||
b, err := opts.ToOAuth1UpdateConsumerMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
resp, err := client.Patch(consumerURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// RequestTokenOptsBuilder allows extensions to add additional parameters to the
|
||||
// RequestToken request.
|
||||
type RequestTokenOptsBuilder interface {
|
||||
ToOAuth1RequestTokenHeaders(string, string) (map[string]string, error)
|
||||
}
|
||||
|
||||
// RequestTokenOpts provides options used to get a consumer unauthorized
|
||||
// request token.
|
||||
type RequestTokenOpts struct {
|
||||
// OAuthConsumerKey is the OAuth1 Consumer Key.
|
||||
OAuthConsumerKey string `q:"oauth_consumer_key" required:"true"`
|
||||
|
||||
// OAuthConsumerSecret is the OAuth1 Consumer Secret. Used to generate
|
||||
// an OAuth1 request signature.
|
||||
OAuthConsumerSecret string `required:"true"`
|
||||
|
||||
// OAuthSignatureMethod is the OAuth1 signature method the Consumer used
|
||||
// to sign the request. Supported values are "HMAC-SHA1" or "PLAINTEXT".
|
||||
// "PLAINTEXT" is not recommended for production usage.
|
||||
OAuthSignatureMethod SignatureMethod `q:"oauth_signature_method" required:"true"`
|
||||
|
||||
// OAuthTimestamp is an OAuth1 request timestamp. If nil, current Unix
|
||||
// timestamp will be used.
|
||||
OAuthTimestamp *time.Time
|
||||
|
||||
// OAuthNonce is an OAuth1 request nonce. Nonce must be a random string,
|
||||
// uniquely generated for each request. Will be generated automatically
|
||||
// when it is not set.
|
||||
OAuthNonce string `q:"oauth_nonce"`
|
||||
|
||||
// RequestedProjectID is a Project ID a consumer user requested an
|
||||
// access to.
|
||||
RequestedProjectID string `h:"Requested-Project-Id"`
|
||||
}
|
||||
|
||||
// ToOAuth1RequestTokenHeaders formats a RequestTokenOpts into a map of request
|
||||
// headers.
|
||||
func (opts RequestTokenOpts) ToOAuth1RequestTokenHeaders(method, u string) (map[string]string, error) {
|
||||
q, err := buildOAuth1QueryString(opts, opts.OAuthTimestamp, "oob")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h, err := gophercloud.BuildHeaders(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signatureKeys := []string{opts.OAuthConsumerSecret}
|
||||
stringToSign := buildStringToSign(method, u, q.Query())
|
||||
signature := url.QueryEscape(signString(opts.OAuthSignatureMethod, stringToSign, signatureKeys))
|
||||
authHeader := buildAuthHeader(q.Query(), signature)
|
||||
|
||||
h["Authorization"] = authHeader
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// RequestToken requests an unauthorized OAuth1 Token.
|
||||
func RequestToken(client *gophercloud.ServiceClient, opts RequestTokenOptsBuilder) (r TokenResult) {
|
||||
h, err := opts.ToOAuth1RequestTokenHeaders("POST", requestTokenURL(client))
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.Post(requestTokenURL(client), nil, nil, &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{201},
|
||||
KeepResponseBody: true,
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
if r.Err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if v := r.Header.Get("Content-Type"); v != OAuth1TokenContentType {
|
||||
r.Err = fmt.Errorf("unsupported Content-Type: %q", v)
|
||||
return
|
||||
}
|
||||
r.Body, r.Err = ioutil.ReadAll(resp.Body)
|
||||
return
|
||||
}
|
||||
|
||||
// AuthorizeTokenOptsBuilder allows extensions to add additional parameters to
|
||||
// the AuthorizeToken request.
|
||||
type AuthorizeTokenOptsBuilder interface {
|
||||
ToOAuth1AuthorizeTokenMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// AuthorizeTokenOpts provides options used to authorize a request token.
|
||||
type AuthorizeTokenOpts struct {
|
||||
Roles []Role `json:"roles"`
|
||||
}
|
||||
|
||||
// Role is a struct representing a role object in a AuthorizeTokenOpts struct.
|
||||
type Role struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// ToOAuth1AuthorizeTokenMap formats an AuthorizeTokenOpts into an authorize token
|
||||
// request.
|
||||
func (opts AuthorizeTokenOpts) ToOAuth1AuthorizeTokenMap() (map[string]interface{}, error) {
|
||||
for _, r := range opts.Roles {
|
||||
if r == (Role{}) {
|
||||
return nil, fmt.Errorf("role must not be empty")
|
||||
}
|
||||
}
|
||||
return gophercloud.BuildRequestBody(opts, "")
|
||||
}
|
||||
|
||||
// AuthorizeToken authorizes an unauthorized consumer token.
|
||||
func AuthorizeToken(client *gophercloud.ServiceClient, id string, opts AuthorizeTokenOptsBuilder) (r AuthorizeTokenResult) {
|
||||
b, err := opts.ToOAuth1AuthorizeTokenMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
resp, err := client.Put(authorizeTokenURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// CreateAccessTokenOptsBuilder allows extensions to add additional parameters
|
||||
// to the CreateAccessToken request.
|
||||
type CreateAccessTokenOptsBuilder interface {
|
||||
ToOAuth1CreateAccessTokenHeaders(string, string) (map[string]string, error)
|
||||
}
|
||||
|
||||
// CreateAccessTokenOpts provides options used to create an OAuth1 token.
|
||||
type CreateAccessTokenOpts struct {
|
||||
// OAuthConsumerKey is the OAuth1 Consumer Key.
|
||||
OAuthConsumerKey string `q:"oauth_consumer_key" required:"true"`
|
||||
|
||||
// OAuthConsumerSecret is the OAuth1 Consumer Secret. Used to generate
|
||||
// an OAuth1 request signature.
|
||||
OAuthConsumerSecret string `required:"true"`
|
||||
|
||||
// OAuthToken is the OAuth1 Request Token.
|
||||
OAuthToken string `q:"oauth_token" required:"true"`
|
||||
|
||||
// OAuthTokenSecret is the OAuth1 Request Token Secret. Used to generate
|
||||
// an OAuth1 request signature.
|
||||
OAuthTokenSecret string `required:"true"`
|
||||
|
||||
// OAuthVerifier is the OAuth1 verification code.
|
||||
OAuthVerifier string `q:"oauth_verifier" required:"true"`
|
||||
|
||||
// OAuthSignatureMethod is the OAuth1 signature method the Consumer used
|
||||
// to sign the request. Supported values are "HMAC-SHA1" or "PLAINTEXT".
|
||||
// "PLAINTEXT" is not recommended for production usage.
|
||||
OAuthSignatureMethod SignatureMethod `q:"oauth_signature_method" required:"true"`
|
||||
|
||||
// OAuthTimestamp is an OAuth1 request timestamp. If nil, current Unix
|
||||
// timestamp will be used.
|
||||
OAuthTimestamp *time.Time
|
||||
|
||||
// OAuthNonce is an OAuth1 request nonce. Nonce must be a random string,
|
||||
// uniquely generated for each request. Will be generated automatically
|
||||
// when it is not set.
|
||||
OAuthNonce string `q:"oauth_nonce"`
|
||||
}
|
||||
|
||||
// ToOAuth1CreateAccessTokenHeaders formats a CreateAccessTokenOpts into a map of
|
||||
// request headers.
|
||||
func (opts CreateAccessTokenOpts) ToOAuth1CreateAccessTokenHeaders(method, u string) (map[string]string, error) {
|
||||
q, err := buildOAuth1QueryString(opts, opts.OAuthTimestamp, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signatureKeys := []string{opts.OAuthConsumerSecret, opts.OAuthTokenSecret}
|
||||
stringToSign := buildStringToSign(method, u, q.Query())
|
||||
signature := url.QueryEscape(signString(opts.OAuthSignatureMethod, stringToSign, signatureKeys))
|
||||
authHeader := buildAuthHeader(q.Query(), signature)
|
||||
|
||||
headers := map[string]string{
|
||||
"Authorization": authHeader,
|
||||
}
|
||||
|
||||
return headers, nil
|
||||
}
|
||||
|
||||
// CreateAccessToken creates a new OAuth1 Access Token
|
||||
func CreateAccessToken(client *gophercloud.ServiceClient, opts CreateAccessTokenOptsBuilder) (r TokenResult) {
|
||||
h, err := opts.ToOAuth1CreateAccessTokenHeaders("POST", createAccessTokenURL(client))
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.Post(createAccessTokenURL(client), nil, nil, &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{201},
|
||||
KeepResponseBody: true,
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
if r.Err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if v := r.Header.Get("Content-Type"); v != OAuth1TokenContentType {
|
||||
r.Err = fmt.Errorf("unsupported Content-Type: %q", v)
|
||||
return
|
||||
}
|
||||
r.Body, r.Err = ioutil.ReadAll(resp.Body)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAccessToken retrieves details on a single OAuth1 access token by an ID.
|
||||
func GetAccessToken(client *gophercloud.ServiceClient, userID string, id string) (r GetAccessTokenResult) {
|
||||
resp, err := client.Get(userAccessTokenURL(client, userID, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// RevokeAccessToken revokes an OAuth1 access token.
|
||||
func RevokeAccessToken(client *gophercloud.ServiceClient, userID string, id string) (r RevokeAccessTokenResult) {
|
||||
resp, err := client.Delete(userAccessTokenURL(client, userID, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// ListAccessTokens enumerates authorized access tokens.
|
||||
func ListAccessTokens(client *gophercloud.ServiceClient, userID string) pagination.Pager {
|
||||
url := userAccessTokensURL(client, userID)
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return AccessTokensPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// ListAccessTokenRoles enumerates authorized access token roles.
|
||||
func ListAccessTokenRoles(client *gophercloud.ServiceClient, userID string, id string) pagination.Pager {
|
||||
url := userAccessTokenRolesURL(client, userID, id)
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return AccessTokenRolesPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// GetAccessTokenRole retrieves details on a single OAuth1 access token role by
|
||||
// an ID.
|
||||
func GetAccessTokenRole(client *gophercloud.ServiceClient, userID string, id string, roleID string) (r GetAccessTokenRoleResult) {
|
||||
resp, err := client.Get(userAccessTokenRoleURL(client, userID, id, roleID), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// The following are small helper functions used to help build the signature.
|
||||
|
||||
// buildOAuth1QueryString builds a URLEncoded parameters string specific for
|
||||
// OAuth1-based requests.
|
||||
func buildOAuth1QueryString(opts interface{}, timestamp *time.Time, callback string) (*url.URL, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := q.Query()
|
||||
|
||||
if timestamp != nil {
|
||||
// use provided timestamp
|
||||
query.Set("oauth_timestamp", strconv.FormatInt(timestamp.Unix(), 10))
|
||||
} else {
|
||||
// use current timestamp
|
||||
query.Set("oauth_timestamp", strconv.FormatInt(time.Now().UTC().Unix(), 10))
|
||||
}
|
||||
|
||||
if query.Get("oauth_nonce") == "" {
|
||||
// when nonce is not set, generate a random one
|
||||
query.Set("oauth_nonce", strconv.FormatInt(rand.Int63(), 10)+query.Get("oauth_timestamp"))
|
||||
}
|
||||
|
||||
if callback != "" {
|
||||
query.Set("oauth_callback", callback)
|
||||
}
|
||||
query.Set("oauth_version", "1.0")
|
||||
|
||||
return &url.URL{RawQuery: query.Encode()}, nil
|
||||
}
|
||||
|
||||
// buildStringToSign builds a string to be signed.
|
||||
func buildStringToSign(method string, u string, query url.Values) []byte {
|
||||
parsedURL, _ := url.Parse(u)
|
||||
p := parsedURL.Port()
|
||||
s := parsedURL.Scheme
|
||||
|
||||
// Default scheme port must be stripped
|
||||
if s == "http" && p == "80" || s == "https" && p == "443" {
|
||||
parsedURL.Host = strings.TrimSuffix(parsedURL.Host, ":"+p)
|
||||
}
|
||||
|
||||
// Ensure that URL doesn't contain queries
|
||||
parsedURL.RawQuery = ""
|
||||
|
||||
v := strings.Join(
|
||||
[]string{method, url.QueryEscape(parsedURL.String()), url.QueryEscape(query.Encode())}, "&")
|
||||
|
||||
return []byte(v)
|
||||
}
|
||||
|
||||
// signString signs a string using an OAuth1 signature method.
|
||||
func signString(signatureMethod SignatureMethod, strToSign []byte, signatureKeys []string) string {
|
||||
var key []byte
|
||||
for i, k := range signatureKeys {
|
||||
key = append(key, []byte(url.QueryEscape(k))...)
|
||||
if i == 0 {
|
||||
key = append(key, '&')
|
||||
}
|
||||
}
|
||||
|
||||
var signedString string
|
||||
switch signatureMethod {
|
||||
case PLAINTEXT:
|
||||
signedString = string(key)
|
||||
default:
|
||||
h := hmac.New(sha1.New, key)
|
||||
h.Write(strToSign)
|
||||
signedString = base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
return signedString
|
||||
}
|
||||
|
||||
// buildAuthHeader generates an OAuth1 Authorization header with a signature
|
||||
// calculated using an OAuth1 signature method.
|
||||
func buildAuthHeader(query url.Values, signature string) string {
|
||||
var authHeader []string
|
||||
var keys []string
|
||||
for k := range query {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
for _, v := range query[k] {
|
||||
authHeader = append(authHeader, fmt.Sprintf("%s=%q", k, url.QueryEscape(v)))
|
||||
}
|
||||
}
|
||||
|
||||
authHeader = append(authHeader, fmt.Sprintf("oauth_signature=%q", signature))
|
||||
|
||||
return "OAuth " + strings.Join(authHeader, ", ")
|
||||
}
|
305
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/results.go
generated
vendored
Normal file
305
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/results.go
generated
vendored
Normal file
|
@ -0,0 +1,305 @@
|
|||
package oauth1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Consumer represents a delegated authorization request between two
|
||||
// identities.
|
||||
type Consumer struct {
|
||||
ID string `json:"id"`
|
||||
Secret string `json:"secret"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type consumerResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// CreateConsumerResult is the response from a Create operation. Call its
|
||||
// Extract method to interpret it as a Consumer.
|
||||
type CreateConsumerResult struct {
|
||||
consumerResult
|
||||
}
|
||||
|
||||
// UpdateConsumerResult is the response from a Create operation. Call its
|
||||
// Extract method to interpret it as a Consumer.
|
||||
type UpdateConsumerResult struct {
|
||||
consumerResult
|
||||
}
|
||||
|
||||
// DeleteConsumerResult is the response from a Delete operation. Call its
|
||||
// ExtractErr to determine if the request succeeded or failed.
|
||||
type DeleteConsumerResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// ConsumersPage is a single page of Region results.
|
||||
type ConsumersPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// GetConsumerResult is the response from a Get operation. Call its Extract
|
||||
// method to interpret it as a Consumer.
|
||||
type GetConsumerResult struct {
|
||||
consumerResult
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a page of Consumers contains any results.
|
||||
func (c ConsumersPage) IsEmpty() (bool, error) {
|
||||
consumers, err := ExtractConsumers(c)
|
||||
return len(consumers) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL extracts the "next" link from the links section of the result.
|
||||
func (c ConsumersPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links struct {
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
} `json:"links"`
|
||||
}
|
||||
err := c.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.Links.Next, err
|
||||
}
|
||||
|
||||
// ExtractConsumers returns a slice of Consumers contained in a single page of
|
||||
// results.
|
||||
func ExtractConsumers(r pagination.Page) ([]Consumer, error) {
|
||||
var s struct {
|
||||
Consumers []Consumer `json:"consumers"`
|
||||
}
|
||||
err := (r.(ConsumersPage)).ExtractInto(&s)
|
||||
return s.Consumers, err
|
||||
}
|
||||
|
||||
// Extract interprets any consumer result as a Consumer.
|
||||
func (c consumerResult) Extract() (*Consumer, error) {
|
||||
var s struct {
|
||||
Consumer *Consumer `json:"consumer"`
|
||||
}
|
||||
err := c.ExtractInto(&s)
|
||||
return s.Consumer, err
|
||||
}
|
||||
|
||||
// Token contains an OAuth1 token.
|
||||
type Token struct {
|
||||
// OAuthToken is the key value for the oauth token that the Identity API returns.
|
||||
OAuthToken string `q:"oauth_token"`
|
||||
// OAuthTokenSecret is the secret value associated with the OAuth Token.
|
||||
OAuthTokenSecret string `q:"oauth_token_secret"`
|
||||
// OAUthExpiresAt is the date and time when an OAuth token expires.
|
||||
OAUthExpiresAt *time.Time `q:"-"`
|
||||
}
|
||||
|
||||
// TokenResult is a struct to handle
|
||||
// "Content-Type: application/x-www-form-urlencoded" response.
|
||||
type TokenResult struct {
|
||||
gophercloud.Result
|
||||
Body []byte
|
||||
}
|
||||
|
||||
// Extract interprets any OAuth1 token result as a Token.
|
||||
func (r TokenResult) Extract() (*Token, error) {
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
}
|
||||
|
||||
values, err := url.ParseQuery(string(r.Body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
token := &Token{
|
||||
OAuthToken: values.Get("oauth_token"),
|
||||
OAuthTokenSecret: values.Get("oauth_token_secret"),
|
||||
}
|
||||
|
||||
if v := values.Get("oauth_expires_at"); v != "" {
|
||||
if t, err := time.Parse(gophercloud.RFC3339Milli, v); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
token.OAUthExpiresAt = &t
|
||||
}
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// AuthorizedToken contains an OAuth1 authorized token info.
|
||||
type AuthorizedToken struct {
|
||||
// OAuthVerifier is the ID of the token verifier.
|
||||
OAuthVerifier string `json:"oauth_verifier"`
|
||||
}
|
||||
|
||||
type AuthorizeTokenResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets AuthorizeTokenResult result as a AuthorizedToken.
|
||||
func (r AuthorizeTokenResult) Extract() (*AuthorizedToken, error) {
|
||||
var s struct {
|
||||
AuthorizedToken *AuthorizedToken `json:"token"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.AuthorizedToken, err
|
||||
}
|
||||
|
||||
// AccessToken represents an AccessToken response as a struct.
|
||||
type AccessToken struct {
|
||||
ID string `json:"id"`
|
||||
ConsumerID string `json:"consumer_id"`
|
||||
ProjectID string `json:"project_id"`
|
||||
AuthorizingUserID string `json:"authorizing_user_id"`
|
||||
ExpiresAt *time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (r *AccessToken) UnmarshalJSON(b []byte) error {
|
||||
type tmp AccessToken
|
||||
var s struct {
|
||||
tmp
|
||||
ExpiresAt *gophercloud.JSONRFC3339Milli `json:"expires_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = AccessToken(s.tmp)
|
||||
|
||||
if s.ExpiresAt != nil {
|
||||
t := time.Time(*s.ExpiresAt)
|
||||
r.ExpiresAt = &t
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetAccessTokenResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets any GetAccessTokenResult result as an AccessToken.
|
||||
func (r GetAccessTokenResult) Extract() (*AccessToken, error) {
|
||||
var s struct {
|
||||
AccessToken *AccessToken `json:"access_token"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.AccessToken, err
|
||||
}
|
||||
|
||||
// RevokeAccessTokenResult is the response from a Delete operation. Call its
|
||||
// ExtractErr to determine if the request succeeded or failed.
|
||||
type RevokeAccessTokenResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// AccessTokensPage is a single page of Access Tokens results.
|
||||
type AccessTokensPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a an AccessTokensPage contains any results.
|
||||
func (r AccessTokensPage) IsEmpty() (bool, error) {
|
||||
accessTokens, err := ExtractAccessTokens(r)
|
||||
return len(accessTokens) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL extracts the "next" link from the links section of the result.
|
||||
func (r AccessTokensPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links struct {
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
} `json:"links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.Links.Next, err
|
||||
}
|
||||
|
||||
// ExtractAccessTokens returns a slice of AccessTokens contained in a single
|
||||
// page of results.
|
||||
func ExtractAccessTokens(r pagination.Page) ([]AccessToken, error) {
|
||||
var s struct {
|
||||
AccessTokens []AccessToken `json:"access_tokens"`
|
||||
}
|
||||
err := (r.(AccessTokensPage)).ExtractInto(&s)
|
||||
return s.AccessTokens, err
|
||||
}
|
||||
|
||||
// AccessTokenRole represents an Access Token Role struct.
|
||||
type AccessTokenRole struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
DomainID string `json:"domain_id"`
|
||||
}
|
||||
|
||||
// AccessTokenRolesPage is a single page of Access Token roles results.
|
||||
type AccessTokenRolesPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a an AccessTokensPage contains any results.
|
||||
func (r AccessTokenRolesPage) IsEmpty() (bool, error) {
|
||||
accessTokenRoles, err := ExtractAccessTokenRoles(r)
|
||||
return len(accessTokenRoles) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL extracts the "next" link from the links section of the result.
|
||||
func (r AccessTokenRolesPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links struct {
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
} `json:"links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.Links.Next, err
|
||||
}
|
||||
|
||||
// ExtractAccessTokenRoles returns a slice of AccessTokenRole contained in a
|
||||
// single page of results.
|
||||
func ExtractAccessTokenRoles(r pagination.Page) ([]AccessTokenRole, error) {
|
||||
var s struct {
|
||||
AccessTokenRoles []AccessTokenRole `json:"roles"`
|
||||
}
|
||||
err := (r.(AccessTokenRolesPage)).ExtractInto(&s)
|
||||
return s.AccessTokenRoles, err
|
||||
}
|
||||
|
||||
type GetAccessTokenRoleResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets any GetAccessTokenRoleResult result as an AccessTokenRole.
|
||||
func (r GetAccessTokenRoleResult) Extract() (*AccessTokenRole, error) {
|
||||
var s struct {
|
||||
AccessTokenRole *AccessTokenRole `json:"role"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.AccessTokenRole, err
|
||||
}
|
||||
|
||||
// OAuth1 is an OAuth1 object, returned in OAuth1 token result.
|
||||
type OAuth1 struct {
|
||||
AccessTokenID string `json:"access_token_id"`
|
||||
ConsumerID string `json:"consumer_id"`
|
||||
}
|
||||
|
||||
// TokenExt represents an extension of the base token result.
|
||||
type TokenExt struct {
|
||||
OAuth1 OAuth1 `json:"OS-OAUTH1"`
|
||||
}
|
43
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/urls.go
generated
vendored
Normal file
43
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
package oauth1
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func consumersURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("OS-OAUTH1", "consumers")
|
||||
}
|
||||
|
||||
func consumerURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL("OS-OAUTH1", "consumers", id)
|
||||
}
|
||||
|
||||
func requestTokenURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("OS-OAUTH1", "request_token")
|
||||
}
|
||||
|
||||
func authorizeTokenURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL("OS-OAUTH1", "authorize", id)
|
||||
}
|
||||
|
||||
func createAccessTokenURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("OS-OAUTH1", "access_token")
|
||||
}
|
||||
|
||||
func userAccessTokensURL(c *gophercloud.ServiceClient, userID string) string {
|
||||
return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens")
|
||||
}
|
||||
|
||||
func userAccessTokenURL(c *gophercloud.ServiceClient, userID string, id string) string {
|
||||
return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens", id)
|
||||
}
|
||||
|
||||
func userAccessTokenRolesURL(c *gophercloud.ServiceClient, userID string, id string) string {
|
||||
return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens", id, "roles")
|
||||
}
|
||||
|
||||
func userAccessTokenRoleURL(c *gophercloud.ServiceClient, userID string, id string, roleID string) string {
|
||||
return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens", id, "roles", roleID)
|
||||
}
|
||||
|
||||
func authURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("auth", "tokens")
|
||||
}
|
40
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
40
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
|
@ -8,6 +8,7 @@ type Scope struct {
|
|||
ProjectName string
|
||||
DomainID string
|
||||
DomainName string
|
||||
System bool
|
||||
}
|
||||
|
||||
// AuthOptionsBuilder provides the ability for extensions to add additional
|
||||
|
@ -16,6 +17,7 @@ type AuthOptionsBuilder interface {
|
|||
// ToTokenV3CreateMap assembles the Create request body, returning an error
|
||||
// if parameters are missing or inconsistent.
|
||||
ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error)
|
||||
ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error)
|
||||
ToTokenV3ScopeMap() (map[string]interface{}, error)
|
||||
CanReauth() bool
|
||||
}
|
||||
|
@ -36,6 +38,9 @@ type AuthOptions struct {
|
|||
|
||||
Password string `json:"password,omitempty"`
|
||||
|
||||
// Passcode is used in TOTP authentication method
|
||||
Passcode string `json:"passcode,omitempty"`
|
||||
|
||||
// At most one of DomainID and DomainName must be provided if using Username
|
||||
// with Identity V3. Otherwise, either are optional.
|
||||
DomainID string `json:"-"`
|
||||
|
@ -67,6 +72,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
Username: opts.Username,
|
||||
UserID: opts.UserID,
|
||||
Password: opts.Password,
|
||||
Passcode: opts.Passcode,
|
||||
DomainID: opts.DomainID,
|
||||
DomainName: opts.DomainName,
|
||||
AllowReauth: opts.AllowReauth,
|
||||
|
@ -79,7 +85,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
return gophercloudAuthOpts.ToTokenV3CreateMap(scope)
|
||||
}
|
||||
|
||||
// ToTokenV3CreateMap builds a scope request body from AuthOptions.
|
||||
// ToTokenV3ScopeMap builds a scope request body from AuthOptions.
|
||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||
scope := gophercloud.AuthScope(opts.Scope)
|
||||
|
||||
|
@ -93,10 +99,21 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
|||
}
|
||||
|
||||
func (opts *AuthOptions) CanReauth() bool {
|
||||
if opts.Passcode != "" {
|
||||
// cannot reauth using TOTP passcode
|
||||
return false
|
||||
}
|
||||
|
||||
return opts.AllowReauth
|
||||
}
|
||||
|
||||
func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
|
||||
// ToTokenV3HeadersMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||
// interface in the v3 tokens package.
|
||||
func (opts *AuthOptions) ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func subjectTokenHeaders(subjectToken string) map[string]string {
|
||||
return map[string]string{
|
||||
"X-Subject-Token": subjectToken,
|
||||
}
|
||||
|
@ -120,30 +137,24 @@ func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder) (r CreateResu
|
|||
resp, err := c.Post(tokenURL(c), b, &r.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: map[string]string{"X-Auth-Token": ""},
|
||||
})
|
||||
r.Err = err
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get validates and retrieves information about another token.
|
||||
func Get(c *gophercloud.ServiceClient, token string) (r GetResult) {
|
||||
resp, err := c.Get(tokenURL(c), &r.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: subjectTokenHeaders(c, token),
|
||||
MoreHeaders: subjectTokenHeaders(token),
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate determines if a specified token is valid or not.
|
||||
func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
|
||||
resp, err := c.Head(tokenURL(c), &gophercloud.RequestOpts{
|
||||
MoreHeaders: subjectTokenHeaders(c, token),
|
||||
MoreHeaders: subjectTokenHeaders(token),
|
||||
OkCodes: []int{200, 204, 404},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -155,8 +166,9 @@ func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
|
|||
|
||||
// Revoke immediately makes specified token invalid.
|
||||
func Revoke(c *gophercloud.ServiceClient, token string) (r RevokeResult) {
|
||||
_, r.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{
|
||||
MoreHeaders: subjectTokenHeaders(c, token),
|
||||
resp, err := c.Delete(tokenURL(c), &gophercloud.RequestOpts{
|
||||
MoreHeaders: subjectTokenHeaders(token),
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
48
vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/requests.go
generated
vendored
48
vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/requests.go
generated
vendored
|
@ -206,19 +206,22 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
|||
r.Err = err
|
||||
return r
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{201}})
|
||||
resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{201}})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete implements image delete request.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
resp, err := client.Delete(deleteURL(client, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get implements image get request.
|
||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||
resp, err := client.Get(getURL(client, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -229,10 +232,11 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
|||
r.Err = err
|
||||
return r
|
||||
}
|
||||
_, r.Err = client.Patch(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Patch(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
MoreHeaders: map[string]string{"Content-Type": "application/openstack-images-v2.1-json-patch"},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -378,39 +382,3 @@ func (r UpdateImageProperty) ToImagePatchMap() map[string]interface{} {
|
|||
|
||||
return updateMap
|
||||
}
|
||||
|
||||
// IDFromName is a convienience function that returns an image's ID given its name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
pages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractImages(pages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, s := range all {
|
||||
if s.Name == name {
|
||||
count++
|
||||
id = s.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "image"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "image"}
|
||||
}
|
||||
}
|
||||
|
|
40
vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/results.go
generated
vendored
40
vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/results.go
generated
vendored
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
|
@ -86,13 +87,22 @@ type Image struct {
|
|||
|
||||
// VirtualSize is the virtual size of the image
|
||||
VirtualSize int64 `json:"virtual_size"`
|
||||
|
||||
// OpenStackImageImportMethods is a slice listing the types of import
|
||||
// methods available in the cloud.
|
||||
OpenStackImageImportMethods []string `json:"-"`
|
||||
// OpenStackImageStoreIDs is a slice listing the store IDs available in
|
||||
// the cloud.
|
||||
OpenStackImageStoreIDs []string `json:"-"`
|
||||
}
|
||||
|
||||
func (r *Image) UnmarshalJSON(b []byte) error {
|
||||
type tmp Image
|
||||
var s struct {
|
||||
tmp
|
||||
SizeBytes interface{} `json:"size"`
|
||||
SizeBytes interface{} `json:"size"`
|
||||
OpenStackImageImportMethods string `json:"openstack-image-import-methods"`
|
||||
OpenStackImageStoreIDs string `json:"openstack-image-store-ids"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -120,9 +130,18 @@ func (r *Image) UnmarshalJSON(b []byte) error {
|
|||
if resultMap, ok := result.(map[string]interface{}); ok {
|
||||
delete(resultMap, "self")
|
||||
delete(resultMap, "size")
|
||||
delete(resultMap, "openstack-image-import-methods")
|
||||
delete(resultMap, "openstack-image-store-ids")
|
||||
r.Properties = internal.RemainingKeys(Image{}, resultMap)
|
||||
}
|
||||
|
||||
if v := strings.FieldsFunc(strings.TrimSpace(s.OpenStackImageImportMethods), splitFunc); len(v) > 0 {
|
||||
r.OpenStackImageImportMethods = v
|
||||
}
|
||||
if v := strings.FieldsFunc(strings.TrimSpace(s.OpenStackImageStoreIDs), splitFunc); len(v) > 0 {
|
||||
r.OpenStackImageStoreIDs = v
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -133,6 +152,20 @@ type commonResult struct {
|
|||
// Extract interprets any commonResult as an Image.
|
||||
func (r commonResult) Extract() (*Image, error) {
|
||||
var s *Image
|
||||
if v, ok := r.Body.(map[string]interface{}); ok {
|
||||
for k, h := range r.Header {
|
||||
if strings.ToLower(k) == "openstack-image-import-methods" {
|
||||
for _, s := range h {
|
||||
v["openstack-image-import-methods"] = s
|
||||
}
|
||||
}
|
||||
if strings.ToLower(k) == "openstack-image-store-ids" {
|
||||
for _, s := range h {
|
||||
v["openstack-image-store-ids"] = s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
}
|
||||
|
@ -200,3 +233,8 @@ func ExtractImages(r pagination.Page) ([]Image, error) {
|
|||
err := (r.(ImagePage)).ExtractInto(&s)
|
||||
return s.Images, err
|
||||
}
|
||||
|
||||
// splitFunc is a helper function used to avoid a slice of empty strings.
|
||||
func splitFunc(c rune) bool {
|
||||
return c == ','
|
||||
}
|
||||
|
|
|
@ -80,7 +80,8 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -137,13 +138,15 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
|||
|
||||
// Get retrieves a particular l7policy based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular l7policy based on its unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -208,9 +211,10 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -254,7 +258,8 @@ func CreateRule(c *gophercloud.ServiceClient, policyID string, opts CreateRuleOp
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(ruleRootURL(c, policyID), b, &r.Body, nil)
|
||||
resp, err := c.Post(ruleRootURL(c, policyID), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -309,13 +314,15 @@ func ListRules(c *gophercloud.ServiceClient, policyID string, opts ListRulesOpts
|
|||
|
||||
// GetRule retrieves a particular L7Policy Rule based on its unique ID.
|
||||
func GetRule(c *gophercloud.ServiceClient, policyID string, ruleID string) (r GetRuleResult) {
|
||||
_, r.Err = c.Get(ruleResourceURL(c, policyID, ruleID), &r.Body, nil)
|
||||
resp, err := c.Get(ruleResourceURL(c, policyID, ruleID), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteRule will remove a Rule from a particular L7Policy.
|
||||
func DeleteRule(c *gophercloud.ServiceClient, policyID string, ruleID string) (r DeleteRuleResult) {
|
||||
_, r.Err = c.Delete(ruleResourceURL(c, policyID, ruleID), nil)
|
||||
resp, err := c.Delete(ruleResourceURL(c, policyID, ruleID), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -369,8 +376,9 @@ func UpdateRule(c *gophercloud.ServiceClient, policyID string, ruleID string, op
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(ruleResourceURL(c, policyID, ruleID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(ruleResourceURL(c, policyID, ruleID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -154,13 +154,15 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular Listeners based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -235,20 +237,23 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateR
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular Listeners based on its unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// GetStats will return the shows the current statistics of a particular Listeners.
|
||||
func GetStats(c *gophercloud.ServiceClient, id string) (r StatsResult) {
|
||||
_, r.Err = c.Get(statisticsRootURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(statisticsRootURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -133,13 +133,15 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular Loadbalancer based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -179,9 +181,10 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateR
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -216,26 +219,30 @@ func Delete(c *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r
|
|||
}
|
||||
url += query
|
||||
}
|
||||
_, r.Err = c.Delete(url, nil)
|
||||
resp, err := c.Delete(url, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
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)
|
||||
resp, err := c.Get(statusRootURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// GetStats will return the shows the current statistics of a particular LoadBalancer.
|
||||
func GetStats(c *gophercloud.ServiceClient, id string) (r StatsResult) {
|
||||
_, r.Err = c.Get(statisticsRootURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(statisticsRootURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Failover performs a failover of a load balancer.
|
||||
func Failover(c *gophercloud.ServiceClient, id string) (r FailoverResult) {
|
||||
_, r.Err = c.Put(failoverRootURL(c, id), nil, nil, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(failoverRootURL(c, id), nil, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
12
vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/monitors/requests.go
generated
vendored
12
vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/monitors/requests.go
generated
vendored
|
@ -166,13 +166,15 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular Health Monitor based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -235,14 +237,16 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
return
|
||||
}
|
||||
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular Monitor based on its unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
27
vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools/requests.go
generated
vendored
27
vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools/requests.go
generated
vendored
|
@ -130,13 +130,15 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular pool based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -177,15 +179,17 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular pool based on its unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -298,13 +302,15 @@ func CreateMember(c *gophercloud.ServiceClient, poolID string, opts CreateMember
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(memberRootURL(c, poolID), b, &r.Body, nil)
|
||||
resp, err := c.Post(memberRootURL(c, poolID), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// GetMember retrieves a particular Pool Member based on its unique ID.
|
||||
func GetMember(c *gophercloud.ServiceClient, poolID string, memberID string) (r GetMemberResult) {
|
||||
_, r.Err = c.Get(memberResourceURL(c, poolID, memberID), &r.Body, nil)
|
||||
resp, err := c.Get(memberResourceURL(c, poolID, memberID), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -343,9 +349,10 @@ func UpdateMember(c *gophercloud.ServiceClient, poolID string, memberID string,
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(memberResourceURL(c, poolID, memberID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(memberResourceURL(c, poolID, memberID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201, 202},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -413,13 +420,15 @@ func BatchUpdateMembers(c *gophercloud.ServiceClient, poolID string, opts []Batc
|
|||
|
||||
b := map[string]interface{}{"members": members}
|
||||
|
||||
_, r.Err = c.Put(memberRootURL(c, poolID), b, nil, &gophercloud.RequestOpts{OkCodes: []int{202}})
|
||||
resp, err := c.Put(memberRootURL(c, poolID), b, nil, &gophercloud.RequestOpts{OkCodes: []int{202}})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// DisassociateMember will remove and disassociate a Member from a particular
|
||||
// Pool.
|
||||
func DeleteMember(c *gophercloud.ServiceClient, poolID string, memberID string) (r DeleteMemberResult) {
|
||||
_, r.Err = c.Delete(memberResourceURL(c, poolID, memberID), nil)
|
||||
resp, err := c.Delete(memberResourceURL(c, poolID, memberID), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -29,53 +29,59 @@ func ReplaceAll(client *gophercloud.ServiceClient, resourceType string, resource
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(url, &b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(url, &b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// List all tags on a resource
|
||||
func List(client *gophercloud.ServiceClient, resourceType string, resourceID string) (r ListResult) {
|
||||
url := listURL(client, resourceType, resourceID)
|
||||
_, r.Err = client.Get(url, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := client.Get(url, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteAll deletes all tags on a resource
|
||||
func DeleteAll(client *gophercloud.ServiceClient, resourceType string, resourceID string) (r DeleteResult) {
|
||||
url := deleteAllURL(client, resourceType, resourceID)
|
||||
_, r.Err = client.Delete(url, &gophercloud.RequestOpts{
|
||||
resp, err := client.Delete(url, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{204},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Add a tag on a resource
|
||||
func Add(client *gophercloud.ServiceClient, resourceType string, resourceID string, tag string) (r AddResult) {
|
||||
url := addURL(client, resourceType, resourceID, tag)
|
||||
_, r.Err = client.Put(url, nil, nil, &gophercloud.RequestOpts{
|
||||
resp, err := client.Put(url, nil, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete a tag on a resource
|
||||
func Delete(client *gophercloud.ServiceClient, resourceType string, resourceID string, tag string) (r DeleteResult) {
|
||||
url := deleteURL(client, resourceType, resourceID, tag)
|
||||
_, r.Err = client.Delete(url, &gophercloud.RequestOpts{
|
||||
resp, err := client.Delete(url, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{204},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Confirm if a tag exists on a resource
|
||||
func Confirm(client *gophercloud.ServiceClient, resourceType string, resourceID string, tag string) (r ConfirmResult) {
|
||||
url := confirmURL(client, resourceType, resourceID, tag)
|
||||
_, r.Err = client.Get(url, nil, &gophercloud.RequestOpts{
|
||||
resp, err := client.Get(url, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{204},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -116,13 +116,15 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular floating IP resource based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -167,9 +169,10 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -177,6 +180,7 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
// ensure this is what you want - you can also disassociate the IP from existing
|
||||
// internal ports.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -84,13 +84,15 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular router based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -126,15 +128,17 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular router based on its unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -182,9 +186,10 @@ func AddInterface(c *gophercloud.ServiceClient, id string, opts AddInterfaceOpts
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(addInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(addInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -226,8 +231,9 @@ func RemoveInterface(c *gophercloud.ServiceClient, id string, opts RemoveInterfa
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(removeInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(removeInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -76,7 +76,8 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -109,58 +110,24 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
return
|
||||
}
|
||||
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular security group based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular security group based on its
|
||||
// unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convenience function that returns a security group's ID,
|
||||
// given its name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
pages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractGroups(pages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, s := range all {
|
||||
if s.Name == name {
|
||||
count++
|
||||
id = s.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "security group"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "security group"}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,19 +141,22 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(rootURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get retrieves a particular security group rule based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(resourceURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular security group rule based on its
|
||||
// unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
resp, err := c.Delete(resourceURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
49
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go
generated
vendored
49
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go
generated
vendored
|
@ -60,7 +60,8 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
|||
|
||||
// Get retrieves a specific network based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(getURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(getURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -99,7 +100,8 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(createURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(createURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -130,51 +132,16 @@ func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOptsBuild
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(updateURL(c, networkID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(updateURL(c, networkID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete accepts a unique ID and deletes the network associated with it.
|
||||
func Delete(c *gophercloud.ServiceClient, networkID string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(deleteURL(c, networkID), nil)
|
||||
resp, err := c.Delete(deleteURL(c, networkID), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convenience function that returns a network's ID, given
|
||||
// its name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
pages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractNetworks(pages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, s := range all {
|
||||
if s.Name == name {
|
||||
count++
|
||||
id = s.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "network"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "network"}
|
||||
}
|
||||
}
|
||||
|
|
49
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go
generated
vendored
49
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports/requests.go
generated
vendored
|
@ -97,7 +97,8 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
|||
|
||||
// Get retrieves a specific port based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(getURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(getURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -136,7 +137,8 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(createURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(createURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -171,51 +173,16 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete accepts a unique ID and deletes the port associated with it.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(deleteURL(c, id), nil)
|
||||
resp, err := c.Delete(deleteURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convenience function that returns a port's ID,
|
||||
// given its name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
pages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractPorts(pages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, s := range all {
|
||||
if s.Name == name {
|
||||
count++
|
||||
id = s.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "port"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "port"}
|
||||
}
|
||||
}
|
||||
|
|
49
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/requests.go
generated
vendored
49
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/requests.go
generated
vendored
|
@ -69,7 +69,8 @@ func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
|||
|
||||
// Get retrieves a specific subnet based on its unique ID.
|
||||
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||
_, r.Err = c.Get(getURL(c, id), &r.Body, nil)
|
||||
resp, err := c.Get(getURL(c, id), &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -160,7 +161,8 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(createURL(c), b, &r.Body, nil)
|
||||
resp, err := c.Post(createURL(c), b, &r.Body, nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -219,51 +221,16 @@ func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r
|
|||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
resp, err := c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete accepts a unique ID and deletes the subnet associated with it.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(deleteURL(c, id), nil)
|
||||
resp, err := c.Delete(deleteURL(c, id), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convenience function that returns a subnet's ID,
|
||||
// given its name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
pages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractSubnets(pages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, s := range all {
|
||||
if s.Name == name {
|
||||
count++
|
||||
id = s.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,10 +39,7 @@ func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) (r GetResult) {
|
|||
MoreHeaders: h,
|
||||
OkCodes: []int{204},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -92,9 +89,6 @@ func Update(c *gophercloud.ServiceClient, opts UpdateOptsBuilder) (r UpdateResul
|
|||
MoreHeaders: h,
|
||||
OkCodes: []int{201, 202, 204},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
92
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts/results.go
generated
vendored
92
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts/results.go
generated
vendored
|
@ -2,7 +2,6 @@ package accounts
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -17,7 +16,7 @@ type UpdateResult struct {
|
|||
// UpdateHeader represents the headers returned in the response from an Update
|
||||
// request.
|
||||
type UpdateHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
Date time.Time `json:"-"`
|
||||
|
@ -27,8 +26,7 @@ func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp UpdateHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -37,16 +35,6 @@ func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = UpdateHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
|
||||
return err
|
||||
|
@ -55,18 +43,18 @@ func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
|||
// Extract will return a struct of headers returned from a call to Get. To
|
||||
// obtain a map of headers, call the Extract method on the GetResult.
|
||||
func (r UpdateResult) Extract() (*UpdateHeader, error) {
|
||||
var s *UpdateHeader
|
||||
var s UpdateHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// GetHeader represents the headers returned in the response from a Get request.
|
||||
type GetHeader struct {
|
||||
BytesUsed int64 `json:"-"`
|
||||
QuotaBytes *int64 `json:"-"`
|
||||
ContainerCount int64 `json:"-"`
|
||||
ContentLength int64 `json:"-"`
|
||||
ObjectCount int64 `json:"-"`
|
||||
BytesUsed int64 `json:"X-Account-Bytes-Used,string"`
|
||||
QuotaBytes *int64 `json:"X-Account-Meta-Quota-Bytes,string"`
|
||||
ContainerCount int64 `json:"X-Account-Container-Count,string"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ObjectCount int64 `json:"X-Account-Object-Count,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
TempURLKey string `json:"X-Account-Meta-Temp-URL-Key"`
|
||||
|
@ -78,12 +66,7 @@ func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp GetHeader
|
||||
var s struct {
|
||||
tmp
|
||||
BytesUsed string `json:"X-Account-Bytes-Used"`
|
||||
QuotaBytes string `json:"X-Account-Meta-Quota-Bytes"`
|
||||
ContentLength string `json:"Content-Length"`
|
||||
ContainerCount string `json:"X-Account-Container-Count"`
|
||||
ObjectCount string `json:"X-Account-Object-Count"`
|
||||
Date string `json:"Date"`
|
||||
Date string `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -92,57 +75,6 @@ func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = GetHeader(s.tmp)
|
||||
|
||||
switch s.BytesUsed {
|
||||
case "":
|
||||
r.BytesUsed = 0
|
||||
default:
|
||||
r.BytesUsed, err = strconv.ParseInt(s.BytesUsed, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch s.QuotaBytes {
|
||||
case "":
|
||||
r.QuotaBytes = nil
|
||||
default:
|
||||
v, err := strconv.ParseInt(s.QuotaBytes, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.QuotaBytes = &v
|
||||
}
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch s.ObjectCount {
|
||||
case "":
|
||||
r.ObjectCount = 0
|
||||
default:
|
||||
r.ObjectCount, err = strconv.ParseInt(s.ObjectCount, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch s.ContainerCount {
|
||||
case "":
|
||||
r.ContainerCount = 0
|
||||
default:
|
||||
r.ContainerCount, err = strconv.ParseInt(s.ContainerCount, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if s.Date != "" {
|
||||
r.Date, err = time.Parse(time.RFC1123, s.Date)
|
||||
}
|
||||
|
@ -157,9 +89,9 @@ type GetResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Get.
|
||||
func (r GetResult) Extract() (*GetHeader, error) {
|
||||
var s *GetHeader
|
||||
var s GetHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package containers
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
@ -104,21 +107,39 @@ func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsB
|
|||
h[k] = v
|
||||
}
|
||||
}
|
||||
resp, err := c.Request("PUT", createURL(c, containerName), &gophercloud.RequestOpts{
|
||||
resp, err := c.Request("PUT", createURL(c, url.QueryEscape(containerName)), &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{201, 202, 204},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
resp.Body.Close()
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// BulkDelete is a function that bulk deletes containers.
|
||||
func BulkDelete(c *gophercloud.ServiceClient, containers []string) (r BulkDeleteResult) {
|
||||
// urlencode container names to be on the safe side
|
||||
// https://github.com/openstack/swift/blob/stable/train/swift/common/middleware/bulk.py#L160
|
||||
// https://github.com/openstack/swift/blob/stable/train/swift/common/swob.py#L302
|
||||
encodedContainers := make([]string, len(containers))
|
||||
for i, v := range containers {
|
||||
encodedContainers[i] = url.QueryEscape(v)
|
||||
}
|
||||
r.Err = err
|
||||
b := strings.NewReader(strings.Join(encodedContainers, "\n") + "\n")
|
||||
resp, err := c.Post(bulkDeleteURL(c), b, &r.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: map[string]string{
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "text/plain",
|
||||
},
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete is a function that deletes a container.
|
||||
func Delete(c *gophercloud.ServiceClient, containerName string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(deleteURL(c, containerName), nil)
|
||||
resp, err := c.Delete(deleteURL(c, url.QueryEscape(containerName)), nil)
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -180,14 +201,11 @@ func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsB
|
|||
h[k] = v
|
||||
}
|
||||
}
|
||||
resp, err := c.Request("POST", updateURL(c, containerName), &gophercloud.RequestOpts{
|
||||
resp, err := c.Request("POST", updateURL(c, url.QueryEscape(containerName)), &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{201, 202, 204},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -223,13 +241,10 @@ func Get(c *gophercloud.ServiceClient, containerName string, opts GetOptsBuilder
|
|||
h[k] = v
|
||||
}
|
||||
}
|
||||
resp, err := c.Head(getURL(c, containerName), &gophercloud.RequestOpts{
|
||||
resp, err := c.Head(getURL(c, url.QueryEscape(containerName)), &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{200, 204},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
131
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers/results.go
generated
vendored
131
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers/results.go
generated
vendored
|
@ -3,7 +3,6 @@ package containers
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -92,11 +91,11 @@ func ExtractNames(page pagination.Page) ([]string, error) {
|
|||
// GetHeader represents the headers returned in the response from a Get request.
|
||||
type GetHeader struct {
|
||||
AcceptRanges string `json:"Accept-Ranges"`
|
||||
BytesUsed int64 `json:"-"`
|
||||
ContentLength int64 `json:"-"`
|
||||
BytesUsed int64 `json:"X-Container-Bytes-Used,string"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
ObjectCount int64 `json:"-"`
|
||||
ObjectCount int64 `json:"X-Container-Object-Count,string"`
|
||||
Read []string `json:"-"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
VersionsLocation string `json:"X-Versions-Location"`
|
||||
|
@ -111,12 +110,9 @@ func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp GetHeader
|
||||
var s struct {
|
||||
tmp
|
||||
BytesUsed string `json:"X-Container-Bytes-Used"`
|
||||
ContentLength string `json:"Content-Length"`
|
||||
ObjectCount string `json:"X-Container-Object-Count"`
|
||||
Write string `json:"X-Container-Write"`
|
||||
Read string `json:"X-Container-Read"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
Write string `json:"X-Container-Write"`
|
||||
Read string `json:"X-Container-Read"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -125,36 +121,6 @@ func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = GetHeader(s.tmp)
|
||||
|
||||
switch s.BytesUsed {
|
||||
case "":
|
||||
r.BytesUsed = 0
|
||||
default:
|
||||
r.BytesUsed, err = strconv.ParseInt(s.BytesUsed, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch s.ObjectCount {
|
||||
case "":
|
||||
r.ObjectCount = 0
|
||||
default:
|
||||
r.ObjectCount, err = strconv.ParseInt(s.ObjectCount, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Read = strings.Split(s.Read, ",")
|
||||
r.Write = strings.Split(s.Write, ",")
|
||||
|
||||
|
@ -170,9 +136,9 @@ type GetResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Get.
|
||||
func (r GetResult) Extract() (*GetHeader, error) {
|
||||
var s *GetHeader
|
||||
var s GetHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
|
||||
|
@ -194,7 +160,7 @@ func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
|||
// CreateHeader represents the headers returned in the response from a Create
|
||||
// request.
|
||||
type CreateHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
|
@ -204,8 +170,7 @@ func (r *CreateHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp CreateHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -214,16 +179,6 @@ func (r *CreateHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = CreateHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
|
||||
return err
|
||||
|
@ -238,15 +193,15 @@ type CreateResult struct {
|
|||
// Extract will return a struct of headers returned from a call to Create.
|
||||
// To extract the headers from the HTTP response, call its Extract method.
|
||||
func (r CreateResult) Extract() (*CreateHeader, error) {
|
||||
var s *CreateHeader
|
||||
var s CreateHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// UpdateHeader represents the headers returned in the response from a Update
|
||||
// request.
|
||||
type UpdateHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
|
@ -256,8 +211,7 @@ func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp UpdateHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -266,16 +220,6 @@ func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = UpdateHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
|
||||
return err
|
||||
|
@ -289,15 +233,15 @@ type UpdateResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Update.
|
||||
func (r UpdateResult) Extract() (*UpdateHeader, error) {
|
||||
var s *UpdateHeader
|
||||
var s UpdateHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// DeleteHeader represents the headers returned in the response from a Delete
|
||||
// request.
|
||||
type DeleteHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
|
@ -307,8 +251,7 @@ func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp DeleteHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -317,30 +260,42 @@ func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = DeleteHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of a delete operation. To extract the
|
||||
// the headers from the HTTP response, call its Extract method.
|
||||
// headers from the HTTP response, call its Extract method.
|
||||
type DeleteResult struct {
|
||||
gophercloud.HeaderResult
|
||||
}
|
||||
|
||||
// Extract will return a struct of headers returned from a call to Delete.
|
||||
func (r DeleteResult) Extract() (*DeleteHeader, error) {
|
||||
var s *DeleteHeader
|
||||
var s DeleteHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
type BulkDeleteResponse struct {
|
||||
ResponseStatus string `json:"Response Status"`
|
||||
ResponseBody string `json:"Response Body"`
|
||||
Errors [][]string `json:"Errors"`
|
||||
NumberDeleted int `json:"Number Deleted"`
|
||||
NumberNotFound int `json:"Number Not Found"`
|
||||
}
|
||||
|
||||
// BulkDeleteResult represents the result of a bulk delete operation. To extract
|
||||
// the response object from the HTTP response, call its Extract method.
|
||||
type BulkDeleteResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract will return a BulkDeleteResponse struct returned from a BulkDelete
|
||||
// call.
|
||||
func (r BulkDeleteResult) Extract() (*BulkDeleteResponse, error) {
|
||||
var s BulkDeleteResponse
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
||||
|
|
|
@ -21,3 +21,7 @@ func deleteURL(c *gophercloud.ServiceClient, container string) string {
|
|||
func updateURL(c *gophercloud.ServiceClient, container string) string {
|
||||
return createURL(c, container)
|
||||
}
|
||||
|
||||
func bulkDeleteURL(c *gophercloud.ServiceClient) string {
|
||||
return c.Endpoint + "?bulk-delete=true"
|
||||
}
|
||||
|
|
4
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/doc.go
generated
vendored
4
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/doc.go
generated
vendored
|
@ -98,6 +98,10 @@ Example to Download an Object's Data
|
|||
containerName := "my_container"
|
||||
|
||||
object := objects.Download(objectStorageClient, containerName, objectName, nil)
|
||||
if object.Err != nil {
|
||||
panic(object.Err)
|
||||
}
|
||||
// if "ExtractContent" method is not called, the HTTP connection will remain consumed
|
||||
content, err := object.ExtractContent()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
82
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/requests.go
generated
vendored
82
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/requests.go
generated
vendored
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -53,7 +54,7 @@ func (opts ListOpts) ToObjectListParams() (bool, string, error) {
|
|||
func List(c *gophercloud.ServiceClient, containerName string, opts ListOptsBuilder) pagination.Pager {
|
||||
headers := map[string]string{"Accept": "text/plain", "Content-Type": "text/plain"}
|
||||
|
||||
url := listURL(c, containerName)
|
||||
url := listURL(c, url.QueryEscape(containerName))
|
||||
if opts != nil {
|
||||
full, query, err := opts.ToObjectListParams()
|
||||
if err != nil {
|
||||
|
@ -112,7 +113,7 @@ func (opts DownloadOpts) ToObjectDownloadParams() (map[string]string, string, er
|
|||
// To extract just the content, pass the DownloadResult response to the
|
||||
// ExtractContent function.
|
||||
func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts DownloadOptsBuilder) (r DownloadResult) {
|
||||
url := downloadURL(c, containerName, objectName)
|
||||
url := downloadURL(c, url.QueryEscape(containerName), url.QueryEscape(objectName))
|
||||
h := make(map[string]string)
|
||||
if opts != nil {
|
||||
headers, query, err := opts.ToObjectDownloadParams()
|
||||
|
@ -127,14 +128,11 @@ func Download(c *gophercloud.ServiceClient, containerName, objectName string, op
|
|||
}
|
||||
|
||||
resp, err := c.Get(url, nil, &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{200, 206, 304},
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{200, 206, 304},
|
||||
KeepResponseBody: true,
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
r.Body = resp.Body
|
||||
}
|
||||
r.Err = err
|
||||
r.Body, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -221,7 +219,7 @@ func (opts CreateOpts) ToObjectCreateParams() (io.Reader, map[string]string, str
|
|||
// checksum, the failed request will automatically be retried up to a maximum
|
||||
// of 3 times.
|
||||
func Create(c *gophercloud.ServiceClient, containerName, objectName string, opts CreateOptsBuilder) (r CreateResult) {
|
||||
url := createURL(c, containerName, objectName)
|
||||
url := createURL(c, url.QueryEscape(containerName), url.QueryEscape(objectName))
|
||||
h := make(map[string]string)
|
||||
var b io.Reader
|
||||
if opts != nil {
|
||||
|
@ -237,14 +235,10 @@ func Create(c *gophercloud.ServiceClient, containerName, objectName string, opts
|
|||
b = tmpB
|
||||
}
|
||||
|
||||
resp, err := c.Put(url, nil, nil, &gophercloud.RequestOpts{
|
||||
RawBody: b,
|
||||
resp, err := c.Put(url, b, nil, &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
})
|
||||
r.Err = err
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -289,15 +283,12 @@ func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts C
|
|||
h[k] = v
|
||||
}
|
||||
|
||||
url := copyURL(c, containerName, objectName)
|
||||
url := copyURL(c, url.QueryEscape(containerName), url.QueryEscape(objectName))
|
||||
resp, err := c.Request("COPY", url, &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
OkCodes: []int{201},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -320,7 +311,7 @@ func (opts DeleteOpts) ToObjectDeleteQuery() (string, error) {
|
|||
|
||||
// Delete is a function that deletes an object.
|
||||
func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts DeleteOptsBuilder) (r DeleteResult) {
|
||||
url := deleteURL(c, containerName, objectName)
|
||||
url := deleteURL(c, url.QueryEscape(containerName), url.QueryEscape(objectName))
|
||||
if opts != nil {
|
||||
query, err := opts.ToObjectDeleteQuery()
|
||||
if err != nil {
|
||||
|
@ -330,10 +321,7 @@ func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts
|
|||
url += query
|
||||
}
|
||||
resp, err := c.Delete(url, nil)
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -368,7 +356,7 @@ func (opts GetOpts) ToObjectGetParams() (map[string]string, string, error) {
|
|||
// the custom metadata, pass the GetResult response to the ExtractMetadata
|
||||
// function.
|
||||
func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts GetOptsBuilder) (r GetResult) {
|
||||
url := getURL(c, containerName, objectName)
|
||||
url := getURL(c, url.QueryEscape(containerName), url.QueryEscape(objectName))
|
||||
h := make(map[string]string)
|
||||
if opts != nil {
|
||||
headers, query, err := opts.ToObjectGetParams()
|
||||
|
@ -386,10 +374,7 @@ func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts Ge
|
|||
MoreHeaders: h,
|
||||
OkCodes: []int{200, 204},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -437,14 +422,11 @@ func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts
|
|||
h[k] = v
|
||||
}
|
||||
}
|
||||
url := updateURL(c, containerName, objectName)
|
||||
url := updateURL(c, url.QueryEscape(containerName), url.QueryEscape(objectName))
|
||||
resp, err := c.Post(url, nil, nil, &gophercloud.RequestOpts{
|
||||
MoreHeaders: h,
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = err
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -483,7 +465,7 @@ func CreateTempURL(c *gophercloud.ServiceClient, containerName, objectName strin
|
|||
}
|
||||
duration := time.Duration(opts.TTL) * time.Second
|
||||
expiry := time.Now().Add(duration).Unix()
|
||||
getHeader, err := containers.Get(c, containerName, nil).Extract()
|
||||
getHeader, err := containers.Get(c, url.QueryEscape(containerName), nil).Extract()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -497,7 +479,7 @@ func CreateTempURL(c *gophercloud.ServiceClient, containerName, objectName strin
|
|||
tempURLKey = getHeader.TempURLKey
|
||||
}
|
||||
secretKey := []byte(tempURLKey)
|
||||
url := getURL(c, containerName, objectName)
|
||||
url := getURL(c, url.QueryEscape(containerName), url.QueryEscape(objectName))
|
||||
splitPath := strings.Split(url, opts.Split)
|
||||
baseURL, objectPath := splitPath[0], splitPath[1]
|
||||
objectPath = opts.Split + objectPath
|
||||
|
@ -507,3 +489,27 @@ func CreateTempURL(c *gophercloud.ServiceClient, containerName, objectName strin
|
|||
hexsum := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
return fmt.Sprintf("%s%s?temp_url_sig=%s&temp_url_expires=%d", baseURL, objectPath, hexsum, expiry), nil
|
||||
}
|
||||
|
||||
// BulkDelete is a function that bulk deletes objects.
|
||||
func BulkDelete(c *gophercloud.ServiceClient, container string, objects []string) (r BulkDeleteResult) {
|
||||
// urlencode object names to be on the safe side
|
||||
// https://github.com/openstack/swift/blob/stable/train/swift/common/middleware/bulk.py#L160
|
||||
// https://github.com/openstack/swift/blob/stable/train/swift/common/swob.py#L302
|
||||
encodedObjects := make([]string, len(objects))
|
||||
for i, v := range objects {
|
||||
encodedObjects[i] = strings.Join([]string{
|
||||
url.QueryEscape(container),
|
||||
url.QueryEscape(v)},
|
||||
"/")
|
||||
}
|
||||
b := strings.NewReader(strings.Join(encodedObjects, "\n") + "\n")
|
||||
resp, err := c.Post(bulkDeleteURL(c), b, &r.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: map[string]string{
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "text/plain",
|
||||
},
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
|
||||
return
|
||||
}
|
||||
|
|
134
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/results.go
generated
vendored
134
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/results.go
generated
vendored
|
@ -6,7 +6,6 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -134,7 +133,7 @@ type DownloadHeader struct {
|
|||
AcceptRanges string `json:"Accept-Ranges"`
|
||||
ContentDisposition string `json:"Content-Disposition"`
|
||||
ContentEncoding string `json:"Content-Encoding"`
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
DeleteAt time.Time `json:"-"`
|
||||
|
@ -149,7 +148,6 @@ func (r *DownloadHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp DownloadHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
|
||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||
|
@ -162,16 +160,6 @@ func (r *DownloadHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = DownloadHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch t := s.StaticLargeObject.(type) {
|
||||
case string:
|
||||
if t == "True" || t == "true" {
|
||||
|
@ -197,9 +185,9 @@ type DownloadResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Download.
|
||||
func (r DownloadResult) Extract() (*DownloadHeader, error) {
|
||||
var s *DownloadHeader
|
||||
var s DownloadHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// ExtractContent is a function that takes a DownloadResult's io.Reader body
|
||||
|
@ -216,7 +204,6 @@ func (r *DownloadResult) ExtractContent() ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.Body.Close()
|
||||
return body, nil
|
||||
}
|
||||
|
||||
|
@ -224,7 +211,7 @@ func (r *DownloadResult) ExtractContent() ([]byte, error) {
|
|||
type GetHeader struct {
|
||||
ContentDisposition string `json:"Content-Disposition"`
|
||||
ContentEncoding string `json:"Content-Encoding"`
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
DeleteAt time.Time `json:"-"`
|
||||
|
@ -239,7 +226,6 @@ func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp GetHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
|
||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||
|
@ -252,16 +238,6 @@ func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = GetHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch t := s.StaticLargeObject.(type) {
|
||||
case string:
|
||||
if t == "True" || t == "true" {
|
||||
|
@ -286,9 +262,9 @@ type GetResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Get.
|
||||
func (r GetResult) Extract() (*GetHeader, error) {
|
||||
var s *GetHeader
|
||||
var s GetHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
|
||||
|
@ -310,7 +286,7 @@ func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
|||
// CreateHeader represents the headers returned in the response from a
|
||||
// Create request.
|
||||
type CreateHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
ETag string `json:"Etag"`
|
||||
|
@ -322,9 +298,8 @@ func (r *CreateHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp CreateHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -333,16 +308,6 @@ func (r *CreateHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = CreateHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
r.LastModified = time.Time(s.LastModified)
|
||||
|
||||
|
@ -360,15 +325,15 @@ func (r CreateResult) Extract() (*CreateHeader, error) {
|
|||
//if r.Header.Get("ETag") != fmt.Sprintf("%x", localChecksum) {
|
||||
// return nil, ErrWrongChecksum{}
|
||||
//}
|
||||
var s *CreateHeader
|
||||
var s CreateHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// UpdateHeader represents the headers returned in the response from a
|
||||
// Update request.
|
||||
type UpdateHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
|
@ -378,8 +343,7 @@ func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp UpdateHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -388,16 +352,6 @@ func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = UpdateHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
|
||||
return nil
|
||||
|
@ -410,15 +364,15 @@ type UpdateResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Update.
|
||||
func (r UpdateResult) Extract() (*UpdateHeader, error) {
|
||||
var s *UpdateHeader
|
||||
var s UpdateHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// DeleteHeader represents the headers returned in the response from a
|
||||
// Delete request.
|
||||
type DeleteHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
Date time.Time `json:"-"`
|
||||
TransID string `json:"X-Trans-Id"`
|
||||
|
@ -428,8 +382,7 @@ func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp DeleteHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
|
@ -438,16 +391,6 @@ func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = DeleteHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
|
||||
return nil
|
||||
|
@ -460,15 +403,15 @@ type DeleteResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Delete.
|
||||
func (r DeleteResult) Extract() (*DeleteHeader, error) {
|
||||
var s *DeleteHeader
|
||||
var s DeleteHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// CopyHeader represents the headers returned in the response from a
|
||||
// Copy request.
|
||||
type CopyHeader struct {
|
||||
ContentLength int64 `json:"-"`
|
||||
ContentLength int64 `json:"Content-Length,string"`
|
||||
ContentType string `json:"Content-Type"`
|
||||
CopiedFrom string `json:"X-Copied-From"`
|
||||
CopiedFromLastModified time.Time `json:"-"`
|
||||
|
@ -482,7 +425,6 @@ func (r *CopyHeader) UnmarshalJSON(b []byte) error {
|
|||
type tmp CopyHeader
|
||||
var s struct {
|
||||
tmp
|
||||
ContentLength string `json:"Content-Length"`
|
||||
CopiedFromLastModified gophercloud.JSONRFC1123 `json:"X-Copied-From-Last-Modified"`
|
||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||
|
@ -494,16 +436,6 @@ func (r *CopyHeader) UnmarshalJSON(b []byte) error {
|
|||
|
||||
*r = CopyHeader(s.tmp)
|
||||
|
||||
switch s.ContentLength {
|
||||
case "":
|
||||
r.ContentLength = 0
|
||||
default:
|
||||
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Date = time.Time(s.Date)
|
||||
r.CopiedFromLastModified = time.Time(s.CopiedFromLastModified)
|
||||
r.LastModified = time.Time(s.LastModified)
|
||||
|
@ -518,9 +450,31 @@ type CopyResult struct {
|
|||
|
||||
// Extract will return a struct of headers returned from a call to Copy.
|
||||
func (r CopyResult) Extract() (*CopyHeader, error) {
|
||||
var s *CopyHeader
|
||||
var s CopyHeader
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
return &s, err
|
||||
}
|
||||
|
||||
type BulkDeleteResponse struct {
|
||||
ResponseStatus string `json:"Response Status"`
|
||||
ResponseBody string `json:"Response Body"`
|
||||
Errors [][]string `json:"Errors"`
|
||||
NumberDeleted int `json:"Number Deleted"`
|
||||
NumberNotFound int `json:"Number Not Found"`
|
||||
}
|
||||
|
||||
// BulkDeleteResult represents the result of a bulk delete operation. To extract
|
||||
// the response object from the HTTP response, call its Extract method.
|
||||
type BulkDeleteResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract will return a BulkDeleteResponse struct returned from a BulkDelete
|
||||
// call.
|
||||
func (r BulkDeleteResult) Extract() (*BulkDeleteResponse, error) {
|
||||
var s BulkDeleteResponse
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// extractLastMarker is a function that takes a page of objects and returns the
|
||||
|
|
4
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/urls.go
generated
vendored
4
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/urls.go
generated
vendored
|
@ -31,3 +31,7 @@ func downloadURL(c *gophercloud.ServiceClient, container, object string) string
|
|||
func updateURL(c *gophercloud.ServiceClient, container, object string) string {
|
||||
return copyURL(c, container, object)
|
||||
}
|
||||
|
||||
func bulkDeleteURL(c *gophercloud.ServiceClient) string {
|
||||
return c.Endpoint + "?bulk-delete=true"
|
||||
}
|
||||
|
|
|
@ -54,7 +54,8 @@ func PageResultFromParsed(resp *http.Response, body interface{}) PageResult {
|
|||
// Request performs an HTTP request and extracts the http.Response from the result.
|
||||
func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (*http.Response, error) {
|
||||
return client.Get(url, nil, &gophercloud.RequestOpts{
|
||||
MoreHeaders: headers,
|
||||
OkCodes: []int{200, 204, 300},
|
||||
MoreHeaders: headers,
|
||||
OkCodes: []int{200, 204, 300},
|
||||
KeepResponseBody: true,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -305,6 +305,9 @@ type RequestOpts struct {
|
|||
// ErrorContext specifies the resource error type to return if an error is encountered.
|
||||
// This lets resources override default error messages based on the response status code.
|
||||
ErrorContext error
|
||||
// KeepResponseBody specifies whether to keep the HTTP response body. Usually used, when the HTTP
|
||||
// response body is considered for further use. Valid when JSONResponse is nil.
|
||||
KeepResponseBody bool
|
||||
}
|
||||
|
||||
// requestState contains temporary state for a single ProviderClient.Request() call.
|
||||
|
@ -346,6 +349,11 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
|
|||
contentType = &applicationJSON
|
||||
}
|
||||
|
||||
// Return an error, when "KeepResponseBody" is true and "JSONResponse" is not nil
|
||||
if options.KeepResponseBody && options.JSONResponse != nil {
|
||||
return nil, errors.New("cannot use KeepResponseBody when JSONResponse is not nil")
|
||||
}
|
||||
|
||||
if options.RawBody != nil {
|
||||
body = options.RawBody
|
||||
}
|
||||
|
@ -384,9 +392,6 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
|
|||
req.Header.Set(k, v)
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -414,11 +419,12 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
|
|||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
respErr := ErrUnexpectedResponseCode{
|
||||
URL: url,
|
||||
Method: method,
|
||||
Expected: options.OkCodes,
|
||||
Actual: resp.StatusCode,
|
||||
Body: body,
|
||||
URL: url,
|
||||
Method: method,
|
||||
Expected: options.OkCodes,
|
||||
Actual: resp.StatusCode,
|
||||
Body: body,
|
||||
ResponseHeader: resp.Header,
|
||||
}
|
||||
|
||||
errType := options.ErrorContext
|
||||
|
@ -513,25 +519,40 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
|
|||
// Parse the response body as JSON, if requested to do so.
|
||||
if options.JSONResponse != nil {
|
||||
defer resp.Body.Close()
|
||||
// Don't decode JSON when there is no content
|
||||
if resp.StatusCode == http.StatusNoContent {
|
||||
// read till EOF, otherwise the connection will be closed and cannot be reused
|
||||
_, err = io.Copy(ioutil.Discard, resp.Body)
|
||||
return resp, err
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(options.JSONResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Close unused body to allow the HTTP connection to be reused
|
||||
if !options.KeepResponseBody && options.JSONResponse == nil {
|
||||
defer resp.Body.Close()
|
||||
// read till EOF, otherwise the connection will be closed and cannot be reused
|
||||
if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func defaultOkCodes(method string) []int {
|
||||
switch {
|
||||
case method == "GET":
|
||||
switch method {
|
||||
case "GET", "HEAD":
|
||||
return []int{200}
|
||||
case method == "POST":
|
||||
case "POST":
|
||||
return []int{201, 202}
|
||||
case method == "PUT":
|
||||
case "PUT":
|
||||
return []int{201, 202}
|
||||
case method == "PATCH":
|
||||
case "PATCH":
|
||||
return []int{200, 202, 204}
|
||||
case method == "DELETE":
|
||||
case "DELETE":
|
||||
return []int{202, 204}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,6 +131,18 @@ func (r Result) extractIntoPtr(to interface{}, label string) error {
|
|||
// fields of the struct or composed extension struct
|
||||
// at the end of this method.
|
||||
toValue.Set(newSlice)
|
||||
|
||||
// jtopjian: This was put into place to resolve the issue
|
||||
// described at
|
||||
// https://github.com/gophercloud/gophercloud/issues/1963
|
||||
//
|
||||
// This probably isn't the best fix, but it appears to
|
||||
// be resolving the issue, so I'm going to implement it
|
||||
// for now.
|
||||
//
|
||||
// For future readers, this entire case statement could
|
||||
// use a review.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
|
|
|
@ -152,3 +152,11 @@ func (client *ServiceClient) Request(method, url string, options *RequestOpts) (
|
|||
}
|
||||
return client.ProviderClient.Request(method, url, options)
|
||||
}
|
||||
|
||||
// ParseResponse is a helper function to parse http.Response to constituents.
|
||||
func ParseResponse(resp *http.Response, err error) (io.ReadCloser, http.Header, error) {
|
||||
if resp != nil {
|
||||
return resp.Body, resp.Header, err
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
@ -300,7 +300,7 @@ github.com/googleapis/gax-go/v2
|
|||
github.com/googleapis/gnostic/OpenAPIv2
|
||||
github.com/googleapis/gnostic/compiler
|
||||
github.com/googleapis/gnostic/extensions
|
||||
# github.com/gophercloud/gophercloud v0.7.1-0.20200116011225-46fdd1830e9a => github.com/gophercloud/gophercloud v0.9.0
|
||||
# github.com/gophercloud/gophercloud v0.11.0 => github.com/gophercloud/gophercloud v0.11.0
|
||||
## explicit
|
||||
github.com/gophercloud/gophercloud
|
||||
github.com/gophercloud/gophercloud/internal
|
||||
|
@ -314,12 +314,13 @@ github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhint
|
|||
github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups
|
||||
github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach
|
||||
github.com/gophercloud/gophercloud/openstack/compute/v2/flavors
|
||||
github.com/gophercloud/gophercloud/openstack/compute/v2/images
|
||||
github.com/gophercloud/gophercloud/openstack/compute/v2/servers
|
||||
github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets
|
||||
github.com/gophercloud/gophercloud/openstack/dns/v2/zones
|
||||
github.com/gophercloud/gophercloud/openstack/identity/v2/tenants
|
||||
github.com/gophercloud/gophercloud/openstack/identity/v2/tokens
|
||||
github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens
|
||||
github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1
|
||||
github.com/gophercloud/gophercloud/openstack/identity/v3/tokens
|
||||
github.com/gophercloud/gophercloud/openstack/imageservice/v2/images
|
||||
github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/apiversions
|
||||
|
@ -1363,4 +1364,4 @@ sigs.k8s.io/yaml
|
|||
# k8s.io/cli-runtime => k8s.io/cli-runtime v0.18.6
|
||||
# k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.18.6
|
||||
# k8s.io/code-generator => k8s.io/code-generator v0.18.6
|
||||
# github.com/gophercloud/gophercloud => github.com/gophercloud/gophercloud v0.9.0
|
||||
# github.com/gophercloud/gophercloud => github.com/gophercloud/gophercloud v0.11.0
|
||||
|
|
Loading…
Reference in New Issue