Merge pull request #67782 from dims/yank-in-tree-openstack-cloud-provider
Remove in-tree openstack cloud provider
This commit is contained in:
3
vendor/github.com/gophercloud/gophercloud/.gitignore
generated
vendored
3
vendor/github.com/gophercloud/gophercloud/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
||||
**/*.swp
|
||||
.idea
|
||||
.vscode
|
25
vendor/github.com/gophercloud/gophercloud/.travis.yml
generated
vendored
25
vendor/github.com/gophercloud/gophercloud/.travis.yml
generated
vendored
@@ -1,25 +0,0 @@
|
||||
language: go
|
||||
sudo: false
|
||||
install:
|
||||
- GO111MODULE=off go get golang.org/x/crypto/ssh
|
||||
- GO111MODULE=off go get -v -tags 'fixtures acceptance' ./...
|
||||
- GO111MODULE=off go get github.com/wadey/gocovmerge
|
||||
- GO111MODULE=off go get github.com/mattn/goveralls
|
||||
- GO111MODULE=off go get golang.org/x/tools/cmd/goimports
|
||||
go:
|
||||
- "1.10"
|
||||
- "1.11"
|
||||
- "1.12"
|
||||
- "tip"
|
||||
env:
|
||||
global:
|
||||
- secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ="
|
||||
- GO111MODULE=on
|
||||
before_script:
|
||||
- go vet ./...
|
||||
script:
|
||||
- ./script/coverage
|
||||
- ./script/unittest
|
||||
- ./script/format
|
||||
after_success:
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=cover.out
|
114
vendor/github.com/gophercloud/gophercloud/.zuul.yaml
generated
vendored
114
vendor/github.com/gophercloud/gophercloud/.zuul.yaml
generated
vendored
@@ -1,114 +0,0 @@
|
||||
- job:
|
||||
name: gophercloud-unittest
|
||||
parent: golang-test
|
||||
description: |
|
||||
Run gophercloud unit test
|
||||
run: .zuul/playbooks/gophercloud-unittest/run.yaml
|
||||
nodeset: ubuntu-xenial-ut
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test
|
||||
parent: golang-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on master branch
|
||||
run: .zuul/playbooks/gophercloud-acceptance-test/run.yaml
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-ironic
|
||||
parent: golang-test
|
||||
description: |
|
||||
Run gophercloud ironic acceptance test on master branch
|
||||
run: .zuul/playbooks/gophercloud-acceptance-test-ironic/run.yaml
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-stein
|
||||
parent: gophercloud-acceptance-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on stein branch
|
||||
vars:
|
||||
global_env:
|
||||
OS_BRANCH: stable/stein
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-rocky
|
||||
parent: gophercloud-acceptance-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on rocky branch
|
||||
vars:
|
||||
global_env:
|
||||
OS_BRANCH: stable/rocky
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-queens
|
||||
parent: gophercloud-acceptance-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on queens branch
|
||||
vars:
|
||||
global_env:
|
||||
OS_BRANCH: stable/queens
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-pike
|
||||
parent: gophercloud-acceptance-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on pike branch
|
||||
vars:
|
||||
global_env:
|
||||
OS_BRANCH: stable/pike
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-ocata
|
||||
parent: gophercloud-acceptance-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on ocata branch
|
||||
vars:
|
||||
global_env:
|
||||
OS_BRANCH: stable/ocata
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-newton
|
||||
parent: gophercloud-acceptance-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on newton branch
|
||||
vars:
|
||||
global_env:
|
||||
OS_BRANCH: stable/newton
|
||||
|
||||
- job:
|
||||
name: gophercloud-acceptance-test-mitaka
|
||||
parent: gophercloud-acceptance-test
|
||||
description: |
|
||||
Run gophercloud acceptance test on mitaka branch
|
||||
vars:
|
||||
global_env:
|
||||
OS_BRANCH: stable/mitaka
|
||||
nodeset: ubuntu-trusty
|
||||
|
||||
- project:
|
||||
name: gophercloud/gophercloud
|
||||
check:
|
||||
jobs:
|
||||
- gophercloud-unittest
|
||||
- gophercloud-acceptance-test
|
||||
- gophercloud-acceptance-test-ironic
|
||||
recheck-mitaka:
|
||||
jobs:
|
||||
- gophercloud-acceptance-test-mitaka
|
||||
recheck-newton:
|
||||
jobs:
|
||||
- gophercloud-acceptance-test-newton
|
||||
recheck-ocata:
|
||||
jobs:
|
||||
- gophercloud-acceptance-test-ocata
|
||||
recheck-pike:
|
||||
jobs:
|
||||
- gophercloud-acceptance-test-pike
|
||||
recheck-queens:
|
||||
jobs:
|
||||
- gophercloud-acceptance-test-queens
|
||||
recheck-rocky:
|
||||
jobs:
|
||||
- gophercloud-acceptance-test-rocky
|
||||
recheck-stein:
|
||||
jobs:
|
||||
- gophercloud-acceptance-test-stein
|
0
vendor/github.com/gophercloud/gophercloud/CHANGELOG.md
generated
vendored
0
vendor/github.com/gophercloud/gophercloud/CHANGELOG.md
generated
vendored
191
vendor/github.com/gophercloud/gophercloud/LICENSE
generated
vendored
191
vendor/github.com/gophercloud/gophercloud/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
||||
Copyright 2012-2013 Rackspace, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations under the License.
|
||||
|
||||
------
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
159
vendor/github.com/gophercloud/gophercloud/README.md
generated
vendored
159
vendor/github.com/gophercloud/gophercloud/README.md
generated
vendored
@@ -1,159 +0,0 @@
|
||||
# Gophercloud: an OpenStack SDK for Go
|
||||
[](https://travis-ci.org/gophercloud/gophercloud)
|
||||
[](https://coveralls.io/github/gophercloud/gophercloud?branch=master)
|
||||
|
||||
Gophercloud is an OpenStack Go SDK.
|
||||
|
||||
## Useful links
|
||||
|
||||
* [Reference documentation](http://godoc.org/github.com/gophercloud/gophercloud)
|
||||
* [Effective Go](https://golang.org/doc/effective_go.html)
|
||||
|
||||
## How to install
|
||||
|
||||
Before installing, you need to ensure that your [GOPATH environment variable](https://golang.org/doc/code.html#GOPATH)
|
||||
is pointing to an appropriate directory where you want to install Gophercloud:
|
||||
|
||||
```bash
|
||||
mkdir $HOME/go
|
||||
export GOPATH=$HOME/go
|
||||
```
|
||||
|
||||
To protect yourself against changes in your dependencies, we highly recommend choosing a
|
||||
[dependency management solution](https://github.com/golang/go/wiki/PackageManagementTools) for
|
||||
your projects, such as [godep](https://github.com/tools/godep). Once this is set up, you can install
|
||||
Gophercloud as a dependency like so:
|
||||
|
||||
```bash
|
||||
go get github.com/gophercloud/gophercloud
|
||||
|
||||
# Edit your code to import relevant packages from "github.com/gophercloud/gophercloud"
|
||||
|
||||
godep save ./...
|
||||
```
|
||||
|
||||
This will install all the source files you need into a `Godeps/_workspace` directory, which is
|
||||
referenceable from your own source files when you use the `godep go` command.
|
||||
|
||||
## Getting started
|
||||
|
||||
### Credentials
|
||||
|
||||
Because you'll be hitting an API, you will need to retrieve your OpenStack
|
||||
credentials and either store them as environment variables or in your local Go
|
||||
files. The first method is recommended because it decouples credential
|
||||
information from source code, allowing you to push the latter to your version
|
||||
control system without any security risk.
|
||||
|
||||
You will need to retrieve the following:
|
||||
|
||||
* username
|
||||
* password
|
||||
* a valid Keystone identity URL
|
||||
|
||||
For users that have the OpenStack dashboard installed, there's a shortcut. If
|
||||
you visit the `project/access_and_security` path in Horizon and click on the
|
||||
"Download OpenStack RC File" button at the top right hand corner, you will
|
||||
download a bash file that exports all of your access details to environment
|
||||
variables. To execute the file, run `source admin-openrc.sh` and you will be
|
||||
prompted for your password.
|
||||
|
||||
### Authentication
|
||||
|
||||
Once you have access to your credentials, you can begin plugging them into
|
||||
Gophercloud. The next step is authentication, and this is handled by a base
|
||||
"Provider" struct. To get one, you can either pass in your credentials
|
||||
explicitly, or tell Gophercloud to use environment variables:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack"
|
||||
"github.com/gophercloud/gophercloud/openstack/utils"
|
||||
)
|
||||
|
||||
// Option 1: Pass in the values yourself
|
||||
opts := gophercloud.AuthOptions{
|
||||
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
||||
Username: "{username}",
|
||||
Password: "{password}",
|
||||
}
|
||||
|
||||
// Option 2: Use a utility function to retrieve all your environment variables
|
||||
opts, err := openstack.AuthOptionsFromEnv()
|
||||
```
|
||||
|
||||
Once you have the `opts` variable, you can pass it in and get back a
|
||||
`ProviderClient` struct:
|
||||
|
||||
```go
|
||||
provider, err := openstack.AuthenticatedClient(opts)
|
||||
```
|
||||
|
||||
The `ProviderClient` is the top-level client that all of your OpenStack services
|
||||
derive from. The provider contains all of the authentication details that allow
|
||||
your Go code to access the API - such as the base URL and token ID.
|
||||
|
||||
### Provision a server
|
||||
|
||||
Once we have a base Provider, we inject it as a dependency into each OpenStack
|
||||
service. In order to work with the Compute API, we need a Compute service
|
||||
client; which can be created like so:
|
||||
|
||||
```go
|
||||
client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{
|
||||
Region: os.Getenv("OS_REGION_NAME"),
|
||||
})
|
||||
```
|
||||
|
||||
We then use this `client` for any Compute API operation we want. In our case,
|
||||
we want to provision a new server - so we invoke the `Create` method and pass
|
||||
in the flavor ID (hardware specification) and image ID (operating system) we're
|
||||
interested in:
|
||||
|
||||
```go
|
||||
import "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
|
||||
server, err := servers.Create(client, servers.CreateOpts{
|
||||
Name: "My new server!",
|
||||
FlavorRef: "flavor_id",
|
||||
ImageRef: "image_id",
|
||||
}).Extract()
|
||||
```
|
||||
|
||||
The above code sample creates a new server with the parameters, and embodies the
|
||||
new resource in the `server` variable (a
|
||||
[`servers.Server`](http://godoc.org/github.com/gophercloud/gophercloud) struct).
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
Have a look at the [FAQ](./docs/FAQ.md) for some tips on customizing the way Gophercloud works.
|
||||
|
||||
## Backwards-Compatibility Guarantees
|
||||
|
||||
None. Vendor it and write tests covering the parts you use.
|
||||
|
||||
## Contributing
|
||||
|
||||
See the [contributing guide](./.github/CONTRIBUTING.md).
|
||||
|
||||
## Help and feedback
|
||||
|
||||
If you're struggling with something or have spotted a potential bug, feel free
|
||||
to submit an issue to our [bug tracker](https://github.com/gophercloud/gophercloud/issues).
|
||||
|
||||
## Thank You
|
||||
|
||||
We'd like to extend special thanks and appreciation to the following:
|
||||
|
||||
### OpenLab
|
||||
|
||||
<a href="http://openlabtesting.org/"><img src="./docs/assets/openlab.png" width="600px"></a>
|
||||
|
||||
OpenLab is providing a full CI environment to test each PR and merge for a variety of OpenStack releases.
|
||||
|
||||
### VEXXHOST
|
||||
|
||||
<a href="https://vexxhost.com/"><img src="./docs/assets/vexxhost.png" width="600px"></a>
|
||||
|
||||
VEXXHOST is providing their services to assist with the development and testing of Gophercloud.
|
437
vendor/github.com/gophercloud/gophercloud/auth_options.go
generated
vendored
437
vendor/github.com/gophercloud/gophercloud/auth_options.go
generated
vendored
@@ -1,437 +0,0 @@
|
||||
package gophercloud
|
||||
|
||||
/*
|
||||
AuthOptions stores information needed to authenticate to an OpenStack Cloud.
|
||||
You can populate one manually, or use a provider's AuthOptionsFromEnv() function
|
||||
to read relevant information from the standard environment variables. Pass one
|
||||
to a provider's AuthenticatedClient function to authenticate and obtain a
|
||||
ProviderClient representing an active session on that provider.
|
||||
|
||||
Its fields are the union of those recognized by each identity implementation and
|
||||
provider.
|
||||
|
||||
An example of manually providing authentication information:
|
||||
|
||||
opts := gophercloud.AuthOptions{
|
||||
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
||||
Username: "{username}",
|
||||
Password: "{password}",
|
||||
TenantID: "{tenant_id}",
|
||||
}
|
||||
|
||||
provider, err := openstack.AuthenticatedClient(opts)
|
||||
|
||||
An example of using AuthOptionsFromEnv(), where the environment variables can
|
||||
be read from a file, such as a standard openrc file:
|
||||
|
||||
opts, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(opts)
|
||||
*/
|
||||
type AuthOptions struct {
|
||||
// IdentityEndpoint specifies the HTTP endpoint that is required to work with
|
||||
// the Identity API of the appropriate version. While it's ultimately needed by
|
||||
// all of the identity services, it will often be populated by a provider-level
|
||||
// function.
|
||||
//
|
||||
// The IdentityEndpoint is typically referred to as the "auth_url" or
|
||||
// "OS_AUTH_URL" in the information provided by the cloud operator.
|
||||
IdentityEndpoint string `json:"-"`
|
||||
|
||||
// Username is required if using Identity V2 API. Consult with your provider's
|
||||
// control panel to discover your account's username. In Identity V3, either
|
||||
// UserID or a combination of Username and DomainID or DomainName are needed.
|
||||
Username string `json:"username,omitempty"`
|
||||
UserID string `json:"-"`
|
||||
|
||||
Password string `json:"password,omitempty"`
|
||||
|
||||
// At most one of DomainID and DomainName must be provided if using Username
|
||||
// with Identity V3. Otherwise, either are optional.
|
||||
DomainID string `json:"-"`
|
||||
DomainName string `json:"name,omitempty"`
|
||||
|
||||
// The TenantID and TenantName fields are optional for the Identity V2 API.
|
||||
// The same fields are known as project_id and project_name in the Identity
|
||||
// V3 API, but are collected as TenantID and TenantName here in both cases.
|
||||
// Some providers allow you to specify a TenantName instead of the TenantId.
|
||||
// Some require both. Your provider's authentication policies will determine
|
||||
// how these fields influence authentication.
|
||||
// If DomainID or DomainName are provided, they will also apply to TenantName.
|
||||
// It is not currently possible to authenticate with Username and a Domain
|
||||
// and scope to a Project in a different Domain by using TenantName. To
|
||||
// accomplish that, the ProjectID will need to be provided as the TenantID
|
||||
// option.
|
||||
TenantID string `json:"tenantId,omitempty"`
|
||||
TenantName string `json:"tenantName,omitempty"`
|
||||
|
||||
// AllowReauth should be set to true if you grant permission for Gophercloud to
|
||||
// cache your credentials in memory, and to allow Gophercloud to attempt to
|
||||
// re-authenticate automatically if/when your token expires. If you set it to
|
||||
// false, it will not cache these settings, but re-authentication will not be
|
||||
// possible. This setting defaults to false.
|
||||
//
|
||||
// NOTE: The reauth function will try to re-authenticate endlessly if left
|
||||
// unchecked. The way to limit the number of attempts is to provide a custom
|
||||
// HTTP client to the provider client and provide a transport that implements
|
||||
// the RoundTripper interface and stores the number of failed retries. For an
|
||||
// example of this, see here:
|
||||
// https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311
|
||||
AllowReauth bool `json:"-"`
|
||||
|
||||
// TokenID allows users to authenticate (possibly as another user) with an
|
||||
// authentication token ID.
|
||||
TokenID string `json:"-"`
|
||||
|
||||
// Scope determines the scoping of the authentication request.
|
||||
Scope *AuthScope `json:"-"`
|
||||
|
||||
// Authentication through Application Credentials requires supplying name, project and secret
|
||||
// For project we can use TenantID
|
||||
ApplicationCredentialID string `json:"-"`
|
||||
ApplicationCredentialName string `json:"-"`
|
||||
ApplicationCredentialSecret string `json:"-"`
|
||||
}
|
||||
|
||||
// AuthScope allows a created token to be limited to a specific domain or project.
|
||||
type AuthScope struct {
|
||||
ProjectID string
|
||||
ProjectName string
|
||||
DomainID string
|
||||
DomainName string
|
||||
}
|
||||
|
||||
// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||
// interface in the v2 tokens package
|
||||
func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) {
|
||||
// Populate the request map.
|
||||
authMap := make(map[string]interface{})
|
||||
|
||||
if opts.Username != "" {
|
||||
if opts.Password != "" {
|
||||
authMap["passwordCredentials"] = map[string]interface{}{
|
||||
"username": opts.Username,
|
||||
"password": opts.Password,
|
||||
}
|
||||
} else {
|
||||
return nil, ErrMissingInput{Argument: "Password"}
|
||||
}
|
||||
} else if opts.TokenID != "" {
|
||||
authMap["token"] = map[string]interface{}{
|
||||
"id": opts.TokenID,
|
||||
}
|
||||
} else {
|
||||
return nil, ErrMissingInput{Argument: "Username"}
|
||||
}
|
||||
|
||||
if opts.TenantID != "" {
|
||||
authMap["tenantId"] = opts.TenantID
|
||||
}
|
||||
if opts.TenantName != "" {
|
||||
authMap["tenantName"] = opts.TenantName
|
||||
}
|
||||
|
||||
return map[string]interface{}{"auth": authMap}, nil
|
||||
}
|
||||
|
||||
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
|
||||
type domainReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type projectReq struct {
|
||||
Domain *domainReq `json:"domain,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type userReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Domain *domainReq `json:"domain,omitempty"`
|
||||
}
|
||||
|
||||
type passwordReq struct {
|
||||
User userReq `json:"user"`
|
||||
}
|
||||
|
||||
type tokenReq struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type applicationCredentialReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
User *userReq `json:"user,omitempty"`
|
||||
Secret *string `json:"secret,omitempty"`
|
||||
}
|
||||
|
||||
type identityReq struct {
|
||||
Methods []string `json:"methods"`
|
||||
Password *passwordReq `json:"password,omitempty"`
|
||||
Token *tokenReq `json:"token,omitempty"`
|
||||
ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"`
|
||||
}
|
||||
|
||||
type authReq struct {
|
||||
Identity identityReq `json:"identity"`
|
||||
}
|
||||
|
||||
type request struct {
|
||||
Auth authReq `json:"auth"`
|
||||
}
|
||||
|
||||
// Populate the request structure based on the provided arguments. Create and return an error
|
||||
// if insufficient or incompatible information is present.
|
||||
var req request
|
||||
|
||||
if opts.Password == "" {
|
||||
if opts.TokenID != "" {
|
||||
// Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
|
||||
// parameters.
|
||||
if opts.Username != "" {
|
||||
return nil, ErrUsernameWithToken{}
|
||||
}
|
||||
if opts.UserID != "" {
|
||||
return nil, ErrUserIDWithToken{}
|
||||
}
|
||||
if opts.DomainID != "" {
|
||||
return nil, ErrDomainIDWithToken{}
|
||||
}
|
||||
if opts.DomainName != "" {
|
||||
return nil, ErrDomainNameWithToken{}
|
||||
}
|
||||
|
||||
// Configure the request for Token authentication.
|
||||
req.Auth.Identity.Methods = []string{"token"}
|
||||
req.Auth.Identity.Token = &tokenReq{
|
||||
ID: opts.TokenID,
|
||||
}
|
||||
|
||||
} else if opts.ApplicationCredentialID != "" {
|
||||
// Configure the request for ApplicationCredentialID authentication.
|
||||
// https://github.com/openstack/keystoneauth/blob/stable/rocky/keystoneauth1/identity/v3/application_credential.py#L48-L67
|
||||
// There are three kinds of possible application_credential requests
|
||||
// 1. application_credential id + secret
|
||||
// 2. application_credential name + secret + user_id
|
||||
// 3. application_credential name + secret + username + domain_id / domain_name
|
||||
if opts.ApplicationCredentialSecret == "" {
|
||||
return nil, ErrAppCredMissingSecret{}
|
||||
}
|
||||
req.Auth.Identity.Methods = []string{"application_credential"}
|
||||
req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
|
||||
ID: &opts.ApplicationCredentialID,
|
||||
Secret: &opts.ApplicationCredentialSecret,
|
||||
}
|
||||
} else if opts.ApplicationCredentialName != "" {
|
||||
if opts.ApplicationCredentialSecret == "" {
|
||||
return nil, ErrAppCredMissingSecret{}
|
||||
}
|
||||
|
||||
var userRequest *userReq
|
||||
|
||||
if opts.UserID != "" {
|
||||
// UserID could be used without the domain information
|
||||
userRequest = &userReq{
|
||||
ID: &opts.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
if userRequest == nil && opts.Username == "" {
|
||||
// Make sure that Username or UserID are provided
|
||||
return nil, ErrUsernameOrUserID{}
|
||||
}
|
||||
|
||||
if userRequest == nil && opts.DomainID != "" {
|
||||
userRequest = &userReq{
|
||||
Name: &opts.Username,
|
||||
Domain: &domainReq{ID: &opts.DomainID},
|
||||
}
|
||||
}
|
||||
|
||||
if userRequest == nil && opts.DomainName != "" {
|
||||
userRequest = &userReq{
|
||||
Name: &opts.Username,
|
||||
Domain: &domainReq{Name: &opts.DomainName},
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that DomainID or DomainName are provided among Username
|
||||
if userRequest == nil {
|
||||
return nil, ErrDomainIDOrDomainName{}
|
||||
}
|
||||
|
||||
req.Auth.Identity.Methods = []string{"application_credential"}
|
||||
req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
|
||||
Name: &opts.ApplicationCredentialName,
|
||||
User: userRequest,
|
||||
Secret: &opts.ApplicationCredentialSecret,
|
||||
}
|
||||
} else {
|
||||
// If no password or token ID or ApplicationCredential are available, authentication can't continue.
|
||||
return nil, ErrMissingPassword{}
|
||||
}
|
||||
} else {
|
||||
// Password authentication.
|
||||
req.Auth.Identity.Methods = []string{"password"}
|
||||
|
||||
// At least one of Username and UserID must be specified.
|
||||
if opts.Username == "" && opts.UserID == "" {
|
||||
return nil, ErrUsernameOrUserID{}
|
||||
}
|
||||
|
||||
if opts.Username != "" {
|
||||
// If Username is provided, UserID may not be provided.
|
||||
if opts.UserID != "" {
|
||||
return nil, ErrUsernameOrUserID{}
|
||||
}
|
||||
|
||||
// Either DomainID or DomainName must also be specified.
|
||||
if opts.DomainID == "" && opts.DomainName == "" {
|
||||
return nil, ErrDomainIDOrDomainName{}
|
||||
}
|
||||
|
||||
if opts.DomainID != "" {
|
||||
if opts.DomainName != "" {
|
||||
return nil, ErrDomainIDOrDomainName{}
|
||||
}
|
||||
|
||||
// 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.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.UserID != "" {
|
||||
// If UserID is specified, neither DomainID nor DomainName may be.
|
||||
if opts.DomainID != "" {
|
||||
return nil, ErrDomainIDWithUserID{}
|
||||
}
|
||||
if opts.DomainName != "" {
|
||||
return nil, ErrDomainNameWithUserID{}
|
||||
}
|
||||
|
||||
// Configure the request for UserID and Password authentication.
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{ID: &opts.UserID, Password: opts.Password},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b, err := BuildRequestBody(req, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(scope) != 0 {
|
||||
b["auth"].(map[string]interface{})["scope"] = scope
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||
// For backwards compatibility.
|
||||
// If AuthOptions.Scope was not set, try to determine it.
|
||||
// This works well for common scenarios.
|
||||
if opts.Scope == nil {
|
||||
opts.Scope = new(AuthScope)
|
||||
if opts.TenantID != "" {
|
||||
opts.Scope.ProjectID = opts.TenantID
|
||||
} else {
|
||||
if opts.TenantName != "" {
|
||||
opts.Scope.ProjectName = opts.TenantName
|
||||
opts.Scope.DomainID = opts.DomainID
|
||||
opts.Scope.DomainName = opts.DomainName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Scope.ProjectName != "" {
|
||||
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
||||
// ProjectID may not be supplied.
|
||||
if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" {
|
||||
return nil, ErrScopeDomainIDOrDomainName{}
|
||||
}
|
||||
if opts.Scope.ProjectID != "" {
|
||||
return nil, ErrScopeProjectIDOrProjectName{}
|
||||
}
|
||||
|
||||
if opts.Scope.DomainID != "" {
|
||||
// ProjectName + DomainID
|
||||
return map[string]interface{}{
|
||||
"project": map[string]interface{}{
|
||||
"name": &opts.Scope.ProjectName,
|
||||
"domain": map[string]interface{}{"id": &opts.Scope.DomainID},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if opts.Scope.DomainName != "" {
|
||||
// ProjectName + DomainName
|
||||
return map[string]interface{}{
|
||||
"project": map[string]interface{}{
|
||||
"name": &opts.Scope.ProjectName,
|
||||
"domain": map[string]interface{}{"name": &opts.Scope.DomainName},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
} else if opts.Scope.ProjectID != "" {
|
||||
// ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
|
||||
if opts.Scope.DomainID != "" {
|
||||
return nil, ErrScopeProjectIDAlone{}
|
||||
}
|
||||
if opts.Scope.DomainName != "" {
|
||||
return nil, ErrScopeProjectIDAlone{}
|
||||
}
|
||||
|
||||
// ProjectID
|
||||
return map[string]interface{}{
|
||||
"project": map[string]interface{}{
|
||||
"id": &opts.Scope.ProjectID,
|
||||
},
|
||||
}, nil
|
||||
} else if opts.Scope.DomainID != "" {
|
||||
// DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
|
||||
if opts.Scope.DomainName != "" {
|
||||
return nil, ErrScopeDomainIDOrDomainName{}
|
||||
}
|
||||
|
||||
// DomainID
|
||||
return map[string]interface{}{
|
||||
"domain": map[string]interface{}{
|
||||
"id": &opts.Scope.DomainID,
|
||||
},
|
||||
}, nil
|
||||
} else if opts.Scope.DomainName != "" {
|
||||
// DomainName
|
||||
return map[string]interface{}{
|
||||
"domain": map[string]interface{}{
|
||||
"name": &opts.Scope.DomainName,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (opts AuthOptions) CanReauth() bool {
|
||||
return opts.AllowReauth
|
||||
}
|
52
vendor/github.com/gophercloud/gophercloud/auth_result.go
generated
vendored
52
vendor/github.com/gophercloud/gophercloud/auth_result.go
generated
vendored
@@ -1,52 +0,0 @@
|
||||
package gophercloud
|
||||
|
||||
/*
|
||||
AuthResult is the result from the request that was used to obtain a provider
|
||||
client's Keystone token. It is returned from ProviderClient.GetAuthResult().
|
||||
|
||||
The following types satisfy this interface:
|
||||
|
||||
github.com/gophercloud/gophercloud/openstack/identity/v2/tokens.CreateResult
|
||||
github.com/gophercloud/gophercloud/openstack/identity/v3/tokens.CreateResult
|
||||
|
||||
Usage example:
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
||||
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
)
|
||||
|
||||
func GetAuthenticatedUserID(providerClient *gophercloud.ProviderClient) (string, error) {
|
||||
r := providerClient.GetAuthResult()
|
||||
if r == nil {
|
||||
//ProviderClient did not use openstack.Authenticate(), e.g. because token
|
||||
//was set manually with ProviderClient.SetToken()
|
||||
return "", errors.New("no AuthResult available")
|
||||
}
|
||||
switch r := r.(type) {
|
||||
case tokens2.CreateResult:
|
||||
u, err := r.ExtractUser()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return u.ID, nil
|
||||
case tokens3.CreateResult:
|
||||
u, err := r.ExtractUser()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return u.ID, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("got unexpected AuthResult type %t", r))
|
||||
}
|
||||
}
|
||||
|
||||
Both implementing types share a lot of methods by name, like ExtractUser() in
|
||||
this example. But those methods cannot be part of the AuthResult interface
|
||||
because the return types are different (in this case, type tokens2.User vs.
|
||||
type tokens3.User).
|
||||
*/
|
||||
type AuthResult interface {
|
||||
ExtractTokenID() (string, error)
|
||||
}
|
110
vendor/github.com/gophercloud/gophercloud/doc.go
generated
vendored
110
vendor/github.com/gophercloud/gophercloud/doc.go
generated
vendored
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
Package gophercloud provides a multi-vendor interface to OpenStack-compatible
|
||||
clouds. The library has a three-level hierarchy: providers, services, and
|
||||
resources.
|
||||
|
||||
Authenticating with Providers
|
||||
|
||||
Provider structs represent the cloud providers that offer and manage a
|
||||
collection of services. You will generally want to create one Provider
|
||||
client per OpenStack cloud.
|
||||
|
||||
It is now recommended to use the `clientconfig` package found at
|
||||
https://github.com/gophercloud/utils/tree/master/openstack/clientconfig
|
||||
for all authentication purposes.
|
||||
|
||||
The below documentation is still relevant. clientconfig simply implements
|
||||
the below and presents it in an easier and more flexible way.
|
||||
|
||||
Use your OpenStack credentials to create a Provider client. The
|
||||
IdentityEndpoint is typically refered to as "auth_url" or "OS_AUTH_URL" in
|
||||
information provided by the cloud operator. Additionally, the cloud may refer to
|
||||
TenantID or TenantName as project_id and project_name. Credentials are
|
||||
specified like so:
|
||||
|
||||
opts := gophercloud.AuthOptions{
|
||||
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
||||
Username: "{username}",
|
||||
Password: "{password}",
|
||||
TenantID: "{tenant_id}",
|
||||
}
|
||||
|
||||
provider, err := openstack.AuthenticatedClient(opts)
|
||||
|
||||
You can authenticate with a token by doing:
|
||||
|
||||
opts := gophercloud.AuthOptions{
|
||||
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
||||
TokenID: "{token_id}",
|
||||
TenantID: "{tenant_id}",
|
||||
}
|
||||
|
||||
provider, err := openstack.AuthenticatedClient(opts)
|
||||
|
||||
You may also use the openstack.AuthOptionsFromEnv() helper function. This
|
||||
function reads in standard environment variables frequently found in an
|
||||
OpenStack `openrc` file. Again note that Gophercloud currently uses "tenant"
|
||||
instead of "project".
|
||||
|
||||
opts, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(opts)
|
||||
|
||||
Service Clients
|
||||
|
||||
Service structs are specific to a provider and handle all of the logic and
|
||||
operations for a particular OpenStack service. Examples of services include:
|
||||
Compute, Object Storage, Block Storage. In order to define one, you need to
|
||||
pass in the parent provider, like so:
|
||||
|
||||
opts := gophercloud.EndpointOpts{Region: "RegionOne"}
|
||||
|
||||
client, err := openstack.NewComputeV2(provider, opts)
|
||||
|
||||
Resources
|
||||
|
||||
Resource structs are the domain models that services make use of in order
|
||||
to work with and represent the state of API resources:
|
||||
|
||||
server, err := servers.Get(client, "{serverId}").Extract()
|
||||
|
||||
Intermediate Result structs are returned for API operations, which allow
|
||||
generic access to the HTTP headers, response body, and any errors associated
|
||||
with the network transaction. To turn a result into a usable resource struct,
|
||||
you must call the Extract method which is chained to the response, or an
|
||||
Extract function from an applicable extension:
|
||||
|
||||
result := servers.Get(client, "{serverId}")
|
||||
|
||||
// Attempt to extract the disk configuration from the OS-DCF disk config
|
||||
// extension:
|
||||
config, err := diskconfig.ExtractGet(result)
|
||||
|
||||
All requests that enumerate a collection return a Pager struct that is used to
|
||||
iterate through the results one page at a time. Use the EachPage method on that
|
||||
Pager to handle each successive Page in a closure, then use the appropriate
|
||||
extraction method from that request's package to interpret that Page as a slice
|
||||
of results:
|
||||
|
||||
err := servers.List(client, nil).EachPage(func (page pagination.Page) (bool, error) {
|
||||
s, err := servers.ExtractServers(page)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Handle the []servers.Server slice.
|
||||
|
||||
// Return "false" or an error to prematurely stop fetching new pages.
|
||||
return true, nil
|
||||
})
|
||||
|
||||
If you want to obtain the entire collection of pages without doing any
|
||||
intermediary processing on each page, you can use the AllPages method:
|
||||
|
||||
allPages, err := servers.List(client, nil).AllPages()
|
||||
allServers, err := servers.ExtractServers(allPages)
|
||||
|
||||
This top-level package contains utility functions and data types that are used
|
||||
throughout the provider and service packages. Of particular note for end users
|
||||
are the AuthOptions and EndpointOpts structs.
|
||||
*/
|
||||
package gophercloud
|
76
vendor/github.com/gophercloud/gophercloud/endpoint_search.go
generated
vendored
76
vendor/github.com/gophercloud/gophercloud/endpoint_search.go
generated
vendored
@@ -1,76 +0,0 @@
|
||||
package gophercloud
|
||||
|
||||
// Availability indicates to whom a specific service endpoint is accessible:
|
||||
// the internet at large, internal networks only, or only to administrators.
|
||||
// Different identity services use different terminology for these. Identity v2
|
||||
// lists them as different kinds of URLs within the service catalog ("adminURL",
|
||||
// "internalURL", and "publicURL"), while v3 lists them as "Interfaces" in an
|
||||
// endpoint's response.
|
||||
type Availability string
|
||||
|
||||
const (
|
||||
// AvailabilityAdmin indicates that an endpoint is only available to
|
||||
// administrators.
|
||||
AvailabilityAdmin Availability = "admin"
|
||||
|
||||
// AvailabilityPublic indicates that an endpoint is available to everyone on
|
||||
// the internet.
|
||||
AvailabilityPublic Availability = "public"
|
||||
|
||||
// AvailabilityInternal indicates that an endpoint is only available within
|
||||
// the cluster's internal network.
|
||||
AvailabilityInternal Availability = "internal"
|
||||
)
|
||||
|
||||
// EndpointOpts specifies search criteria used by queries against an
|
||||
// OpenStack service catalog. The options must contain enough information to
|
||||
// unambiguously identify one, and only one, endpoint within the catalog.
|
||||
//
|
||||
// Usually, these are passed to service client factory functions in a provider
|
||||
// package, like "openstack.NewComputeV2()".
|
||||
type EndpointOpts struct {
|
||||
// Type [required] is the service type for the client (e.g., "compute",
|
||||
// "object-store"). Generally, this will be supplied by the service client
|
||||
// function, but a user-given value will be honored if provided.
|
||||
Type string
|
||||
|
||||
// Name [optional] is the service name for the client (e.g., "nova") as it
|
||||
// appears in the service catalog. Services can have the same Type but a
|
||||
// different Name, which is why both Type and Name are sometimes needed.
|
||||
Name string
|
||||
|
||||
// Region [required] is the geographic region in which the endpoint resides,
|
||||
// generally specifying which datacenter should house your resources.
|
||||
// Required only for services that span multiple regions.
|
||||
Region string
|
||||
|
||||
// Availability [optional] is the visibility of the endpoint to be returned.
|
||||
// Valid types include the constants AvailabilityPublic, AvailabilityInternal,
|
||||
// or AvailabilityAdmin from this package.
|
||||
//
|
||||
// Availability is not required, and defaults to AvailabilityPublic. Not all
|
||||
// providers or services offer all Availability options.
|
||||
Availability Availability
|
||||
}
|
||||
|
||||
/*
|
||||
EndpointLocator is an internal function to be used by provider implementations.
|
||||
|
||||
It provides an implementation that locates a single endpoint from a service
|
||||
catalog for a specific ProviderClient based on user-provided EndpointOpts. The
|
||||
provider then uses it to discover related ServiceClients.
|
||||
*/
|
||||
type EndpointLocator func(EndpointOpts) (string, error)
|
||||
|
||||
// ApplyDefaults is an internal method to be used by provider implementations.
|
||||
//
|
||||
// It sets EndpointOpts fields if not already set, including a default type.
|
||||
// Currently, EndpointOpts.Availability defaults to the public endpoint.
|
||||
func (eo *EndpointOpts) ApplyDefaults(t string) {
|
||||
if eo.Type == "" {
|
||||
eo.Type = t
|
||||
}
|
||||
if eo.Availability == "" {
|
||||
eo.Availability = AvailabilityPublic
|
||||
}
|
||||
}
|
471
vendor/github.com/gophercloud/gophercloud/errors.go
generated
vendored
471
vendor/github.com/gophercloud/gophercloud/errors.go
generated
vendored
@@ -1,471 +0,0 @@
|
||||
package gophercloud
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BaseError is an error type that all other error types embed.
|
||||
type BaseError struct {
|
||||
DefaultErrString string
|
||||
Info string
|
||||
}
|
||||
|
||||
func (e BaseError) Error() string {
|
||||
e.DefaultErrString = "An error occurred while executing a Gophercloud request."
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
func (e BaseError) choseErrString() string {
|
||||
if e.Info != "" {
|
||||
return e.Info
|
||||
}
|
||||
return e.DefaultErrString
|
||||
}
|
||||
|
||||
// ErrMissingInput is the error when input is required in a particular
|
||||
// situation but not provided by the user
|
||||
type ErrMissingInput struct {
|
||||
BaseError
|
||||
Argument string
|
||||
}
|
||||
|
||||
func (e ErrMissingInput) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Missing input for argument [%s]", e.Argument)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrInvalidInput is an error type used for most non-HTTP Gophercloud errors.
|
||||
type ErrInvalidInput struct {
|
||||
ErrMissingInput
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (e ErrInvalidInput) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Invalid input provided for argument [%s]: [%+v]", e.Argument, e.Value)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrMissingEnvironmentVariable is the error when environment variable is required
|
||||
// in a particular situation but not provided by the user
|
||||
type ErrMissingEnvironmentVariable struct {
|
||||
BaseError
|
||||
EnvironmentVariable string
|
||||
}
|
||||
|
||||
func (e ErrMissingEnvironmentVariable) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Missing environment variable [%s]", e.EnvironmentVariable)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrMissingAnyoneOfEnvironmentVariables is the error when anyone of the environment variables
|
||||
// is required in a particular situation but not provided by the user
|
||||
type ErrMissingAnyoneOfEnvironmentVariables struct {
|
||||
BaseError
|
||||
EnvironmentVariables []string
|
||||
}
|
||||
|
||||
func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf(
|
||||
"Missing one of the following environment variables [%s]",
|
||||
strings.Join(e.EnvironmentVariables, ", "),
|
||||
)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrUnexpectedResponseCode is returned by the Request method when a response code other than
|
||||
// those listed in OkCodes is encountered.
|
||||
type ErrUnexpectedResponseCode struct {
|
||||
BaseError
|
||||
URL string
|
||||
Method string
|
||||
Expected []int
|
||||
Actual int
|
||||
Body []byte
|
||||
}
|
||||
|
||||
func (e ErrUnexpectedResponseCode) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf(
|
||||
"Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s",
|
||||
e.Expected, e.Method, e.URL, e.Actual, e.Body,
|
||||
)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrDefault400 is the default error type returned on a 400 HTTP response code.
|
||||
type ErrDefault400 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault401 is the default error type returned on a 401 HTTP response code.
|
||||
type ErrDefault401 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault403 is the default error type returned on a 403 HTTP response code.
|
||||
type ErrDefault403 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault404 is the default error type returned on a 404 HTTP response code.
|
||||
type ErrDefault404 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault405 is the default error type returned on a 405 HTTP response code.
|
||||
type ErrDefault405 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault408 is the default error type returned on a 408 HTTP response code.
|
||||
type ErrDefault408 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault409 is the default error type returned on a 409 HTTP response code.
|
||||
type ErrDefault409 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault429 is the default error type returned on a 429 HTTP response code.
|
||||
type ErrDefault429 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault500 is the default error type returned on a 500 HTTP response code.
|
||||
type ErrDefault500 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
// ErrDefault503 is the default error type returned on a 503 HTTP response code.
|
||||
type ErrDefault503 struct {
|
||||
ErrUnexpectedResponseCode
|
||||
}
|
||||
|
||||
func (e ErrDefault400) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf(
|
||||
"Bad request with: [%s %s], error message: %s",
|
||||
e.Method, e.URL, e.Body,
|
||||
)
|
||||
return e.choseErrString()
|
||||
}
|
||||
func (e ErrDefault401) Error() string {
|
||||
return "Authentication failed"
|
||||
}
|
||||
func (e ErrDefault403) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf(
|
||||
"Request forbidden: [%s %s], error message: %s",
|
||||
e.Method, e.URL, e.Body,
|
||||
)
|
||||
return e.choseErrString()
|
||||
}
|
||||
func (e ErrDefault404) Error() string {
|
||||
return "Resource not found"
|
||||
}
|
||||
func (e ErrDefault405) Error() string {
|
||||
return "Method not allowed"
|
||||
}
|
||||
func (e ErrDefault408) Error() string {
|
||||
return "The server timed out waiting for the request"
|
||||
}
|
||||
func (e ErrDefault429) Error() string {
|
||||
return "Too many requests have been sent in a given amount of time. Pause" +
|
||||
" requests, wait up to one minute, and try again."
|
||||
}
|
||||
func (e ErrDefault500) Error() string {
|
||||
return "Internal Server Error"
|
||||
}
|
||||
func (e ErrDefault503) Error() string {
|
||||
return "The service is currently unable to handle the request due to a temporary" +
|
||||
" overloading or maintenance. This is a temporary condition. Try again later."
|
||||
}
|
||||
|
||||
// Err400er is the interface resource error types implement to override the error message
|
||||
// from a 400 error.
|
||||
type Err400er interface {
|
||||
Error400(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err401er is the interface resource error types implement to override the error message
|
||||
// from a 401 error.
|
||||
type Err401er interface {
|
||||
Error401(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err403er is the interface resource error types implement to override the error message
|
||||
// from a 403 error.
|
||||
type Err403er interface {
|
||||
Error403(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err404er is the interface resource error types implement to override the error message
|
||||
// from a 404 error.
|
||||
type Err404er interface {
|
||||
Error404(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err405er is the interface resource error types implement to override the error message
|
||||
// from a 405 error.
|
||||
type Err405er interface {
|
||||
Error405(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err408er is the interface resource error types implement to override the error message
|
||||
// from a 408 error.
|
||||
type Err408er interface {
|
||||
Error408(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err409er is the interface resource error types implement to override the error message
|
||||
// from a 409 error.
|
||||
type Err409er interface {
|
||||
Error409(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err429er is the interface resource error types implement to override the error message
|
||||
// from a 429 error.
|
||||
type Err429er interface {
|
||||
Error429(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err500er is the interface resource error types implement to override the error message
|
||||
// from a 500 error.
|
||||
type Err500er interface {
|
||||
Error500(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// Err503er is the interface resource error types implement to override the error message
|
||||
// from a 503 error.
|
||||
type Err503er interface {
|
||||
Error503(ErrUnexpectedResponseCode) error
|
||||
}
|
||||
|
||||
// ErrTimeOut is the error type returned when an operations times out.
|
||||
type ErrTimeOut struct {
|
||||
BaseError
|
||||
}
|
||||
|
||||
func (e ErrTimeOut) Error() string {
|
||||
e.DefaultErrString = "A time out occurred"
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrUnableToReauthenticate is the error type returned when reauthentication fails.
|
||||
type ErrUnableToReauthenticate struct {
|
||||
BaseError
|
||||
ErrOriginal error
|
||||
}
|
||||
|
||||
func (e ErrUnableToReauthenticate) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Unable to re-authenticate: %s", e.ErrOriginal)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrErrorAfterReauthentication is the error type returned when reauthentication
|
||||
// succeeds, but an error occurs afterword (usually an HTTP error).
|
||||
type ErrErrorAfterReauthentication struct {
|
||||
BaseError
|
||||
ErrOriginal error
|
||||
}
|
||||
|
||||
func (e ErrErrorAfterReauthentication) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.ErrOriginal)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrServiceNotFound is returned when no service in a service catalog matches
|
||||
// the provided EndpointOpts. This is generally returned by provider service
|
||||
// factory methods like "NewComputeV2()" and can mean that a service is not
|
||||
// enabled for your account.
|
||||
type ErrServiceNotFound struct {
|
||||
BaseError
|
||||
}
|
||||
|
||||
func (e ErrServiceNotFound) Error() string {
|
||||
e.DefaultErrString = "No suitable service could be found in the service catalog."
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrEndpointNotFound is returned when no available endpoints match the
|
||||
// provided EndpointOpts. This is also generally returned by provider service
|
||||
// factory methods, and usually indicates that a region was specified
|
||||
// incorrectly.
|
||||
type ErrEndpointNotFound struct {
|
||||
BaseError
|
||||
}
|
||||
|
||||
func (e ErrEndpointNotFound) Error() string {
|
||||
e.DefaultErrString = "No suitable endpoint could be found in the service catalog."
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrResourceNotFound is the error when trying to retrieve a resource's
|
||||
// ID by name and the resource doesn't exist.
|
||||
type ErrResourceNotFound struct {
|
||||
BaseError
|
||||
Name string
|
||||
ResourceType string
|
||||
}
|
||||
|
||||
func (e ErrResourceNotFound) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrMultipleResourcesFound is the error when trying to retrieve a resource's
|
||||
// ID by name and multiple resources have the user-provided name.
|
||||
type ErrMultipleResourcesFound struct {
|
||||
BaseError
|
||||
Name string
|
||||
Count int
|
||||
ResourceType string
|
||||
}
|
||||
|
||||
func (e ErrMultipleResourcesFound) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
// ErrUnexpectedType is the error when an unexpected type is encountered
|
||||
type ErrUnexpectedType struct {
|
||||
BaseError
|
||||
Expected string
|
||||
Actual string
|
||||
}
|
||||
|
||||
func (e ErrUnexpectedType) Error() string {
|
||||
e.DefaultErrString = fmt.Sprintf("Expected %s but got %s", e.Expected, e.Actual)
|
||||
return e.choseErrString()
|
||||
}
|
||||
|
||||
func unacceptedAttributeErr(attribute string) string {
|
||||
return fmt.Sprintf("The base Identity V3 API does not accept authentication by %s", attribute)
|
||||
}
|
||||
|
||||
func redundantWithTokenErr(attribute string) string {
|
||||
return fmt.Sprintf("%s may not be provided when authenticating with a TokenID", attribute)
|
||||
}
|
||||
|
||||
func redundantWithUserID(attribute string) string {
|
||||
return fmt.Sprintf("%s may not be provided when authenticating with a UserID", attribute)
|
||||
}
|
||||
|
||||
// ErrAPIKeyProvided indicates that an APIKey was provided but can't be used.
|
||||
type ErrAPIKeyProvided struct{ BaseError }
|
||||
|
||||
func (e ErrAPIKeyProvided) Error() string {
|
||||
return unacceptedAttributeErr("APIKey")
|
||||
}
|
||||
|
||||
// ErrTenantIDProvided indicates that a TenantID was provided but can't be used.
|
||||
type ErrTenantIDProvided struct{ BaseError }
|
||||
|
||||
func (e ErrTenantIDProvided) Error() string {
|
||||
return unacceptedAttributeErr("TenantID")
|
||||
}
|
||||
|
||||
// ErrTenantNameProvided indicates that a TenantName was provided but can't be used.
|
||||
type ErrTenantNameProvided struct{ BaseError }
|
||||
|
||||
func (e ErrTenantNameProvided) Error() string {
|
||||
return unacceptedAttributeErr("TenantName")
|
||||
}
|
||||
|
||||
// ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead.
|
||||
type ErrUsernameWithToken struct{ BaseError }
|
||||
|
||||
func (e ErrUsernameWithToken) Error() string {
|
||||
return redundantWithTokenErr("Username")
|
||||
}
|
||||
|
||||
// ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead.
|
||||
type ErrUserIDWithToken struct{ BaseError }
|
||||
|
||||
func (e ErrUserIDWithToken) Error() string {
|
||||
return redundantWithTokenErr("UserID")
|
||||
}
|
||||
|
||||
// ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead.
|
||||
type ErrDomainIDWithToken struct{ BaseError }
|
||||
|
||||
func (e ErrDomainIDWithToken) Error() string {
|
||||
return redundantWithTokenErr("DomainID")
|
||||
}
|
||||
|
||||
// ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s
|
||||
type ErrDomainNameWithToken struct{ BaseError }
|
||||
|
||||
func (e ErrDomainNameWithToken) Error() string {
|
||||
return redundantWithTokenErr("DomainName")
|
||||
}
|
||||
|
||||
// ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once.
|
||||
type ErrUsernameOrUserID struct{ BaseError }
|
||||
|
||||
func (e ErrUsernameOrUserID) Error() string {
|
||||
return "Exactly one of Username and UserID must be provided for password authentication"
|
||||
}
|
||||
|
||||
// ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used.
|
||||
type ErrDomainIDWithUserID struct{ BaseError }
|
||||
|
||||
func (e ErrDomainIDWithUserID) Error() string {
|
||||
return redundantWithUserID("DomainID")
|
||||
}
|
||||
|
||||
// ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used.
|
||||
type ErrDomainNameWithUserID struct{ BaseError }
|
||||
|
||||
func (e ErrDomainNameWithUserID) Error() string {
|
||||
return redundantWithUserID("DomainName")
|
||||
}
|
||||
|
||||
// ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it.
|
||||
// It may also indicate that both a DomainID and a DomainName were provided at once.
|
||||
type ErrDomainIDOrDomainName struct{ BaseError }
|
||||
|
||||
func (e ErrDomainIDOrDomainName) Error() string {
|
||||
return "You must provide exactly one of DomainID or DomainName to authenticate by Username"
|
||||
}
|
||||
|
||||
// ErrMissingPassword indicates that no password was provided and no token is available.
|
||||
type ErrMissingPassword struct{ BaseError }
|
||||
|
||||
func (e ErrMissingPassword) Error() string {
|
||||
return "You must provide a password to authenticate"
|
||||
}
|
||||
|
||||
// ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present.
|
||||
type ErrScopeDomainIDOrDomainName struct{ BaseError }
|
||||
|
||||
func (e ErrScopeDomainIDOrDomainName) Error() string {
|
||||
return "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName"
|
||||
}
|
||||
|
||||
// ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope.
|
||||
type ErrScopeProjectIDOrProjectName struct{ BaseError }
|
||||
|
||||
func (e ErrScopeProjectIDOrProjectName) Error() string {
|
||||
return "You must provide at most one of ProjectID or ProjectName in a Scope"
|
||||
}
|
||||
|
||||
// ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope.
|
||||
type ErrScopeProjectIDAlone struct{ BaseError }
|
||||
|
||||
func (e ErrScopeProjectIDAlone) Error() string {
|
||||
return "ProjectID must be supplied alone in a Scope"
|
||||
}
|
||||
|
||||
// ErrScopeEmpty indicates that no credentials were provided in a Scope.
|
||||
type ErrScopeEmpty struct{ BaseError }
|
||||
|
||||
func (e ErrScopeEmpty) Error() string {
|
||||
return "You must provide either a Project or Domain in a Scope"
|
||||
}
|
||||
|
||||
// ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name
|
||||
type ErrAppCredMissingSecret struct{ BaseError }
|
||||
|
||||
func (e ErrAppCredMissingSecret) Error() string {
|
||||
return "You must provide an Application Credential Secret"
|
||||
}
|
125
vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go
generated
vendored
125
vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go
generated
vendored
@@ -1,125 +0,0 @@
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
var nilOptions = gophercloud.AuthOptions{}
|
||||
|
||||
/*
|
||||
AuthOptionsFromEnv fills out an identity.AuthOptions structure with the
|
||||
settings found on the various OpenStack OS_* environment variables.
|
||||
|
||||
The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME,
|
||||
OS_PASSWORD and OS_PROJECT_ID.
|
||||
|
||||
Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must have settings,
|
||||
or an error will result. OS_PROJECT_ID, is optional.
|
||||
|
||||
OS_TENANT_ID and OS_TENANT_NAME are deprecated forms of OS_PROJECT_ID and
|
||||
OS_PROJECT_NAME and the latter are expected against a v3 auth api.
|
||||
|
||||
If OS_PROJECT_ID and OS_PROJECT_NAME are set, they will still be referred
|
||||
as "tenant" in Gophercloud.
|
||||
|
||||
If OS_PROJECT_NAME is set, it requires OS_PROJECT_ID to be set as well to
|
||||
handle projects not on the default domain.
|
||||
|
||||
To use this function, first set the OS_* environment variables (for example,
|
||||
by sourcing an `openrc` file), then:
|
||||
|
||||
opts, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(opts)
|
||||
*/
|
||||
func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
||||
authURL := os.Getenv("OS_AUTH_URL")
|
||||
username := os.Getenv("OS_USERNAME")
|
||||
userID := os.Getenv("OS_USERID")
|
||||
password := os.Getenv("OS_PASSWORD")
|
||||
tenantID := os.Getenv("OS_TENANT_ID")
|
||||
tenantName := os.Getenv("OS_TENANT_NAME")
|
||||
domainID := os.Getenv("OS_DOMAIN_ID")
|
||||
domainName := os.Getenv("OS_DOMAIN_NAME")
|
||||
applicationCredentialID := os.Getenv("OS_APPLICATION_CREDENTIAL_ID")
|
||||
applicationCredentialName := os.Getenv("OS_APPLICATION_CREDENTIAL_NAME")
|
||||
applicationCredentialSecret := os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET")
|
||||
|
||||
// If OS_PROJECT_ID is set, overwrite tenantID with the value.
|
||||
if v := os.Getenv("OS_PROJECT_ID"); v != "" {
|
||||
tenantID = v
|
||||
}
|
||||
|
||||
// If OS_PROJECT_NAME is set, overwrite tenantName with the value.
|
||||
if v := os.Getenv("OS_PROJECT_NAME"); v != "" {
|
||||
tenantName = v
|
||||
}
|
||||
|
||||
if authURL == "" {
|
||||
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||
EnvironmentVariable: "OS_AUTH_URL",
|
||||
}
|
||||
return nilOptions, err
|
||||
}
|
||||
|
||||
if userID == "" && username == "" {
|
||||
// Empty username and userID could be ignored, when applicationCredentialID and applicationCredentialSecret are set
|
||||
if applicationCredentialID == "" && applicationCredentialSecret == "" {
|
||||
err := gophercloud.ErrMissingAnyoneOfEnvironmentVariables{
|
||||
EnvironmentVariables: []string{"OS_USERID", "OS_USERNAME"},
|
||||
}
|
||||
return nilOptions, err
|
||||
}
|
||||
}
|
||||
|
||||
if password == "" && applicationCredentialID == "" && applicationCredentialName == "" {
|
||||
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||
EnvironmentVariable: "OS_PASSWORD",
|
||||
}
|
||||
return nilOptions, err
|
||||
}
|
||||
|
||||
if (applicationCredentialID != "" || applicationCredentialName != "") && applicationCredentialSecret == "" {
|
||||
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||
EnvironmentVariable: "OS_APPLICATION_CREDENTIAL_SECRET",
|
||||
}
|
||||
return nilOptions, err
|
||||
}
|
||||
|
||||
if domainID == "" && domainName == "" && tenantID == "" && tenantName != "" {
|
||||
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||
EnvironmentVariable: "OS_PROJECT_ID",
|
||||
}
|
||||
return nilOptions, err
|
||||
}
|
||||
|
||||
if applicationCredentialID == "" && applicationCredentialName != "" && applicationCredentialSecret != "" {
|
||||
if userID == "" && username == "" {
|
||||
return nilOptions, gophercloud.ErrMissingAnyoneOfEnvironmentVariables{
|
||||
EnvironmentVariables: []string{"OS_USERID", "OS_USERNAME"},
|
||||
}
|
||||
}
|
||||
if username != "" && domainID == "" && domainName == "" {
|
||||
return nilOptions, gophercloud.ErrMissingAnyoneOfEnvironmentVariables{
|
||||
EnvironmentVariables: []string{"OS_DOMAIN_ID", "OS_DOMAIN_NAME"},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ao := gophercloud.AuthOptions{
|
||||
IdentityEndpoint: authURL,
|
||||
UserID: userID,
|
||||
Username: username,
|
||||
Password: password,
|
||||
TenantID: tenantID,
|
||||
TenantName: tenantName,
|
||||
DomainID: domainID,
|
||||
DomainName: domainName,
|
||||
ApplicationCredentialID: applicationCredentialID,
|
||||
ApplicationCredentialName: applicationCredentialName,
|
||||
ApplicationCredentialSecret: applicationCredentialSecret,
|
||||
}
|
||||
|
||||
return ao, nil
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
Package volumeactions provides information and interaction with volumes in the
|
||||
OpenStack Block Storage service. A volume is a detachable block storage
|
||||
device, akin to a USB hard drive.
|
||||
|
||||
Example of Attaching a Volume to an Instance
|
||||
|
||||
attachOpts := volumeactions.AttachOpts{
|
||||
MountPoint: "/mnt",
|
||||
Mode: "rw",
|
||||
InstanceUUID: server.ID,
|
||||
}
|
||||
|
||||
err := volumeactions.Attach(client, volume.ID, attachOpts).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
detachOpts := volumeactions.DetachOpts{
|
||||
AttachmentID: volume.Attachments[0].AttachmentID,
|
||||
}
|
||||
|
||||
err = volumeactions.Detach(client, volume.ID, detachOpts).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
Example of Creating an Image from a Volume
|
||||
|
||||
uploadImageOpts := volumeactions.UploadImageOpts{
|
||||
ImageName: "my_vol",
|
||||
Force: true,
|
||||
}
|
||||
|
||||
volumeImage, err := volumeactions.UploadImage(client, volume.ID, uploadImageOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%+v\n", volumeImage)
|
||||
|
||||
Example of Extending a Volume's Size
|
||||
|
||||
extendOpts := volumeactions.ExtendSizeOpts{
|
||||
NewSize: 100,
|
||||
}
|
||||
|
||||
err := volumeactions.ExtendSize(client, volume.ID, extendOpts).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example of Initializing a Volume Connection
|
||||
|
||||
connectOpts := &volumeactions.InitializeConnectionOpts{
|
||||
IP: "127.0.0.1",
|
||||
Host: "stack",
|
||||
Initiator: "iqn.1994-05.com.redhat:17cf566367d2",
|
||||
Multipath: gophercloud.Disabled,
|
||||
Platform: "x86_64",
|
||||
OSType: "linux2",
|
||||
}
|
||||
|
||||
connectionInfo, err := volumeactions.InitializeConnection(client, volume.ID, connectOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%+v\n", connectionInfo["data"])
|
||||
|
||||
terminateOpts := &volumeactions.InitializeConnectionOpts{
|
||||
IP: "127.0.0.1",
|
||||
Host: "stack",
|
||||
Initiator: "iqn.1994-05.com.redhat:17cf566367d2",
|
||||
Multipath: gophercloud.Disabled,
|
||||
Platform: "x86_64",
|
||||
OSType: "linux2",
|
||||
}
|
||||
|
||||
err = volumeactions.TerminateConnection(client, volume.ID, terminateOpts).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package volumeactions
|
@@ -1,269 +0,0 @@
|
||||
package volumeactions
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
// AttachOptsBuilder allows extensions to add additional parameters to the
|
||||
// Attach request.
|
||||
type AttachOptsBuilder interface {
|
||||
ToVolumeAttachMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// AttachMode describes the attachment mode for volumes.
|
||||
type AttachMode string
|
||||
|
||||
// These constants determine how a volume is attached.
|
||||
const (
|
||||
ReadOnly AttachMode = "ro"
|
||||
ReadWrite AttachMode = "rw"
|
||||
)
|
||||
|
||||
// AttachOpts contains options for attaching a Volume.
|
||||
type AttachOpts struct {
|
||||
// The mountpoint of this volume.
|
||||
MountPoint string `json:"mountpoint,omitempty"`
|
||||
|
||||
// The nova instance ID, can't set simultaneously with HostName.
|
||||
InstanceUUID string `json:"instance_uuid,omitempty"`
|
||||
|
||||
// The hostname of baremetal host, can't set simultaneously with InstanceUUID.
|
||||
HostName string `json:"host_name,omitempty"`
|
||||
|
||||
// Mount mode of this volume.
|
||||
Mode AttachMode `json:"mode,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeAttachMap assembles a request body based on the contents of a
|
||||
// AttachOpts.
|
||||
func (opts AttachOpts) ToVolumeAttachMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "os-attach")
|
||||
}
|
||||
|
||||
// Attach will attach a volume based on the values in AttachOpts.
|
||||
func Attach(client *gophercloud.ServiceClient, id string, opts AttachOptsBuilder) (r AttachResult) {
|
||||
b, err := opts.ToVolumeAttachMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// BeginDetach will mark the volume as detaching.
|
||||
func BeginDetaching(client *gophercloud.ServiceClient, id string) (r BeginDetachingResult) {
|
||||
b := map[string]interface{}{"os-begin_detaching": make(map[string]interface{})}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// DetachOptsBuilder allows extensions to add additional parameters to the
|
||||
// Detach request.
|
||||
type DetachOptsBuilder interface {
|
||||
ToVolumeDetachMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// DetachOpts contains options for detaching a Volume.
|
||||
type DetachOpts struct {
|
||||
// AttachmentID is the ID of the attachment between a volume and instance.
|
||||
AttachmentID string `json:"attachment_id,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeDetachMap assembles a request body based on the contents of a
|
||||
// DetachOpts.
|
||||
func (opts DetachOpts) ToVolumeDetachMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "os-detach")
|
||||
}
|
||||
|
||||
// Detach will detach a volume based on volume ID.
|
||||
func Detach(client *gophercloud.ServiceClient, id string, opts DetachOptsBuilder) (r DetachResult) {
|
||||
b, err := opts.ToVolumeDetachMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Reserve will reserve a volume based on volume ID.
|
||||
func Reserve(client *gophercloud.ServiceClient, id string) (r ReserveResult) {
|
||||
b := map[string]interface{}{"os-reserve": make(map[string]interface{})}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201, 202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Unreserve will unreserve a volume based on volume ID.
|
||||
func Unreserve(client *gophercloud.ServiceClient, id string) (r UnreserveResult) {
|
||||
b := map[string]interface{}{"os-unreserve": make(map[string]interface{})}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201, 202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// InitializeConnectionOptsBuilder allows extensions to add additional parameters to the
|
||||
// InitializeConnection request.
|
||||
type InitializeConnectionOptsBuilder interface {
|
||||
ToVolumeInitializeConnectionMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// InitializeConnectionOpts hosts options for InitializeConnection.
|
||||
// The fields are specific to the storage driver in use and the destination
|
||||
// attachment.
|
||||
type InitializeConnectionOpts struct {
|
||||
IP string `json:"ip,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Initiator string `json:"initiator,omitempty"`
|
||||
Wwpns []string `json:"wwpns,omitempty"`
|
||||
Wwnns string `json:"wwnns,omitempty"`
|
||||
Multipath *bool `json:"multipath,omitempty"`
|
||||
Platform string `json:"platform,omitempty"`
|
||||
OSType string `json:"os_type,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeInitializeConnectionMap assembles a request body based on the contents of a
|
||||
// InitializeConnectionOpts.
|
||||
func (opts InitializeConnectionOpts) ToVolumeInitializeConnectionMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "connector")
|
||||
return map[string]interface{}{"os-initialize_connection": b}, err
|
||||
}
|
||||
|
||||
// InitializeConnection initializes an iSCSI connection by volume ID.
|
||||
func InitializeConnection(client *gophercloud.ServiceClient, id string, opts InitializeConnectionOptsBuilder) (r InitializeConnectionResult) {
|
||||
b, err := opts.ToVolumeInitializeConnectionMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201, 202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// TerminateConnectionOptsBuilder allows extensions to add additional parameters to the
|
||||
// TerminateConnection request.
|
||||
type TerminateConnectionOptsBuilder interface {
|
||||
ToVolumeTerminateConnectionMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// TerminateConnectionOpts hosts options for TerminateConnection.
|
||||
type TerminateConnectionOpts struct {
|
||||
IP string `json:"ip,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Initiator string `json:"initiator,omitempty"`
|
||||
Wwpns []string `json:"wwpns,omitempty"`
|
||||
Wwnns string `json:"wwnns,omitempty"`
|
||||
Multipath *bool `json:"multipath,omitempty"`
|
||||
Platform string `json:"platform,omitempty"`
|
||||
OSType string `json:"os_type,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeTerminateConnectionMap assembles a request body based on the contents of a
|
||||
// TerminateConnectionOpts.
|
||||
func (opts TerminateConnectionOpts) ToVolumeTerminateConnectionMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "connector")
|
||||
return map[string]interface{}{"os-terminate_connection": b}, err
|
||||
}
|
||||
|
||||
// TerminateConnection terminates an iSCSI connection by volume ID.
|
||||
func TerminateConnection(client *gophercloud.ServiceClient, id string, opts TerminateConnectionOptsBuilder) (r TerminateConnectionResult) {
|
||||
b, err := opts.ToVolumeTerminateConnectionMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// ExtendSizeOptsBuilder allows extensions to add additional parameters to the
|
||||
// ExtendSize request.
|
||||
type ExtendSizeOptsBuilder interface {
|
||||
ToVolumeExtendSizeMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// ExtendSizeOpts contains options for extending the size of an existing Volume.
|
||||
// This object is passed to the volumes.ExtendSize function.
|
||||
type ExtendSizeOpts struct {
|
||||
// NewSize is the new size of the volume, in GB.
|
||||
NewSize int `json:"new_size" required:"true"`
|
||||
}
|
||||
|
||||
// ToVolumeExtendSizeMap assembles a request body based on the contents of an
|
||||
// ExtendSizeOpts.
|
||||
func (opts ExtendSizeOpts) ToVolumeExtendSizeMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "os-extend")
|
||||
}
|
||||
|
||||
// ExtendSize will extend the size of the volume based on the provided information.
|
||||
// This operation does not return a response body.
|
||||
func ExtendSize(client *gophercloud.ServiceClient, id string, opts ExtendSizeOptsBuilder) (r ExtendSizeResult) {
|
||||
b, err := opts.ToVolumeExtendSizeMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// UploadImageOptsBuilder allows extensions to add additional parameters to the
|
||||
// UploadImage request.
|
||||
type UploadImageOptsBuilder interface {
|
||||
ToVolumeUploadImageMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UploadImageOpts contains options for uploading a Volume to image storage.
|
||||
type UploadImageOpts struct {
|
||||
// Container format, may be bare, ofv, ova, etc.
|
||||
ContainerFormat string `json:"container_format,omitempty"`
|
||||
|
||||
// Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc.
|
||||
DiskFormat string `json:"disk_format,omitempty"`
|
||||
|
||||
// The name of image that will be stored in glance.
|
||||
ImageName string `json:"image_name,omitempty"`
|
||||
|
||||
// Force image creation, usable if volume attached to instance.
|
||||
Force bool `json:"force,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeUploadImageMap assembles a request body based on the contents of a
|
||||
// UploadImageOpts.
|
||||
func (opts UploadImageOpts) ToVolumeUploadImageMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "os-volume_upload_image")
|
||||
}
|
||||
|
||||
// UploadImage will upload an image based on the values in UploadImageOptsBuilder.
|
||||
func UploadImage(client *gophercloud.ServiceClient, id string, opts UploadImageOptsBuilder) (r UploadImageResult) {
|
||||
b, err := opts.ToVolumeUploadImageMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// ForceDelete will delete the volume regardless of state.
|
||||
func ForceDelete(client *gophercloud.ServiceClient, id string) (r ForceDeleteResult) {
|
||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-force_delete": ""}, nil, nil)
|
||||
return
|
||||
}
|
@@ -1,191 +0,0 @@
|
||||
package volumeactions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
// AttachResult contains the response body and error from an Attach request.
|
||||
type AttachResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// BeginDetachingResult contains the response body and error from a BeginDetach
|
||||
// request.
|
||||
type BeginDetachingResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// DetachResult contains the response body and error from a Detach request.
|
||||
type DetachResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// UploadImageResult contains the response body and error from an UploadImage
|
||||
// request.
|
||||
type UploadImageResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// ReserveResult contains the response body and error from a Reserve request.
|
||||
type ReserveResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// UnreserveResult contains the response body and error from an Unreserve
|
||||
// request.
|
||||
type UnreserveResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// TerminateConnectionResult contains the response body and error from a
|
||||
// TerminateConnection request.
|
||||
type TerminateConnectionResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// InitializeConnectionResult contains the response body and error from an
|
||||
// InitializeConnection request.
|
||||
type InitializeConnectionResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// ExtendSizeResult contains the response body and error from an ExtendSize request.
|
||||
type ExtendSizeResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// Extract will get the connection information out of the
|
||||
// InitializeConnectionResult object.
|
||||
//
|
||||
// This will be a generic map[string]interface{} and the results will be
|
||||
// dependent on the type of connection made.
|
||||
func (r InitializeConnectionResult) Extract() (map[string]interface{}, error) {
|
||||
var s struct {
|
||||
ConnectionInfo map[string]interface{} `json:"connection_info"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.ConnectionInfo, err
|
||||
}
|
||||
|
||||
// ImageVolumeType contains volume type information obtained from UploadImage
|
||||
// action.
|
||||
type ImageVolumeType struct {
|
||||
// The ID of a volume type.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Human-readable display name for the volume type.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Human-readable description for the volume type.
|
||||
Description string `json:"display_description"`
|
||||
|
||||
// Flag for public access.
|
||||
IsPublic bool `json:"is_public"`
|
||||
|
||||
// Extra specifications for volume type.
|
||||
ExtraSpecs map[string]interface{} `json:"extra_specs"`
|
||||
|
||||
// ID of quality of service specs.
|
||||
QosSpecsID string `json:"qos_specs_id"`
|
||||
|
||||
// Flag for deletion status of volume type.
|
||||
Deleted bool `json:"deleted"`
|
||||
|
||||
// The date when volume type was deleted.
|
||||
DeletedAt time.Time `json:"-"`
|
||||
|
||||
// The date when volume type was created.
|
||||
CreatedAt time.Time `json:"-"`
|
||||
|
||||
// The date when this volume was last updated.
|
||||
UpdatedAt time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (r *ImageVolumeType) UnmarshalJSON(b []byte) error {
|
||||
type tmp ImageVolumeType
|
||||
var s struct {
|
||||
tmp
|
||||
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
||||
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
||||
DeletedAt gophercloud.JSONRFC3339MilliNoZ `json:"deleted_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = ImageVolumeType(s.tmp)
|
||||
|
||||
r.CreatedAt = time.Time(s.CreatedAt)
|
||||
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||
r.DeletedAt = time.Time(s.DeletedAt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// VolumeImage contains information about volume uploaded to an image service.
|
||||
type VolumeImage struct {
|
||||
// The ID of a volume an image is created from.
|
||||
VolumeID string `json:"id"`
|
||||
|
||||
// Container format, may be bare, ofv, ova, etc.
|
||||
ContainerFormat string `json:"container_format"`
|
||||
|
||||
// Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc.
|
||||
DiskFormat string `json:"disk_format"`
|
||||
|
||||
// Human-readable description for the volume.
|
||||
Description string `json:"display_description"`
|
||||
|
||||
// The ID of the created image.
|
||||
ImageID string `json:"image_id"`
|
||||
|
||||
// Human-readable display name for the image.
|
||||
ImageName string `json:"image_name"`
|
||||
|
||||
// Size of the volume in GB.
|
||||
Size int `json:"size"`
|
||||
|
||||
// Current status of the volume.
|
||||
Status string `json:"status"`
|
||||
|
||||
// The date when this volume was last updated.
|
||||
UpdatedAt time.Time `json:"-"`
|
||||
|
||||
// Volume type object of used volume.
|
||||
VolumeType ImageVolumeType `json:"volume_type"`
|
||||
}
|
||||
|
||||
func (r *VolumeImage) UnmarshalJSON(b []byte) error {
|
||||
type tmp VolumeImage
|
||||
var s struct {
|
||||
tmp
|
||||
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = VolumeImage(s.tmp)
|
||||
|
||||
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Extract will get an object with info about the uploaded image out of the
|
||||
// UploadImageResult object.
|
||||
func (r UploadImageResult) Extract() (VolumeImage, error) {
|
||||
var s struct {
|
||||
VolumeImage VolumeImage `json:"os-volume_upload_image"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.VolumeImage, err
|
||||
}
|
||||
|
||||
// ForceDeleteResult contains the response body and error from a ForceDelete request.
|
||||
type ForceDeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
package volumeactions
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func actionURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL("volumes", id, "action")
|
||||
}
|
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/doc.go
generated
vendored
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/doc.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
// Package volumes provides information and interaction with volumes in the
|
||||
// OpenStack Block Storage service. A volume is a detachable block storage
|
||||
// device, akin to a USB hard drive. It can only be attached to one instance at
|
||||
// a time.
|
||||
package volumes
|
172
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go
generated
vendored
172
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go
generated
vendored
@@ -1,172 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToVolumeCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts contains options for creating a Volume. This object is passed to
|
||||
// the volumes.Create function. For more information about these parameters,
|
||||
// see the Volume object.
|
||||
type CreateOpts struct {
|
||||
Size int `json:"size" required:"true"`
|
||||
AvailabilityZone string `json:"availability_zone,omitempty"`
|
||||
Description string `json:"display_description,omitempty"`
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
Name string `json:"display_name,omitempty"`
|
||||
SnapshotID string `json:"snapshot_id,omitempty"`
|
||||
SourceVolID string `json:"source_volid,omitempty"`
|
||||
ImageID string `json:"imageRef,omitempty"`
|
||||
VolumeType string `json:"volume_type,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeCreateMap assembles a request body based on the contents of a
|
||||
// CreateOpts.
|
||||
func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "volume")
|
||||
}
|
||||
|
||||
// Create will create a new Volume based on the values in CreateOpts. To extract
|
||||
// the Volume object from the response, call the Extract method on the
|
||||
// CreateResult.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToVolumeCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will delete the existing Volume with the provided ID.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the List
|
||||
// request.
|
||||
type ListOptsBuilder interface {
|
||||
ToVolumeListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts holds options for listing Volumes. It is passed to the volumes.List
|
||||
// function.
|
||||
type ListOpts struct {
|
||||
// admin-only option. Set it to true to see all tenant volumes.
|
||||
AllTenants bool `q:"all_tenants"`
|
||||
// List only volumes that contain Metadata.
|
||||
Metadata map[string]string `q:"metadata"`
|
||||
// List only volumes that have Name as the display name.
|
||||
Name string `q:"display_name"`
|
||||
// List only volumes that have a status of Status.
|
||||
Status string `q:"status"`
|
||||
}
|
||||
|
||||
// ToVolumeListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToVolumeListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List returns Volumes optionally limited by the conditions provided in ListOpts.
|
||||
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := listURL(client)
|
||||
if opts != nil {
|
||||
query, err := opts.ToVolumeListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return VolumePage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToVolumeUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts contain options for updating an existing Volume. This object is passed
|
||||
// to the volumes.Update function. For more information about the parameters, see
|
||||
// the Volume object.
|
||||
type UpdateOpts struct {
|
||||
Name *string `json:"display_name,omitempty"`
|
||||
Description *string `json:"display_description,omitempty"`
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeUpdateMap assembles a request body based on the contents of an
|
||||
// UpdateOpts.
|
||||
func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "volume")
|
||||
}
|
||||
|
||||
// Update will update the Volume with provided information. To extract the updated
|
||||
// Volume from the response, call the Extract method on the UpdateResult.
|
||||
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToVolumeUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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,
|
||||
}
|
||||
|
||||
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"}
|
||||
}
|
||||
}
|
109
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/results.go
generated
vendored
109
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/results.go
generated
vendored
@@ -1,109 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Volume contains all the information associated with an OpenStack Volume.
|
||||
type Volume struct {
|
||||
// Current status of the volume.
|
||||
Status string `json:"status"`
|
||||
// Human-readable display name for the volume.
|
||||
Name string `json:"display_name"`
|
||||
// Instances onto which the volume is attached.
|
||||
Attachments []map[string]interface{} `json:"attachments"`
|
||||
// This parameter is no longer used.
|
||||
AvailabilityZone string `json:"availability_zone"`
|
||||
// Indicates whether this is a bootable volume.
|
||||
Bootable string `json:"bootable"`
|
||||
// The date when this volume was created.
|
||||
CreatedAt time.Time `json:"-"`
|
||||
// Human-readable description for the volume.
|
||||
Description string `json:"display_description"`
|
||||
// The type of volume to create, either SATA or SSD.
|
||||
VolumeType string `json:"volume_type"`
|
||||
// The ID of the snapshot from which the volume was created
|
||||
SnapshotID string `json:"snapshot_id"`
|
||||
// The ID of another block storage volume from which the current volume was created
|
||||
SourceVolID string `json:"source_volid"`
|
||||
// Arbitrary key-value pairs defined by the user.
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
// Unique identifier for the volume.
|
||||
ID string `json:"id"`
|
||||
// Size of the volume in GB.
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
func (r *Volume) UnmarshalJSON(b []byte) error {
|
||||
type tmp Volume
|
||||
var s struct {
|
||||
tmp
|
||||
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = Volume(s.tmp)
|
||||
|
||||
r.CreatedAt = time.Time(s.CreatedAt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateResult contains the response body and error from a Create request.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult contains the response body and error from a Get request.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult contains the response body and error from a Delete request.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
||||
type VolumePage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if a VolumePage contains no Volumes.
|
||||
func (r VolumePage) IsEmpty() (bool, error) {
|
||||
volumes, err := ExtractVolumes(r)
|
||||
return len(volumes) == 0, err
|
||||
}
|
||||
|
||||
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
|
||||
func ExtractVolumes(r pagination.Page) ([]Volume, error) {
|
||||
var s struct {
|
||||
Volumes []Volume `json:"volumes"`
|
||||
}
|
||||
err := (r.(VolumePage)).ExtractInto(&s)
|
||||
return s.Volumes, err
|
||||
}
|
||||
|
||||
// UpdateResult contains the response body and error from an Update request.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract will get the Volume object out of the commonResult object.
|
||||
func (r commonResult) Extract() (*Volume, error) {
|
||||
var s struct {
|
||||
Volume *Volume `json:"volume"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Volume, err
|
||||
}
|
23
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/urls.go
generated
vendored
23
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/urls.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func createURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("volumes")
|
||||
}
|
||||
|
||||
func listURL(c *gophercloud.ServiceClient) string {
|
||||
return createURL(c)
|
||||
}
|
||||
|
||||
func deleteURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL("volumes", id)
|
||||
}
|
||||
|
||||
func getURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(c, id)
|
||||
}
|
||||
|
||||
func updateURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(c, id)
|
||||
}
|
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/util.go
generated
vendored
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/util.go
generated
vendored
@@ -1,22 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
// WaitForStatus will continually poll the resource, checking for a particular
|
||||
// status. It will do this for the amount of seconds defined.
|
||||
func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error {
|
||||
return gophercloud.WaitFor(secs, func() (bool, error) {
|
||||
current, err := Get(c, id).Extract()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if current.Status == status {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/doc.go
generated
vendored
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/doc.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
// Package volumes provides information and interaction with volumes in the
|
||||
// OpenStack Block Storage service. A volume is a detachable block storage
|
||||
// device, akin to a USB hard drive. It can only be attached to one instance at
|
||||
// a time.
|
||||
package volumes
|
235
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go
generated
vendored
235
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go
generated
vendored
@@ -1,235 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToVolumeCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts contains options for creating a Volume. This object is passed to
|
||||
// the volumes.Create function. For more information about these parameters,
|
||||
// see the Volume object.
|
||||
type CreateOpts struct {
|
||||
// The size of the volume, in GB
|
||||
Size int `json:"size" required:"true"`
|
||||
// The availability zone
|
||||
AvailabilityZone string `json:"availability_zone,omitempty"`
|
||||
// ConsistencyGroupID is the ID of a consistency group
|
||||
ConsistencyGroupID string `json:"consistencygroup_id,omitempty"`
|
||||
// The volume description
|
||||
Description string `json:"description,omitempty"`
|
||||
// One or more metadata key and value pairs to associate with the volume
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
// The volume name
|
||||
Name string `json:"name,omitempty"`
|
||||
// the ID of the existing volume snapshot
|
||||
SnapshotID string `json:"snapshot_id,omitempty"`
|
||||
// SourceReplica is a UUID of an existing volume to replicate with
|
||||
SourceReplica string `json:"source_replica,omitempty"`
|
||||
// the ID of the existing volume
|
||||
SourceVolID string `json:"source_volid,omitempty"`
|
||||
// The ID of the image from which you want to create the volume.
|
||||
// Required to create a bootable volume.
|
||||
ImageID string `json:"imageRef,omitempty"`
|
||||
// The associated volume type
|
||||
VolumeType string `json:"volume_type,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeCreateMap assembles a request body based on the contents of a
|
||||
// CreateOpts.
|
||||
func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "volume")
|
||||
}
|
||||
|
||||
// Create will create a new Volume based on the values in CreateOpts. To extract
|
||||
// the Volume object from the response, call the Extract method on the
|
||||
// CreateResult.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToVolumeCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteOptsBuilder allows extensions to add additional parameters to the
|
||||
// Delete request.
|
||||
type DeleteOptsBuilder interface {
|
||||
ToVolumeDeleteQuery() (string, error)
|
||||
}
|
||||
|
||||
// DeleteOpts contains options for deleting a Volume. This object is passed to
|
||||
// the volumes.Delete function.
|
||||
type DeleteOpts struct {
|
||||
// Delete all snapshots of this volume as well.
|
||||
Cascade bool `q:"cascade"`
|
||||
}
|
||||
|
||||
// ToLoadBalancerDeleteQuery formats a DeleteOpts into a query string.
|
||||
func (opts DeleteOpts) ToVolumeDeleteQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// Delete will delete the existing Volume with the provided ID.
|
||||
func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) {
|
||||
url := deleteURL(client, id)
|
||||
if opts != nil {
|
||||
query, err := opts.ToVolumeDeleteQuery()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
url += query
|
||||
}
|
||||
_, r.Err = client.Delete(url, nil)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the List
|
||||
// request.
|
||||
type ListOptsBuilder interface {
|
||||
ToVolumeListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts holds options for listing Volumes. It is passed to the volumes.List
|
||||
// function.
|
||||
type ListOpts struct {
|
||||
// AllTenants will retrieve volumes of all tenants/projects.
|
||||
AllTenants bool `q:"all_tenants"`
|
||||
|
||||
// Metadata will filter results based on specified metadata.
|
||||
Metadata map[string]string `q:"metadata"`
|
||||
|
||||
// Name will filter by the specified volume name.
|
||||
Name string `q:"name"`
|
||||
|
||||
// Status will filter by the specified status.
|
||||
Status string `q:"status"`
|
||||
|
||||
// TenantID will filter by a specific tenant/project ID.
|
||||
// Setting AllTenants is required for this.
|
||||
TenantID string `q:"project_id"`
|
||||
|
||||
// Comma-separated list of sort keys and optional sort directions in the
|
||||
// form of <key>[:<direction>].
|
||||
Sort string `q:"sort"`
|
||||
|
||||
// Requests a page size of items.
|
||||
Limit int `q:"limit"`
|
||||
|
||||
// Used in conjunction with limit to return a slice of items.
|
||||
Offset int `q:"offset"`
|
||||
|
||||
// The ID of the last-seen item.
|
||||
Marker string `q:"marker"`
|
||||
}
|
||||
|
||||
// ToVolumeListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToVolumeListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List returns Volumes optionally limited by the conditions provided in ListOpts.
|
||||
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := listURL(client)
|
||||
if opts != nil {
|
||||
query, err := opts.ToVolumeListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return VolumePage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToVolumeUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts contain options for updating an existing Volume. This object is passed
|
||||
// to the volumes.Update function. For more information about the parameters, see
|
||||
// the Volume object.
|
||||
type UpdateOpts struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeUpdateMap assembles a request body based on the contents of an
|
||||
// UpdateOpts.
|
||||
func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "volume")
|
||||
}
|
||||
|
||||
// Update will update the Volume with provided information. To extract the updated
|
||||
// Volume from the response, call the Extract method on the UpdateResult.
|
||||
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToVolumeUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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,
|
||||
}
|
||||
|
||||
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"}
|
||||
}
|
||||
}
|
167
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
167
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
@@ -1,167 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
type Attachment struct {
|
||||
AttachedAt time.Time `json:"-"`
|
||||
AttachmentID string `json:"attachment_id"`
|
||||
Device string `json:"device"`
|
||||
HostName string `json:"host_name"`
|
||||
ID string `json:"id"`
|
||||
ServerID string `json:"server_id"`
|
||||
VolumeID string `json:"volume_id"`
|
||||
}
|
||||
|
||||
func (r *Attachment) UnmarshalJSON(b []byte) error {
|
||||
type tmp Attachment
|
||||
var s struct {
|
||||
tmp
|
||||
AttachedAt gophercloud.JSONRFC3339MilliNoZ `json:"attached_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = Attachment(s.tmp)
|
||||
|
||||
r.AttachedAt = time.Time(s.AttachedAt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Volume contains all the information associated with an OpenStack Volume.
|
||||
type Volume struct {
|
||||
// Unique identifier for the volume.
|
||||
ID string `json:"id"`
|
||||
// Current status of the volume.
|
||||
Status string `json:"status"`
|
||||
// Size of the volume in GB.
|
||||
Size int `json:"size"`
|
||||
// AvailabilityZone is which availability zone the volume is in.
|
||||
AvailabilityZone string `json:"availability_zone"`
|
||||
// The date when this volume was created.
|
||||
CreatedAt time.Time `json:"-"`
|
||||
// The date when this volume was last updated
|
||||
UpdatedAt time.Time `json:"-"`
|
||||
// Instances onto which the volume is attached.
|
||||
Attachments []Attachment `json:"attachments"`
|
||||
// Human-readable display name for the volume.
|
||||
Name string `json:"name"`
|
||||
// Human-readable description for the volume.
|
||||
Description string `json:"description"`
|
||||
// The type of volume to create, either SATA or SSD.
|
||||
VolumeType string `json:"volume_type"`
|
||||
// The ID of the snapshot from which the volume was created
|
||||
SnapshotID string `json:"snapshot_id"`
|
||||
// The ID of another block storage volume from which the current volume was created
|
||||
SourceVolID string `json:"source_volid"`
|
||||
// Arbitrary key-value pairs defined by the user.
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
// UserID is the id of the user who created the volume.
|
||||
UserID string `json:"user_id"`
|
||||
// Indicates whether this is a bootable volume.
|
||||
Bootable string `json:"bootable"`
|
||||
// Encrypted denotes if the volume is encrypted.
|
||||
Encrypted bool `json:"encrypted"`
|
||||
// ReplicationStatus is the status of replication.
|
||||
ReplicationStatus string `json:"replication_status"`
|
||||
// ConsistencyGroupID is the consistency group ID.
|
||||
ConsistencyGroupID string `json:"consistencygroup_id"`
|
||||
// Multiattach denotes if the volume is multi-attach capable.
|
||||
Multiattach bool `json:"multiattach"`
|
||||
}
|
||||
|
||||
func (r *Volume) UnmarshalJSON(b []byte) error {
|
||||
type tmp Volume
|
||||
var s struct {
|
||||
tmp
|
||||
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
||||
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = Volume(s.tmp)
|
||||
|
||||
r.CreatedAt = time.Time(s.CreatedAt)
|
||||
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
||||
type VolumePage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if a ListResult contains no Volumes.
|
||||
func (r VolumePage) IsEmpty() (bool, error) {
|
||||
volumes, err := ExtractVolumes(r)
|
||||
return len(volumes) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||
// next page of results.
|
||||
func (r VolumePage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"volumes_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
|
||||
func ExtractVolumes(r pagination.Page) ([]Volume, error) {
|
||||
var s []Volume
|
||||
err := ExtractVolumesInto(r, &s)
|
||||
return s, err
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract will get the Volume object out of the commonResult object.
|
||||
func (r commonResult) Extract() (*Volume, error) {
|
||||
var s Volume
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
||||
|
||||
func (r commonResult) ExtractInto(v interface{}) error {
|
||||
return r.Result.ExtractIntoStructPtr(v, "volume")
|
||||
}
|
||||
|
||||
func ExtractVolumesInto(r pagination.Page, v interface{}) error {
|
||||
return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes")
|
||||
}
|
||||
|
||||
// CreateResult contains the response body and error from a Create request.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult contains the response body and error from a Get request.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult contains the response body and error from an Update request.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult contains the response body and error from a Delete request.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
23
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/urls.go
generated
vendored
23
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/urls.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func createURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("volumes")
|
||||
}
|
||||
|
||||
func listURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("volumes", "detail")
|
||||
}
|
||||
|
||||
func deleteURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL("volumes", id)
|
||||
}
|
||||
|
||||
func getURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(c, id)
|
||||
}
|
||||
|
||||
func updateURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(c, id)
|
||||
}
|
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/util.go
generated
vendored
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/util.go
generated
vendored
@@ -1,22 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
// WaitForStatus will continually poll the resource, checking for a particular
|
||||
// status. It will do this for the amount of seconds defined.
|
||||
func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error {
|
||||
return gophercloud.WaitFor(secs, func() (bool, error) {
|
||||
current, err := Get(c, id).Extract()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if current.Status == status {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/doc.go
generated
vendored
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/doc.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
// Package volumes provides information and interaction with volumes in the
|
||||
// OpenStack Block Storage service. A volume is a detachable block storage
|
||||
// device, akin to a USB hard drive. It can only be attached to one instance at
|
||||
// a time.
|
||||
package volumes
|
237
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go
generated
vendored
237
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go
generated
vendored
@@ -1,237 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToVolumeCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts contains options for creating a Volume. This object is passed to
|
||||
// the volumes.Create function. For more information about these parameters,
|
||||
// see the Volume object.
|
||||
type CreateOpts struct {
|
||||
// The size of the volume, in GB
|
||||
Size int `json:"size" required:"true"`
|
||||
// The availability zone
|
||||
AvailabilityZone string `json:"availability_zone,omitempty"`
|
||||
// ConsistencyGroupID is the ID of a consistency group
|
||||
ConsistencyGroupID string `json:"consistencygroup_id,omitempty"`
|
||||
// The volume description
|
||||
Description string `json:"description,omitempty"`
|
||||
// One or more metadata key and value pairs to associate with the volume
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
// The volume name
|
||||
Name string `json:"name,omitempty"`
|
||||
// the ID of the existing volume snapshot
|
||||
SnapshotID string `json:"snapshot_id,omitempty"`
|
||||
// SourceReplica is a UUID of an existing volume to replicate with
|
||||
SourceReplica string `json:"source_replica,omitempty"`
|
||||
// the ID of the existing volume
|
||||
SourceVolID string `json:"source_volid,omitempty"`
|
||||
// The ID of the image from which you want to create the volume.
|
||||
// Required to create a bootable volume.
|
||||
ImageID string `json:"imageRef,omitempty"`
|
||||
// The associated volume type
|
||||
VolumeType string `json:"volume_type,omitempty"`
|
||||
// Multiattach denotes if the volume is multi-attach capable.
|
||||
Multiattach bool `json:"multiattach,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeCreateMap assembles a request body based on the contents of a
|
||||
// CreateOpts.
|
||||
func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "volume")
|
||||
}
|
||||
|
||||
// Create will create a new Volume based on the values in CreateOpts. To extract
|
||||
// the Volume object from the response, call the Extract method on the
|
||||
// CreateResult.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToVolumeCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteOptsBuilder allows extensions to add additional parameters to the
|
||||
// Delete request.
|
||||
type DeleteOptsBuilder interface {
|
||||
ToVolumeDeleteQuery() (string, error)
|
||||
}
|
||||
|
||||
// DeleteOpts contains options for deleting a Volume. This object is passed to
|
||||
// the volumes.Delete function.
|
||||
type DeleteOpts struct {
|
||||
// Delete all snapshots of this volume as well.
|
||||
Cascade bool `q:"cascade"`
|
||||
}
|
||||
|
||||
// ToLoadBalancerDeleteQuery formats a DeleteOpts into a query string.
|
||||
func (opts DeleteOpts) ToVolumeDeleteQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// Delete will delete the existing Volume with the provided ID.
|
||||
func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) {
|
||||
url := deleteURL(client, id)
|
||||
if opts != nil {
|
||||
query, err := opts.ToVolumeDeleteQuery()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
url += query
|
||||
}
|
||||
_, r.Err = client.Delete(url, nil)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the List
|
||||
// request.
|
||||
type ListOptsBuilder interface {
|
||||
ToVolumeListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts holds options for listing Volumes. It is passed to the volumes.List
|
||||
// function.
|
||||
type ListOpts struct {
|
||||
// AllTenants will retrieve volumes of all tenants/projects.
|
||||
AllTenants bool `q:"all_tenants"`
|
||||
|
||||
// Metadata will filter results based on specified metadata.
|
||||
Metadata map[string]string `q:"metadata"`
|
||||
|
||||
// Name will filter by the specified volume name.
|
||||
Name string `q:"name"`
|
||||
|
||||
// Status will filter by the specified status.
|
||||
Status string `q:"status"`
|
||||
|
||||
// TenantID will filter by a specific tenant/project ID.
|
||||
// Setting AllTenants is required for this.
|
||||
TenantID string `q:"project_id"`
|
||||
|
||||
// Comma-separated list of sort keys and optional sort directions in the
|
||||
// form of <key>[:<direction>].
|
||||
Sort string `q:"sort"`
|
||||
|
||||
// Requests a page size of items.
|
||||
Limit int `q:"limit"`
|
||||
|
||||
// Used in conjunction with limit to return a slice of items.
|
||||
Offset int `q:"offset"`
|
||||
|
||||
// The ID of the last-seen item.
|
||||
Marker string `q:"marker"`
|
||||
}
|
||||
|
||||
// ToVolumeListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToVolumeListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List returns Volumes optionally limited by the conditions provided in ListOpts.
|
||||
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := listURL(client)
|
||||
if opts != nil {
|
||||
query, err := opts.ToVolumeListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return VolumePage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToVolumeUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts contain options for updating an existing Volume. This object is passed
|
||||
// to the volumes.Update function. For more information about the parameters, see
|
||||
// the Volume object.
|
||||
type UpdateOpts struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// ToVolumeUpdateMap assembles a request body based on the contents of an
|
||||
// UpdateOpts.
|
||||
func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "volume")
|
||||
}
|
||||
|
||||
// Update will update the Volume with provided information. To extract the updated
|
||||
// Volume from the response, call the Extract method on the UpdateResult.
|
||||
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToVolumeUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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,
|
||||
}
|
||||
|
||||
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"}
|
||||
}
|
||||
}
|
172
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go
generated
vendored
172
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go
generated
vendored
@@ -1,172 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Attachment represents a Volume Attachment record
|
||||
type Attachment struct {
|
||||
AttachedAt time.Time `json:"-"`
|
||||
AttachmentID string `json:"attachment_id"`
|
||||
Device string `json:"device"`
|
||||
HostName string `json:"host_name"`
|
||||
ID string `json:"id"`
|
||||
ServerID string `json:"server_id"`
|
||||
VolumeID string `json:"volume_id"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON is our unmarshalling helper
|
||||
func (r *Attachment) UnmarshalJSON(b []byte) error {
|
||||
type tmp Attachment
|
||||
var s struct {
|
||||
tmp
|
||||
AttachedAt gophercloud.JSONRFC3339MilliNoZ `json:"attached_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = Attachment(s.tmp)
|
||||
|
||||
r.AttachedAt = time.Time(s.AttachedAt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Volume contains all the information associated with an OpenStack Volume.
|
||||
type Volume struct {
|
||||
// Unique identifier for the volume.
|
||||
ID string `json:"id"`
|
||||
// Current status of the volume.
|
||||
Status string `json:"status"`
|
||||
// Size of the volume in GB.
|
||||
Size int `json:"size"`
|
||||
// AvailabilityZone is which availability zone the volume is in.
|
||||
AvailabilityZone string `json:"availability_zone"`
|
||||
// The date when this volume was created.
|
||||
CreatedAt time.Time `json:"-"`
|
||||
// The date when this volume was last updated
|
||||
UpdatedAt time.Time `json:"-"`
|
||||
// Instances onto which the volume is attached.
|
||||
Attachments []Attachment `json:"attachments"`
|
||||
// Human-readable display name for the volume.
|
||||
Name string `json:"name"`
|
||||
// Human-readable description for the volume.
|
||||
Description string `json:"description"`
|
||||
// The type of volume to create, either SATA or SSD.
|
||||
VolumeType string `json:"volume_type"`
|
||||
// The ID of the snapshot from which the volume was created
|
||||
SnapshotID string `json:"snapshot_id"`
|
||||
// The ID of another block storage volume from which the current volume was created
|
||||
SourceVolID string `json:"source_volid"`
|
||||
// Arbitrary key-value pairs defined by the user.
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
// UserID is the id of the user who created the volume.
|
||||
UserID string `json:"user_id"`
|
||||
// Indicates whether this is a bootable volume.
|
||||
Bootable string `json:"bootable"`
|
||||
// Encrypted denotes if the volume is encrypted.
|
||||
Encrypted bool `json:"encrypted"`
|
||||
// ReplicationStatus is the status of replication.
|
||||
ReplicationStatus string `json:"replication_status"`
|
||||
// ConsistencyGroupID is the consistency group ID.
|
||||
ConsistencyGroupID string `json:"consistencygroup_id"`
|
||||
// Multiattach denotes if the volume is multi-attach capable.
|
||||
Multiattach bool `json:"multiattach"`
|
||||
// Image metadata entries, only included for volumes that were created from an image, or from a snapshot of a volume originally created from an image.
|
||||
VolumeImageMetadata map[string]string `json:"volume_image_metadata"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON another unmarshalling function
|
||||
func (r *Volume) UnmarshalJSON(b []byte) error {
|
||||
type tmp Volume
|
||||
var s struct {
|
||||
tmp
|
||||
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
||||
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = Volume(s.tmp)
|
||||
|
||||
r.CreatedAt = time.Time(s.CreatedAt)
|
||||
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
||||
type VolumePage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if a ListResult contains no Volumes.
|
||||
func (r VolumePage) IsEmpty() (bool, error) {
|
||||
volumes, err := ExtractVolumes(r)
|
||||
return len(volumes) == 0, err
|
||||
}
|
||||
|
||||
func (page VolumePage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"volumes_links"`
|
||||
}
|
||||
err := page.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
|
||||
func ExtractVolumes(r pagination.Page) ([]Volume, error) {
|
||||
var s []Volume
|
||||
err := ExtractVolumesInto(r, &s)
|
||||
return s, err
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract will get the Volume object out of the commonResult object.
|
||||
func (r commonResult) Extract() (*Volume, error) {
|
||||
var s Volume
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// ExtractInto converts our response data into a volume struct
|
||||
func (r commonResult) ExtractInto(v interface{}) error {
|
||||
return r.Result.ExtractIntoStructPtr(v, "volume")
|
||||
}
|
||||
|
||||
// ExtractVolumesInto similar to ExtractInto but operates on a `list` of volumes
|
||||
func ExtractVolumesInto(r pagination.Page, v interface{}) error {
|
||||
return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes")
|
||||
}
|
||||
|
||||
// CreateResult contains the response body and error from a Create request.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult contains the response body and error from a Get request.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult contains the response body and error from an Update request.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult contains the response body and error from a Delete request.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
23
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/urls.go
generated
vendored
23
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/urls.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func createURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("volumes")
|
||||
}
|
||||
|
||||
func listURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("volumes", "detail")
|
||||
}
|
||||
|
||||
func deleteURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL("volumes", id)
|
||||
}
|
||||
|
||||
func getURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(c, id)
|
||||
}
|
||||
|
||||
func updateURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(c, id)
|
||||
}
|
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/util.go
generated
vendored
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/util.go
generated
vendored
@@ -1,22 +0,0 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
// WaitForStatus will continually poll the resource, checking for a particular
|
||||
// status. It will do this for the amount of seconds defined.
|
||||
func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error {
|
||||
return gophercloud.WaitFor(secs, func() (bool, error) {
|
||||
current, err := Get(c, id).Extract()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if current.Status == status {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
438
vendor/github.com/gophercloud/gophercloud/openstack/client.go
generated
vendored
438
vendor/github.com/gophercloud/gophercloud/openstack/client.go
generated
vendored
@@ -1,438 +0,0 @@
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
||||
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
"github.com/gophercloud/gophercloud/openstack/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
// v2 represents Keystone v2.
|
||||
// It should never increase beyond 2.0.
|
||||
v2 = "v2.0"
|
||||
|
||||
// v3 represents Keystone v3.
|
||||
// The version can be anything from v3 to v3.x.
|
||||
v3 = "v3"
|
||||
)
|
||||
|
||||
/*
|
||||
NewClient prepares an unauthenticated ProviderClient instance.
|
||||
Most users will probably prefer using the AuthenticatedClient function
|
||||
instead.
|
||||
|
||||
This is useful if you wish to explicitly control the version of the identity
|
||||
service that's used for authentication explicitly, for example.
|
||||
|
||||
A basic example of using this would be:
|
||||
|
||||
ao, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.NewClient(ao.IdentityEndpoint)
|
||||
client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{})
|
||||
*/
|
||||
func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
|
||||
base, err := utils.BaseEndpoint(endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
endpoint = gophercloud.NormalizeURL(endpoint)
|
||||
base = gophercloud.NormalizeURL(base)
|
||||
|
||||
p := new(gophercloud.ProviderClient)
|
||||
p.IdentityBase = base
|
||||
p.IdentityEndpoint = endpoint
|
||||
p.UseTokenLock()
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
/*
|
||||
AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint
|
||||
specified by the options, acquires a token, and returns a Provider Client
|
||||
instance that's ready to operate.
|
||||
|
||||
If the full path to a versioned identity endpoint was specified (example:
|
||||
http://example.com:5000/v3), that path will be used as the endpoint to query.
|
||||
|
||||
If a versionless endpoint was specified (example: http://example.com:5000/),
|
||||
the endpoint will be queried to determine which versions of the identity service
|
||||
are available, then chooses the most recent or most supported version.
|
||||
|
||||
Example:
|
||||
|
||||
ao, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(ao)
|
||||
client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
|
||||
Region: os.Getenv("OS_REGION_NAME"),
|
||||
})
|
||||
*/
|
||||
func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) {
|
||||
client, err := NewClient(options.IdentityEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = Authenticate(client, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// Authenticate or re-authenticate against the most recent identity service
|
||||
// supported at the provided endpoint.
|
||||
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
|
||||
versions := []*utils.Version{
|
||||
{ID: v2, Priority: 20, Suffix: "/v2.0/"},
|
||||
{ID: v3, Priority: 30, Suffix: "/v3/"},
|
||||
}
|
||||
|
||||
chosen, endpoint, err := utils.ChooseVersion(client, versions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch chosen.ID {
|
||||
case v2:
|
||||
return v2auth(client, endpoint, options, gophercloud.EndpointOpts{})
|
||||
case v3:
|
||||
return v3auth(client, endpoint, &options, gophercloud.EndpointOpts{})
|
||||
default:
|
||||
// The switch statement must be out of date from the versions list.
|
||||
return fmt.Errorf("Unrecognized identity version: %s", chosen.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// AuthenticateV2 explicitly authenticates against the identity v2 endpoint.
|
||||
func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
|
||||
return v2auth(client, "", options, eo)
|
||||
}
|
||||
|
||||
func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
|
||||
v2Client, err := NewIdentityV2(client, eo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if endpoint != "" {
|
||||
v2Client.Endpoint = endpoint
|
||||
}
|
||||
|
||||
v2Opts := tokens2.AuthOptions{
|
||||
IdentityEndpoint: options.IdentityEndpoint,
|
||||
Username: options.Username,
|
||||
Password: options.Password,
|
||||
TenantID: options.TenantID,
|
||||
TenantName: options.TenantName,
|
||||
AllowReauth: options.AllowReauth,
|
||||
TokenID: options.TokenID,
|
||||
}
|
||||
|
||||
result := tokens2.Create(v2Client, v2Opts)
|
||||
|
||||
err = client.SetTokenAndAuthResult(result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
catalog, err := result.ExtractServiceCatalog()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if options.AllowReauth {
|
||||
// here we're creating a throw-away client (tac). it's a copy of the user's provider client, but
|
||||
// with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`,
|
||||
// this should retry authentication only once
|
||||
tac := *client
|
||||
tac.SetThrowaway(true)
|
||||
tac.ReauthFunc = nil
|
||||
tac.SetTokenAndAuthResult(nil)
|
||||
tao := options
|
||||
tao.AllowReauth = false
|
||||
client.ReauthFunc = func() error {
|
||||
err := v2auth(&tac, endpoint, tao, eo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client.CopyTokenFrom(&tac)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
|
||||
return V2EndpointURL(catalog, opts)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AuthenticateV3 explicitly authenticates against the identity v3 service.
|
||||
func AuthenticateV3(client *gophercloud.ProviderClient, options tokens3.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error {
|
||||
return v3auth(client, "", options, eo)
|
||||
}
|
||||
|
||||
func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error {
|
||||
// Override the generated service endpoint with the one returned by the version endpoint.
|
||||
v3Client, err := NewIdentityV3(client, eo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if endpoint != "" {
|
||||
v3Client.Endpoint = endpoint
|
||||
}
|
||||
|
||||
result := tokens3.Create(v3Client, opts)
|
||||
|
||||
err = client.SetTokenAndAuthResult(result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
catalog, err := result.ExtractServiceCatalog()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.CanReauth() {
|
||||
// here we're creating a throw-away client (tac). it's a copy of the user's provider client, but
|
||||
// with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`,
|
||||
// this should retry authentication only once
|
||||
tac := *client
|
||||
tac.SetThrowaway(true)
|
||||
tac.ReauthFunc = nil
|
||||
tac.SetTokenAndAuthResult(nil)
|
||||
var tao tokens3.AuthOptionsBuilder
|
||||
switch ot := opts.(type) {
|
||||
case *gophercloud.AuthOptions:
|
||||
o := *ot
|
||||
o.AllowReauth = false
|
||||
tao = &o
|
||||
case *tokens3.AuthOptions:
|
||||
o := *ot
|
||||
o.AllowReauth = false
|
||||
tao = &o
|
||||
default:
|
||||
tao = opts
|
||||
}
|
||||
client.ReauthFunc = func() error {
|
||||
err := v3auth(&tac, endpoint, tao, eo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client.CopyTokenFrom(&tac)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
|
||||
return V3EndpointURL(catalog, opts)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewIdentityV2 creates a ServiceClient that may be used to interact with the
|
||||
// v2 identity service.
|
||||
func NewIdentityV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
endpoint := client.IdentityBase + "v2.0/"
|
||||
clientType := "identity"
|
||||
var err error
|
||||
if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
|
||||
eo.ApplyDefaults(clientType)
|
||||
endpoint, err = client.EndpointLocator(eo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &gophercloud.ServiceClient{
|
||||
ProviderClient: client,
|
||||
Endpoint: endpoint,
|
||||
Type: clientType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewIdentityV3 creates a ServiceClient that may be used to access the v3
|
||||
// identity service.
|
||||
func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
endpoint := client.IdentityBase + "v3/"
|
||||
clientType := "identity"
|
||||
var err error
|
||||
if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
|
||||
eo.ApplyDefaults(clientType)
|
||||
endpoint, err = client.EndpointLocator(eo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure endpoint still has a suffix of v3.
|
||||
// This is because EndpointLocator might have found a versionless
|
||||
// endpoint or the published endpoint is still /v2.0. In both
|
||||
// cases, we need to fix the endpoint to point to /v3.
|
||||
base, err := utils.BaseEndpoint(endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base = gophercloud.NormalizeURL(base)
|
||||
|
||||
endpoint = base + "v3/"
|
||||
|
||||
return &gophercloud.ServiceClient{
|
||||
ProviderClient: client,
|
||||
Endpoint: endpoint,
|
||||
Type: clientType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts, clientType string) (*gophercloud.ServiceClient, error) {
|
||||
sc := new(gophercloud.ServiceClient)
|
||||
eo.ApplyDefaults(clientType)
|
||||
url, err := client.EndpointLocator(eo)
|
||||
if err != nil {
|
||||
return sc, err
|
||||
}
|
||||
sc.ProviderClient = client
|
||||
sc.Endpoint = url
|
||||
sc.Type = clientType
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
// NewBareMetalV1 creates a ServiceClient that may be used with the v1
|
||||
// bare metal package.
|
||||
func NewBareMetalV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "baremetal")
|
||||
}
|
||||
|
||||
// NewBareMetalIntrospectionV1 creates a ServiceClient that may be used with the v1
|
||||
// bare metal introspection package.
|
||||
func NewBareMetalIntrospectionV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "baremetal-inspector")
|
||||
}
|
||||
|
||||
// NewObjectStorageV1 creates a ServiceClient that may be used with the v1
|
||||
// object storage package.
|
||||
func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "object-store")
|
||||
}
|
||||
|
||||
// NewComputeV2 creates a ServiceClient that may be used with the v2 compute
|
||||
// package.
|
||||
func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "compute")
|
||||
}
|
||||
|
||||
// NewNetworkV2 creates a ServiceClient that may be used with the v2 network
|
||||
// package.
|
||||
func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
sc, err := initClientOpts(client, eo, "network")
|
||||
sc.ResourceBase = sc.Endpoint + "v2.0/"
|
||||
return sc, err
|
||||
}
|
||||
|
||||
// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1
|
||||
// block storage service.
|
||||
func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "volume")
|
||||
}
|
||||
|
||||
// NewBlockStorageV2 creates a ServiceClient that may be used to access the v2
|
||||
// block storage service.
|
||||
func NewBlockStorageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "volumev2")
|
||||
}
|
||||
|
||||
// NewBlockStorageV3 creates a ServiceClient that may be used to access the v3 block storage service.
|
||||
func NewBlockStorageV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "volumev3")
|
||||
}
|
||||
|
||||
// NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service.
|
||||
func NewSharedFileSystemV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "sharev2")
|
||||
}
|
||||
|
||||
// NewCDNV1 creates a ServiceClient that may be used to access the OpenStack v1
|
||||
// CDN service.
|
||||
func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "cdn")
|
||||
}
|
||||
|
||||
// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1
|
||||
// orchestration service.
|
||||
func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "orchestration")
|
||||
}
|
||||
|
||||
// NewDBV1 creates a ServiceClient that may be used to access the v1 DB service.
|
||||
func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "database")
|
||||
}
|
||||
|
||||
// NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS
|
||||
// service.
|
||||
func NewDNSV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
sc, err := initClientOpts(client, eo, "dns")
|
||||
sc.ResourceBase = sc.Endpoint + "v2/"
|
||||
return sc, err
|
||||
}
|
||||
|
||||
// NewImageServiceV2 creates a ServiceClient that may be used to access the v2
|
||||
// image service.
|
||||
func NewImageServiceV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
sc, err := initClientOpts(client, eo, "image")
|
||||
sc.ResourceBase = sc.Endpoint + "v2/"
|
||||
return sc, err
|
||||
}
|
||||
|
||||
// NewLoadBalancerV2 creates a ServiceClient that may be used to access the v2
|
||||
// load balancer service.
|
||||
func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
sc, err := initClientOpts(client, eo, "load-balancer")
|
||||
sc.ResourceBase = sc.Endpoint + "v2.0/"
|
||||
return sc, err
|
||||
}
|
||||
|
||||
// NewClusteringV1 creates a ServiceClient that may be used with the v1 clustering
|
||||
// package.
|
||||
func NewClusteringV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "clustering")
|
||||
}
|
||||
|
||||
// NewMessagingV2 creates a ServiceClient that may be used with the v2 messaging
|
||||
// service.
|
||||
func NewMessagingV2(client *gophercloud.ProviderClient, clientID string, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
sc, err := initClientOpts(client, eo, "messaging")
|
||||
sc.MoreHeaders = map[string]string{"Client-ID": clientID}
|
||||
return sc, err
|
||||
}
|
||||
|
||||
// NewContainerV1 creates a ServiceClient that may be used with v1 container package
|
||||
func NewContainerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "container")
|
||||
}
|
||||
|
||||
// NewKeyManagerV1 creates a ServiceClient that may be used with the v1 key
|
||||
// manager service.
|
||||
func NewKeyManagerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
sc, err := initClientOpts(client, eo, "key-manager")
|
||||
sc.ResourceBase = sc.Endpoint + "v1/"
|
||||
return sc, err
|
||||
}
|
||||
|
||||
// NewContainerInfraV1 creates a ServiceClient that may be used with the v1 container infra management
|
||||
// package.
|
||||
func NewContainerInfraV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "container-infra")
|
||||
}
|
||||
|
||||
// NewWorkflowV2 creates a ServiceClient that may be used with the v2 workflow management package.
|
||||
func NewWorkflowV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||
return initClientOpts(client, eo, "workflowv2")
|
||||
}
|
52
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/doc.go
generated
vendored
52
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/doc.go
generated
vendored
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
Package extensions provides information and interaction with the different
|
||||
extensions available for an OpenStack service.
|
||||
|
||||
The purpose of OpenStack API extensions is to:
|
||||
|
||||
- Introduce new features in the API without requiring a version change.
|
||||
- Introduce vendor-specific niche functionality.
|
||||
- Act as a proving ground for experimental functionalities that might be
|
||||
included in a future version of the API.
|
||||
|
||||
Extensions usually have tags that prevent conflicts with other extensions that
|
||||
define attributes or resources with the same names, and with core resources and
|
||||
attributes. Because an extension might not be supported by all plug-ins, its
|
||||
availability varies with deployments and the specific plug-in.
|
||||
|
||||
The results of this package vary depending on the type of Service Client used.
|
||||
In the following examples, note how the only difference is the creation of the
|
||||
Service Client.
|
||||
|
||||
Example of Retrieving Compute Extensions
|
||||
|
||||
ao, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(ao)
|
||||
computeClient, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{
|
||||
Region: os.Getenv("OS_REGION_NAME"),
|
||||
})
|
||||
|
||||
allPages, err := extensions.List(computeClient).Allpages()
|
||||
allExtensions, err := extensions.ExtractExtensions(allPages)
|
||||
|
||||
for _, extension := range allExtensions{
|
||||
fmt.Println("%+v\n", extension)
|
||||
}
|
||||
|
||||
|
||||
Example of Retrieving Network Extensions
|
||||
|
||||
ao, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(ao)
|
||||
networkClient, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
|
||||
Region: os.Getenv("OS_REGION_NAME"),
|
||||
})
|
||||
|
||||
allPages, err := extensions.List(networkClient).Allpages()
|
||||
allExtensions, err := extensions.ExtractExtensions(allPages)
|
||||
|
||||
for _, extension := range allExtensions{
|
||||
fmt.Println("%+v\n", extension)
|
||||
}
|
||||
*/
|
||||
package extensions
|
20
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/requests.go
generated
vendored
20
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/requests.go
generated
vendored
@@ -1,20 +0,0 @@
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Get retrieves information for a specific extension using its alias.
|
||||
func Get(c *gophercloud.ServiceClient, alias string) (r GetResult) {
|
||||
_, r.Err = c.Get(ExtensionURL(c, alias), &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over the full collection of extensions.
|
||||
// It does not accept query parameters.
|
||||
func List(c *gophercloud.ServiceClient) pagination.Pager {
|
||||
return pagination.NewPager(c, ListExtensionURL(c), func(r pagination.PageResult) pagination.Page {
|
||||
return ExtensionPage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
53
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/results.go
generated
vendored
53
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/results.go
generated
vendored
@@ -1,53 +0,0 @@
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// GetResult temporarily stores the result of a Get call.
|
||||
// Use its Extract() method to interpret it as an Extension.
|
||||
type GetResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets a GetResult as an Extension.
|
||||
func (r GetResult) Extract() (*Extension, error) {
|
||||
var s struct {
|
||||
Extension *Extension `json:"extension"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Extension, err
|
||||
}
|
||||
|
||||
// Extension is a struct that represents an OpenStack extension.
|
||||
type Extension struct {
|
||||
Updated string `json:"updated"`
|
||||
Name string `json:"name"`
|
||||
Links []interface{} `json:"links"`
|
||||
Namespace string `json:"namespace"`
|
||||
Alias string `json:"alias"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ExtensionPage is the page returned by a pager when traversing over a collection of extensions.
|
||||
type ExtensionPage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty checks whether an ExtensionPage struct is empty.
|
||||
func (r ExtensionPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractExtensions(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// ExtractExtensions accepts a Page struct, specifically an ExtensionPage
|
||||
// struct, and extracts the elements into a slice of Extension structs.
|
||||
// In other words, a generic collection is mapped into a relevant slice.
|
||||
func ExtractExtensions(r pagination.Page) ([]Extension, error) {
|
||||
var s struct {
|
||||
Extensions []Extension `json:"extensions"`
|
||||
}
|
||||
err := (r.(ExtensionPage)).ExtractInto(&s)
|
||||
return s.Extensions, err
|
||||
}
|
13
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/urls.go
generated
vendored
13
vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/urls.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
package extensions
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
// ExtensionURL generates the URL for an extension resource by name.
|
||||
func ExtensionURL(c *gophercloud.ServiceClient, name string) string {
|
||||
return c.ServiceURL("extensions", name)
|
||||
}
|
||||
|
||||
// ListExtensionURL generates the URL for the extensions resource collection.
|
||||
func ListExtensionURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("extensions")
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
Package attachinterfaces provides the ability to retrieve and manage network
|
||||
interfaces through Nova.
|
||||
|
||||
Example of Listing a Server's Interfaces
|
||||
|
||||
serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f"
|
||||
allPages, err := attachinterfaces.List(computeClient, serverID).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allInterfaces, err := attachinterfaces.ExtractInterfaces(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, interface := range allInterfaces {
|
||||
fmt.Printf("%+v\n", interface)
|
||||
}
|
||||
|
||||
Example to Get a Server's Interface
|
||||
|
||||
portID = "0dde1598-b374-474e-986f-5b8dd1df1d4e"
|
||||
serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f"
|
||||
interface, err := attachinterfaces.Get(computeClient, serverID, portID).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a new Interface attachment on the Server
|
||||
|
||||
networkID := "8a5fe506-7e9f-4091-899b-96336909d93c"
|
||||
serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f"
|
||||
attachOpts := attachinterfaces.CreateOpts{
|
||||
NetworkID: networkID,
|
||||
}
|
||||
interface, err := attachinterfaces.Create(computeClient, serverID, attachOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete an Interface attachment from the Server
|
||||
|
||||
portID = "0dde1598-b374-474e-986f-5b8dd1df1d4e"
|
||||
serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f"
|
||||
err := attachinterfaces.Delete(computeClient, serverID, portID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package attachinterfaces
|
@@ -1,72 +0,0 @@
|
||||
package attachinterfaces
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// List makes a request against the nova API to list the server's interfaces.
|
||||
func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
|
||||
return pagination.NewPager(client, listInterfaceURL(client, serverID), func(r pagination.PageResult) pagination.Page {
|
||||
return InterfacePage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
||||
|
||||
// Get requests details on a single interface attachment by the server and port IDs.
|
||||
func Get(client *gophercloud.ServiceClient, serverID, portID string) (r GetResult) {
|
||||
_, r.Err = client.Get(getInterfaceURL(client, serverID, portID), &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToAttachInterfacesCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts specifies parameters of a new interface attachment.
|
||||
type CreateOpts struct {
|
||||
// PortID is the ID of the port for which you want to create an interface.
|
||||
// The NetworkID and PortID parameters are mutually exclusive.
|
||||
// If you do not specify the PortID parameter, the OpenStack Networking API
|
||||
// v2.0 allocates a port and creates an interface for it on the network.
|
||||
PortID string `json:"port_id,omitempty"`
|
||||
|
||||
// NetworkID is the ID of the network for which you want to create an interface.
|
||||
// The NetworkID and PortID parameters are mutually exclusive.
|
||||
// If you do not specify the NetworkID parameter, the OpenStack Networking
|
||||
// API v2.0 uses the network information cache that is associated with the instance.
|
||||
NetworkID string `json:"net_id,omitempty"`
|
||||
|
||||
// Slice of FixedIPs. If you request a specific FixedIP address without a
|
||||
// NetworkID, the request returns a Bad Request (400) response code.
|
||||
// Note: this uses the FixedIP struct, but only the IPAddress field can be used.
|
||||
FixedIPs []FixedIP `json:"fixed_ips,omitempty"`
|
||||
}
|
||||
|
||||
// ToAttachInterfacesCreateMap constructs a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToAttachInterfacesCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "interfaceAttachment")
|
||||
}
|
||||
|
||||
// Create requests the creation of a new interface attachment on the server.
|
||||
func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToAttachInterfacesCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createInterfaceURL(client, serverID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete makes a request against the nova API to detach a single interface from the server.
|
||||
// It needs server and port IDs to make a such request.
|
||||
func Delete(client *gophercloud.ServiceClient, serverID, portID string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteInterfaceURL(client, serverID, portID), nil)
|
||||
return
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
package attachinterfaces
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
type attachInterfaceResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets any attachInterfaceResult as an Interface, if possible.
|
||||
func (r attachInterfaceResult) Extract() (*Interface, error) {
|
||||
var s struct {
|
||||
Interface *Interface `json:"interfaceAttachment"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Interface, err
|
||||
}
|
||||
|
||||
// GetResult is the response from a Get operation. Call its Extract
|
||||
// method to interpret it as an Interface.
|
||||
type GetResult struct {
|
||||
attachInterfaceResult
|
||||
}
|
||||
|
||||
// CreateResult is the response from a Create operation. Call its Extract
|
||||
// method to interpret it as an Interface.
|
||||
type CreateResult struct {
|
||||
attachInterfaceResult
|
||||
}
|
||||
|
||||
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||
// method to determine if the call succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// FixedIP represents a Fixed IP Address.
|
||||
// This struct is also used when creating an attachment,
|
||||
// but it is not possible to specify a SubnetID.
|
||||
type FixedIP struct {
|
||||
SubnetID string `json:"subnet_id,omitempty"`
|
||||
IPAddress string `json:"ip_address"`
|
||||
}
|
||||
|
||||
// Interface represents a network interface on a server.
|
||||
type Interface struct {
|
||||
PortState string `json:"port_state"`
|
||||
FixedIPs []FixedIP `json:"fixed_ips"`
|
||||
PortID string `json:"port_id"`
|
||||
NetID string `json:"net_id"`
|
||||
MACAddr string `json:"mac_addr"`
|
||||
}
|
||||
|
||||
// InterfacePage abstracts the raw results of making a List() request against
|
||||
// the API.
|
||||
//
|
||||
// As OpenStack extensions may freely alter the response bodies of structures
|
||||
// returned to the client, you may only safely access the data provided through
|
||||
// the ExtractInterfaces call.
|
||||
type InterfacePage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if an InterfacePage contains no interfaces.
|
||||
func (r InterfacePage) IsEmpty() (bool, error) {
|
||||
interfaces, err := ExtractInterfaces(r)
|
||||
return len(interfaces) == 0, err
|
||||
}
|
||||
|
||||
// ExtractInterfaces interprets the results of a single page from a List() call,
|
||||
// producing a slice of Interface structs.
|
||||
func ExtractInterfaces(r pagination.Page) ([]Interface, error) {
|
||||
var s struct {
|
||||
Interfaces []Interface `json:"interfaceAttachments"`
|
||||
}
|
||||
err := (r.(InterfacePage)).ExtractInto(&s)
|
||||
return s.Interfaces, err
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package attachinterfaces
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func listInterfaceURL(client *gophercloud.ServiceClient, serverID string) string {
|
||||
return client.ServiceURL("servers", serverID, "os-interface")
|
||||
}
|
||||
|
||||
func getInterfaceURL(client *gophercloud.ServiceClient, serverID, portID string) string {
|
||||
return client.ServiceURL("servers", serverID, "os-interface", portID)
|
||||
}
|
||||
|
||||
func createInterfaceURL(client *gophercloud.ServiceClient, serverID string) string {
|
||||
return client.ServiceURL("servers", serverID, "os-interface")
|
||||
}
|
||||
func deleteInterfaceURL(client *gophercloud.ServiceClient, serverID, portID string) string {
|
||||
return client.ServiceURL("servers", serverID, "os-interface", portID)
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
Package volumeattach provides the ability to attach and detach volumes
|
||||
from servers.
|
||||
|
||||
Example to Attach a Volume
|
||||
|
||||
serverID := "7ac8686c-de71-4acb-9600-ec18b1a1ed6d"
|
||||
volumeID := "87463836-f0e2-4029-abf6-20c8892a3103"
|
||||
|
||||
createOpts := volumeattach.CreateOpts{
|
||||
Device: "/dev/vdc",
|
||||
VolumeID: volumeID,
|
||||
}
|
||||
|
||||
result, err := volumeattach.Create(computeClient, serverID, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Detach a Volume
|
||||
|
||||
serverID := "7ac8686c-de71-4acb-9600-ec18b1a1ed6d"
|
||||
attachmentID := "ed081613-1c9b-4231-aa5e-ebfd4d87f983"
|
||||
|
||||
err := volumeattach.Delete(computeClient, serverID, attachmentID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package volumeattach
|
@@ -1,60 +0,0 @@
|
||||
package volumeattach
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// List returns a Pager that allows you to iterate over a collection of
|
||||
// VolumeAttachments.
|
||||
func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
|
||||
return pagination.NewPager(client, listURL(client, serverID), func(r pagination.PageResult) pagination.Page {
|
||||
return VolumeAttachmentPage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add parameters to the Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToVolumeAttachmentCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts specifies volume attachment creation or import parameters.
|
||||
type CreateOpts struct {
|
||||
// Device is the device that the volume will attach to the instance as.
|
||||
// Omit for "auto".
|
||||
Device string `json:"device,omitempty"`
|
||||
|
||||
// VolumeID is the ID of the volume to attach to the instance.
|
||||
VolumeID string `json:"volumeId" required:"true"`
|
||||
}
|
||||
|
||||
// ToVolumeAttachmentCreateMap constructs a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToVolumeAttachmentCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "volumeAttachment")
|
||||
}
|
||||
|
||||
// Create requests the creation of a new volume attachment on the server.
|
||||
func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToVolumeAttachmentCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client, serverID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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)
|
||||
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)
|
||||
return
|
||||
}
|
@@ -1,77 +0,0 @@
|
||||
package volumeattach
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// VolumeAttachment contains attachment information between a volume
|
||||
// and server.
|
||||
type VolumeAttachment struct {
|
||||
// ID is a unique id of the attachment.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Device is what device the volume is attached as.
|
||||
Device string `json:"device"`
|
||||
|
||||
// VolumeID is the ID of the attached volume.
|
||||
VolumeID string `json:"volumeId"`
|
||||
|
||||
// ServerID is the ID of the instance that has the volume attached.
|
||||
ServerID string `json:"serverId"`
|
||||
}
|
||||
|
||||
// VolumeAttachmentPage stores a single page all of VolumeAttachment
|
||||
// results from a List call.
|
||||
type VolumeAttachmentPage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a VolumeAttachmentPage is empty.
|
||||
func (page VolumeAttachmentPage) IsEmpty() (bool, error) {
|
||||
va, err := ExtractVolumeAttachments(page)
|
||||
return len(va) == 0, err
|
||||
}
|
||||
|
||||
// ExtractVolumeAttachments interprets a page of results as a slice of
|
||||
// VolumeAttachment.
|
||||
func ExtractVolumeAttachments(r pagination.Page) ([]VolumeAttachment, error) {
|
||||
var s struct {
|
||||
VolumeAttachments []VolumeAttachment `json:"volumeAttachments"`
|
||||
}
|
||||
err := (r.(VolumeAttachmentPage)).ExtractInto(&s)
|
||||
return s.VolumeAttachments, err
|
||||
}
|
||||
|
||||
// VolumeAttachmentResult is the result from a volume attachment operation.
|
||||
type VolumeAttachmentResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a method that attempts to interpret any VolumeAttachment resource
|
||||
// response as a VolumeAttachment struct.
|
||||
func (r VolumeAttachmentResult) Extract() (*VolumeAttachment, error) {
|
||||
var s struct {
|
||||
VolumeAttachment *VolumeAttachment `json:"volumeAttachment"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.VolumeAttachment, err
|
||||
}
|
||||
|
||||
// CreateResult is the response from a Create operation. Call its Extract method
|
||||
// to interpret it as a VolumeAttachment.
|
||||
type CreateResult struct {
|
||||
VolumeAttachmentResult
|
||||
}
|
||||
|
||||
// GetResult is the response from a Get operation. Call its Extract method to
|
||||
// interpret it as a VolumeAttachment.
|
||||
type GetResult struct {
|
||||
VolumeAttachmentResult
|
||||
}
|
||||
|
||||
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||
// method to determine if the call succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
package volumeattach
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
const resourcePath = "os-volume_attachments"
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient, serverID string) string {
|
||||
return c.ServiceURL("servers", serverID, resourcePath)
|
||||
}
|
||||
|
||||
func listURL(c *gophercloud.ServiceClient, serverID string) string {
|
||||
return resourceURL(c, serverID)
|
||||
}
|
||||
|
||||
func createURL(c *gophercloud.ServiceClient, serverID string) string {
|
||||
return resourceURL(c, serverID)
|
||||
}
|
||||
|
||||
func getURL(c *gophercloud.ServiceClient, serverID, aID string) string {
|
||||
return c.ServiceURL("servers", serverID, resourcePath, aID)
|
||||
}
|
||||
|
||||
func deleteURL(c *gophercloud.ServiceClient, serverID, aID string) string {
|
||||
return getURL(c, serverID, aID)
|
||||
}
|
137
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go
generated
vendored
137
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go
generated
vendored
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
Package flavors provides information and interaction with the flavor API
|
||||
in the OpenStack Compute service.
|
||||
|
||||
A flavor is an available hardware configuration for a server. Each flavor
|
||||
has a unique combination of disk space, memory capacity and priority for CPU
|
||||
time.
|
||||
|
||||
Example to List Flavors
|
||||
|
||||
listOpts := flavors.ListOpts{
|
||||
AccessType: flavors.PublicAccess,
|
||||
}
|
||||
|
||||
allPages, err := flavors.ListDetail(computeClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allFlavors, err := flavors.ExtractFlavors(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, flavor := range allFlavors {
|
||||
fmt.Printf("%+v\n", flavor)
|
||||
}
|
||||
|
||||
Example to Create a Flavor
|
||||
|
||||
createOpts := flavors.CreateOpts{
|
||||
ID: "1",
|
||||
Name: "m1.tiny",
|
||||
Disk: gophercloud.IntToPointer(1),
|
||||
RAM: 512,
|
||||
VCPUs: 1,
|
||||
RxTxFactor: 1.0,
|
||||
}
|
||||
|
||||
flavor, err := flavors.Create(computeClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to List Flavor Access
|
||||
|
||||
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
|
||||
|
||||
allPages, err := flavors.ListAccesses(computeClient, flavorID).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allAccesses, err := flavors.ExtractAccesses(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, access := range allAccesses {
|
||||
fmt.Printf("%+v", access)
|
||||
}
|
||||
|
||||
Example to Grant Access to a Flavor
|
||||
|
||||
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
|
||||
|
||||
accessOpts := flavors.AddAccessOpts{
|
||||
Tenant: "15153a0979884b59b0592248ef947921",
|
||||
}
|
||||
|
||||
accessList, err := flavors.AddAccess(computeClient, flavor.ID, accessOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Remove/Revoke Access to a Flavor
|
||||
|
||||
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
|
||||
|
||||
accessOpts := flavors.RemoveAccessOpts{
|
||||
Tenant: "15153a0979884b59b0592248ef947921",
|
||||
}
|
||||
|
||||
accessList, err := flavors.RemoveAccess(computeClient, flavor.ID, accessOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create Extra Specs for a Flavor
|
||||
|
||||
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
|
||||
|
||||
createOpts := flavors.ExtraSpecsOpts{
|
||||
"hw:cpu_policy": "CPU-POLICY",
|
||||
"hw:cpu_thread_policy": "CPU-THREAD-POLICY",
|
||||
}
|
||||
createdExtraSpecs, err := flavors.CreateExtraSpecs(computeClient, flavorID, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%+v", createdExtraSpecs)
|
||||
|
||||
Example to Get Extra Specs for a Flavor
|
||||
|
||||
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
|
||||
|
||||
extraSpecs, err := flavors.ListExtraSpecs(computeClient, flavorID).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%+v", extraSpecs)
|
||||
|
||||
Example to Update Extra Specs for a Flavor
|
||||
|
||||
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
|
||||
|
||||
updateOpts := flavors.ExtraSpecsOpts{
|
||||
"hw:cpu_thread_policy": "CPU-THREAD-POLICY-UPDATED",
|
||||
}
|
||||
updatedExtraSpec, err := flavors.UpdateExtraSpec(computeClient, flavorID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%+v", updatedExtraSpec)
|
||||
|
||||
Example to Delete an Extra Spec for a Flavor
|
||||
|
||||
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
|
||||
err := flavors.DeleteExtraSpec(computeClient, flavorID, "hw:cpu_thread_policy").ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package flavors
|
357
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
357
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
@@ -1,357 +0,0 @@
|
||||
package flavors
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||
// List request.
|
||||
type ListOptsBuilder interface {
|
||||
ToFlavorListQuery() (string, error)
|
||||
}
|
||||
|
||||
/*
|
||||
AccessType maps to OpenStack's Flavor.is_public field. Although the is_public
|
||||
field is boolean, the request options are ternary, which is why AccessType is
|
||||
a string. The following values are allowed:
|
||||
|
||||
The AccessType arguement is optional, and if it is not supplied, OpenStack
|
||||
returns the PublicAccess flavors.
|
||||
*/
|
||||
type AccessType string
|
||||
|
||||
const (
|
||||
// PublicAccess returns public flavors and private flavors associated with
|
||||
// that project.
|
||||
PublicAccess AccessType = "true"
|
||||
|
||||
// PrivateAccess (admin only) returns private flavors, across all projects.
|
||||
PrivateAccess AccessType = "false"
|
||||
|
||||
// AllAccess (admin only) returns public and private flavors across all
|
||||
// projects.
|
||||
AllAccess AccessType = "None"
|
||||
)
|
||||
|
||||
/*
|
||||
ListOpts filters the results returned by the List() function.
|
||||
For example, a flavor with a minDisk field of 10 will not be returned if you
|
||||
specify MinDisk set to 20.
|
||||
|
||||
Typically, software will use the last ID of the previous call to List to set
|
||||
the Marker for the current call.
|
||||
*/
|
||||
type ListOpts struct {
|
||||
// ChangesSince, if provided, instructs List to return only those things which
|
||||
// have changed since the timestamp provided.
|
||||
ChangesSince string `q:"changes-since"`
|
||||
|
||||
// MinDisk and MinRAM, if provided, elides flavors which do not meet your
|
||||
// criteria.
|
||||
MinDisk int `q:"minDisk"`
|
||||
MinRAM int `q:"minRam"`
|
||||
|
||||
// SortDir allows to select sort direction.
|
||||
// It can be "asc" or "desc" (default).
|
||||
SortDir string `q:"sort_dir"`
|
||||
|
||||
// SortKey allows to sort by one of the flavors attributes.
|
||||
// Default is flavorid.
|
||||
SortKey string `q:"sort_key"`
|
||||
|
||||
// Marker and Limit control paging.
|
||||
// Marker instructs List where to start listing from.
|
||||
Marker string `q:"marker"`
|
||||
|
||||
// Limit instructs List to refrain from sending excessively large lists of
|
||||
// flavors.
|
||||
Limit int `q:"limit"`
|
||||
|
||||
// AccessType, if provided, instructs List which set of flavors to return.
|
||||
// If IsPublic not provided, flavors for the current project are returned.
|
||||
AccessType AccessType `q:"is_public"`
|
||||
}
|
||||
|
||||
// ToFlavorListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToFlavorListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// ListDetail instructs OpenStack to provide a list of flavors.
|
||||
// You may provide criteria by which List curtails its results for easier
|
||||
// processing.
|
||||
func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := listURL(client)
|
||||
if opts != nil {
|
||||
query, err := opts.ToFlavorListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return FlavorPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
type CreateOptsBuilder interface {
|
||||
ToFlavorCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts specifies parameters used for creating a flavor.
|
||||
type CreateOpts struct {
|
||||
// Name is the name of the flavor.
|
||||
Name string `json:"name" required:"true"`
|
||||
|
||||
// RAM is the memory of the flavor, measured in MB.
|
||||
RAM int `json:"ram" required:"true"`
|
||||
|
||||
// VCPUs is the number of vcpus for the flavor.
|
||||
VCPUs int `json:"vcpus" required:"true"`
|
||||
|
||||
// Disk the amount of root disk space, measured in GB.
|
||||
Disk *int `json:"disk" required:"true"`
|
||||
|
||||
// ID is a unique ID for the flavor.
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// Swap is the amount of swap space for the flavor, measured in MB.
|
||||
Swap *int `json:"swap,omitempty"`
|
||||
|
||||
// RxTxFactor alters the network bandwidth of a flavor.
|
||||
RxTxFactor float64 `json:"rxtx_factor,omitempty"`
|
||||
|
||||
// IsPublic flags a flavor as being available to all projects or not.
|
||||
IsPublic *bool `json:"os-flavor-access:is_public,omitempty"`
|
||||
|
||||
// Ephemeral is the amount of ephemeral disk space, measured in GB.
|
||||
Ephemeral *int `json:"OS-FLV-EXT-DATA:ephemeral,omitempty"`
|
||||
}
|
||||
|
||||
// ToFlavorCreateMap constructs a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "flavor")
|
||||
}
|
||||
|
||||
// Create requests the creation of a new flavor.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToFlavorCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes the specified flavor ID.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// ListAccesses retrieves the tenants which have access to a flavor.
|
||||
func ListAccesses(client *gophercloud.ServiceClient, id string) pagination.Pager {
|
||||
url := accessURL(client, id)
|
||||
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return AccessPage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
||||
|
||||
// AddAccessOptsBuilder allows extensions to add additional parameters to the
|
||||
// AddAccess requests.
|
||||
type AddAccessOptsBuilder interface {
|
||||
ToFlavorAddAccessMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// AddAccessOpts represents options for adding access to a flavor.
|
||||
type AddAccessOpts struct {
|
||||
// Tenant is the project/tenant ID to grant access.
|
||||
Tenant string `json:"tenant"`
|
||||
}
|
||||
|
||||
// ToFlavorAddAccessMap constructs a request body from AddAccessOpts.
|
||||
func (opts AddAccessOpts) ToFlavorAddAccessMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "addTenantAccess")
|
||||
}
|
||||
|
||||
// AddAccess grants a tenant/project access to a flavor.
|
||||
func AddAccess(client *gophercloud.ServiceClient, id string, opts AddAccessOptsBuilder) (r AddAccessResult) {
|
||||
b, err := opts.ToFlavorAddAccessMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// RemoveAccessOptsBuilder allows extensions to add additional parameters to the
|
||||
// RemoveAccess requests.
|
||||
type RemoveAccessOptsBuilder interface {
|
||||
ToFlavorRemoveAccessMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// RemoveAccessOpts represents options for removing access to a flavor.
|
||||
type RemoveAccessOpts struct {
|
||||
// Tenant is the project/tenant ID to grant access.
|
||||
Tenant string `json:"tenant"`
|
||||
}
|
||||
|
||||
// ToFlavorRemoveAccessMap constructs a request body from RemoveAccessOpts.
|
||||
func (opts RemoveAccessOpts) ToFlavorRemoveAccessMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "removeTenantAccess")
|
||||
}
|
||||
|
||||
// RemoveAccess removes/revokes a tenant/project access to a flavor.
|
||||
func RemoveAccess(client *gophercloud.ServiceClient, id string, opts RemoveAccessOptsBuilder) (r RemoveAccessResult) {
|
||||
b, err := opts.ToFlavorRemoveAccessMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// ExtraSpecs requests all the extra-specs for the given flavor ID.
|
||||
func ListExtraSpecs(client *gophercloud.ServiceClient, flavorID string) (r ListExtraSpecsResult) {
|
||||
_, r.Err = client.Get(extraSpecsListURL(client, flavorID), &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func GetExtraSpec(client *gophercloud.ServiceClient, flavorID string, key string) (r GetExtraSpecResult) {
|
||||
_, r.Err = client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// CreateExtraSpecsOptsBuilder allows extensions to add additional parameters to the
|
||||
// CreateExtraSpecs requests.
|
||||
type CreateExtraSpecsOptsBuilder interface {
|
||||
ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// ExtraSpecsOpts is a map that contains key-value pairs.
|
||||
type ExtraSpecsOpts map[string]string
|
||||
|
||||
// ToFlavorExtraSpecsCreateMap assembles a body for a Create request based on
|
||||
// the contents of ExtraSpecsOpts.
|
||||
func (opts ExtraSpecsOpts) ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{"extra_specs": opts}, nil
|
||||
}
|
||||
|
||||
// CreateExtraSpecs will create or update the extra-specs key-value pairs for
|
||||
// the specified Flavor.
|
||||
func CreateExtraSpecs(client *gophercloud.ServiceClient, flavorID string, opts CreateExtraSpecsOptsBuilder) (r CreateExtraSpecsResult) {
|
||||
b, err := opts.ToFlavorExtraSpecsCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(extraSpecsCreateURL(client, flavorID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateExtraSpecOptsBuilder allows extensions to add additional parameters to
|
||||
// the Update request.
|
||||
type UpdateExtraSpecOptsBuilder interface {
|
||||
ToFlavorExtraSpecUpdateMap() (map[string]string, string, error)
|
||||
}
|
||||
|
||||
// ToFlavorExtraSpecUpdateMap assembles a body for an Update request based on
|
||||
// the contents of a ExtraSpecOpts.
|
||||
func (opts ExtraSpecsOpts) ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) {
|
||||
if len(opts) != 1 {
|
||||
err := gophercloud.ErrInvalidInput{}
|
||||
err.Argument = "flavors.ExtraSpecOpts"
|
||||
err.Info = "Must have 1 and only one key-value pair"
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var key string
|
||||
for k := range opts {
|
||||
key = k
|
||||
}
|
||||
|
||||
return opts, key, nil
|
||||
}
|
||||
|
||||
// UpdateExtraSpec will updates the value of the specified flavor's extra spec
|
||||
// for the key in opts.
|
||||
func UpdateExtraSpec(client *gophercloud.ServiceClient, flavorID string, opts UpdateExtraSpecOptsBuilder) (r UpdateExtraSpecResult) {
|
||||
b, key, err := opts.ToFlavorExtraSpecUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(extraSpecUpdateURL(client, flavorID, key), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convienience function that returns a flavor's ID given its
|
||||
// name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
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
|
||||
}
|
||||
}
|
252
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go
generated
vendored
252
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go
generated
vendored
@@ -1,252 +0,0 @@
|
||||
package flavors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// CreateResult is the response of a Get operations. Call its Extract method to
|
||||
// interpret it as a Flavor.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult is the response of a Get operations. Call its Extract method to
|
||||
// interpret it as a Flavor.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// 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 provides access to the individual Flavor returned by the Get and
|
||||
// Create functions.
|
||||
func (r commonResult) Extract() (*Flavor, error) {
|
||||
var s struct {
|
||||
Flavor *Flavor `json:"flavor"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Flavor, err
|
||||
}
|
||||
|
||||
// Flavor represent (virtual) hardware configurations for server resources
|
||||
// in a region.
|
||||
type Flavor struct {
|
||||
// ID is the flavor's unique ID.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Disk is the amount of root disk, measured in GB.
|
||||
Disk int `json:"disk"`
|
||||
|
||||
// RAM is the amount of memory, measured in MB.
|
||||
RAM int `json:"ram"`
|
||||
|
||||
// Name is the name of the flavor.
|
||||
Name string `json:"name"`
|
||||
|
||||
// RxTxFactor describes bandwidth alterations of the flavor.
|
||||
RxTxFactor float64 `json:"rxtx_factor"`
|
||||
|
||||
// Swap is the amount of swap space, measured in MB.
|
||||
Swap int `json:"-"`
|
||||
|
||||
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
|
||||
VCPUs int `json:"vcpus"`
|
||||
|
||||
// IsPublic indicates whether the flavor is public.
|
||||
IsPublic bool `json:"os-flavor-access:is_public"`
|
||||
|
||||
// Ephemeral is the amount of ephemeral disk space, measured in GB.
|
||||
Ephemeral int `json:"OS-FLV-EXT-DATA:ephemeral"`
|
||||
}
|
||||
|
||||
func (r *Flavor) UnmarshalJSON(b []byte) error {
|
||||
type tmp Flavor
|
||||
var s struct {
|
||||
tmp
|
||||
Swap interface{} `json:"swap"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*r = Flavor(s.tmp)
|
||||
|
||||
switch t := s.Swap.(type) {
|
||||
case float64:
|
||||
r.Swap = int(t)
|
||||
case string:
|
||||
switch t {
|
||||
case "":
|
||||
r.Swap = 0
|
||||
default:
|
||||
swap, err := strconv.ParseFloat(t, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Swap = int(swap)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FlavorPage contains a single page of all flavors from a ListDetails call.
|
||||
type FlavorPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines if a FlavorPage contains any results.
|
||||
func (page FlavorPage) IsEmpty() (bool, error) {
|
||||
flavors, err := ExtractFlavors(page)
|
||||
return len(flavors) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||
// next page of results.
|
||||
func (page FlavorPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"flavors_links"`
|
||||
}
|
||||
err := page.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// ExtractFlavors provides access to the list of flavors in a page acquired
|
||||
// from the ListDetail operation.
|
||||
func ExtractFlavors(r pagination.Page) ([]Flavor, error) {
|
||||
var s struct {
|
||||
Flavors []Flavor `json:"flavors"`
|
||||
}
|
||||
err := (r.(FlavorPage)).ExtractInto(&s)
|
||||
return s.Flavors, err
|
||||
}
|
||||
|
||||
// AccessPage contains a single page of all FlavorAccess entries for a flavor.
|
||||
type AccessPage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty indicates whether an AccessPage is empty.
|
||||
func (page AccessPage) IsEmpty() (bool, error) {
|
||||
v, err := ExtractAccesses(page)
|
||||
return len(v) == 0, err
|
||||
}
|
||||
|
||||
// ExtractAccesses interprets a page of results as a slice of FlavorAccess.
|
||||
func ExtractAccesses(r pagination.Page) ([]FlavorAccess, error) {
|
||||
var s struct {
|
||||
FlavorAccesses []FlavorAccess `json:"flavor_access"`
|
||||
}
|
||||
err := (r.(AccessPage)).ExtractInto(&s)
|
||||
return s.FlavorAccesses, err
|
||||
}
|
||||
|
||||
type accessResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// AddAccessResult is the response of an AddAccess operation. Call its
|
||||
// Extract method to interpret it as a slice of FlavorAccess.
|
||||
type AddAccessResult struct {
|
||||
accessResult
|
||||
}
|
||||
|
||||
// RemoveAccessResult is the response of a RemoveAccess operation. Call its
|
||||
// Extract method to interpret it as a slice of FlavorAccess.
|
||||
type RemoveAccessResult struct {
|
||||
accessResult
|
||||
}
|
||||
|
||||
// Extract provides access to the result of an access create or delete.
|
||||
// The result will be all accesses that the flavor has.
|
||||
func (r accessResult) Extract() ([]FlavorAccess, error) {
|
||||
var s struct {
|
||||
FlavorAccesses []FlavorAccess `json:"flavor_access"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.FlavorAccesses, err
|
||||
}
|
||||
|
||||
// FlavorAccess represents an ACL of tenant access to a specific Flavor.
|
||||
type FlavorAccess struct {
|
||||
// FlavorID is the unique ID of the flavor.
|
||||
FlavorID string `json:"flavor_id"`
|
||||
|
||||
// TenantID is the unique ID of the tenant.
|
||||
TenantID string `json:"tenant_id"`
|
||||
}
|
||||
|
||||
// Extract interprets any extraSpecsResult as ExtraSpecs, if possible.
|
||||
func (r extraSpecsResult) Extract() (map[string]string, error) {
|
||||
var s struct {
|
||||
ExtraSpecs map[string]string `json:"extra_specs"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.ExtraSpecs, err
|
||||
}
|
||||
|
||||
// extraSpecsResult contains the result of a call for (potentially) multiple
|
||||
// key-value pairs. Call its Extract method to interpret it as a
|
||||
// map[string]interface.
|
||||
type extraSpecsResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// ListExtraSpecsResult contains the result of a Get operation. Call its Extract
|
||||
// method to interpret it as a map[string]interface.
|
||||
type ListExtraSpecsResult struct {
|
||||
extraSpecsResult
|
||||
}
|
||||
|
||||
// CreateExtraSpecResult contains the result of a Create operation. Call its
|
||||
// Extract method to interpret it as a map[string]interface.
|
||||
type CreateExtraSpecsResult struct {
|
||||
extraSpecsResult
|
||||
}
|
||||
|
||||
// extraSpecResult contains the result of a call for individual a single
|
||||
// key-value pair.
|
||||
type extraSpecResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// GetExtraSpecResult contains the result of a Get operation. Call its Extract
|
||||
// method to interpret it as a map[string]interface.
|
||||
type GetExtraSpecResult struct {
|
||||
extraSpecResult
|
||||
}
|
||||
|
||||
// UpdateExtraSpecResult contains the result of an Update operation. Call its
|
||||
// Extract method to interpret it as a map[string]interface.
|
||||
type UpdateExtraSpecResult struct {
|
||||
extraSpecResult
|
||||
}
|
||||
|
||||
// DeleteExtraSpecResult contains the result of a Delete operation. Call its
|
||||
// ExtractErr method to determine if the call succeeded or failed.
|
||||
type DeleteExtraSpecResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// Extract interprets any extraSpecResult as an ExtraSpec, if possible.
|
||||
func (r extraSpecResult) Extract() (map[string]string, error) {
|
||||
var s map[string]string
|
||||
err := r.ExtractInto(&s)
|
||||
return s, err
|
||||
}
|
49
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go
generated
vendored
49
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go
generated
vendored
@@ -1,49 +0,0 @@
|
||||
package flavors
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
func getURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("flavors", id)
|
||||
}
|
||||
|
||||
func listURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("flavors", "detail")
|
||||
}
|
||||
|
||||
func createURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("flavors")
|
||||
}
|
||||
|
||||
func deleteURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("flavors", id)
|
||||
}
|
||||
|
||||
func accessURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("flavors", id, "os-flavor-access")
|
||||
}
|
||||
|
||||
func accessActionURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("flavors", id, "action")
|
||||
}
|
||||
|
||||
func extraSpecsListURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("flavors", id, "os-extra_specs")
|
||||
}
|
||||
|
||||
func extraSpecsGetURL(client *gophercloud.ServiceClient, id, key string) string {
|
||||
return client.ServiceURL("flavors", id, "os-extra_specs", key)
|
||||
}
|
||||
|
||||
func extraSpecsCreateURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("flavors", id, "os-extra_specs")
|
||||
}
|
||||
|
||||
func extraSpecUpdateURL(client *gophercloud.ServiceClient, id, key string) string {
|
||||
return client.ServiceURL("flavors", id, "os-extra_specs", key)
|
||||
}
|
||||
|
||||
func extraSpecDeleteURL(client *gophercloud.ServiceClient, id, key string) string {
|
||||
return client.ServiceURL("flavors", id, "os-extra_specs", key)
|
||||
}
|
32
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/doc.go
generated
vendored
32
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/doc.go
generated
vendored
@@ -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
|
||||
}
|
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/urls.go
generated
vendored
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/urls.go
generated
vendored
@@ -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)
|
||||
}
|
115
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/doc.go
generated
vendored
115
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/doc.go
generated
vendored
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
Package servers provides information and interaction with the server API
|
||||
resource in the OpenStack Compute service.
|
||||
|
||||
A server is a virtual machine instance in the compute system. In order for
|
||||
one to be provisioned, a valid flavor and image are required.
|
||||
|
||||
Example to List Servers
|
||||
|
||||
listOpts := servers.ListOpts{
|
||||
AllTenants: true,
|
||||
}
|
||||
|
||||
allPages, err := servers.List(computeClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allServers, err := servers.ExtractServers(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, server := range allServers {
|
||||
fmt.Printf("%+v\n", server)
|
||||
}
|
||||
|
||||
Example to Create a Server
|
||||
|
||||
createOpts := servers.CreateOpts{
|
||||
Name: "server_name",
|
||||
ImageRef: "image-uuid",
|
||||
FlavorRef: "flavor-uuid",
|
||||
}
|
||||
|
||||
server, err := servers.Create(computeClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a Server
|
||||
|
||||
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
|
||||
err := servers.Delete(computeClient, serverID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Force Delete a Server
|
||||
|
||||
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
|
||||
err := servers.ForceDelete(computeClient, serverID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Reboot a Server
|
||||
|
||||
rebootOpts := servers.RebootOpts{
|
||||
Type: servers.SoftReboot,
|
||||
}
|
||||
|
||||
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
|
||||
|
||||
err := servers.Reboot(computeClient, serverID, rebootOpts).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Rebuild a Server
|
||||
|
||||
rebuildOpts := servers.RebuildOpts{
|
||||
Name: "new_name",
|
||||
ImageID: "image-uuid",
|
||||
}
|
||||
|
||||
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
|
||||
|
||||
server, err := servers.Rebuilt(computeClient, serverID, rebuildOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Resize a Server
|
||||
|
||||
resizeOpts := servers.ResizeOpts{
|
||||
FlavorRef: "flavor-uuid",
|
||||
}
|
||||
|
||||
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
|
||||
|
||||
err := servers.Resize(computeClient, serverID, resizeOpts).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = servers.ConfirmResize(computeClient, serverID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Snapshot a Server
|
||||
|
||||
snapshotOpts := servers.CreateImageOpts{
|
||||
Name: "snapshot_name",
|
||||
}
|
||||
|
||||
serverID := "d9072956-1560-487c-97f2-18bdf65ec749"
|
||||
|
||||
image, err := servers.CreateImage(computeClient, serverID, snapshotOpts).ExtractImageID()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package servers
|
71
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/errors.go
generated
vendored
71
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/errors.go
generated
vendored
@@ -1,71 +0,0 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
// ErrNeitherImageIDNorImageNameProvided is the error when neither the image
|
||||
// ID nor the image name is provided for a server operation
|
||||
type ErrNeitherImageIDNorImageNameProvided struct{ gophercloud.ErrMissingInput }
|
||||
|
||||
func (e ErrNeitherImageIDNorImageNameProvided) Error() string {
|
||||
return "One and only one of the image ID and the image name must be provided."
|
||||
}
|
||||
|
||||
// ErrNeitherFlavorIDNorFlavorNameProvided is the error when neither the flavor
|
||||
// ID nor the flavor name is provided for a server operation
|
||||
type ErrNeitherFlavorIDNorFlavorNameProvided struct{ gophercloud.ErrMissingInput }
|
||||
|
||||
func (e ErrNeitherFlavorIDNorFlavorNameProvided) Error() string {
|
||||
return "One and only one of the flavor ID and the flavor name must be provided."
|
||||
}
|
||||
|
||||
type ErrNoClientProvidedForIDByName struct{ gophercloud.ErrMissingInput }
|
||||
|
||||
func (e ErrNoClientProvidedForIDByName) Error() string {
|
||||
return "A service client must be provided to find a resource ID by name."
|
||||
}
|
||||
|
||||
// ErrInvalidHowParameterProvided is the error when an unknown value is given
|
||||
// for the `how` argument
|
||||
type ErrInvalidHowParameterProvided struct{ gophercloud.ErrInvalidInput }
|
||||
|
||||
// ErrNoAdminPassProvided is the error when an administrative password isn't
|
||||
// provided for a server operation
|
||||
type ErrNoAdminPassProvided struct{ gophercloud.ErrMissingInput }
|
||||
|
||||
// ErrNoImageIDProvided is the error when an image ID isn't provided for a server
|
||||
// operation
|
||||
type ErrNoImageIDProvided struct{ gophercloud.ErrMissingInput }
|
||||
|
||||
// ErrNoIDProvided is the error when a server ID isn't provided for a server
|
||||
// operation
|
||||
type ErrNoIDProvided struct{ gophercloud.ErrMissingInput }
|
||||
|
||||
// ErrServer is a generic error type for servers HTTP operations.
|
||||
type ErrServer struct {
|
||||
gophercloud.ErrUnexpectedResponseCode
|
||||
ID string
|
||||
}
|
||||
|
||||
func (se ErrServer) Error() string {
|
||||
return fmt.Sprintf("Error while executing HTTP request for server [%s]", se.ID)
|
||||
}
|
||||
|
||||
// Error404 overrides the generic 404 error message.
|
||||
func (se ErrServer) Error404(e gophercloud.ErrUnexpectedResponseCode) error {
|
||||
se.ErrUnexpectedResponseCode = e
|
||||
return &ErrServerNotFound{se}
|
||||
}
|
||||
|
||||
// ErrServerNotFound is the error when a 404 is received during server HTTP
|
||||
// operations.
|
||||
type ErrServerNotFound struct {
|
||||
ErrServer
|
||||
}
|
||||
|
||||
func (e ErrServerNotFound) Error() string {
|
||||
return fmt.Sprintf("I couldn't find server [%s]", e.ID)
|
||||
}
|
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/microversions.go
generated
vendored
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/microversions.go
generated
vendored
@@ -1,11 +0,0 @@
|
||||
package servers
|
||||
|
||||
// ExtractTags will extract the tags of a server.
|
||||
// This requires the client to be set to microversion 2.26 or later.
|
||||
func (r serverResult) ExtractTags() ([]string, error) {
|
||||
var s struct {
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Tags, err
|
||||
}
|
812
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
812
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
@@ -1,812 +0,0 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||
// List request.
|
||||
type ListOptsBuilder interface {
|
||||
ToServerListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts allows the filtering and sorting of paginated collections through
|
||||
// the API. Filtering is achieved by passing in struct field values that map to
|
||||
// the server attributes you want to see returned. Marker and Limit are used
|
||||
// for pagination.
|
||||
type ListOpts struct {
|
||||
// ChangesSince is a time/date stamp for when the server last changed status.
|
||||
ChangesSince string `q:"changes-since"`
|
||||
|
||||
// Image is the name of the image in URL format.
|
||||
Image string `q:"image"`
|
||||
|
||||
// Flavor is the name of the flavor in URL format.
|
||||
Flavor string `q:"flavor"`
|
||||
|
||||
// Name of the server as a string; can be queried with regular expressions.
|
||||
// Realize that ?name=bob returns both bob and bobb. If you need to match bob
|
||||
// only, you can use a regular expression matching the syntax of the
|
||||
// underlying database server implemented for Compute.
|
||||
Name string `q:"name"`
|
||||
|
||||
// Status is the value of the status of the server so that you can filter on
|
||||
// "ACTIVE" for example.
|
||||
Status string `q:"status"`
|
||||
|
||||
// Host is the name of the host as a string.
|
||||
Host string `q:"host"`
|
||||
|
||||
// Marker is a UUID of the server at which you want to set a marker.
|
||||
Marker string `q:"marker"`
|
||||
|
||||
// Limit is an integer value for the limit of values to return.
|
||||
Limit int `q:"limit"`
|
||||
|
||||
// AllTenants is a bool to show all tenants.
|
||||
AllTenants bool `q:"all_tenants"`
|
||||
|
||||
// TenantID lists servers for a particular tenant.
|
||||
// Setting "AllTenants = true" is required.
|
||||
TenantID string `q:"tenant_id"`
|
||||
}
|
||||
|
||||
// ToServerListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToServerListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List makes a request against the API to list servers accessible to you.
|
||||
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := listDetailURL(client)
|
||||
if opts != nil {
|
||||
query, err := opts.ToServerListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return ServerPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToServerCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// Network is used within CreateOpts to control a new server's network
|
||||
// attachments.
|
||||
type Network struct {
|
||||
// UUID of a network to attach to the newly provisioned server.
|
||||
// Required unless Port is provided.
|
||||
UUID string
|
||||
|
||||
// Port of a neutron network to attach to the newly provisioned server.
|
||||
// Required unless UUID is provided.
|
||||
Port string
|
||||
|
||||
// FixedIP specifies a fixed IPv4 address to be used on this network.
|
||||
FixedIP string
|
||||
}
|
||||
|
||||
// Personality is an array of files that are injected into the server at launch.
|
||||
type Personality []*File
|
||||
|
||||
// File is used within CreateOpts and RebuildOpts to inject a file into the
|
||||
// server at launch.
|
||||
// File implements the json.Marshaler interface, so when a Create or Rebuild
|
||||
// operation is requested, json.Marshal will call File's MarshalJSON method.
|
||||
type File struct {
|
||||
// Path of the file.
|
||||
Path string
|
||||
|
||||
// Contents of the file. Maximum content size is 255 bytes.
|
||||
Contents []byte
|
||||
}
|
||||
|
||||
// MarshalJSON marshals the escaped file, base64 encoding the contents.
|
||||
func (f *File) MarshalJSON() ([]byte, error) {
|
||||
file := struct {
|
||||
Path string `json:"path"`
|
||||
Contents string `json:"contents"`
|
||||
}{
|
||||
Path: f.Path,
|
||||
Contents: base64.StdEncoding.EncodeToString(f.Contents),
|
||||
}
|
||||
return json.Marshal(file)
|
||||
}
|
||||
|
||||
// CreateOpts specifies server creation parameters.
|
||||
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.
|
||||
// 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 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:"-"`
|
||||
|
||||
// UserData contains configuration information or scripts to use upon launch.
|
||||
// Create will base64-encode it for you, if it isn't already.
|
||||
UserData []byte `json:"-"`
|
||||
|
||||
// AvailabilityZone in which to launch the server.
|
||||
AvailabilityZone string `json:"availability_zone,omitempty"`
|
||||
|
||||
// Networks dictates how this server will be attached to available networks.
|
||||
// By default, the server will be attached to all isolated networks for the
|
||||
// tenant.
|
||||
Networks []Network `json:"-"`
|
||||
|
||||
// Metadata contains key-value pairs (up to 255 bytes each) to attach to the
|
||||
// server.
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
|
||||
// Personality includes files to inject into the server at launch.
|
||||
// Create will base64-encode file contents for you.
|
||||
Personality Personality `json:"personality,omitempty"`
|
||||
|
||||
// ConfigDrive enables metadata injection through a configuration drive.
|
||||
ConfigDrive *bool `json:"config_drive,omitempty"`
|
||||
|
||||
// AdminPass sets the root user password. If not set, a randomly-generated
|
||||
// password will be created and returned in the response.
|
||||
AdminPass string `json:"adminPass,omitempty"`
|
||||
|
||||
// AccessIPv4 specifies an IPv4 address for the instance.
|
||||
AccessIPv4 string `json:"accessIPv4,omitempty"`
|
||||
|
||||
// AccessIPv6 specifies an IPv6 address for the instance.
|
||||
AccessIPv6 string `json:"accessIPv6,omitempty"`
|
||||
|
||||
// Min specifies Minimum number of servers to launch.
|
||||
Min int `json:"min_count,omitempty"`
|
||||
|
||||
// Max specifies Maximum number of servers to launch.
|
||||
Max int `json:"max_count,omitempty"`
|
||||
|
||||
// ServiceClient will allow calls to be made to retrieve an image or
|
||||
// flavor ID by name.
|
||||
ServiceClient *gophercloud.ServiceClient `json:"-"`
|
||||
|
||||
// Tags allows a server to be tagged with single-word metadata.
|
||||
// Requires microversion 2.52 or later.
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.UserData != nil {
|
||||
var userData string
|
||||
if _, err := base64.StdEncoding.DecodeString(string(opts.UserData)); err != nil {
|
||||
userData = base64.StdEncoding.EncodeToString(opts.UserData)
|
||||
} else {
|
||||
userData = string(opts.UserData)
|
||||
}
|
||||
b["user_data"] = &userData
|
||||
}
|
||||
|
||||
if len(opts.SecurityGroups) > 0 {
|
||||
securityGroups := make([]map[string]interface{}, len(opts.SecurityGroups))
|
||||
for i, groupName := range opts.SecurityGroups {
|
||||
securityGroups[i] = map[string]interface{}{"name": groupName}
|
||||
}
|
||||
b["security_groups"] = securityGroups
|
||||
}
|
||||
|
||||
if len(opts.Networks) > 0 {
|
||||
networks := make([]map[string]interface{}, len(opts.Networks))
|
||||
for i, net := range opts.Networks {
|
||||
networks[i] = make(map[string]interface{})
|
||||
if net.UUID != "" {
|
||||
networks[i]["uuid"] = net.UUID
|
||||
}
|
||||
if net.Port != "" {
|
||||
networks[i]["port"] = net.Port
|
||||
}
|
||||
if net.FixedIP != "" {
|
||||
networks[i]["fixed_ip"] = net.FixedIP
|
||||
}
|
||||
}
|
||||
b["networks"] = networks
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
if opts.Max != 0 {
|
||||
b["max_count"] = opts.Max
|
||||
}
|
||||
|
||||
return map[string]interface{}{"server": b}, nil
|
||||
}
|
||||
|
||||
// Create requests a server to be provisioned to the user in the current tenant.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
reqBody, err := opts.ToServerCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(listURL(client), reqBody, &r.Body, nil)
|
||||
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)
|
||||
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)
|
||||
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{
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional attributes to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToServerUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts specifies the base attributes that may be updated on an existing
|
||||
// server.
|
||||
type UpdateOpts struct {
|
||||
// Name changes the displayed name of the server.
|
||||
// The server host name will *not* change.
|
||||
// Server names are not constrained to be unique, even within the same tenant.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// AccessIPv4 provides a new IPv4 address for the instance.
|
||||
AccessIPv4 string `json:"accessIPv4,omitempty"`
|
||||
|
||||
// AccessIPv6 provides a new IPv6 address for the instance.
|
||||
AccessIPv6 string `json:"accessIPv6,omitempty"`
|
||||
}
|
||||
|
||||
// ToServerUpdateMap formats an UpdateOpts structure into a request body.
|
||||
func (opts UpdateOpts) ToServerUpdateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "server")
|
||||
}
|
||||
|
||||
// Update requests that various attributes of the indicated server be changed.
|
||||
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToServerUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// ChangeAdminPassword alters the administrator or root password for a specified
|
||||
// server.
|
||||
func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) (r ActionResult) {
|
||||
b := map[string]interface{}{
|
||||
"changePassword": map[string]string{
|
||||
"adminPass": newPassword,
|
||||
},
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// RebootMethod describes the mechanisms by which a server reboot can be requested.
|
||||
type RebootMethod string
|
||||
|
||||
// These constants determine how a server should be rebooted.
|
||||
// See the Reboot() function for further details.
|
||||
const (
|
||||
SoftReboot RebootMethod = "SOFT"
|
||||
HardReboot RebootMethod = "HARD"
|
||||
OSReboot = SoftReboot
|
||||
PowerCycle = HardReboot
|
||||
)
|
||||
|
||||
// RebootOptsBuilder allows extensions to add additional parameters to the
|
||||
// reboot request.
|
||||
type RebootOptsBuilder interface {
|
||||
ToServerRebootMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// RebootOpts provides options to the reboot request.
|
||||
type RebootOpts struct {
|
||||
// Type is the type of reboot to perform on the server.
|
||||
Type RebootMethod `json:"type" required:"true"`
|
||||
}
|
||||
|
||||
// ToServerRebootMap builds a body for the reboot request.
|
||||
func (opts RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "reboot")
|
||||
}
|
||||
|
||||
/*
|
||||
Reboot requests that a given server reboot.
|
||||
|
||||
Two methods exist for rebooting a server:
|
||||
|
||||
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.
|
||||
|
||||
SoftReboot (aka OSReboot) simply tells the OS to restart under its own
|
||||
procedure.
|
||||
E.g., in Linux, asking it to enter runlevel 6, or executing
|
||||
"sudo shutdown -r now", or by asking Windows to rtart the machine.
|
||||
*/
|
||||
func Reboot(client *gophercloud.ServiceClient, id string, opts RebootOptsBuilder) (r ActionResult) {
|
||||
b, err := opts.ToServerRebootMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// RebuildOptsBuilder allows extensions to provide additional parameters to the
|
||||
// rebuild request.
|
||||
type RebuildOptsBuilder interface {
|
||||
ToServerRebuildMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// RebuildOpts represents the configuration options used in a server rebuild
|
||||
// operation.
|
||||
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:"-"`
|
||||
|
||||
// Name to set the server to
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// AccessIPv4 [optional] provides a new IPv4 address for the instance.
|
||||
AccessIPv4 string `json:"accessIPv4,omitempty"`
|
||||
|
||||
// AccessIPv6 [optional] provides a new IPv6 address for the instance.
|
||||
AccessIPv6 string `json:"accessIPv6,omitempty"`
|
||||
|
||||
// Metadata [optional] contains key-value pairs (up to 255 bytes each)
|
||||
// to attach to the server.
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
|
||||
// Personality [optional] includes files to inject into the server at launch.
|
||||
// Rebuild will base64-encode file contents for you.
|
||||
Personality Personality `json:"personality,omitempty"`
|
||||
|
||||
// ServiceClient will allow calls to be made to retrieve an image or
|
||||
// flavor ID by name.
|
||||
ServiceClient *gophercloud.ServiceClient `json:"-"`
|
||||
}
|
||||
|
||||
// ToServerRebuildMap formats a RebuildOpts struct into a map for use in JSON
|
||||
func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "")
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
// Rebuild will reprovision the server according to the configuration options
|
||||
// provided in the RebuildOpts struct.
|
||||
func Rebuild(client *gophercloud.ServiceClient, id string, opts RebuildOptsBuilder) (r RebuildResult) {
|
||||
b, err := opts.ToServerRebuildMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// ResizeOptsBuilder allows extensions to add additional parameters to the
|
||||
// resize request.
|
||||
type ResizeOptsBuilder interface {
|
||||
ToServerResizeMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// ResizeOpts represents the configuration options used to control a Resize
|
||||
// operation.
|
||||
type ResizeOpts struct {
|
||||
// FlavorRef is the ID of the flavor you wish your server to become.
|
||||
FlavorRef string `json:"flavorRef" required:"true"`
|
||||
}
|
||||
|
||||
// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON
|
||||
// request body for the Resize request.
|
||||
func (opts ResizeOpts) ToServerResizeMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "resize")
|
||||
}
|
||||
|
||||
// Resize instructs the provider to change the flavor of the server.
|
||||
//
|
||||
// Note that this implies rebuilding it.
|
||||
//
|
||||
// Unfortunately, one cannot pass rebuild parameters to the resize function.
|
||||
// When the resize completes, the server will be in VERIFY_RESIZE state.
|
||||
// While in this state, you can explore the use of the new server's
|
||||
// configuration. If you like it, call ConfirmResize() to commit the resize
|
||||
// permanently. Otherwise, call RevertResize() to restore the old configuration.
|
||||
func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) (r ActionResult) {
|
||||
b, err := opts.ToServerResizeMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
|
||||
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{
|
||||
OkCodes: []int{201, 202, 204},
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// ResetMetadataOptsBuilder allows extensions to add additional parameters to
|
||||
// the Reset request.
|
||||
type ResetMetadataOptsBuilder interface {
|
||||
ToMetadataResetMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// MetadataOpts is a map that contains key-value pairs.
|
||||
type MetadataOpts map[string]string
|
||||
|
||||
// ToMetadataResetMap assembles a body for a Reset request based on the contents
|
||||
// of a MetadataOpts.
|
||||
func (opts MetadataOpts) ToMetadataResetMap() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{"metadata": opts}, nil
|
||||
}
|
||||
|
||||
// ToMetadataUpdateMap assembles a body for an Update request based on the
|
||||
// contents of a MetadataOpts.
|
||||
func (opts MetadataOpts) ToMetadataUpdateMap() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{"metadata": opts}, nil
|
||||
}
|
||||
|
||||
// ResetMetadata will create multiple new key-value pairs for the given server
|
||||
// ID.
|
||||
// Note: Using this operation will erase any already-existing metadata and
|
||||
// create the new metadata provided. To keep any already-existing metadata,
|
||||
// use the UpdateMetadatas or UpdateMetadata function.
|
||||
func ResetMetadata(client *gophercloud.ServiceClient, id string, opts ResetMetadataOptsBuilder) (r ResetMetadataResult) {
|
||||
b, err := opts.ToMetadataResetMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(metadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
|
||||
// the Create request.
|
||||
type UpdateMetadataOptsBuilder interface {
|
||||
ToMetadataUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateMetadata updates (or creates) all the metadata specified by opts for
|
||||
// the given server ID. This operation does not affect already-existing metadata
|
||||
// that is not specified by opts.
|
||||
func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) (r UpdateMetadataResult) {
|
||||
b, err := opts.ToMetadataUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(metadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// MetadatumOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type MetadatumOptsBuilder interface {
|
||||
ToMetadatumCreateMap() (map[string]interface{}, string, error)
|
||||
}
|
||||
|
||||
// MetadatumOpts is a map of length one that contains a key-value pair.
|
||||
type MetadatumOpts map[string]string
|
||||
|
||||
// ToMetadatumCreateMap assembles a body for a Create request based on the
|
||||
// contents of a MetadataumOpts.
|
||||
func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string, error) {
|
||||
if len(opts) != 1 {
|
||||
err := gophercloud.ErrInvalidInput{}
|
||||
err.Argument = "servers.MetadatumOpts"
|
||||
err.Info = "Must have 1 and only 1 key-value pair"
|
||||
return nil, "", err
|
||||
}
|
||||
metadatum := map[string]interface{}{"meta": opts}
|
||||
var key string
|
||||
for k := range metadatum["meta"].(MetadatumOpts) {
|
||||
key = k
|
||||
}
|
||||
return metadatum, key, nil
|
||||
}
|
||||
|
||||
// CreateMetadatum will create or update the key-value pair with the given key
|
||||
// for the given server ID.
|
||||
func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts MetadatumOptsBuilder) (r CreateMetadatumResult) {
|
||||
b, key, err := opts.ToMetadatumCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(metadatumURL(client, id, key), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// ListAddresses makes a request against the API to list the servers IP
|
||||
// addresses.
|
||||
func ListAddresses(client *gophercloud.ServiceClient, id string) pagination.Pager {
|
||||
return pagination.NewPager(client, listAddressesURL(client, id), func(r pagination.PageResult) pagination.Page {
|
||||
return AddressPage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
||||
|
||||
// ListAddressesByNetwork makes a request against the API to list the servers IP
|
||||
// addresses for the given network.
|
||||
func ListAddressesByNetwork(client *gophercloud.ServiceClient, id, network string) pagination.Pager {
|
||||
return pagination.NewPager(client, listAddressesByNetworkURL(client, id, network), func(r pagination.PageResult) pagination.Page {
|
||||
return NetworkAddressPage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateImageOptsBuilder allows extensions to add additional parameters to the
|
||||
// CreateImage request.
|
||||
type CreateImageOptsBuilder interface {
|
||||
ToServerCreateImageMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateImageOpts provides options to pass to the CreateImage request.
|
||||
type CreateImageOpts struct {
|
||||
// Name of the image/snapshot.
|
||||
Name string `json:"name" required:"true"`
|
||||
|
||||
// Metadata contains key-value pairs (up to 255 bytes each) to attach to
|
||||
// the created image.
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// ToServerCreateImageMap formats a CreateImageOpts structure into a request
|
||||
// body.
|
||||
func (opts CreateImageOpts) ToServerCreateImageMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "createImage")
|
||||
}
|
||||
|
||||
// CreateImage makes a request against the nova API to schedule an image to be
|
||||
// created of the server
|
||||
func CreateImage(client *gophercloud.ServiceClient, id string, opts CreateImageOptsBuilder) (r CreateImageResult) {
|
||||
b, err := opts.ToServerCreateImageMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
resp, err := client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{202},
|
||||
})
|
||||
r.Err = err
|
||||
r.Header = resp.Header
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// ShowConsoleOutputOptsBuilder is the interface types must satisfy in order to be
|
||||
// used as ShowConsoleOutput options
|
||||
type ShowConsoleOutputOptsBuilder interface {
|
||||
ToServerShowConsoleOutputMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// ShowConsoleOutputOpts satisfies the ShowConsoleOutputOptsBuilder
|
||||
type ShowConsoleOutputOpts struct {
|
||||
// The number of lines to fetch from the end of console log.
|
||||
// All lines will be returned if this is not specified.
|
||||
Length int `json:"length,omitempty"`
|
||||
}
|
||||
|
||||
// ToServerShowConsoleOutputMap formats a ShowConsoleOutputOpts structure into a request body.
|
||||
func (opts ShowConsoleOutputOpts) ToServerShowConsoleOutputMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "os-getConsoleOutput")
|
||||
}
|
||||
|
||||
// ShowConsoleOutput makes a request against the nova API to get console log from the server
|
||||
func ShowConsoleOutput(client *gophercloud.ServiceClient, id string, opts ShowConsoleOutputOptsBuilder) (r ShowConsoleOutputResult) {
|
||||
b, err := opts.ToServerShowConsoleOutputMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
414
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
414
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
@@ -1,414 +0,0 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
type serverResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets any serverResult as a Server, if possible.
|
||||
func (r serverResult) Extract() (*Server, error) {
|
||||
var s Server
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
||||
|
||||
func (r serverResult) ExtractInto(v interface{}) error {
|
||||
return r.Result.ExtractIntoStructPtr(v, "server")
|
||||
}
|
||||
|
||||
func ExtractServersInto(r pagination.Page, v interface{}) error {
|
||||
return r.(ServerPage).Result.ExtractIntoSlicePtr(v, "servers")
|
||||
}
|
||||
|
||||
// CreateResult is the response from a Create operation. Call its Extract
|
||||
// method to interpret it as a Server.
|
||||
type CreateResult struct {
|
||||
serverResult
|
||||
}
|
||||
|
||||
// GetResult is the response from a Get operation. Call its Extract
|
||||
// method to interpret it as a Server.
|
||||
type GetResult struct {
|
||||
serverResult
|
||||
}
|
||||
|
||||
// UpdateResult is the response from an Update operation. Call its Extract
|
||||
// method to interpret it as a Server.
|
||||
type UpdateResult struct {
|
||||
serverResult
|
||||
}
|
||||
|
||||
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||
// method to determine if the call succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// RebuildResult is the response from a Rebuild operation. Call its Extract
|
||||
// method to interpret it as a Server.
|
||||
type RebuildResult struct {
|
||||
serverResult
|
||||
}
|
||||
|
||||
// ActionResult represents the result of server action operations, like reboot.
|
||||
// Call its ExtractErr method to determine if the action succeeded or failed.
|
||||
type ActionResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// CreateImageResult is the response from a CreateImage operation. Call its
|
||||
// ExtractImageID method to retrieve the ID of the newly created image.
|
||||
type CreateImageResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// ShowConsoleOutputResult represents the result of console output from a server
|
||||
type ShowConsoleOutputResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract will return the console output from a ShowConsoleOutput request.
|
||||
func (r ShowConsoleOutputResult) Extract() (string, error) {
|
||||
var s struct {
|
||||
Output string `json:"output"`
|
||||
}
|
||||
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Output, err
|
||||
}
|
||||
|
||||
// GetPasswordResult represent the result of a get os-server-password operation.
|
||||
// Call its ExtractPassword method to retrieve the password.
|
||||
type GetPasswordResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// ExtractPassword gets the encrypted password.
|
||||
// If privateKey != nil the password is decrypted with the private key.
|
||||
// If privateKey == nil the encrypted password is returned and can be decrypted
|
||||
// with:
|
||||
// echo '<pwd>' | base64 -D | openssl rsautl -decrypt -inkey <private_key>
|
||||
func (r GetPasswordResult) ExtractPassword(privateKey *rsa.PrivateKey) (string, error) {
|
||||
var s struct {
|
||||
Password string `json:"password"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err == nil && privateKey != nil && s.Password != "" {
|
||||
return decryptPassword(s.Password, privateKey)
|
||||
}
|
||||
return s.Password, err
|
||||
}
|
||||
|
||||
func decryptPassword(encryptedPassword string, privateKey *rsa.PrivateKey) (string, error) {
|
||||
b64EncryptedPassword := make([]byte, base64.StdEncoding.DecodedLen(len(encryptedPassword)))
|
||||
|
||||
n, err := base64.StdEncoding.Decode(b64EncryptedPassword, []byte(encryptedPassword))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to base64 decode encrypted password: %s", err)
|
||||
}
|
||||
password, err := rsa.DecryptPKCS1v15(nil, privateKey, b64EncryptedPassword[0:n])
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to decrypt password: %s", err)
|
||||
}
|
||||
|
||||
return string(password), nil
|
||||
}
|
||||
|
||||
// ExtractImageID gets the ID of the newly created server image from the header.
|
||||
func (r CreateImageResult) ExtractImageID() (string, error) {
|
||||
if r.Err != nil {
|
||||
return "", r.Err
|
||||
}
|
||||
// Get the image id from the header
|
||||
u, err := url.ParseRequestURI(r.Header.Get("Location"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
imageID := path.Base(u.Path)
|
||||
if imageID == "." || imageID == "/" {
|
||||
return "", fmt.Errorf("Failed to parse the ID of newly created image: %s", u)
|
||||
}
|
||||
return imageID, nil
|
||||
}
|
||||
|
||||
// Server represents a server/instance in the OpenStack cloud.
|
||||
type Server struct {
|
||||
// ID uniquely identifies this server amongst all other servers,
|
||||
// including those not accessible to the current tenant.
|
||||
ID string `json:"id"`
|
||||
|
||||
// TenantID identifies the tenant owning this server resource.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// UserID uniquely identifies the user account owning the tenant.
|
||||
UserID string `json:"user_id"`
|
||||
|
||||
// Name contains the human-readable name for the server.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Updated and Created contain ISO-8601 timestamps of when the state of the
|
||||
// server last changed, and when it was created.
|
||||
Updated time.Time `json:"updated"`
|
||||
Created time.Time `json:"created"`
|
||||
|
||||
// HostID is the host where the server is located in the cloud.
|
||||
HostID string `json:"hostid"`
|
||||
|
||||
// Status contains the current operational status of the server,
|
||||
// such as IN_PROGRESS or ACTIVE.
|
||||
Status string `json:"status"`
|
||||
|
||||
// Progress ranges from 0..100.
|
||||
// A request made against the server completes only once Progress reaches 100.
|
||||
Progress int `json:"progress"`
|
||||
|
||||
// AccessIPv4 and AccessIPv6 contain the IP addresses of the server,
|
||||
// suitable for remote access for administration.
|
||||
AccessIPv4 string `json:"accessIPv4"`
|
||||
AccessIPv6 string `json:"accessIPv6"`
|
||||
|
||||
// Image refers to a JSON object, which itself indicates the OS image used to
|
||||
// deploy the server.
|
||||
Image map[string]interface{} `json:"-"`
|
||||
|
||||
// Flavor refers to a JSON object, which itself indicates the hardware
|
||||
// configuration of the deployed server.
|
||||
Flavor map[string]interface{} `json:"flavor"`
|
||||
|
||||
// Addresses includes a list of all IP addresses assigned to the server,
|
||||
// keyed by pool.
|
||||
Addresses map[string]interface{} `json:"addresses"`
|
||||
|
||||
// Metadata includes a list of all user-specified key-value pairs attached
|
||||
// to the server.
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
|
||||
// Links includes HTTP references to the itself, useful for passing along to
|
||||
// other APIs that might want a server reference.
|
||||
Links []interface{} `json:"links"`
|
||||
|
||||
// KeyName indicates which public key was injected into the server on launch.
|
||||
KeyName string `json:"key_name"`
|
||||
|
||||
// AdminPass will generally be empty (""). However, it will contain the
|
||||
// administrative password chosen when provisioning a new server without a
|
||||
// set AdminPass setting in the first place.
|
||||
// Note that this is the ONLY time this field will be valid.
|
||||
AdminPass string `json:"adminPass"`
|
||||
|
||||
// SecurityGroups includes the security groups that this instance has applied
|
||||
// to it.
|
||||
SecurityGroups []map[string]interface{} `json:"security_groups"`
|
||||
|
||||
// Fault contains failure information about a server.
|
||||
Fault Fault `json:"fault"`
|
||||
}
|
||||
|
||||
type Fault struct {
|
||||
Code int `json:"code"`
|
||||
Created time.Time `json:"created"`
|
||||
Details string `json:"details"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (r *Server) UnmarshalJSON(b []byte) error {
|
||||
type tmp Server
|
||||
var s struct {
|
||||
tmp
|
||||
Image interface{} `json:"image"`
|
||||
}
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*r = Server(s.tmp)
|
||||
|
||||
switch t := s.Image.(type) {
|
||||
case map[string]interface{}:
|
||||
r.Image = t
|
||||
case string:
|
||||
switch t {
|
||||
case "":
|
||||
r.Image = nil
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ServerPage abstracts the raw results of making a List() request against
|
||||
// the API. As OpenStack extensions may freely alter the response bodies of
|
||||
// structures returned to the client, you may only safely access the data
|
||||
// provided through the ExtractServers call.
|
||||
type ServerPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if a page contains no Server results.
|
||||
func (r ServerPage) IsEmpty() (bool, error) {
|
||||
s, err := ExtractServers(r)
|
||||
return len(s) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||
// next page of results.
|
||||
func (r ServerPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"servers_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// ExtractServers interprets the results of a single page from a List() call,
|
||||
// producing a slice of Server entities.
|
||||
func ExtractServers(r pagination.Page) ([]Server, error) {
|
||||
var s []Server
|
||||
err := ExtractServersInto(r, &s)
|
||||
return s, err
|
||||
}
|
||||
|
||||
// MetadataResult contains the result of a call for (potentially) multiple
|
||||
// key-value pairs. Call its Extract method to interpret it as a
|
||||
// map[string]interface.
|
||||
type MetadataResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// GetMetadataResult contains the result of a Get operation. Call its Extract
|
||||
// method to interpret it as a map[string]interface.
|
||||
type GetMetadataResult struct {
|
||||
MetadataResult
|
||||
}
|
||||
|
||||
// ResetMetadataResult contains the result of a Reset operation. Call its
|
||||
// Extract method to interpret it as a map[string]interface.
|
||||
type ResetMetadataResult struct {
|
||||
MetadataResult
|
||||
}
|
||||
|
||||
// UpdateMetadataResult contains the result of an Update operation. Call its
|
||||
// Extract method to interpret it as a map[string]interface.
|
||||
type UpdateMetadataResult struct {
|
||||
MetadataResult
|
||||
}
|
||||
|
||||
// MetadatumResult contains the result of a call for individual a single
|
||||
// key-value pair.
|
||||
type MetadatumResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// GetMetadatumResult contains the result of a Get operation. Call its Extract
|
||||
// method to interpret it as a map[string]interface.
|
||||
type GetMetadatumResult struct {
|
||||
MetadatumResult
|
||||
}
|
||||
|
||||
// CreateMetadatumResult contains the result of a Create operation. Call its
|
||||
// Extract method to interpret it as a map[string]interface.
|
||||
type CreateMetadatumResult struct {
|
||||
MetadatumResult
|
||||
}
|
||||
|
||||
// DeleteMetadatumResult contains the result of a Delete operation. Call its
|
||||
// ExtractErr method to determine if the call succeeded or failed.
|
||||
type DeleteMetadatumResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// Extract interprets any MetadataResult as a Metadata, if possible.
|
||||
func (r MetadataResult) Extract() (map[string]string, error) {
|
||||
var s struct {
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Metadata, err
|
||||
}
|
||||
|
||||
// Extract interprets any MetadatumResult as a Metadatum, if possible.
|
||||
func (r MetadatumResult) Extract() (map[string]string, error) {
|
||||
var s struct {
|
||||
Metadatum map[string]string `json:"meta"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Metadatum, err
|
||||
}
|
||||
|
||||
// Address represents an IP address.
|
||||
type Address struct {
|
||||
Version int `json:"version"`
|
||||
Address string `json:"addr"`
|
||||
}
|
||||
|
||||
// AddressPage abstracts the raw results of making a ListAddresses() request
|
||||
// against the API. As OpenStack extensions may freely alter the response bodies
|
||||
// of structures returned to the client, you may only safely access the data
|
||||
// provided through the ExtractAddresses call.
|
||||
type AddressPage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if an AddressPage contains no networks.
|
||||
func (r AddressPage) IsEmpty() (bool, error) {
|
||||
addresses, err := ExtractAddresses(r)
|
||||
return len(addresses) == 0, err
|
||||
}
|
||||
|
||||
// ExtractAddresses interprets the results of a single page from a
|
||||
// ListAddresses() call, producing a map of addresses.
|
||||
func ExtractAddresses(r pagination.Page) (map[string][]Address, error) {
|
||||
var s struct {
|
||||
Addresses map[string][]Address `json:"addresses"`
|
||||
}
|
||||
err := (r.(AddressPage)).ExtractInto(&s)
|
||||
return s.Addresses, err
|
||||
}
|
||||
|
||||
// NetworkAddressPage abstracts the raw results of making a
|
||||
// ListAddressesByNetwork() request against the API.
|
||||
// As OpenStack extensions may freely alter the response bodies of structures
|
||||
// returned to the client, you may only safely access the data provided through
|
||||
// the ExtractAddresses call.
|
||||
type NetworkAddressPage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if a NetworkAddressPage contains no addresses.
|
||||
func (r NetworkAddressPage) IsEmpty() (bool, error) {
|
||||
addresses, err := ExtractNetworkAddresses(r)
|
||||
return len(addresses) == 0, err
|
||||
}
|
||||
|
||||
// ExtractNetworkAddresses interprets the results of a single page from a
|
||||
// ListAddressesByNetwork() call, producing a slice of addresses.
|
||||
func ExtractNetworkAddresses(r pagination.Page) ([]Address, error) {
|
||||
var s map[string][]Address
|
||||
err := (r.(NetworkAddressPage)).ExtractInto(&s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var key string
|
||||
for k := range s {
|
||||
key = k
|
||||
}
|
||||
|
||||
return s[key], err
|
||||
}
|
51
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/urls.go
generated
vendored
51
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/urls.go
generated
vendored
@@ -1,51 +0,0 @@
|
||||
package servers
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func createURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("servers")
|
||||
}
|
||||
|
||||
func listURL(client *gophercloud.ServiceClient) string {
|
||||
return createURL(client)
|
||||
}
|
||||
|
||||
func listDetailURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("servers", "detail")
|
||||
}
|
||||
|
||||
func deleteURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("servers", id)
|
||||
}
|
||||
|
||||
func getURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(client, id)
|
||||
}
|
||||
|
||||
func updateURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return deleteURL(client, id)
|
||||
}
|
||||
|
||||
func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("servers", id, "action")
|
||||
}
|
||||
|
||||
func metadatumURL(client *gophercloud.ServiceClient, id, key string) string {
|
||||
return client.ServiceURL("servers", id, "metadata", key)
|
||||
}
|
||||
|
||||
func metadataURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("servers", id, "metadata")
|
||||
}
|
||||
|
||||
func listAddressesURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("servers", id, "ips")
|
||||
}
|
||||
|
||||
func listAddressesByNetworkURL(client *gophercloud.ServiceClient, id, network string) string {
|
||||
return client.ServiceURL("servers", id, "ips", network)
|
||||
}
|
||||
|
||||
func passwordURL(client *gophercloud.ServiceClient, id string) string {
|
||||
return client.ServiceURL("servers", id, "os-server-password")
|
||||
}
|
21
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/util.go
generated
vendored
21
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/util.go
generated
vendored
@@ -1,21 +0,0 @@
|
||||
package servers
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
// WaitForStatus will continually poll a server until it successfully
|
||||
// transitions to a specified status. It will do this for at most the number
|
||||
// of seconds specified.
|
||||
func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error {
|
||||
return gophercloud.WaitFor(secs, func() (bool, error) {
|
||||
current, err := Get(c, id).Extract()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if current.Status == status {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
14
vendor/github.com/gophercloud/gophercloud/openstack/doc.go
generated
vendored
14
vendor/github.com/gophercloud/gophercloud/openstack/doc.go
generated
vendored
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
Package openstack contains resources for the individual OpenStack projects
|
||||
supported in Gophercloud. It also includes functions to authenticate to an
|
||||
OpenStack cloud and for provisioning various service-level clients.
|
||||
|
||||
Example of Creating a Service Client
|
||||
|
||||
ao, err := openstack.AuthOptionsFromEnv()
|
||||
provider, err := openstack.AuthenticatedClient(ao)
|
||||
client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
|
||||
Region: os.Getenv("OS_REGION_NAME"),
|
||||
})
|
||||
*/
|
||||
package openstack
|
107
vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go
generated
vendored
107
vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go
generated
vendored
@@ -1,107 +0,0 @@
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
||||
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
)
|
||||
|
||||
/*
|
||||
V2EndpointURL discovers the endpoint URL for a specific service from a
|
||||
ServiceCatalog acquired during the v2 identity service.
|
||||
|
||||
The specified EndpointOpts are used to identify a unique, unambiguous endpoint
|
||||
to return. It's an error both when multiple endpoints match the provided
|
||||
criteria and when none do. The minimum that can be specified is a Type, but you
|
||||
will also often need to specify a Name and/or a Region depending on what's
|
||||
available on your OpenStack deployment.
|
||||
*/
|
||||
func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
|
||||
// Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided.
|
||||
var endpoints = make([]tokens2.Endpoint, 0, 1)
|
||||
for _, entry := range catalog.Entries {
|
||||
if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) {
|
||||
for _, endpoint := range entry.Endpoints {
|
||||
if opts.Region == "" || endpoint.Region == opts.Region {
|
||||
endpoints = append(endpoints, endpoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report an error if the options were ambiguous.
|
||||
if len(endpoints) > 1 {
|
||||
err := &ErrMultipleMatchingEndpointsV2{}
|
||||
err.Endpoints = endpoints
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Extract the appropriate URL from the matching Endpoint.
|
||||
for _, endpoint := range endpoints {
|
||||
switch opts.Availability {
|
||||
case gophercloud.AvailabilityPublic:
|
||||
return gophercloud.NormalizeURL(endpoint.PublicURL), nil
|
||||
case gophercloud.AvailabilityInternal:
|
||||
return gophercloud.NormalizeURL(endpoint.InternalURL), nil
|
||||
case gophercloud.AvailabilityAdmin:
|
||||
return gophercloud.NormalizeURL(endpoint.AdminURL), nil
|
||||
default:
|
||||
err := &ErrInvalidAvailabilityProvided{}
|
||||
err.Argument = "Availability"
|
||||
err.Value = opts.Availability
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Report an error if there were no matching endpoints.
|
||||
err := &gophercloud.ErrEndpointNotFound{}
|
||||
return "", err
|
||||
}
|
||||
|
||||
/*
|
||||
V3EndpointURL discovers the endpoint URL for a specific service from a Catalog
|
||||
acquired during the v3 identity service.
|
||||
|
||||
The specified EndpointOpts are used to identify a unique, unambiguous endpoint
|
||||
to return. It's an error both when multiple endpoints match the provided
|
||||
criteria and when none do. The minimum that can be specified is a Type, but you
|
||||
will also often need to specify a Name and/or a Region depending on what's
|
||||
available on your OpenStack deployment.
|
||||
*/
|
||||
func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
|
||||
// Extract Endpoints from the catalog entries that match the requested Type, Interface,
|
||||
// Name if provided, and Region if provided.
|
||||
var endpoints = make([]tokens3.Endpoint, 0, 1)
|
||||
for _, entry := range catalog.Entries {
|
||||
if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) {
|
||||
for _, endpoint := range entry.Endpoints {
|
||||
if opts.Availability != gophercloud.AvailabilityAdmin &&
|
||||
opts.Availability != gophercloud.AvailabilityPublic &&
|
||||
opts.Availability != gophercloud.AvailabilityInternal {
|
||||
err := &ErrInvalidAvailabilityProvided{}
|
||||
err.Argument = "Availability"
|
||||
err.Value = opts.Availability
|
||||
return "", err
|
||||
}
|
||||
if (opts.Availability == gophercloud.Availability(endpoint.Interface)) &&
|
||||
(opts.Region == "" || endpoint.Region == opts.Region || endpoint.RegionID == opts.Region) {
|
||||
endpoints = append(endpoints, endpoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report an error if the options were ambiguous.
|
||||
if len(endpoints) > 1 {
|
||||
return "", ErrMultipleMatchingEndpointsV3{Endpoints: endpoints}
|
||||
}
|
||||
|
||||
// Extract the URL from the matching Endpoint.
|
||||
for _, endpoint := range endpoints {
|
||||
return gophercloud.NormalizeURL(endpoint.URL), nil
|
||||
}
|
||||
|
||||
// Report an error if there were no matching endpoints.
|
||||
err := &gophercloud.ErrEndpointNotFound{}
|
||||
return "", err
|
||||
}
|
71
vendor/github.com/gophercloud/gophercloud/openstack/errors.go
generated
vendored
71
vendor/github.com/gophercloud/gophercloud/openstack/errors.go
generated
vendored
@@ -1,71 +0,0 @@
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
||||
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
)
|
||||
|
||||
// ErrEndpointNotFound is the error when no suitable endpoint can be found
|
||||
// in the user's catalog
|
||||
type ErrEndpointNotFound struct{ gophercloud.BaseError }
|
||||
|
||||
func (e ErrEndpointNotFound) Error() string {
|
||||
return "No suitable endpoint could be found in the service catalog."
|
||||
}
|
||||
|
||||
// ErrInvalidAvailabilityProvided is the error when an invalid endpoint
|
||||
// availability is provided
|
||||
type ErrInvalidAvailabilityProvided struct{ gophercloud.ErrInvalidInput }
|
||||
|
||||
func (e ErrInvalidAvailabilityProvided) Error() string {
|
||||
return fmt.Sprintf("Unexpected availability in endpoint query: %s", e.Value)
|
||||
}
|
||||
|
||||
// ErrMultipleMatchingEndpointsV2 is the error when more than one endpoint
|
||||
// for the given options is found in the v2 catalog
|
||||
type ErrMultipleMatchingEndpointsV2 struct {
|
||||
gophercloud.BaseError
|
||||
Endpoints []tokens2.Endpoint
|
||||
}
|
||||
|
||||
func (e ErrMultipleMatchingEndpointsV2) Error() string {
|
||||
return fmt.Sprintf("Discovered %d matching endpoints: %#v", len(e.Endpoints), e.Endpoints)
|
||||
}
|
||||
|
||||
// ErrMultipleMatchingEndpointsV3 is the error when more than one endpoint
|
||||
// for the given options is found in the v3 catalog
|
||||
type ErrMultipleMatchingEndpointsV3 struct {
|
||||
gophercloud.BaseError
|
||||
Endpoints []tokens3.Endpoint
|
||||
}
|
||||
|
||||
func (e ErrMultipleMatchingEndpointsV3) Error() string {
|
||||
return fmt.Sprintf("Discovered %d matching endpoints: %#v", len(e.Endpoints), e.Endpoints)
|
||||
}
|
||||
|
||||
// ErrNoAuthURL is the error when the OS_AUTH_URL environment variable is not
|
||||
// found
|
||||
type ErrNoAuthURL struct{ gophercloud.ErrInvalidInput }
|
||||
|
||||
func (e ErrNoAuthURL) Error() string {
|
||||
return "Environment variable OS_AUTH_URL needs to be set."
|
||||
}
|
||||
|
||||
// ErrNoUsername is the error when the OS_USERNAME environment variable is not
|
||||
// found
|
||||
type ErrNoUsername struct{ gophercloud.ErrInvalidInput }
|
||||
|
||||
func (e ErrNoUsername) Error() string {
|
||||
return "Environment variable OS_USERNAME needs to be set."
|
||||
}
|
||||
|
||||
// ErrNoPassword is the error when the OS_PASSWORD environment variable is not
|
||||
// found
|
||||
type ErrNoPassword struct{ gophercloud.ErrInvalidInput }
|
||||
|
||||
func (e ErrNoPassword) Error() string {
|
||||
return "Environment variable OS_PASSWORD needs to be set."
|
||||
}
|
65
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/doc.go
generated
vendored
65
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/doc.go
generated
vendored
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
Package tenants provides information and interaction with the
|
||||
tenants API resource for the OpenStack Identity service.
|
||||
|
||||
See http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
|
||||
and http://developer.openstack.org/api-ref-identity-v2.html#admin-tenants
|
||||
for more information.
|
||||
|
||||
Example to List Tenants
|
||||
|
||||
listOpts := tenants.ListOpts{
|
||||
Limit: 2,
|
||||
}
|
||||
|
||||
allPages, err := tenants.List(identityClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allTenants, err := tenants.ExtractTenants(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, tenant := range allTenants {
|
||||
fmt.Printf("%+v\n", tenant)
|
||||
}
|
||||
|
||||
Example to Create a Tenant
|
||||
|
||||
createOpts := tenants.CreateOpts{
|
||||
Name: "tenant_name",
|
||||
Description: "this is a tenant",
|
||||
Enabled: gophercloud.Enabled,
|
||||
}
|
||||
|
||||
tenant, err := tenants.Create(identityClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a Tenant
|
||||
|
||||
tenantID := "e6db6ed6277c461a853458589063b295"
|
||||
|
||||
updateOpts := tenants.UpdateOpts{
|
||||
Description: "this is a new description",
|
||||
Enabled: gophercloud.Disabled,
|
||||
}
|
||||
|
||||
tenant, err := tenants.Update(identityClient, tenantID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a Tenant
|
||||
|
||||
tenantID := "e6db6ed6277c461a853458589063b295"
|
||||
|
||||
err := tenants.Delete(identitYClient, tenantID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package tenants
|
116
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
116
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
@@ -1,116 +0,0 @@
|
||||
package tenants
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListOpts filters the Tenants that are returned by the List call.
|
||||
type ListOpts struct {
|
||||
// Marker is the ID of the last Tenant on the previous page.
|
||||
Marker string `q:"marker"`
|
||||
|
||||
// Limit specifies the page size.
|
||||
Limit int `q:"limit"`
|
||||
}
|
||||
|
||||
// List enumerates the Tenants to which the current token has access.
|
||||
func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager {
|
||||
url := listURL(client)
|
||||
if opts != nil {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += q.String()
|
||||
}
|
||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||
return TenantPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOpts represents the options needed when creating new tenant.
|
||||
type CreateOpts struct {
|
||||
// Name is the name of the tenant.
|
||||
Name string `json:"name" required:"true"`
|
||||
|
||||
// Description is the description of the tenant.
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// Enabled sets the tenant status to enabled or disabled.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
// CreateOptsBuilder enables extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToTenantCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// ToTenantCreateMap assembles a request body based on the contents of
|
||||
// a CreateOpts.
|
||||
func (opts CreateOpts) ToTenantCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "tenant")
|
||||
}
|
||||
|
||||
// Create is the operation responsible for creating new tenant.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToTenantCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToTenantUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts specifies the base attributes that may be updated on an existing
|
||||
// tenant.
|
||||
type UpdateOpts struct {
|
||||
// Name is the name of the tenant.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Description is the description of the tenant.
|
||||
Description *string `json:"description,omitempty"`
|
||||
|
||||
// Enabled sets the tenant status to enabled or disabled.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
// ToTenantUpdateMap formats an UpdateOpts structure into a request body.
|
||||
func (opts UpdateOpts) ToTenantUpdateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "tenant")
|
||||
}
|
||||
|
||||
// Update is the operation responsible for updating exist tenants by their TenantID.
|
||||
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToTenantUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Put(updateURL(client, id), &b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
91
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/results.go
generated
vendored
91
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/results.go
generated
vendored
@@ -1,91 +0,0 @@
|
||||
package tenants
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Tenant is a grouping of users in the identity service.
|
||||
type Tenant struct {
|
||||
// ID is a unique identifier for this tenant.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Name is a friendlier user-facing name for this tenant.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Description is a human-readable explanation of this Tenant's purpose.
|
||||
Description string `json:"description"`
|
||||
|
||||
// Enabled indicates whether or not a tenant is active.
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// TenantPage is a single page of Tenant results.
|
||||
type TenantPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a page of Tenants contains any results.
|
||||
func (r TenantPage) IsEmpty() (bool, error) {
|
||||
tenants, err := ExtractTenants(r)
|
||||
return len(tenants) == 0, err
|
||||
}
|
||||
|
||||
// NextPageURL extracts the "next" link from the tenants_links section of the result.
|
||||
func (r TenantPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"tenants_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// ExtractTenants returns a slice of Tenants contained in a single page of
|
||||
// results.
|
||||
func ExtractTenants(r pagination.Page) ([]Tenant, error) {
|
||||
var s struct {
|
||||
Tenants []Tenant `json:"tenants"`
|
||||
}
|
||||
err := (r.(TenantPage)).ExtractInto(&s)
|
||||
return s.Tenants, err
|
||||
}
|
||||
|
||||
type tenantResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets any tenantResults as a Tenant.
|
||||
func (r tenantResult) Extract() (*Tenant, error) {
|
||||
var s struct {
|
||||
Tenant *Tenant `json:"tenant"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Tenant, err
|
||||
}
|
||||
|
||||
// GetResult is the response from a Get request. Call its Extract method to
|
||||
// interpret it as a Tenant.
|
||||
type GetResult struct {
|
||||
tenantResult
|
||||
}
|
||||
|
||||
// CreateResult is the response from a Create request. Call its Extract method
|
||||
// to interpret it as a Tenant.
|
||||
type CreateResult struct {
|
||||
tenantResult
|
||||
}
|
||||
|
||||
// DeleteResult is the response from a Get request. Call its ExtractErr method
|
||||
// to determine if the call succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// UpdateResult is the response from a Update request. Call its Extract method
|
||||
// to interpret it as a Tenant.
|
||||
type UpdateResult struct {
|
||||
tenantResult
|
||||
}
|
23
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/urls.go
generated
vendored
23
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/urls.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
package tenants
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func listURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("tenants")
|
||||
}
|
||||
|
||||
func getURL(client *gophercloud.ServiceClient, tenantID string) string {
|
||||
return client.ServiceURL("tenants", tenantID)
|
||||
}
|
||||
|
||||
func createURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("tenants")
|
||||
}
|
||||
|
||||
func deleteURL(client *gophercloud.ServiceClient, tenantID string) string {
|
||||
return client.ServiceURL("tenants", tenantID)
|
||||
}
|
||||
|
||||
func updateURL(client *gophercloud.ServiceClient, tenantID string) string {
|
||||
return client.ServiceURL("tenants", tenantID)
|
||||
}
|
46
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/doc.go
generated
vendored
46
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/doc.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
Package tokens provides information and interaction with the token API
|
||||
resource for the OpenStack Identity service.
|
||||
|
||||
For more information, see:
|
||||
http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
|
||||
|
||||
Example to Create an Unscoped Token from a Password
|
||||
|
||||
authOpts := gophercloud.AuthOptions{
|
||||
Username: "user",
|
||||
Password: "pass"
|
||||
}
|
||||
|
||||
token, err := tokens.Create(identityClient, authOpts).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token from a Tenant ID and Password
|
||||
|
||||
authOpts := gophercloud.AuthOptions{
|
||||
Username: "user",
|
||||
Password: "password",
|
||||
TenantID: "fc394f2ab2df4114bde39905f800dc57"
|
||||
}
|
||||
|
||||
token, err := tokens.Create(identityClient, authOpts).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token from a Tenant Name and Password
|
||||
|
||||
authOpts := gophercloud.AuthOptions{
|
||||
Username: "user",
|
||||
Password: "password",
|
||||
TenantName: "tenantname"
|
||||
}
|
||||
|
||||
token, err := tokens.Create(identityClient, authOpts).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package tokens
|
103
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
generated
vendored
103
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
generated
vendored
@@ -1,103 +0,0 @@
|
||||
package tokens
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
// PasswordCredentialsV2 represents the required options to authenticate
|
||||
// with a username and password.
|
||||
type PasswordCredentialsV2 struct {
|
||||
Username string `json:"username" required:"true"`
|
||||
Password string `json:"password" required:"true"`
|
||||
}
|
||||
|
||||
// TokenCredentialsV2 represents the required options to authenticate
|
||||
// with a token.
|
||||
type TokenCredentialsV2 struct {
|
||||
ID string `json:"id,omitempty" required:"true"`
|
||||
}
|
||||
|
||||
// AuthOptionsV2 wraps a gophercloud AuthOptions in order to adhere to the
|
||||
// AuthOptionsBuilder interface.
|
||||
type AuthOptionsV2 struct {
|
||||
PasswordCredentials *PasswordCredentialsV2 `json:"passwordCredentials,omitempty" xor:"TokenCredentials"`
|
||||
|
||||
// The TenantID and TenantName fields are optional for the Identity V2 API.
|
||||
// Some providers allow you to specify a TenantName instead of the TenantId.
|
||||
// Some require both. Your provider's authentication policies will determine
|
||||
// how these fields influence authentication.
|
||||
TenantID string `json:"tenantId,omitempty"`
|
||||
TenantName string `json:"tenantName,omitempty"`
|
||||
|
||||
// TokenCredentials allows users to authenticate (possibly as another user)
|
||||
// with an authentication token ID.
|
||||
TokenCredentials *TokenCredentialsV2 `json:"token,omitempty" xor:"PasswordCredentials"`
|
||||
}
|
||||
|
||||
// AuthOptionsBuilder allows extensions to add additional parameters to the
|
||||
// token create request.
|
||||
type AuthOptionsBuilder interface {
|
||||
// ToTokenCreateMap assembles the Create request body, returning an error
|
||||
// if parameters are missing or inconsistent.
|
||||
ToTokenV2CreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// AuthOptions are the valid options for Openstack Identity v2 authentication.
|
||||
// For field descriptions, see gophercloud.AuthOptions.
|
||||
type AuthOptions struct {
|
||||
IdentityEndpoint string `json:"-"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
TenantID string `json:"tenantId,omitempty"`
|
||||
TenantName string `json:"tenantName,omitempty"`
|
||||
AllowReauth bool `json:"-"`
|
||||
TokenID string
|
||||
}
|
||||
|
||||
// ToTokenV2CreateMap builds a token request body from the given AuthOptions.
|
||||
func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) {
|
||||
v2Opts := AuthOptionsV2{
|
||||
TenantID: opts.TenantID,
|
||||
TenantName: opts.TenantName,
|
||||
}
|
||||
|
||||
if opts.Password != "" {
|
||||
v2Opts.PasswordCredentials = &PasswordCredentialsV2{
|
||||
Username: opts.Username,
|
||||
Password: opts.Password,
|
||||
}
|
||||
} else {
|
||||
v2Opts.TokenCredentials = &TokenCredentialsV2{
|
||||
ID: opts.TokenID,
|
||||
}
|
||||
}
|
||||
|
||||
b, err := gophercloud.BuildRequestBody(v2Opts, "auth")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Create authenticates to the identity service and attempts to acquire a Token.
|
||||
// Generally, rather than interact with this call directly, end users should
|
||||
// call openstack.AuthenticatedClient(), which abstracts all of the gory details
|
||||
// about navigating service catalogs and such.
|
||||
func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) (r CreateResult) {
|
||||
b, err := auth.ToTokenV2CreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(CreateURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 203},
|
||||
MoreHeaders: map[string]string{"X-Auth-Token": ""},
|
||||
})
|
||||
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{
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
return
|
||||
}
|
174
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go
generated
vendored
174
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go
generated
vendored
@@ -1,174 +0,0 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/identity/v2/tenants"
|
||||
)
|
||||
|
||||
// Token provides only the most basic information related to an authentication
|
||||
// token.
|
||||
type Token struct {
|
||||
// ID provides the primary means of identifying a user to the OpenStack API.
|
||||
// OpenStack defines this field as an opaque value, so do not depend on its
|
||||
// content. It is safe, however, to compare for equality.
|
||||
ID string
|
||||
|
||||
// ExpiresAt provides a timestamp in ISO 8601 format, indicating when the
|
||||
// authentication token becomes invalid. After this point in time, future
|
||||
// API requests made using this authentication token will respond with
|
||||
// errors. Either the caller will need to reauthenticate manually, or more
|
||||
// preferably, the caller should exploit automatic re-authentication.
|
||||
// See the AuthOptions structure for more details.
|
||||
ExpiresAt time.Time
|
||||
|
||||
// Tenant provides information about the tenant to which this token grants
|
||||
// access.
|
||||
Tenant tenants.Tenant
|
||||
}
|
||||
|
||||
// Role is a role for a user.
|
||||
type Role struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// User is an OpenStack user.
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
UserName string `json:"username"`
|
||||
Roles []Role `json:"roles"`
|
||||
}
|
||||
|
||||
// Endpoint represents a single API endpoint offered by a service.
|
||||
// It provides the public and internal URLs, if supported, along with a region
|
||||
// specifier, again if provided.
|
||||
//
|
||||
// The significance of the Region field will depend upon your provider.
|
||||
//
|
||||
// In addition, the interface offered by the service will have version
|
||||
// information associated with it through the VersionId, VersionInfo, and
|
||||
// VersionList fields, if provided or supported.
|
||||
//
|
||||
// In all cases, fields which aren't supported by the provider and service
|
||||
// combined will assume a zero-value ("").
|
||||
type Endpoint struct {
|
||||
TenantID string `json:"tenantId"`
|
||||
PublicURL string `json:"publicURL"`
|
||||
InternalURL string `json:"internalURL"`
|
||||
AdminURL string `json:"adminURL"`
|
||||
Region string `json:"region"`
|
||||
VersionID string `json:"versionId"`
|
||||
VersionInfo string `json:"versionInfo"`
|
||||
VersionList string `json:"versionList"`
|
||||
}
|
||||
|
||||
// CatalogEntry provides a type-safe interface to an Identity API V2 service
|
||||
// catalog listing.
|
||||
//
|
||||
// Each class of service, such as cloud DNS or block storage services, will have
|
||||
// a single CatalogEntry representing it.
|
||||
//
|
||||
// Note: when looking for the desired service, try, whenever possible, to key
|
||||
// off the type field. Otherwise, you'll tie the representation of the service
|
||||
// to a specific provider.
|
||||
type CatalogEntry struct {
|
||||
// Name will contain the provider-specified name for the service.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Type will contain a type string if OpenStack defines a type for the
|
||||
// service. Otherwise, for provider-specific services, the provider may assign
|
||||
// their own type strings.
|
||||
Type string `json:"type"`
|
||||
|
||||
// Endpoints will let the caller iterate over all the different endpoints that
|
||||
// may exist for the service.
|
||||
Endpoints []Endpoint `json:"endpoints"`
|
||||
}
|
||||
|
||||
// ServiceCatalog provides a view into the service catalog from a previous,
|
||||
// successful authentication.
|
||||
type ServiceCatalog struct {
|
||||
Entries []CatalogEntry
|
||||
}
|
||||
|
||||
// CreateResult is the response from a Create request. Use ExtractToken() to
|
||||
// interpret it as a Token, or ExtractServiceCatalog() to interpret it as a
|
||||
// service catalog.
|
||||
type CreateResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// GetResult is the deferred response from a Get call, which is the same with a
|
||||
// Created token. Use ExtractUser() to interpret it as a User.
|
||||
type GetResult struct {
|
||||
CreateResult
|
||||
}
|
||||
|
||||
// ExtractToken returns the just-created Token from a CreateResult.
|
||||
func (r CreateResult) ExtractToken() (*Token, error) {
|
||||
var s struct {
|
||||
Access struct {
|
||||
Token struct {
|
||||
Expires string `json:"expires"`
|
||||
ID string `json:"id"`
|
||||
Tenant tenants.Tenant `json:"tenant"`
|
||||
} `json:"token"`
|
||||
} `json:"access"`
|
||||
}
|
||||
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expiresTs, err := time.Parse(gophercloud.RFC3339Milli, s.Access.Token.Expires)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Token{
|
||||
ID: s.Access.Token.ID,
|
||||
ExpiresAt: expiresTs,
|
||||
Tenant: s.Access.Token.Tenant,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ExtractTokenID implements the gophercloud.AuthResult interface. The returned
|
||||
// string is the same as the ID field of the Token struct returned from
|
||||
// ExtractToken().
|
||||
func (r CreateResult) ExtractTokenID() (string, error) {
|
||||
var s struct {
|
||||
Access struct {
|
||||
Token struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"token"`
|
||||
} `json:"access"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Access.Token.ID, err
|
||||
}
|
||||
|
||||
// ExtractServiceCatalog returns the ServiceCatalog that was generated along
|
||||
// with the user's Token.
|
||||
func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
|
||||
var s struct {
|
||||
Access struct {
|
||||
Entries []CatalogEntry `json:"serviceCatalog"`
|
||||
} `json:"access"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return &ServiceCatalog{Entries: s.Access.Entries}, err
|
||||
}
|
||||
|
||||
// ExtractUser returns the User from a GetResult.
|
||||
func (r GetResult) ExtractUser() (*User, error) {
|
||||
var s struct {
|
||||
Access struct {
|
||||
User User `json:"user"`
|
||||
} `json:"access"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return &s.Access.User, err
|
||||
}
|
13
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/urls.go
generated
vendored
13
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/urls.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
package tokens
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
// CreateURL generates the URL used to create new Tokens.
|
||||
func CreateURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("tokens")
|
||||
}
|
||||
|
||||
// GetURL generates the URL used to Validate Tokens.
|
||||
func GetURL(client *gophercloud.ServiceClient, token string) string {
|
||||
return client.ServiceURL("tokens", token)
|
||||
}
|
26
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts/doc.go
generated
vendored
26
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts/doc.go
generated
vendored
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
Package trusts enables management of OpenStack Identity Trusts.
|
||||
|
||||
Example to Create a Token with Username, Password, and Trust ID
|
||||
|
||||
var trustToken struct {
|
||||
tokens.Token
|
||||
trusts.TokenExt
|
||||
}
|
||||
|
||||
authOptions := tokens.AuthOptions{
|
||||
UserID: "username",
|
||||
Password: "password",
|
||||
}
|
||||
|
||||
createOpts := trusts.AuthOptsExt{
|
||||
AuthOptionsBuilder: authOptions,
|
||||
TrustID: "de0945a",
|
||||
}
|
||||
|
||||
err := tokens.Create(identityClient, createOpts).ExtractInto(&trustToken)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package trusts
|
@@ -1,39 +0,0 @@
|
||||
package trusts
|
||||
|
||||
import "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
|
||||
|
||||
// AuthOptsExt extends the base Identity v3 tokens AuthOpts with a TrustID.
|
||||
type AuthOptsExt struct {
|
||||
tokens.AuthOptionsBuilder
|
||||
|
||||
// TrustID is the ID of the trust.
|
||||
TrustID string `json:"id"`
|
||||
}
|
||||
|
||||
// ToTokenV3CreateMap builds a create request body from the AuthOpts.
|
||||
func (opts AuthOptsExt) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
|
||||
return opts.AuthOptionsBuilder.ToTokenV3CreateMap(scope)
|
||||
}
|
||||
|
||||
// ToTokenV3ScopeMap builds a scope from AuthOpts.
|
||||
func (opts AuthOptsExt) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||
b, err := opts.AuthOptionsBuilder.ToTokenV3ScopeMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.TrustID != "" {
|
||||
if b == nil {
|
||||
b = make(map[string]interface{})
|
||||
}
|
||||
b["OS-TRUST:trust"] = map[string]interface{}{
|
||||
"id": opts.TrustID,
|
||||
}
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (opts AuthOptsExt) CanReauth() bool {
|
||||
return opts.AuthOptionsBuilder.CanReauth()
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
package trusts
|
||||
|
||||
// TrusteeUser represents the trusted user ID of a trust.
|
||||
type TrusteeUser struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// TrustorUser represents the trusting user ID of a trust.
|
||||
type TrustorUser struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// Trust represents a delegated authorization request between two
|
||||
// identities.
|
||||
type Trust struct {
|
||||
ID string `json:"id"`
|
||||
Impersonation bool `json:"impersonation"`
|
||||
TrusteeUser TrusteeUser `json:"trustee_user"`
|
||||
TrustorUser TrustorUser `json:"trustor_user"`
|
||||
RedelegatedTrustID string `json:"redelegated_trust_id"`
|
||||
RedelegationCount int `json:"redelegation_count"`
|
||||
}
|
||||
|
||||
// TokenExt represents an extension of the base token result.
|
||||
type TokenExt struct {
|
||||
Trust Trust `json:"OS-TRUST:trust"`
|
||||
}
|
108
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/doc.go
generated
vendored
108
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/doc.go
generated
vendored
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
Package tokens provides information and interaction with the token API
|
||||
resource for the OpenStack Identity service.
|
||||
|
||||
For more information, see:
|
||||
http://developer.openstack.org/api-ref-identity-v3.html#tokens-v3
|
||||
|
||||
Example to Create a Token From a Username and Password
|
||||
|
||||
authOptions := tokens.AuthOptions{
|
||||
UserID: "username",
|
||||
Password: "password",
|
||||
}
|
||||
|
||||
token, err := tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token From a Username, Password, and Domain
|
||||
|
||||
authOptions := tokens.AuthOptions{
|
||||
UserID: "username",
|
||||
Password: "password",
|
||||
DomainID: "default",
|
||||
}
|
||||
|
||||
token, err := tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
authOptions = tokens.AuthOptions{
|
||||
UserID: "username",
|
||||
Password: "password",
|
||||
DomainName: "default",
|
||||
}
|
||||
|
||||
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token From a Token
|
||||
|
||||
authOptions := tokens.AuthOptions{
|
||||
TokenID: "token_id",
|
||||
}
|
||||
|
||||
token, err := tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token from a Username and Password with Project ID Scope
|
||||
|
||||
scope := tokens.Scope{
|
||||
ProjectID: "0fe36e73809d46aeae6705c39077b1b3",
|
||||
}
|
||||
|
||||
authOptions := tokens.AuthOptions{
|
||||
Scope: &scope,
|
||||
UserID: "username",
|
||||
Password: "password",
|
||||
}
|
||||
|
||||
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token from a Username and Password with Domain ID Scope
|
||||
|
||||
scope := tokens.Scope{
|
||||
DomainID: "default",
|
||||
}
|
||||
|
||||
authOptions := tokens.AuthOptions{
|
||||
Scope: &scope,
|
||||
UserID: "username",
|
||||
Password: "password",
|
||||
}
|
||||
|
||||
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Token from a Username and Password with Project Name Scope
|
||||
|
||||
scope := tokens.Scope{
|
||||
ProjectName: "project_name",
|
||||
DomainID: "default",
|
||||
}
|
||||
|
||||
authOptions := tokens.AuthOptions{
|
||||
Scope: &scope,
|
||||
UserID: "username",
|
||||
Password: "password",
|
||||
}
|
||||
|
||||
token, err = tokens.Create(identityClient, authOptions).ExtractToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
*/
|
||||
package tokens
|
162
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
162
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
@@ -1,162 +0,0 @@
|
||||
package tokens
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
// Scope allows a created token to be limited to a specific domain or project.
|
||||
type Scope struct {
|
||||
ProjectID string
|
||||
ProjectName string
|
||||
DomainID string
|
||||
DomainName string
|
||||
}
|
||||
|
||||
// AuthOptionsBuilder provides the ability for extensions to add additional
|
||||
// parameters to AuthOptions. Extensions must satisfy all required methods.
|
||||
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)
|
||||
ToTokenV3ScopeMap() (map[string]interface{}, error)
|
||||
CanReauth() bool
|
||||
}
|
||||
|
||||
// AuthOptions represents options for authenticating a user.
|
||||
type AuthOptions struct {
|
||||
// IdentityEndpoint specifies the HTTP endpoint that is required to work with
|
||||
// the Identity API of the appropriate version. While it's ultimately needed
|
||||
// by all of the identity services, it will often be populated by a
|
||||
// provider-level function.
|
||||
IdentityEndpoint string `json:"-"`
|
||||
|
||||
// Username is required if using Identity V2 API. Consult with your provider's
|
||||
// control panel to discover your account's username. In Identity V3, either
|
||||
// UserID or a combination of Username and DomainID or DomainName are needed.
|
||||
Username string `json:"username,omitempty"`
|
||||
UserID string `json:"id,omitempty"`
|
||||
|
||||
Password string `json:"password,omitempty"`
|
||||
|
||||
// At most one of DomainID and DomainName must be provided if using Username
|
||||
// with Identity V3. Otherwise, either are optional.
|
||||
DomainID string `json:"-"`
|
||||
DomainName string `json:"name,omitempty"`
|
||||
|
||||
// AllowReauth should be set to true if you grant permission for Gophercloud
|
||||
// to cache your credentials in memory, and to allow Gophercloud to attempt
|
||||
// to re-authenticate automatically if/when your token expires. If you set
|
||||
// it to false, it will not cache these settings, but re-authentication will
|
||||
// not be possible. This setting defaults to false.
|
||||
AllowReauth bool `json:"-"`
|
||||
|
||||
// TokenID allows users to authenticate (possibly as another user) with an
|
||||
// authentication token ID.
|
||||
TokenID string `json:"-"`
|
||||
|
||||
// Authentication through Application Credentials requires supplying name, project and secret
|
||||
// For project we can use TenantID
|
||||
ApplicationCredentialID string `json:"-"`
|
||||
ApplicationCredentialName string `json:"-"`
|
||||
ApplicationCredentialSecret string `json:"-"`
|
||||
|
||||
Scope Scope `json:"-"`
|
||||
}
|
||||
|
||||
// ToTokenV3CreateMap builds a request body from AuthOptions.
|
||||
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
|
||||
gophercloudAuthOpts := gophercloud.AuthOptions{
|
||||
Username: opts.Username,
|
||||
UserID: opts.UserID,
|
||||
Password: opts.Password,
|
||||
DomainID: opts.DomainID,
|
||||
DomainName: opts.DomainName,
|
||||
AllowReauth: opts.AllowReauth,
|
||||
TokenID: opts.TokenID,
|
||||
ApplicationCredentialID: opts.ApplicationCredentialID,
|
||||
ApplicationCredentialName: opts.ApplicationCredentialName,
|
||||
ApplicationCredentialSecret: opts.ApplicationCredentialSecret,
|
||||
}
|
||||
|
||||
return gophercloudAuthOpts.ToTokenV3CreateMap(scope)
|
||||
}
|
||||
|
||||
// ToTokenV3CreateMap builds a scope request body from AuthOptions.
|
||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||
scope := gophercloud.AuthScope(opts.Scope)
|
||||
|
||||
gophercloudAuthOpts := gophercloud.AuthOptions{
|
||||
Scope: &scope,
|
||||
DomainID: opts.DomainID,
|
||||
DomainName: opts.DomainName,
|
||||
}
|
||||
|
||||
return gophercloudAuthOpts.ToTokenV3ScopeMap()
|
||||
}
|
||||
|
||||
func (opts *AuthOptions) CanReauth() bool {
|
||||
return opts.AllowReauth
|
||||
}
|
||||
|
||||
func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
|
||||
return map[string]string{
|
||||
"X-Subject-Token": subjectToken,
|
||||
}
|
||||
}
|
||||
|
||||
// Create authenticates and either generates a new token, or changes the Scope
|
||||
// of an existing token.
|
||||
func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder) (r CreateResult) {
|
||||
scope, err := opts.ToTokenV3ScopeMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
b, err := opts.ToTokenV3CreateMap(scope)
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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),
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
if resp != nil {
|
||||
r.Header = resp.Header
|
||||
}
|
||||
r.Err = 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),
|
||||
OkCodes: []int{200, 204, 404},
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return resp.StatusCode == 200 || resp.StatusCode == 204, nil
|
||||
}
|
||||
|
||||
// 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),
|
||||
})
|
||||
return
|
||||
}
|
178
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
generated
vendored
178
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
generated
vendored
@@ -1,178 +0,0 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
)
|
||||
|
||||
// Endpoint represents a single API endpoint offered by a service.
|
||||
// It matches either a public, internal or admin URL.
|
||||
// If supported, it contains a region specifier, again if provided.
|
||||
// The significance of the Region field will depend upon your provider.
|
||||
type Endpoint struct {
|
||||
ID string `json:"id"`
|
||||
Region string `json:"region"`
|
||||
RegionID string `json:"region_id"`
|
||||
Interface string `json:"interface"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// CatalogEntry provides a type-safe interface to an Identity API V3 service
|
||||
// catalog listing. Each class of service, such as cloud DNS or block storage
|
||||
// services, could have multiple CatalogEntry representing it (one by interface
|
||||
// type, e.g public, admin or internal).
|
||||
//
|
||||
// Note: when looking for the desired service, try, whenever possible, to key
|
||||
// off the type field. Otherwise, you'll tie the representation of the service
|
||||
// to a specific provider.
|
||||
type CatalogEntry struct {
|
||||
// Service ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Name will contain the provider-specified name for the service.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Type will contain a type string if OpenStack defines a type for the
|
||||
// service. Otherwise, for provider-specific services, the provider may
|
||||
// assign their own type strings.
|
||||
Type string `json:"type"`
|
||||
|
||||
// Endpoints will let the caller iterate over all the different endpoints that
|
||||
// may exist for the service.
|
||||
Endpoints []Endpoint `json:"endpoints"`
|
||||
}
|
||||
|
||||
// ServiceCatalog provides a view into the service catalog from a previous,
|
||||
// successful authentication.
|
||||
type ServiceCatalog struct {
|
||||
Entries []CatalogEntry `json:"catalog"`
|
||||
}
|
||||
|
||||
// Domain provides information about the domain to which this token grants
|
||||
// access.
|
||||
type Domain struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// User represents a user resource that exists in the Identity Service.
|
||||
type User struct {
|
||||
Domain Domain `json:"domain"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// Role provides information about roles to which User is authorized.
|
||||
type Role struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// Project provides information about project to which User is authorized.
|
||||
type Project struct {
|
||||
Domain Domain `json:"domain"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// commonResult is the response from a request. A commonResult has various
|
||||
// methods which can be used to extract different details about the result.
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a shortcut for ExtractToken.
|
||||
// This function is deprecated and still present for backward compatibility.
|
||||
func (r commonResult) Extract() (*Token, error) {
|
||||
return r.ExtractToken()
|
||||
}
|
||||
|
||||
// ExtractToken interprets a commonResult as a Token.
|
||||
func (r commonResult) ExtractToken() (*Token, error) {
|
||||
var s Token
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Parse the token itself from the stored headers.
|
||||
s.ID = r.Header.Get("X-Subject-Token")
|
||||
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// ExtractTokenID implements the gophercloud.AuthResult interface. The returned
|
||||
// string is the same as the ID field of the Token struct returned from
|
||||
// ExtractToken().
|
||||
func (r CreateResult) ExtractTokenID() (string, error) {
|
||||
return r.Header.Get("X-Subject-Token"), r.Err
|
||||
}
|
||||
|
||||
// ExtractServiceCatalog returns the ServiceCatalog that was generated along
|
||||
// with the user's Token.
|
||||
func (r commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
|
||||
var s ServiceCatalog
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
||||
|
||||
// ExtractUser returns the User that is the owner of the Token.
|
||||
func (r commonResult) ExtractUser() (*User, error) {
|
||||
var s struct {
|
||||
User *User `json:"user"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.User, err
|
||||
}
|
||||
|
||||
// ExtractRoles returns Roles to which User is authorized.
|
||||
func (r commonResult) ExtractRoles() ([]Role, error) {
|
||||
var s struct {
|
||||
Roles []Role `json:"roles"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Roles, err
|
||||
}
|
||||
|
||||
// ExtractProject returns Project to which User is authorized.
|
||||
func (r commonResult) ExtractProject() (*Project, error) {
|
||||
var s struct {
|
||||
Project *Project `json:"project"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Project, err
|
||||
}
|
||||
|
||||
// CreateResult is the response from a Create request. Use ExtractToken()
|
||||
// to interpret it as a Token, or ExtractServiceCatalog() to interpret it
|
||||
// as a service catalog.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult is the response from a Get request. Use ExtractToken()
|
||||
// to interpret it as a Token, or ExtractServiceCatalog() to interpret it
|
||||
// as a service catalog.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// RevokeResult is response from a Revoke request.
|
||||
type RevokeResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// Token is a string that grants a user access to a controlled set of services
|
||||
// in an OpenStack provider. Each Token is valid for a set length of time.
|
||||
type Token struct {
|
||||
// ID is the issued token.
|
||||
ID string `json:"id"`
|
||||
|
||||
// ExpiresAt is the timestamp at which this token will no longer be accepted.
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
}
|
||||
|
||||
func (r commonResult) ExtractInto(v interface{}) error {
|
||||
return r.ExtractIntoStructPtr(v, "token")
|
||||
}
|
7
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/urls.go
generated
vendored
7
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/urls.go
generated
vendored
@@ -1,7 +0,0 @@
|
||||
package tokens
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func tokenURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("auth", "tokens")
|
||||
}
|
41
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/delegate.go
generated
vendored
41
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/delegate.go
generated
vendored
@@ -1,41 +0,0 @@
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
common "github.com/gophercloud/gophercloud/openstack/common/extensions"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Extension is a single OpenStack extension.
|
||||
type Extension struct {
|
||||
common.Extension
|
||||
}
|
||||
|
||||
// GetResult wraps a GetResult from common.
|
||||
type GetResult struct {
|
||||
common.GetResult
|
||||
}
|
||||
|
||||
// ExtractExtensions interprets a Page as a slice of Extensions.
|
||||
func ExtractExtensions(page pagination.Page) ([]Extension, error) {
|
||||
inner, err := common.ExtractExtensions(page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outer := make([]Extension, len(inner))
|
||||
for index, ext := range inner {
|
||||
outer[index] = Extension{ext}
|
||||
}
|
||||
return outer, nil
|
||||
}
|
||||
|
||||
// Get retrieves information for a specific extension using its alias.
|
||||
func Get(c *gophercloud.ServiceClient, alias string) GetResult {
|
||||
return GetResult{common.Get(c, alias)}
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over the full collection of extensions.
|
||||
// It does not accept query parameters.
|
||||
func List(c *gophercloud.ServiceClient) pagination.Pager {
|
||||
return common.List(c)
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
Package external provides information and interaction with the external
|
||||
extension for the OpenStack Networking service.
|
||||
|
||||
Example to List Networks with External Information
|
||||
|
||||
iTrue := true
|
||||
networkListOpts := networks.ListOpts{}
|
||||
listOpts := external.ListOptsExt{
|
||||
ListOptsBuilder: networkListOpts,
|
||||
External: &iTrue,
|
||||
}
|
||||
|
||||
type NetworkWithExternalExt struct {
|
||||
networks.Network
|
||||
external.NetworkExternalExt
|
||||
}
|
||||
|
||||
var allNetworks []NetworkWithExternalExt
|
||||
|
||||
allPages, err := networks.List(networkClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = networks.ExtractNetworksInto(allPages, &allNetworks)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, network := range allNetworks {
|
||||
fmt.Println("%+v\n", network)
|
||||
}
|
||||
|
||||
Example to Create a Network with External Information
|
||||
|
||||
iTrue := true
|
||||
networkCreateOpts := networks.CreateOpts{
|
||||
Name: "private",
|
||||
AdminStateUp: &iTrue,
|
||||
}
|
||||
|
||||
createOpts := external.CreateOptsExt{
|
||||
networkCreateOpts,
|
||||
&iTrue,
|
||||
}
|
||||
|
||||
network, err := networks.Create(networkClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package external
|
@@ -1,84 +0,0 @@
|
||||
package external
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
|
||||
)
|
||||
|
||||
// ListOptsExt adds the external network options to the base ListOpts.
|
||||
type ListOptsExt struct {
|
||||
networks.ListOptsBuilder
|
||||
External *bool `q:"router:external"`
|
||||
}
|
||||
|
||||
// ToNetworkListQuery adds the router:external option to the base network
|
||||
// list options.
|
||||
func (opts ListOptsExt) ToNetworkListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts.ListOptsBuilder)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
params := q.Query()
|
||||
if opts.External != nil {
|
||||
v := strconv.FormatBool(*opts.External)
|
||||
params.Add("router:external", v)
|
||||
}
|
||||
|
||||
q = &url.URL{RawQuery: params.Encode()}
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// CreateOptsExt is the structure used when creating new external network
|
||||
// resources. It embeds networks.CreateOpts and so inherits all of its required
|
||||
// and optional fields, with the addition of the External field.
|
||||
type CreateOptsExt struct {
|
||||
networks.CreateOptsBuilder
|
||||
External *bool `json:"router:external,omitempty"`
|
||||
}
|
||||
|
||||
// ToNetworkCreateMap adds the router:external options to the base network
|
||||
// creation options.
|
||||
func (opts CreateOptsExt) ToNetworkCreateMap() (map[string]interface{}, error) {
|
||||
base, err := opts.CreateOptsBuilder.ToNetworkCreateMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.External == nil {
|
||||
return base, nil
|
||||
}
|
||||
|
||||
networkMap := base["network"].(map[string]interface{})
|
||||
networkMap["router:external"] = opts.External
|
||||
|
||||
return base, nil
|
||||
}
|
||||
|
||||
// UpdateOptsExt is the structure used when updating existing external network
|
||||
// resources. It embeds networks.UpdateOpts and so inherits all of its required
|
||||
// and optional fields, with the addition of the External field.
|
||||
type UpdateOptsExt struct {
|
||||
networks.UpdateOptsBuilder
|
||||
External *bool `json:"router:external,omitempty"`
|
||||
}
|
||||
|
||||
// ToNetworkUpdateMap casts an UpdateOpts struct to a map.
|
||||
func (opts UpdateOptsExt) ToNetworkUpdateMap() (map[string]interface{}, error) {
|
||||
base, err := opts.UpdateOptsBuilder.ToNetworkUpdateMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.External == nil {
|
||||
return base, nil
|
||||
}
|
||||
|
||||
networkMap := base["network"].(map[string]interface{})
|
||||
networkMap["router:external"] = opts.External
|
||||
|
||||
return base, nil
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
package external
|
||||
|
||||
// NetworkExternalExt represents a decorated form of a Network with based on the
|
||||
// "external-net" extension.
|
||||
type NetworkExternalExt struct {
|
||||
// Specifies whether the network is an external network or not.
|
||||
External bool `json:"router:external"`
|
||||
}
|
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
package floatingips enables management and retrieval of Floating IPs from the
|
||||
OpenStack Networking service.
|
||||
|
||||
Example to List Floating IPs
|
||||
|
||||
listOpts := floatingips.ListOpts{
|
||||
FloatingNetworkID: "a6917946-38ab-4ffd-a55a-26c0980ce5ee",
|
||||
}
|
||||
|
||||
allPages, err := floatingips.List(networkClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allFIPs, err := floatingips.ExtractFloatingIPs(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, fip := range allFIPs {
|
||||
fmt.Printf("%+v\n", fip)
|
||||
}
|
||||
|
||||
Example to Create a Floating IP
|
||||
|
||||
createOpts := floatingips.CreateOpts{
|
||||
FloatingNetworkID: "a6917946-38ab-4ffd-a55a-26c0980ce5ee",
|
||||
}
|
||||
|
||||
fip, err := floatingips.Create(networkingClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a Floating IP
|
||||
|
||||
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
|
||||
portID := "76d0a61b-b8e5-490c-9892-4cf674f2bec8"
|
||||
|
||||
updateOpts := floatingips.UpdateOpts{
|
||||
PortID: &portID,
|
||||
}
|
||||
|
||||
fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Disassociate a Floating IP with a Port
|
||||
|
||||
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
|
||||
|
||||
updateOpts := floatingips.UpdateOpts{
|
||||
PortID: new(string),
|
||||
}
|
||||
|
||||
fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a Floating IP
|
||||
|
||||
fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
|
||||
err := floatingips.Delete(networkClient, fipID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package floatingips
|
@@ -1,182 +0,0 @@
|
||||
package floatingips
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||
// List request.
|
||||
type ListOptsBuilder interface {
|
||||
ToFloatingIPListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts allows the filtering and sorting of paginated collections through
|
||||
// the API. Filtering is achieved by passing in struct field values that map to
|
||||
// the floating IP attributes you want to see returned. SortKey allows you to
|
||||
// sort by a particular network attribute. SortDir sets the direction, and is
|
||||
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
||||
type ListOpts struct {
|
||||
ID string `q:"id"`
|
||||
Description string `q:"description"`
|
||||
FloatingNetworkID string `q:"floating_network_id"`
|
||||
PortID string `q:"port_id"`
|
||||
FixedIP string `q:"fixed_ip_address"`
|
||||
FloatingIP string `q:"floating_ip_address"`
|
||||
TenantID string `q:"tenant_id"`
|
||||
ProjectID string `q:"project_id"`
|
||||
Limit int `q:"limit"`
|
||||
Marker string `q:"marker"`
|
||||
SortKey string `q:"sort_key"`
|
||||
SortDir string `q:"sort_dir"`
|
||||
RouterID string `q:"router_id"`
|
||||
Status string `q:"status"`
|
||||
Tags string `q:"tags"`
|
||||
TagsAny string `q:"tags-any"`
|
||||
NotTags string `q:"not-tags"`
|
||||
NotTagsAny string `q:"not-tags-any"`
|
||||
}
|
||||
|
||||
// ToNetworkListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToFloatingIPListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over a collection of
|
||||
// floating IP resources. It accepts a ListOpts struct, which allows you to
|
||||
// filter and sort the returned collection for greater efficiency.
|
||||
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := rootURL(c)
|
||||
if opts != nil {
|
||||
query, err := opts.ToFloatingIPListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||
return FloatingIPPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToFloatingIPCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts contains all the values needed to create a new floating IP
|
||||
// resource. The only required fields are FloatingNetworkID and PortID which
|
||||
// refer to the external network and internal port respectively.
|
||||
type CreateOpts struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
FloatingNetworkID string `json:"floating_network_id" required:"true"`
|
||||
FloatingIP string `json:"floating_ip_address,omitempty"`
|
||||
PortID string `json:"port_id,omitempty"`
|
||||
FixedIP string `json:"fixed_ip_address,omitempty"`
|
||||
SubnetID string `json:"subnet_id,omitempty"`
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
ProjectID string `json:"project_id,omitempty"`
|
||||
}
|
||||
|
||||
// ToFloatingIPCreateMap allows CreateOpts to satisfy the CreateOptsBuilder
|
||||
// interface
|
||||
func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "floatingip")
|
||||
}
|
||||
|
||||
// Create accepts a CreateOpts struct and uses the values provided to create a
|
||||
// new floating IP resource. You can create floating IPs on external networks
|
||||
// only. If you provide a FloatingNetworkID which refers to a network that is
|
||||
// not external (i.e. its `router:external' attribute is False), the operation
|
||||
// will fail and return a 400 error.
|
||||
//
|
||||
// If you do not specify a FloatingIP address value, the operation will
|
||||
// automatically allocate an available address for the new resource. If you do
|
||||
// choose to specify one, it must fall within the subnet range for the external
|
||||
// network - otherwise the operation returns a 400 error. If the FloatingIP
|
||||
// address is already in use, the operation returns a 409 error code.
|
||||
//
|
||||
// You can associate the new resource with an internal port by using the PortID
|
||||
// field. If you specify a PortID that is not valid, the operation will fail and
|
||||
// return 404 error code.
|
||||
//
|
||||
// You must also configure an IP address for the port associated with the PortID
|
||||
// you have provided - this is what the FixedIP refers to: an IP fixed to a
|
||||
// port. Because a port might be associated with multiple IP addresses, you can
|
||||
// use the FixedIP field to associate a particular IP address rather than have
|
||||
// the API assume for you. If you specify an IP address that is not valid, the
|
||||
// operation will fail and return a 400 error code. If the PortID and FixedIP
|
||||
// are already associated with another resource, the operation will fail and
|
||||
// returns a 409 error code.
|
||||
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToFloatingIPCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToFloatingIPUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts contains the values used when updating a floating IP resource. The
|
||||
// only value that can be updated is which internal port the floating IP is
|
||||
// linked to. To associate the floating IP with a new internal port, provide its
|
||||
// ID. To disassociate the floating IP from all ports, provide an empty string.
|
||||
type UpdateOpts struct {
|
||||
Description *string `json:"description,omitempty"`
|
||||
PortID *string `json:"port_id,omitempty"`
|
||||
FixedIP string `json:"fixed_ip_address,omitempty"`
|
||||
}
|
||||
|
||||
// ToFloatingIPUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder
|
||||
// interface
|
||||
func (opts UpdateOpts) ToFloatingIPUpdateMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "floatingip")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if m := b["floatingip"].(map[string]interface{}); m["port_id"] == "" {
|
||||
m["port_id"] = nil
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Update allows floating IP resources to be updated. Currently, the only way to
|
||||
// "update" a floating IP is to associate it with a new internal port, or
|
||||
// disassociated it from all ports. See UpdateOpts for instructions of how to
|
||||
// do this.
|
||||
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToFloatingIPUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular floating IP resource. Please
|
||||
// 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)
|
||||
return
|
||||
}
|
@@ -1,131 +0,0 @@
|
||||
package floatingips
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// FloatingIP represents a floating IP resource. A floating IP is an external
|
||||
// IP address that is mapped to an internal port and, optionally, a specific
|
||||
// IP address on a private network. In other words, it enables access to an
|
||||
// instance on a private network from an external network. For this reason,
|
||||
// floating IPs can only be defined on networks where the `router:external'
|
||||
// attribute (provided by the external network extension) is set to True.
|
||||
type FloatingIP struct {
|
||||
// ID is the unique identifier for the floating IP instance.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Description for the floating IP instance.
|
||||
Description string `json:"description"`
|
||||
|
||||
// FloatingNetworkID is the UUID of the external network where the floating
|
||||
// IP is to be created.
|
||||
FloatingNetworkID string `json:"floating_network_id"`
|
||||
|
||||
// FloatingIP is the address of the floating IP on the external network.
|
||||
FloatingIP string `json:"floating_ip_address"`
|
||||
|
||||
// PortID is the UUID of the port on an internal network that is associated
|
||||
// with the floating IP.
|
||||
PortID string `json:"port_id"`
|
||||
|
||||
// FixedIP is the specific IP address of the internal port which should be
|
||||
// associated with the floating IP.
|
||||
FixedIP string `json:"fixed_ip_address"`
|
||||
|
||||
// TenantID is the project owner of the floating IP. Only admin users can
|
||||
// specify a project identifier other than its own.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// ProjectID is the project owner of the floating IP.
|
||||
ProjectID string `json:"project_id"`
|
||||
|
||||
// Status is the condition of the API resource.
|
||||
Status string `json:"status"`
|
||||
|
||||
// RouterID is the ID of the router used for this floating IP.
|
||||
RouterID string `json:"router_id"`
|
||||
|
||||
// Tags optionally set via extensions/attributestags
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract will extract a FloatingIP resource from a result.
|
||||
func (r commonResult) Extract() (*FloatingIP, error) {
|
||||
var s FloatingIP
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
||||
|
||||
func (r commonResult) ExtractInto(v interface{}) error {
|
||||
return r.Result.ExtractIntoStructPtr(v, "floatingip")
|
||||
}
|
||||
|
||||
// CreateResult represents the result of a create operation. Call its Extract
|
||||
// method to interpret it as a FloatingIP.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult represents the result of a get operation. Call its Extract
|
||||
// method to interpret it as a FloatingIP.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult represents the result of an update operation. Call its Extract
|
||||
// method to interpret it as a FloatingIP.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of an update operation. Call its
|
||||
// ExtractErr method to determine if the request succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// FloatingIPPage is the page returned by a pager when traversing over a
|
||||
// collection of floating IPs.
|
||||
type FloatingIPPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// NextPageURL is invoked when a paginated collection of floating IPs has
|
||||
// reached the end of a page and the pager seeks to traverse over a new one.
|
||||
// In order to do this, it needs to construct the next page's URL.
|
||||
func (r FloatingIPPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"floatingips_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether a FloatingIPPage struct is empty.
|
||||
func (r FloatingIPPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractFloatingIPs(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// ExtractFloatingIPs accepts a Page struct, specifically a FloatingIPPage
|
||||
// struct, and extracts the elements into a slice of FloatingIP structs. In
|
||||
// other words, a generic collection is mapped into a relevant slice.
|
||||
func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) {
|
||||
var s struct {
|
||||
FloatingIPs []FloatingIP `json:"floatingips"`
|
||||
}
|
||||
err := (r.(FloatingIPPage)).ExtractInto(&s)
|
||||
return s.FloatingIPs, err
|
||||
}
|
||||
|
||||
func ExtractFloatingIPsInto(r pagination.Page, v interface{}) error {
|
||||
return r.(FloatingIPPage).Result.ExtractIntoSlicePtr(v, "floatingips")
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package floatingips
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
const resourcePath = "floatingips"
|
||||
|
||||
func rootURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL(resourcePath)
|
||||
}
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(resourcePath, id)
|
||||
}
|
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
Package routers enables management and retrieval of Routers from the OpenStack
|
||||
Networking service.
|
||||
|
||||
Example to List Routers
|
||||
|
||||
listOpts := routers.ListOpts{}
|
||||
allPages, err := routers.List(networkClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allRouters, err := routers.ExtractRouters(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, router := range allRoutes {
|
||||
fmt.Printf("%+v\n", router)
|
||||
}
|
||||
|
||||
Example to Create a Router
|
||||
|
||||
iTrue := true
|
||||
gwi := routers.GatewayInfo{
|
||||
NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b",
|
||||
}
|
||||
|
||||
createOpts := routers.CreateOpts{
|
||||
Name: "router_1",
|
||||
AdminStateUp: &iTrue,
|
||||
GatewayInfo: &gwi,
|
||||
}
|
||||
|
||||
router, err := routers.Create(networkClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a Router
|
||||
|
||||
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
|
||||
|
||||
routes := []routers.Route{{
|
||||
DestinationCIDR: "40.0.1.0/24",
|
||||
NextHop: "10.1.0.10",
|
||||
}}
|
||||
|
||||
updateOpts := routers.UpdateOpts{
|
||||
Name: "new_name",
|
||||
Routes: routes,
|
||||
}
|
||||
|
||||
router, err := routers.Update(networkClient, routerID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Remove all Routes from a Router
|
||||
|
||||
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
|
||||
|
||||
routes := []routers.Route{}
|
||||
|
||||
updateOpts := routers.UpdateOpts{
|
||||
Routes: routes,
|
||||
}
|
||||
|
||||
router, err := routers.Update(networkClient, routerID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a Router
|
||||
|
||||
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
|
||||
err := routers.Delete(networkClient, routerID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Add an Interface to a Router
|
||||
|
||||
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
|
||||
|
||||
intOpts := routers.AddInterfaceOpts{
|
||||
SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1",
|
||||
}
|
||||
|
||||
interface, err := routers.AddInterface(networkClient, routerID, intOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Remove an Interface from a Router
|
||||
|
||||
routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
|
||||
|
||||
intOpts := routers.RemoveInterfaceOpts{
|
||||
SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1",
|
||||
}
|
||||
|
||||
interface, err := routers.RemoveInterface(networkClient, routerID, intOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package routers
|
@@ -1,233 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListOpts allows the filtering and sorting of paginated collections through
|
||||
// the API. Filtering is achieved by passing in struct field values that map to
|
||||
// the floating IP attributes you want to see returned. SortKey allows you to
|
||||
// sort by a particular network attribute. SortDir sets the direction, and is
|
||||
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
||||
type ListOpts struct {
|
||||
ID string `q:"id"`
|
||||
Name string `q:"name"`
|
||||
Description string `q:"description"`
|
||||
AdminStateUp *bool `q:"admin_state_up"`
|
||||
Distributed *bool `q:"distributed"`
|
||||
Status string `q:"status"`
|
||||
TenantID string `q:"tenant_id"`
|
||||
ProjectID string `q:"project_id"`
|
||||
Limit int `q:"limit"`
|
||||
Marker string `q:"marker"`
|
||||
SortKey string `q:"sort_key"`
|
||||
SortDir string `q:"sort_dir"`
|
||||
Tags string `q:"tags"`
|
||||
TagsAny string `q:"tags-any"`
|
||||
NotTags string `q:"not-tags"`
|
||||
NotTagsAny string `q:"not-tags-any"`
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over a collection of
|
||||
// routers. It accepts a ListOpts struct, which allows you to filter and sort
|
||||
// the returned collection for greater efficiency.
|
||||
//
|
||||
// Default policy settings return only those routers that are owned by the
|
||||
// tenant who submits the request, unless an admin user submits the request.
|
||||
func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
|
||||
q, err := gophercloud.BuildQueryString(&opts)
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
u := rootURL(c) + q.String()
|
||||
return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page {
|
||||
return RouterPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToRouterCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts contains all the values needed to create a new router. There are
|
||||
// no required values.
|
||||
type CreateOpts struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
Distributed *bool `json:"distributed,omitempty"`
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
ProjectID string `json:"project_id,omitempty"`
|
||||
GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"`
|
||||
AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"`
|
||||
}
|
||||
|
||||
// ToRouterCreateMap builds a create request body from CreateOpts.
|
||||
func (opts CreateOpts) ToRouterCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "router")
|
||||
}
|
||||
|
||||
// Create accepts a CreateOpts struct and uses the values to create a new
|
||||
// logical router. When it is created, the router does not have an internal
|
||||
// interface - it is not associated to any subnet.
|
||||
//
|
||||
// You can optionally specify an external gateway for a router using the
|
||||
// GatewayInfo struct. The external gateway for the router must be plugged into
|
||||
// an external network (it is external if its `router:external' field is set to
|
||||
// true).
|
||||
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToRouterCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToRouterUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts contains the values used when updating a router.
|
||||
type UpdateOpts struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
Distributed *bool `json:"distributed,omitempty"`
|
||||
GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"`
|
||||
Routes []Route `json:"routes"`
|
||||
}
|
||||
|
||||
// ToRouterUpdateMap builds an update body based on UpdateOpts.
|
||||
func (opts UpdateOpts) ToRouterUpdateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "router")
|
||||
}
|
||||
|
||||
// Update allows routers to be updated. You can update the name, administrative
|
||||
// state, and the external gateway. For more information about how to set the
|
||||
// external gateway for a router, see Create. This operation does not enable
|
||||
// the update of router interfaces. To do this, use the AddInterface and
|
||||
// RemoveInterface functions.
|
||||
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToRouterUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// AddInterfaceOptsBuilder allows extensions to add additional parameters to
|
||||
// the AddInterface request.
|
||||
type AddInterfaceOptsBuilder interface {
|
||||
ToRouterAddInterfaceMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// AddInterfaceOpts represents the options for adding an interface to a router.
|
||||
type AddInterfaceOpts struct {
|
||||
SubnetID string `json:"subnet_id,omitempty" xor:"PortID"`
|
||||
PortID string `json:"port_id,omitempty" xor:"SubnetID"`
|
||||
}
|
||||
|
||||
// ToRouterAddInterfaceMap builds a request body from AddInterfaceOpts.
|
||||
func (opts AddInterfaceOpts) ToRouterAddInterfaceMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "")
|
||||
}
|
||||
|
||||
// AddInterface attaches a subnet to an internal router interface. You must
|
||||
// specify either a SubnetID or PortID in the request body. If you specify both,
|
||||
// the operation will fail and an error will be returned.
|
||||
//
|
||||
// If you specify a SubnetID, the gateway IP address for that particular subnet
|
||||
// is used to create the router interface. Alternatively, if you specify a
|
||||
// PortID, the IP address associated with the port is used to create the router
|
||||
// interface.
|
||||
//
|
||||
// If you reference a port that is associated with multiple IP addresses, or
|
||||
// if the port is associated with zero IP addresses, the operation will fail and
|
||||
// a 400 Bad Request error will be returned.
|
||||
//
|
||||
// If you reference a port already in use, the operation will fail and a 409
|
||||
// Conflict error will be returned.
|
||||
//
|
||||
// The PortID that is returned after using Extract() on the result of this
|
||||
// operation can either be the same PortID passed in or, on the other hand, the
|
||||
// identifier of a new port created by this operation. After the operation
|
||||
// completes, the device ID of the port is set to the router ID, and the
|
||||
// device owner attribute is set to `network:router_interface'.
|
||||
func AddInterface(c *gophercloud.ServiceClient, id string, opts AddInterfaceOptsBuilder) (r InterfaceResult) {
|
||||
b, err := opts.ToRouterAddInterfaceMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(addInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// RemoveInterfaceOptsBuilder allows extensions to add additional parameters to
|
||||
// the RemoveInterface request.
|
||||
type RemoveInterfaceOptsBuilder interface {
|
||||
ToRouterRemoveInterfaceMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// RemoveInterfaceOpts represents options for removing an interface from
|
||||
// a router.
|
||||
type RemoveInterfaceOpts struct {
|
||||
SubnetID string `json:"subnet_id,omitempty" or:"PortID"`
|
||||
PortID string `json:"port_id,omitempty" or:"SubnetID"`
|
||||
}
|
||||
|
||||
// ToRouterRemoveInterfaceMap builds a request body based on
|
||||
// RemoveInterfaceOpts.
|
||||
func (opts RemoveInterfaceOpts) ToRouterRemoveInterfaceMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "")
|
||||
}
|
||||
|
||||
// RemoveInterface removes an internal router interface, which detaches a
|
||||
// subnet from the router. You must specify either a SubnetID or PortID, since
|
||||
// these values are used to identify the router interface to remove.
|
||||
//
|
||||
// Unlike AddInterface, you can also specify both a SubnetID and PortID. If you
|
||||
// choose to specify both, the subnet ID must correspond to the subnet ID of
|
||||
// the first IP address on the port specified by the port ID. Otherwise, the
|
||||
// operation will fail and return a 409 Conflict error.
|
||||
//
|
||||
// If the router, subnet or port which are referenced do not exist or are not
|
||||
// visible to you, the operation will fail and a 404 Not Found error will be
|
||||
// returned. After this operation completes, the port connecting the router
|
||||
// with the subnet is removed from the subnet for the network.
|
||||
func RemoveInterface(c *gophercloud.ServiceClient, id string, opts RemoveInterfaceOptsBuilder) (r InterfaceResult) {
|
||||
b, err := opts.ToRouterRemoveInterfaceMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(removeInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
@@ -1,181 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// GatewayInfo represents the information of an external gateway for any
|
||||
// particular network router.
|
||||
type GatewayInfo struct {
|
||||
NetworkID string `json:"network_id,omitempty"`
|
||||
EnableSNAT *bool `json:"enable_snat,omitempty"`
|
||||
ExternalFixedIPs []ExternalFixedIP `json:"external_fixed_ips,omitempty"`
|
||||
}
|
||||
|
||||
// ExternalFixedIP is the IP address and subnet ID of the external gateway of a
|
||||
// router.
|
||||
type ExternalFixedIP struct {
|
||||
IPAddress string `json:"ip_address,omitempty"`
|
||||
SubnetID string `json:"subnet_id"`
|
||||
}
|
||||
|
||||
// Route is a possible route in a router.
|
||||
type Route struct {
|
||||
NextHop string `json:"nexthop"`
|
||||
DestinationCIDR string `json:"destination"`
|
||||
}
|
||||
|
||||
// Router represents a Neutron router. A router is a logical entity that
|
||||
// forwards packets across internal subnets and NATs (network address
|
||||
// translation) them on external networks through an appropriate gateway.
|
||||
//
|
||||
// A router has an interface for each subnet with which it is associated. By
|
||||
// default, the IP address of such interface is the subnet's gateway IP. Also,
|
||||
// whenever a router is associated with a subnet, a port for that router
|
||||
// interface is added to the subnet's network.
|
||||
type Router struct {
|
||||
// Status indicates whether or not a router is currently operational.
|
||||
Status string `json:"status"`
|
||||
|
||||
// GateayInfo provides information on external gateway for the router.
|
||||
GatewayInfo GatewayInfo `json:"external_gateway_info"`
|
||||
|
||||
// AdminStateUp is the administrative state of the router.
|
||||
AdminStateUp bool `json:"admin_state_up"`
|
||||
|
||||
// Distributed is whether router is disitrubted or not.
|
||||
Distributed bool `json:"distributed"`
|
||||
|
||||
// Name is the human readable name for the router. It does not have to be
|
||||
// unique.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Description for the router.
|
||||
Description string `json:"description"`
|
||||
|
||||
// ID is the unique identifier for the router.
|
||||
ID string `json:"id"`
|
||||
|
||||
// TenantID is the project owner of the router. Only admin users can
|
||||
// specify a project identifier other than its own.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// ProjectID is the project owner of the router.
|
||||
ProjectID string `json:"project_id"`
|
||||
|
||||
// Routes are a collection of static routes that the router will host.
|
||||
Routes []Route `json:"routes"`
|
||||
|
||||
// Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others.
|
||||
// Used to make network resources highly available.
|
||||
AvailabilityZoneHints []string `json:"availability_zone_hints"`
|
||||
|
||||
// Tags optionally set via extensions/attributestags
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
// RouterPage is the page returned by a pager when traversing over a
|
||||
// collection of routers.
|
||||
type RouterPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// NextPageURL is invoked when a paginated collection of routers has reached
|
||||
// the end of a page and the pager seeks to traverse over a new one. In order
|
||||
// to do this, it needs to construct the next page's URL.
|
||||
func (r RouterPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"routers_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether a RouterPage struct is empty.
|
||||
func (r RouterPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractRouters(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// ExtractRouters accepts a Page struct, specifically a RouterPage struct,
|
||||
// and extracts the elements into a slice of Router structs. In other words,
|
||||
// a generic collection is mapped into a relevant slice.
|
||||
func ExtractRouters(r pagination.Page) ([]Router, error) {
|
||||
var s struct {
|
||||
Routers []Router `json:"routers"`
|
||||
}
|
||||
err := (r.(RouterPage)).ExtractInto(&s)
|
||||
return s.Routers, err
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts a router.
|
||||
func (r commonResult) Extract() (*Router, error) {
|
||||
var s struct {
|
||||
Router *Router `json:"router"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Router, err
|
||||
}
|
||||
|
||||
// CreateResult represents the result of a create operation. Call its Extract
|
||||
// method to interpret it as a Router.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult represents the result of a get operation. Call its Extract
|
||||
// method to interpret it as a Router.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult represents the result of an update operation. Call its Extract
|
||||
// method to interpret it as a Router.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of a delete operation. Call its ExtractErr
|
||||
// method to determine if the request succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// InterfaceInfo represents information about a particular router interface. As
|
||||
// mentioned above, in order for a router to forward to a subnet, it needs an
|
||||
// interface.
|
||||
type InterfaceInfo struct {
|
||||
// SubnetID is the ID of the subnet which this interface is associated with.
|
||||
SubnetID string `json:"subnet_id"`
|
||||
|
||||
// PortID is the ID of the port that is a part of the subnet.
|
||||
PortID string `json:"port_id"`
|
||||
|
||||
// ID is the UUID of the interface.
|
||||
ID string `json:"id"`
|
||||
|
||||
// TenantID is the owner of the interface.
|
||||
TenantID string `json:"tenant_id"`
|
||||
}
|
||||
|
||||
// InterfaceResult represents the result of interface operations, such as
|
||||
// AddInterface() and RemoveInterface(). Call its Extract method to interpret
|
||||
// the result as a InterfaceInfo.
|
||||
type InterfaceResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts an information struct.
|
||||
func (r InterfaceResult) Extract() (*InterfaceInfo, error) {
|
||||
var s InterfaceInfo
|
||||
err := r.ExtractInto(&s)
|
||||
return &s, err
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package routers
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
const resourcePath = "routers"
|
||||
|
||||
func rootURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL(resourcePath)
|
||||
}
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(resourcePath, id)
|
||||
}
|
||||
|
||||
func addInterfaceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(resourcePath, id, "add_router_interface")
|
||||
}
|
||||
|
||||
func removeInterfaceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(resourcePath, id, "remove_router_interface")
|
||||
}
|
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
Package l7policies provides information and interaction with L7Policies and
|
||||
Rules of the LBaaS v2 extension for the OpenStack Networking service.
|
||||
|
||||
Example to Create a L7Policy
|
||||
|
||||
createOpts := l7policies.CreateOpts{
|
||||
Name: "redirect-example.com",
|
||||
ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d",
|
||||
Action: l7policies.ActionRedirectToURL,
|
||||
RedirectURL: "http://www.example.com",
|
||||
}
|
||||
l7policy, err := l7policies.Create(lbClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to List L7Policies
|
||||
|
||||
listOpts := l7policies.ListOpts{
|
||||
ListenerID: "c79a4468-d788-410c-bf79-9a8ef6354852",
|
||||
}
|
||||
allPages, err := l7policies.List(lbClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
allL7Policies, err := l7policies.ExtractL7Policies(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, l7policy := range allL7Policies {
|
||||
fmt.Printf("%+v\n", l7policy)
|
||||
}
|
||||
|
||||
Example to Get a L7Policy
|
||||
|
||||
l7policy, err := l7policies.Get(lbClient, "023f2e34-7806-443b-bfae-16c324569a3d").Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a L7Policy
|
||||
|
||||
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
err := l7policies.Delete(lbClient, l7policyID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a L7Policy
|
||||
|
||||
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
name := "new-name"
|
||||
updateOpts := l7policies.UpdateOpts{
|
||||
Name: &name,
|
||||
}
|
||||
l7policy, err := l7policies.Update(lbClient, l7policyID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Rule
|
||||
|
||||
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
createOpts := l7policies.CreateRuleOpts{
|
||||
RuleType: l7policies.TypePath,
|
||||
CompareType: l7policies.CompareTypeRegex,
|
||||
Value: "/images*",
|
||||
}
|
||||
rule, err := l7policies.CreateRule(lbClient, l7policyID, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to List L7 Rules
|
||||
|
||||
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
listOpts := l7policies.ListRulesOpts{
|
||||
RuleType: l7policies.TypePath,
|
||||
}
|
||||
allPages, err := l7policies.ListRules(lbClient, l7policyID, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
allRules, err := l7policies.ExtractRules(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, rule := allRules {
|
||||
fmt.Printf("%+v\n", rule)
|
||||
}
|
||||
|
||||
Example to Get a l7 rule
|
||||
|
||||
l7rule, err := l7policies.GetRule(lbClient, "023f2e34-7806-443b-bfae-16c324569a3d", "53ad8ab8-40fa-11e8-a508-00224d6b7bc1").Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a l7 rule
|
||||
|
||||
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
ruleID := "64dba99f-8af8-4200-8882-e32a0660f23e"
|
||||
err := l7policies.DeleteRule(lbClient, l7policyID, ruleID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a Rule
|
||||
|
||||
l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
ruleID := "64dba99f-8af8-4200-8882-e32a0660f23e"
|
||||
updateOpts := l7policies.UpdateRuleOpts{
|
||||
RuleType: l7policies.TypePath,
|
||||
CompareType: l7policies.CompareTypeRegex,
|
||||
Value: "/images/special*",
|
||||
}
|
||||
rule, err := l7policies.UpdateRule(lbClient, l7policyID, ruleID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package l7policies
|
@@ -1,376 +0,0 @@
|
||||
package l7policies
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToL7PolicyCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
type Action string
|
||||
type RuleType string
|
||||
type CompareType string
|
||||
|
||||
const (
|
||||
ActionRedirectToPool Action = "REDIRECT_TO_POOL"
|
||||
ActionRedirectToURL Action = "REDIRECT_TO_URL"
|
||||
ActionReject Action = "REJECT"
|
||||
|
||||
TypeCookie RuleType = "COOKIE"
|
||||
TypeFileType RuleType = "FILE_TYPE"
|
||||
TypeHeader RuleType = "HEADER"
|
||||
TypeHostName RuleType = "HOST_NAME"
|
||||
TypePath RuleType = "PATH"
|
||||
|
||||
CompareTypeContains CompareType = "CONTAINS"
|
||||
CompareTypeEndWith CompareType = "ENDS_WITH"
|
||||
CompareTypeEqual CompareType = "EQUAL_TO"
|
||||
CompareTypeRegex CompareType = "REGEX"
|
||||
CompareTypeStartWith CompareType = "STARTS_WITH"
|
||||
)
|
||||
|
||||
// CreateOpts is the common options struct used in this package's Create
|
||||
// operation.
|
||||
type CreateOpts struct {
|
||||
// Name of the L7 policy.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// The ID of the listener.
|
||||
ListenerID string `json:"listener_id" required:"true"`
|
||||
|
||||
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT.
|
||||
Action Action `json:"action" required:"true"`
|
||||
|
||||
// The position of this policy on the listener.
|
||||
Position int32 `json:"position,omitempty"`
|
||||
|
||||
// A human-readable description for the resource.
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// TenantID is the UUID of the tenant who owns the L7 policy in octavia.
|
||||
// Only administrative users can specify a project UUID other than their own.
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
|
||||
// Requests matching this policy will be redirected to the pool with this ID.
|
||||
// Only valid if action is REDIRECT_TO_POOL.
|
||||
RedirectPoolID string `json:"redirect_pool_id,omitempty"`
|
||||
|
||||
// Requests matching this policy will be redirected to this URL.
|
||||
// Only valid if action is REDIRECT_TO_URL.
|
||||
RedirectURL string `json:"redirect_url,omitempty"`
|
||||
|
||||
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
}
|
||||
|
||||
// ToL7PolicyCreateMap builds a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToL7PolicyCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "l7policy")
|
||||
}
|
||||
|
||||
// Create accepts a CreateOpts struct and uses the values to create a new l7policy.
|
||||
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToL7PolicyCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||
// List request.
|
||||
type ListOptsBuilder interface {
|
||||
ToL7PolicyListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts allows the filtering and sorting of paginated collections through
|
||||
// the API.
|
||||
type ListOpts struct {
|
||||
Name string `q:"name"`
|
||||
Description string `q:"description"`
|
||||
ListenerID string `q:"listener_id"`
|
||||
Action string `q:"action"`
|
||||
TenantID string `q:"tenant_id"`
|
||||
RedirectPoolID string `q:"redirect_pool_id"`
|
||||
RedirectURL string `q:"redirect_url"`
|
||||
Position int32 `q:"position"`
|
||||
AdminStateUp bool `q:"admin_state_up"`
|
||||
ID string `q:"id"`
|
||||
Limit int `q:"limit"`
|
||||
Marker string `q:"marker"`
|
||||
SortKey string `q:"sort_key"`
|
||||
SortDir string `q:"sort_dir"`
|
||||
}
|
||||
|
||||
// ToL7PolicyListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToL7PolicyListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over a collection of
|
||||
// l7policies. It accepts a ListOpts struct, which allows you to filter and sort
|
||||
// the returned collection for greater efficiency.
|
||||
//
|
||||
// Default policy settings return only those l7policies that are owned by the
|
||||
// project who submits the request, unless an admin user submits the request.
|
||||
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := rootURL(c)
|
||||
if opts != nil {
|
||||
query, err := opts.ToL7PolicyListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||
return L7PolicyPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToL7PolicyUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts is the common options struct used in this package's Update
|
||||
// operation.
|
||||
type UpdateOpts struct {
|
||||
// Name of the L7 policy, empty string is allowed.
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
||||
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT.
|
||||
Action Action `json:"action,omitempty"`
|
||||
|
||||
// The position of this policy on the listener.
|
||||
Position int32 `json:"position,omitempty"`
|
||||
|
||||
// A human-readable description for the resource, empty string is allowed.
|
||||
Description *string `json:"description,omitempty"`
|
||||
|
||||
// Requests matching this policy will be redirected to the pool with this ID.
|
||||
// Only valid if action is REDIRECT_TO_POOL.
|
||||
RedirectPoolID *string `json:"redirect_pool_id,omitempty"`
|
||||
|
||||
// Requests matching this policy will be redirected to this URL.
|
||||
// Only valid if action is REDIRECT_TO_URL.
|
||||
RedirectURL *string `json:"redirect_url,omitempty"`
|
||||
|
||||
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
}
|
||||
|
||||
// ToL7PolicyUpdateMap builds a request body from UpdateOpts.
|
||||
func (opts UpdateOpts) ToL7PolicyUpdateMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "l7policy")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := b["l7policy"].(map[string]interface{})
|
||||
|
||||
if m["redirect_pool_id"] == "" {
|
||||
m["redirect_pool_id"] = nil
|
||||
}
|
||||
|
||||
if m["redirect_url"] == "" {
|
||||
m["redirect_url"] = nil
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Update allows l7policy to be updated.
|
||||
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToL7PolicyUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// CreateRuleOpts is the common options struct used in this package's CreateRule
|
||||
// operation.
|
||||
type CreateRuleOpts struct {
|
||||
// The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH.
|
||||
RuleType RuleType `json:"type" required:"true"`
|
||||
|
||||
// The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH, EQUAL_TO, REGEX, or STARTS_WITH.
|
||||
CompareType CompareType `json:"compare_type" required:"true"`
|
||||
|
||||
// The value to use for the comparison. For example, the file type to compare.
|
||||
Value string `json:"value" required:"true"`
|
||||
|
||||
// TenantID is the UUID of the tenant who owns the rule in octavia.
|
||||
// Only administrative users can specify a project UUID other than their own.
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
|
||||
// The key to use for the comparison. For example, the name of the cookie to evaluate.
|
||||
Key string `json:"key,omitempty"`
|
||||
|
||||
// When true the logic of the rule is inverted. For example, with invert true,
|
||||
// equal to would become not equal to. Default is false.
|
||||
Invert bool `json:"invert,omitempty"`
|
||||
|
||||
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
}
|
||||
|
||||
// ToRuleCreateMap builds a request body from CreateRuleOpts.
|
||||
func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "rule")
|
||||
}
|
||||
|
||||
// CreateRule will create and associate a Rule with a particular L7Policy.
|
||||
func CreateRule(c *gophercloud.ServiceClient, policyID string, opts CreateRuleOpts) (r CreateRuleResult) {
|
||||
b, err := opts.ToRuleCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(ruleRootURL(c, policyID), b, &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// ListRulesOptsBuilder allows extensions to add additional parameters to the
|
||||
// ListRules request.
|
||||
type ListRulesOptsBuilder interface {
|
||||
ToRulesListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListRulesOpts allows the filtering and sorting of paginated collections
|
||||
// through the API.
|
||||
type ListRulesOpts struct {
|
||||
RuleType RuleType `q:"type"`
|
||||
TenantID string `q:"tenant_id"`
|
||||
CompareType CompareType `q:"compare_type"`
|
||||
Value string `q:"value"`
|
||||
Key string `q:"key"`
|
||||
Invert bool `q:"invert"`
|
||||
AdminStateUp bool `q:"admin_state_up"`
|
||||
ID string `q:"id"`
|
||||
Limit int `q:"limit"`
|
||||
Marker string `q:"marker"`
|
||||
SortKey string `q:"sort_key"`
|
||||
SortDir string `q:"sort_dir"`
|
||||
}
|
||||
|
||||
// ToRulesListQuery formats a ListOpts into a query string.
|
||||
func (opts ListRulesOpts) ToRulesListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// ListRules returns a Pager which allows you to iterate over a collection of
|
||||
// rules. It accepts a ListRulesOptsBuilder, which allows you to filter and
|
||||
// sort the returned collection for greater efficiency.
|
||||
//
|
||||
// Default policy settings return only those rules that are owned by the
|
||||
// project who submits the request, unless an admin user submits the request.
|
||||
func ListRules(c *gophercloud.ServiceClient, policyID string, opts ListRulesOptsBuilder) pagination.Pager {
|
||||
url := ruleRootURL(c, policyID)
|
||||
if opts != nil {
|
||||
query, err := opts.ToRulesListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||
return RulePage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateRuleOptsBuilder allows to add additional parameters to the PUT request.
|
||||
type UpdateRuleOptsBuilder interface {
|
||||
ToRuleUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateRuleOpts is the common options struct used in this package's Update
|
||||
// operation.
|
||||
type UpdateRuleOpts struct {
|
||||
// The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH.
|
||||
RuleType RuleType `json:"type,omitempty"`
|
||||
|
||||
// The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH, EQUAL_TO, REGEX, or STARTS_WITH.
|
||||
CompareType CompareType `json:"compare_type,omitempty"`
|
||||
|
||||
// The value to use for the comparison. For example, the file type to compare.
|
||||
Value string `json:"value,omitempty"`
|
||||
|
||||
// The key to use for the comparison. For example, the name of the cookie to evaluate.
|
||||
Key *string `json:"key,omitempty"`
|
||||
|
||||
// When true the logic of the rule is inverted. For example, with invert true,
|
||||
// equal to would become not equal to. Default is false.
|
||||
Invert *bool `json:"invert,omitempty"`
|
||||
|
||||
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
}
|
||||
|
||||
// ToRuleUpdateMap builds a request body from UpdateRuleOpts.
|
||||
func (opts UpdateRuleOpts) ToRuleUpdateMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "rule")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if m := b["rule"].(map[string]interface{}); m["key"] == "" {
|
||||
m["key"] = nil
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// UpdateRule allows Rule to be updated.
|
||||
func UpdateRule(c *gophercloud.ServiceClient, policyID string, ruleID string, opts UpdateRuleOptsBuilder) (r UpdateRuleResult) {
|
||||
b, err := opts.ToRuleUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(ruleResourceURL(c, policyID, ruleID), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201, 202},
|
||||
})
|
||||
return
|
||||
}
|
@@ -1,245 +0,0 @@
|
||||
package l7policies
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// L7Policy is a collection of L7 rules associated with a Listener, and which
|
||||
// may also have an association to a back-end pool.
|
||||
type L7Policy struct {
|
||||
// The unique ID for the L7 policy.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Name of the L7 policy.
|
||||
Name string `json:"name"`
|
||||
|
||||
// The ID of the listener.
|
||||
ListenerID string `json:"listener_id"`
|
||||
|
||||
// The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT.
|
||||
Action string `json:"action"`
|
||||
|
||||
// The position of this policy on the listener.
|
||||
Position int32 `json:"position"`
|
||||
|
||||
// A human-readable description for the resource.
|
||||
Description string `json:"description"`
|
||||
|
||||
// TenantID is the UUID of the tenant who owns the L7 policy in octavia.
|
||||
// Only administrative users can specify a project UUID other than their own.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// Requests matching this policy will be redirected to the pool with this ID.
|
||||
// Only valid if action is REDIRECT_TO_POOL.
|
||||
RedirectPoolID string `json:"redirect_pool_id"`
|
||||
|
||||
// Requests matching this policy will be redirected to this URL.
|
||||
// Only valid if action is REDIRECT_TO_URL.
|
||||
RedirectURL string `json:"redirect_url"`
|
||||
|
||||
// The administrative state of the L7 policy, which is up (true) or down (false).
|
||||
AdminStateUp bool `json:"admin_state_up"`
|
||||
|
||||
// The provisioning status of the L7 policy.
|
||||
// This value is ACTIVE, PENDING_* or ERROR.
|
||||
// This field seems to only be returned during a call to a load balancer's /status
|
||||
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||
ProvisioningStatus string `json:"provisioning_status"`
|
||||
|
||||
// The operating status of the L7 policy.
|
||||
// This field seems to only be returned during a call to a load balancer's /status
|
||||
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||
OperatingStatus string `json:"operating_status"`
|
||||
|
||||
// Rules are List of associated L7 rule IDs.
|
||||
Rules []Rule `json:"rules"`
|
||||
}
|
||||
|
||||
// Rule represents layer 7 load balancing rule.
|
||||
type Rule struct {
|
||||
// The unique ID for the L7 rule.
|
||||
ID string `json:"id"`
|
||||
|
||||
// The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH.
|
||||
RuleType string `json:"type"`
|
||||
|
||||
// The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH, EQUAL_TO, REGEX, or STARTS_WITH.
|
||||
CompareType string `json:"compare_type"`
|
||||
|
||||
// The value to use for the comparison. For example, the file type to compare.
|
||||
Value string `json:"value"`
|
||||
|
||||
// TenantID is the UUID of the tenant who owns the rule in octavia.
|
||||
// Only administrative users can specify a project UUID other than their own.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// The key to use for the comparison. For example, the name of the cookie to evaluate.
|
||||
Key string `json:"key"`
|
||||
|
||||
// When true the logic of the rule is inverted. For example, with invert true,
|
||||
// equal to would become not equal to. Default is false.
|
||||
Invert bool `json:"invert"`
|
||||
|
||||
// The administrative state of the L7 rule, which is up (true) or down (false).
|
||||
AdminStateUp bool `json:"admin_state_up"`
|
||||
|
||||
// The provisioning status of the L7 rule.
|
||||
// This value is ACTIVE, PENDING_* or ERROR.
|
||||
// This field seems to only be returned during a call to a load balancer's /status
|
||||
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||
ProvisioningStatus string `json:"provisioning_status"`
|
||||
|
||||
// The operating status of the L7 policy.
|
||||
// This field seems to only be returned during a call to a load balancer's /status
|
||||
// see: https://github.com/gophercloud/gophercloud/issues/1362
|
||||
OperatingStatus string `json:"operating_status"`
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts a l7policy.
|
||||
func (r commonResult) Extract() (*L7Policy, error) {
|
||||
var s struct {
|
||||
L7Policy *L7Policy `json:"l7policy"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.L7Policy, err
|
||||
}
|
||||
|
||||
// CreateResult represents the result of a Create operation. Call its Extract
|
||||
// method to interpret the result as a L7Policy.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// L7PolicyPage is the page returned by a pager when traversing over a
|
||||
// collection of l7policies.
|
||||
type L7PolicyPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// NextPageURL is invoked when a paginated collection of l7policies has reached
|
||||
// the end of a page and the pager seeks to traverse over a new one. In order
|
||||
// to do this, it needs to construct the next page's URL.
|
||||
func (r L7PolicyPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"l7policies_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether a L7PolicyPage struct is empty.
|
||||
func (r L7PolicyPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractL7Policies(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// ExtractL7Policies accepts a Page struct, specifically a L7PolicyPage struct,
|
||||
// and extracts the elements into a slice of L7Policy structs. In other words,
|
||||
// a generic collection is mapped into a relevant slice.
|
||||
func ExtractL7Policies(r pagination.Page) ([]L7Policy, error) {
|
||||
var s struct {
|
||||
L7Policies []L7Policy `json:"l7policies"`
|
||||
}
|
||||
err := (r.(L7PolicyPage)).ExtractInto(&s)
|
||||
return s.L7Policies, err
|
||||
}
|
||||
|
||||
// GetResult represents the result of a Get operation. Call its Extract
|
||||
// method to interpret the result as a L7Policy.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of a Delete operation. Call its
|
||||
// ExtractErr method to determine if the request succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// UpdateResult represents the result of an Update operation. Call its Extract
|
||||
// method to interpret the result as a L7Policy.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
type commonRuleResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts a rule.
|
||||
func (r commonRuleResult) Extract() (*Rule, error) {
|
||||
var s struct {
|
||||
Rule *Rule `json:"rule"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Rule, err
|
||||
}
|
||||
|
||||
// CreateRuleResult represents the result of a CreateRule operation.
|
||||
// Call its Extract method to interpret it as a Rule.
|
||||
type CreateRuleResult struct {
|
||||
commonRuleResult
|
||||
}
|
||||
|
||||
// RulePage is the page returned by a pager when traversing over a
|
||||
// collection of Rules in a L7Policy.
|
||||
type RulePage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// NextPageURL is invoked when a paginated collection of rules has reached
|
||||
// the end of a page and the pager seeks to traverse over a new one. In order
|
||||
// to do this, it needs to construct the next page's URL.
|
||||
func (r RulePage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"rules_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether a RulePage struct is empty.
|
||||
func (r RulePage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractRules(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// ExtractRules accepts a Page struct, specifically a RulePage struct,
|
||||
// and extracts the elements into a slice of Rules structs. In other words,
|
||||
// a generic collection is mapped into a relevant slice.
|
||||
func ExtractRules(r pagination.Page) ([]Rule, error) {
|
||||
var s struct {
|
||||
Rules []Rule `json:"rules"`
|
||||
}
|
||||
err := (r.(RulePage)).ExtractInto(&s)
|
||||
return s.Rules, err
|
||||
}
|
||||
|
||||
// GetRuleResult represents the result of a GetRule operation.
|
||||
// Call its Extract method to interpret it as a Rule.
|
||||
type GetRuleResult struct {
|
||||
commonRuleResult
|
||||
}
|
||||
|
||||
// DeleteRuleResult represents the result of a DeleteRule operation.
|
||||
// Call its ExtractErr method to determine if the request succeeded or failed.
|
||||
type DeleteRuleResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// UpdateRuleResult represents the result of an UpdateRule operation.
|
||||
// Call its Extract method to interpret it as a Rule.
|
||||
type UpdateRuleResult struct {
|
||||
commonRuleResult
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
package l7policies
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
const (
|
||||
rootPath = "lbaas"
|
||||
resourcePath = "l7policies"
|
||||
rulePath = "rules"
|
||||
)
|
||||
|
||||
func rootURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL(rootPath, resourcePath)
|
||||
}
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(rootPath, resourcePath, id)
|
||||
}
|
||||
|
||||
func ruleRootURL(c *gophercloud.ServiceClient, policyID string) string {
|
||||
return c.ServiceURL(rootPath, resourcePath, policyID, rulePath)
|
||||
}
|
||||
|
||||
func ruleResourceURL(c *gophercloud.ServiceClient, policyID string, ruleID string) string {
|
||||
return c.ServiceURL(rootPath, resourcePath, policyID, rulePath, ruleID)
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
Package listeners provides information and interaction with Listeners of the
|
||||
LBaaS v2 extension for the OpenStack Networking service.
|
||||
|
||||
Example to List Listeners
|
||||
|
||||
listOpts := listeners.ListOpts{
|
||||
LoadbalancerID : "ca430f80-1737-4712-8dc6-3f640d55594b",
|
||||
}
|
||||
|
||||
allPages, err := listeners.List(networkClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allListeners, err := listeners.ExtractListeners(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, listener := range allListeners {
|
||||
fmt.Printf("%+v\n", listener)
|
||||
}
|
||||
|
||||
Example to Create a Listener
|
||||
|
||||
createOpts := listeners.CreateOpts{
|
||||
Protocol: "TCP",
|
||||
Name: "db",
|
||||
LoadbalancerID: "79e05663-7f03-45d2-a092-8b94062f22ab",
|
||||
AdminStateUp: gophercloud.Enabled,
|
||||
DefaultPoolID: "41efe233-7591-43c5-9cf7-923964759f9e",
|
||||
ProtocolPort: 3306,
|
||||
}
|
||||
|
||||
listener, err := listeners.Create(networkClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a Listener
|
||||
|
||||
listenerID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
|
||||
i1001 := 1001
|
||||
updateOpts := listeners.UpdateOpts{
|
||||
ConnLimit: &i1001,
|
||||
}
|
||||
|
||||
listener, err := listeners.Update(networkClient, listenerID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a Listener
|
||||
|
||||
listenerID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
err := listeners.Delete(networkClient, listenerID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package listeners
|
@@ -1,212 +0,0 @@
|
||||
package listeners
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Type Protocol represents a listener protocol.
|
||||
type Protocol string
|
||||
|
||||
// Supported attributes for create/update operations.
|
||||
const (
|
||||
ProtocolTCP Protocol = "TCP"
|
||||
ProtocolHTTP Protocol = "HTTP"
|
||||
ProtocolHTTPS Protocol = "HTTPS"
|
||||
ProtocolTerminatedHTTPS Protocol = "TERMINATED_HTTPS"
|
||||
)
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||
// List request.
|
||||
type ListOptsBuilder interface {
|
||||
ToListenerListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts allows the filtering and sorting of paginated collections through
|
||||
// the API. Filtering is achieved by passing in struct field values that map to
|
||||
// the floating IP attributes you want to see returned. SortKey allows you to
|
||||
// sort by a particular listener attribute. SortDir sets the direction, and is
|
||||
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
||||
type ListOpts struct {
|
||||
ID string `q:"id"`
|
||||
Name string `q:"name"`
|
||||
AdminStateUp *bool `q:"admin_state_up"`
|
||||
TenantID string `q:"tenant_id"`
|
||||
ProjectID string `q:"project_id"`
|
||||
LoadbalancerID string `q:"loadbalancer_id"`
|
||||
DefaultPoolID string `q:"default_pool_id"`
|
||||
Protocol string `q:"protocol"`
|
||||
ProtocolPort int `q:"protocol_port"`
|
||||
ConnectionLimit int `q:"connection_limit"`
|
||||
Limit int `q:"limit"`
|
||||
Marker string `q:"marker"`
|
||||
SortKey string `q:"sort_key"`
|
||||
SortDir string `q:"sort_dir"`
|
||||
}
|
||||
|
||||
// ToListenerListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToListenerListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over a collection of
|
||||
// listeners. It accepts a ListOpts struct, which allows you to filter and sort
|
||||
// the returned collection for greater efficiency.
|
||||
//
|
||||
// Default policy settings return only those listeners that are owned by the
|
||||
// tenant who submits the request, unless an admin user submits the request.
|
||||
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := rootURL(c)
|
||||
if opts != nil {
|
||||
query, err := opts.ToListenerListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||
return ListenerPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToListenerCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts represents options for creating a listener.
|
||||
type CreateOpts struct {
|
||||
// The load balancer on which to provision this listener.
|
||||
LoadbalancerID string `json:"loadbalancer_id" required:"true"`
|
||||
|
||||
// The protocol - can either be TCP, HTTP or HTTPS.
|
||||
Protocol Protocol `json:"protocol" required:"true"`
|
||||
|
||||
// The port on which to listen for client traffic.
|
||||
ProtocolPort int `json:"protocol_port" required:"true"`
|
||||
|
||||
// TenantID is only required if the caller has an admin role and wants
|
||||
// to create a pool for another project.
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
|
||||
// ProjectID is only required if the caller has an admin role and wants
|
||||
// to create a pool for another project.
|
||||
ProjectID string `json:"project_id,omitempty"`
|
||||
|
||||
// Human-readable name for the Listener. Does not have to be unique.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// The ID of the default pool with which the Listener is associated.
|
||||
DefaultPoolID string `json:"default_pool_id,omitempty"`
|
||||
|
||||
// Human-readable description for the Listener.
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// The maximum number of connections allowed for the Listener.
|
||||
ConnLimit *int `json:"connection_limit,omitempty"`
|
||||
|
||||
// A reference to a Barbican container of TLS secrets.
|
||||
DefaultTlsContainerRef string `json:"default_tls_container_ref,omitempty"`
|
||||
|
||||
// A list of references to TLS secrets.
|
||||
SniContainerRefs []string `json:"sni_container_refs,omitempty"`
|
||||
|
||||
// The administrative state of the Listener. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
}
|
||||
|
||||
// ToListenerCreateMap builds a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToListenerCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "listener")
|
||||
}
|
||||
|
||||
// Create is an operation which provisions a new Listeners based on the
|
||||
// configuration defined in the CreateOpts struct. Once the request is
|
||||
// validated and progress has started on the provisioning process, a
|
||||
// CreateResult will be returned.
|
||||
//
|
||||
// Users with an admin role can create Listeners on behalf of other tenants by
|
||||
// specifying a TenantID attribute different than their own.
|
||||
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToListenerCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToListenerUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts represents options for updating a Listener.
|
||||
type UpdateOpts struct {
|
||||
// Human-readable name for the Listener. Does not have to be unique.
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
||||
// The ID of the default pool with which the Listener is associated.
|
||||
DefaultPoolID *string `json:"default_pool_id,omitempty"`
|
||||
|
||||
// Human-readable description for the Listener.
|
||||
Description *string `json:"description,omitempty"`
|
||||
|
||||
// The maximum number of connections allowed for the Listener.
|
||||
ConnLimit *int `json:"connection_limit,omitempty"`
|
||||
|
||||
// A reference to a Barbican container of TLS secrets.
|
||||
DefaultTlsContainerRef string `json:"default_tls_container_ref,omitempty"`
|
||||
|
||||
// A list of references to TLS secrets.
|
||||
SniContainerRefs []string `json:"sni_container_refs,omitempty"`
|
||||
|
||||
// The administrative state of the Listener. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
}
|
||||
|
||||
// ToListenerUpdateMap builds a request body from UpdateOpts.
|
||||
func (opts UpdateOpts) ToListenerUpdateMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "listener")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if m := b["listener"].(map[string]interface{}); m["default_pool_id"] == "" {
|
||||
m["default_pool_id"] = nil
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Update is an operation which modifies the attributes of the specified
|
||||
// Listener.
|
||||
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) {
|
||||
b, err := opts.ToListenerUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
@@ -1,141 +0,0 @@
|
||||
package listeners
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
type LoadBalancerID struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// Listener is the primary load balancing configuration object that specifies
|
||||
// the loadbalancer and port on which client traffic is received, as well
|
||||
// as other details such as the load balancing method to be use, protocol, etc.
|
||||
type Listener struct {
|
||||
// The unique ID for the Listener.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Owner of the Listener.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// Human-readable name for the Listener. Does not have to be unique.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Human-readable description for the Listener.
|
||||
Description string `json:"description"`
|
||||
|
||||
// The protocol to loadbalance. A valid value is TCP, HTTP, or HTTPS.
|
||||
Protocol string `json:"protocol"`
|
||||
|
||||
// The port on which to listen to client traffic that is associated with the
|
||||
// Loadbalancer. A valid value is from 0 to 65535.
|
||||
ProtocolPort int `json:"protocol_port"`
|
||||
|
||||
// The UUID of default pool. Must have compatible protocol with listener.
|
||||
DefaultPoolID string `json:"default_pool_id"`
|
||||
|
||||
// A list of load balancer IDs.
|
||||
Loadbalancers []LoadBalancerID `json:"loadbalancers"`
|
||||
|
||||
// The maximum number of connections allowed for the Loadbalancer.
|
||||
// Default is -1, meaning no limit.
|
||||
ConnLimit int `json:"connection_limit"`
|
||||
|
||||
// The list of references to TLS secrets.
|
||||
SniContainerRefs []string `json:"sni_container_refs"`
|
||||
|
||||
// A reference to a Barbican container of TLS secrets.
|
||||
DefaultTlsContainerRef string `json:"default_tls_container_ref"`
|
||||
|
||||
// The administrative state of the Listener. A valid value is true (UP) or false (DOWN).
|
||||
AdminStateUp bool `json:"admin_state_up"`
|
||||
|
||||
// Pools are the pools which are part of this listener.
|
||||
Pools []pools.Pool `json:"pools"`
|
||||
|
||||
// L7policies are the L7 policies which are part of this listener.
|
||||
// This field seems to only be returned during a call to a load balancer's /status
|
||||
// see: https://github.com/gophercloud/gophercloud/issues/1352
|
||||
L7Policies []l7policies.L7Policy `json:"l7policies"`
|
||||
|
||||
// The provisioning status of the listener.
|
||||
// This value is ACTIVE, PENDING_* or ERROR.
|
||||
ProvisioningStatus string `json:"provisioning_status"`
|
||||
}
|
||||
|
||||
// ListenerPage is the page returned by a pager when traversing over a
|
||||
// collection of listeners.
|
||||
type ListenerPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// NextPageURL is invoked when a paginated collection of listeners has reached
|
||||
// the end of a page and the pager seeks to traverse over a new one. In order
|
||||
// to do this, it needs to construct the next page's URL.
|
||||
func (r ListenerPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"listeners_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether a ListenerPage struct is empty.
|
||||
func (r ListenerPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractListeners(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// ExtractListeners accepts a Page struct, specifically a ListenerPage struct,
|
||||
// and extracts the elements into a slice of Listener structs. In other words,
|
||||
// a generic collection is mapped into a relevant slice.
|
||||
func ExtractListeners(r pagination.Page) ([]Listener, error) {
|
||||
var s struct {
|
||||
Listeners []Listener `json:"listeners"`
|
||||
}
|
||||
err := (r.(ListenerPage)).ExtractInto(&s)
|
||||
return s.Listeners, err
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts a listener.
|
||||
func (r commonResult) Extract() (*Listener, error) {
|
||||
var s struct {
|
||||
Listener *Listener `json:"listener"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Listener, err
|
||||
}
|
||||
|
||||
// CreateResult represents the result of a create operation. Call its Extract
|
||||
// method to interpret it as a Listener.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult represents the result of a get operation. Call its Extract
|
||||
// method to interpret it as a Listener.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult represents the result of an update operation. Call its Extract
|
||||
// method to interpret it as a Listener.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of a delete operation. Call its
|
||||
// ExtractErr method to determine if the request succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
package listeners
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
const (
|
||||
rootPath = "lbaas"
|
||||
resourcePath = "listeners"
|
||||
)
|
||||
|
||||
func rootURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL(rootPath, resourcePath)
|
||||
}
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(rootPath, resourcePath, id)
|
||||
}
|
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
Package loadbalancers provides information and interaction with Load Balancers
|
||||
of the LBaaS v2 extension for the OpenStack Networking service.
|
||||
|
||||
Example to List Load Balancers
|
||||
|
||||
listOpts := loadbalancers.ListOpts{
|
||||
Provider: "haproxy",
|
||||
}
|
||||
|
||||
allPages, err := loadbalancers.List(networkClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allLoadbalancers, err := loadbalancers.ExtractLoadBalancers(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, lb := range allLoadbalancers {
|
||||
fmt.Printf("%+v\n", lb)
|
||||
}
|
||||
|
||||
Example to Create a Load Balancer
|
||||
|
||||
createOpts := loadbalancers.CreateOpts{
|
||||
Name: "db_lb",
|
||||
AdminStateUp: gophercloud.Enabled,
|
||||
VipSubnetID: "9cedb85d-0759-4898-8a4b-fa5a5ea10086",
|
||||
VipAddress: "10.30.176.48",
|
||||
Flavor: "medium",
|
||||
Provider: "haproxy",
|
||||
}
|
||||
|
||||
lb, err := loadbalancers.Create(networkClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a Load Balancer
|
||||
|
||||
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
|
||||
i1001 := 1001
|
||||
updateOpts := loadbalancers.UpdateOpts{
|
||||
Name: "new-name",
|
||||
}
|
||||
|
||||
lb, err := loadbalancers.Update(networkClient, lbID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a Load Balancers
|
||||
|
||||
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
err := loadbalancers.Delete(networkClient, lbID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Get the Status of a Load Balancer
|
||||
|
||||
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
status, err := loadbalancers.GetStatuses(networkClient, LBID).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Get the Statistics of a Load Balancer
|
||||
|
||||
lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
|
||||
stats, err := loadbalancers.GetStats(networkClient, LBID).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package loadbalancers
|
@@ -1,204 +0,0 @@
|
||||
package loadbalancers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||
// List request.
|
||||
type ListOptsBuilder interface {
|
||||
ToLoadBalancerListQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListOpts allows the filtering and sorting of paginated collections through
|
||||
// the API. Filtering is achieved by passing in struct field values that map to
|
||||
// the Loadbalancer attributes you want to see returned. SortKey allows you to
|
||||
// sort by a particular attribute. SortDir sets the direction, and is
|
||||
// either `asc' or `desc'. Marker and Limit are used for pagination.
|
||||
type ListOpts struct {
|
||||
Description string `q:"description"`
|
||||
AdminStateUp *bool `q:"admin_state_up"`
|
||||
TenantID string `q:"tenant_id"`
|
||||
ProjectID string `q:"project_id"`
|
||||
ProvisioningStatus string `q:"provisioning_status"`
|
||||
VipAddress string `q:"vip_address"`
|
||||
VipPortID string `q:"vip_port_id"`
|
||||
VipSubnetID string `q:"vip_subnet_id"`
|
||||
ID string `q:"id"`
|
||||
OperatingStatus string `q:"operating_status"`
|
||||
Name string `q:"name"`
|
||||
Flavor string `q:"flavor"`
|
||||
Provider string `q:"provider"`
|
||||
Limit int `q:"limit"`
|
||||
Marker string `q:"marker"`
|
||||
SortKey string `q:"sort_key"`
|
||||
SortDir string `q:"sort_dir"`
|
||||
}
|
||||
|
||||
// ToLoadBalancerListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToLoadBalancerListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over a collection of
|
||||
// load balancers. It accepts a ListOpts struct, which allows you to filter
|
||||
// and sort the returned collection for greater efficiency.
|
||||
//
|
||||
// Default policy settings return only those load balancers that are owned by
|
||||
// the tenant who submits the request, unless an admin user submits the request.
|
||||
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||
url := rootURL(c)
|
||||
if opts != nil {
|
||||
query, err := opts.ToLoadBalancerListQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
}
|
||||
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||
return LoadBalancerPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Create request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToLoadBalancerCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts is the common options struct used in this package's Create
|
||||
// operation.
|
||||
type CreateOpts struct {
|
||||
// Human-readable name for the Loadbalancer. Does not have to be unique.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Human-readable description for the Loadbalancer.
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// The network on which to allocate the Loadbalancer's address. A tenant can
|
||||
// only create Loadbalancers on networks authorized by policy (e.g. networks
|
||||
// that belong to them or networks that are shared).
|
||||
VipSubnetID string `json:"vip_subnet_id" required:"true"`
|
||||
|
||||
// TenantID is the UUID of the project who owns the Loadbalancer.
|
||||
// Only administrative users can specify a project UUID other than their own.
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
|
||||
// ProjectID is the UUID of the project who owns the Loadbalancer.
|
||||
// Only administrative users can specify a project UUID other than their own.
|
||||
ProjectID string `json:"project_id,omitempty"`
|
||||
|
||||
// The IP address of the Loadbalancer.
|
||||
VipAddress string `json:"vip_address,omitempty"`
|
||||
|
||||
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
|
||||
// The UUID of a flavor.
|
||||
Flavor string `json:"flavor,omitempty"`
|
||||
|
||||
// The name of the provider.
|
||||
Provider string `json:"provider,omitempty"`
|
||||
}
|
||||
|
||||
// ToLoadBalancerCreateMap builds a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToLoadBalancerCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "loadbalancer")
|
||||
}
|
||||
|
||||
// Create is an operation which provisions a new loadbalancer based on the
|
||||
// configuration defined in the CreateOpts struct. Once the request is
|
||||
// validated and progress has started on the provisioning process, a
|
||||
// CreateResult will be returned.
|
||||
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToLoadBalancerCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||
// Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToLoadBalancerUpdateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// UpdateOpts is the common options struct used in this package's Update
|
||||
// operation.
|
||||
type UpdateOpts struct {
|
||||
// Human-readable name for the Loadbalancer. Does not have to be unique.
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
||||
// Human-readable description for the Loadbalancer.
|
||||
Description *string `json:"description,omitempty"`
|
||||
|
||||
// The administrative state of the Loadbalancer. A valid value is true (UP)
|
||||
// or false (DOWN).
|
||||
AdminStateUp *bool `json:"admin_state_up,omitempty"`
|
||||
}
|
||||
|
||||
// ToLoadBalancerUpdateMap builds a request body from UpdateOpts.
|
||||
func (opts UpdateOpts) ToLoadBalancerUpdateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "loadbalancer")
|
||||
}
|
||||
|
||||
// Update is an operation which modifies the attributes of the specified
|
||||
// LoadBalancer.
|
||||
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) {
|
||||
b, err := opts.ToLoadBalancerUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 202},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete will permanently delete a particular LoadBalancer based on its
|
||||
// unique ID.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(resourceURL(c, id), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// CascadingDelete is like `Delete`, but will also delete any of the load balancer's
|
||||
// children (listener, monitor, etc).
|
||||
// NOTE: This function will only work with Octavia load balancers; Neutron does not
|
||||
// support this.
|
||||
func CascadingDelete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
if c.Type != "load-balancer" {
|
||||
r.Err = fmt.Errorf("error prior to running cascade delete: only Octavia LBs supported")
|
||||
return
|
||||
}
|
||||
u := fmt.Sprintf("%s?cascade=true", resourceURL(c, id))
|
||||
_, r.Err = c.Delete(u, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// GetStatuses will return the status of a particular LoadBalancer.
|
||||
func GetStatuses(c *gophercloud.ServiceClient, id string) (r GetStatusesResult) {
|
||||
_, r.Err = c.Get(statusRootURL(c, id), &r.Body, nil)
|
||||
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)
|
||||
return
|
||||
}
|
@@ -1,186 +0,0 @@
|
||||
package loadbalancers
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// LoadBalancer is the primary load balancing configuration object that
|
||||
// specifies the virtual IP address on which client traffic is received, as well
|
||||
// as other details such as the load balancing method to be use, protocol, etc.
|
||||
type LoadBalancer struct {
|
||||
// Human-readable description for the Loadbalancer.
|
||||
Description string `json:"description"`
|
||||
|
||||
// The administrative state of the Loadbalancer.
|
||||
// A valid value is true (UP) or false (DOWN).
|
||||
AdminStateUp bool `json:"admin_state_up"`
|
||||
|
||||
// Owner of the LoadBalancer.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// The provisioning status of the LoadBalancer.
|
||||
// This value is ACTIVE, PENDING_CREATE or ERROR.
|
||||
ProvisioningStatus string `json:"provisioning_status"`
|
||||
|
||||
// The IP address of the Loadbalancer.
|
||||
VipAddress string `json:"vip_address"`
|
||||
|
||||
// The UUID of the port associated with the IP address.
|
||||
VipPortID string `json:"vip_port_id"`
|
||||
|
||||
// The UUID of the subnet on which to allocate the virtual IP for the
|
||||
// Loadbalancer address.
|
||||
VipSubnetID string `json:"vip_subnet_id"`
|
||||
|
||||
// The unique ID for the LoadBalancer.
|
||||
ID string `json:"id"`
|
||||
|
||||
// The operating status of the LoadBalancer. This value is ONLINE or OFFLINE.
|
||||
OperatingStatus string `json:"operating_status"`
|
||||
|
||||
// Human-readable name for the LoadBalancer. Does not have to be unique.
|
||||
Name string `json:"name"`
|
||||
|
||||
// The UUID of a flavor if set.
|
||||
Flavor string `json:"flavor"`
|
||||
|
||||
// The name of the provider.
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// Listeners are the listeners related to this Loadbalancer.
|
||||
Listeners []listeners.Listener `json:"listeners"`
|
||||
|
||||
// Pools are the pools related to this Loadbalancer.
|
||||
Pools []pools.Pool `json:"pools"`
|
||||
}
|
||||
|
||||
// StatusTree represents the status of a loadbalancer.
|
||||
type StatusTree struct {
|
||||
Loadbalancer *LoadBalancer `json:"loadbalancer"`
|
||||
}
|
||||
|
||||
type Stats struct {
|
||||
// The currently active connections.
|
||||
ActiveConnections int `json:"active_connections"`
|
||||
|
||||
// The total bytes received.
|
||||
BytesIn int `json:"bytes_in"`
|
||||
|
||||
// The total bytes sent.
|
||||
BytesOut int `json:"bytes_out"`
|
||||
|
||||
// The total requests that were unable to be fulfilled.
|
||||
RequestErrors int `json:"request_errors"`
|
||||
|
||||
// The total connections handled.
|
||||
TotalConnections int `json:"total_connections"`
|
||||
}
|
||||
|
||||
// LoadBalancerPage is the page returned by a pager when traversing over a
|
||||
// collection of load balancers.
|
||||
type LoadBalancerPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// NextPageURL is invoked when a paginated collection of load balancers has
|
||||
// reached the end of a page and the pager seeks to traverse over a new one.
|
||||
// In order to do this, it needs to construct the next page's URL.
|
||||
func (r LoadBalancerPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"loadbalancers_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether a LoadBalancerPage struct is empty.
|
||||
func (r LoadBalancerPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractLoadBalancers(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// ExtractLoadBalancers accepts a Page struct, specifically a LoadbalancerPage
|
||||
// struct, and extracts the elements into a slice of LoadBalancer structs. In
|
||||
// other words, a generic collection is mapped into a relevant slice.
|
||||
func ExtractLoadBalancers(r pagination.Page) ([]LoadBalancer, error) {
|
||||
var s struct {
|
||||
LoadBalancers []LoadBalancer `json:"loadbalancers"`
|
||||
}
|
||||
err := (r.(LoadBalancerPage)).ExtractInto(&s)
|
||||
return s.LoadBalancers, err
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts a loadbalancer.
|
||||
func (r commonResult) Extract() (*LoadBalancer, error) {
|
||||
var s struct {
|
||||
LoadBalancer *LoadBalancer `json:"loadbalancer"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.LoadBalancer, err
|
||||
}
|
||||
|
||||
// GetStatusesResult represents the result of a GetStatuses operation.
|
||||
// Call its Extract method to interpret it as a StatusTree.
|
||||
type GetStatusesResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts the status of
|
||||
// a Loadbalancer.
|
||||
func (r GetStatusesResult) Extract() (*StatusTree, error) {
|
||||
var s struct {
|
||||
Statuses *StatusTree `json:"statuses"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Statuses, err
|
||||
}
|
||||
|
||||
// StatsResult represents the result of a GetStats operation.
|
||||
// Call its Extract method to interpret it as a Stats.
|
||||
type StatsResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a function that accepts a result and extracts the status of
|
||||
// a Loadbalancer.
|
||||
func (r StatsResult) Extract() (*Stats, error) {
|
||||
var s struct {
|
||||
Stats *Stats `json:"stats"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Stats, err
|
||||
}
|
||||
|
||||
// CreateResult represents the result of a create operation. Call its Extract
|
||||
// method to interpret it as a LoadBalancer.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult represents the result of a get operation. Call its Extract
|
||||
// method to interpret it as a LoadBalancer.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult represents the result of an update operation. Call its Extract
|
||||
// method to interpret it as a LoadBalancer.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of a delete operation. Call its
|
||||
// ExtractErr method to determine if the request succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user