vendor: github.com/terraform-providers/terraform-provider-openstack@v1.15.0
This commit is contained in:
parent
651ee113ac
commit
a67e6e19b1
5
go.mod
5
go.mod
|
@ -45,7 +45,8 @@ require (
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c // indirect
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c // indirect
|
||||||
github.com/google/go-cmp v0.2.0
|
github.com/google/go-cmp v0.2.0
|
||||||
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e // indirect
|
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e // indirect
|
||||||
github.com/gophercloud/gophercloud v0.0.0-20170524130959-3027adb1ce72
|
github.com/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968
|
||||||
|
github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01 // indirect
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f // indirect
|
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f // indirect
|
||||||
github.com/gorilla/websocket v1.4.0 // indirect
|
github.com/gorilla/websocket v1.4.0 // indirect
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
|
||||||
|
@ -118,7 +119,7 @@ require (
|
||||||
github.com/soheilhy/cmux v0.1.4 // indirect
|
github.com/soheilhy/cmux v0.1.4 // indirect
|
||||||
github.com/spf13/afero v1.0.2
|
github.com/spf13/afero v1.0.2
|
||||||
github.com/terraform-providers/terraform-provider-aws v1.52.0
|
github.com/terraform-providers/terraform-provider-aws v1.52.0
|
||||||
github.com/terraform-providers/terraform-provider-openstack v0.0.0-20170616075611-4080a521c6ea
|
github.com/terraform-providers/terraform-provider-openstack v1.15.0
|
||||||
github.com/terraform-providers/terraform-provider-template v1.0.0 // indirect
|
github.com/terraform-providers/terraform-provider-template v1.0.0 // indirect
|
||||||
github.com/terraform-providers/terraform-provider-tls v1.2.0 // indirect
|
github.com/terraform-providers/terraform-provider-tls v1.2.0 // indirect
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 // indirect
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 // indirect
|
||||||
|
|
10
go.sum
10
go.sum
|
@ -103,8 +103,10 @@ github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASu
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e h1:CYRpN206UTHUinz3VJoLaBdy1gEGeJNsqT0mvswDcMw=
|
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e h1:CYRpN206UTHUinz3VJoLaBdy1gEGeJNsqT0mvswDcMw=
|
||||||
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||||
github.com/gophercloud/gophercloud v0.0.0-20170524130959-3027adb1ce72 h1:I0ssFkBxJw27fhEVIBVjGQVMqKj5HyzfvfIhdr5Tx2E=
|
github.com/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968 h1:Pu+HW4kcQozw0QyrTTgLE+3RXNqFhQNNzhbnoLFL83c=
|
||||||
github.com/gophercloud/gophercloud v0.0.0-20170524130959-3027adb1ce72/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
|
github.com/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
|
||||||
|
github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01 h1:OgCNGSnEalfkRpn//WGJHhpo7fkP+LhTpvEITZ7CkK4=
|
||||||
|
github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01/go.mod h1:wjDF8z83zTeg5eMLml5EBSlAhbF7G8DobyI1YsMuyzw=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f h1:JJ2EP5vV3LAD2U1CxQtD7PTOO15Y96kXmKDz7TjxGHs=
|
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f h1:JJ2EP5vV3LAD2U1CxQtD7PTOO15Y96kXmKDz7TjxGHs=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||||
|
@ -301,8 +303,8 @@ github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d h1:Z4EH+5Effv
|
||||||
github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw=
|
github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw=
|
||||||
github.com/terraform-providers/terraform-provider-aws v1.52.0 h1:hfFaKOUtL/ud9Y4PFgFT7F8Ss61lMIK1P+ndPEhPA7s=
|
github.com/terraform-providers/terraform-provider-aws v1.52.0 h1:hfFaKOUtL/ud9Y4PFgFT7F8Ss61lMIK1P+ndPEhPA7s=
|
||||||
github.com/terraform-providers/terraform-provider-aws v1.52.0/go.mod h1:uvqaeKnm2ydZ2LuKuW1NDNBu6heC/7IDGXWm36/6oKs=
|
github.com/terraform-providers/terraform-provider-aws v1.52.0/go.mod h1:uvqaeKnm2ydZ2LuKuW1NDNBu6heC/7IDGXWm36/6oKs=
|
||||||
github.com/terraform-providers/terraform-provider-openstack v0.0.0-20170616075611-4080a521c6ea h1:IfuzHOI3XwwYZS2Xw8SQbxOtGXlIUrKtXtuDCTNxmsQ=
|
github.com/terraform-providers/terraform-provider-openstack v1.15.0 h1:adpjqej+F8BAX9dHmuPF47sUIkgifeqBu6p7iCsyj0Y=
|
||||||
github.com/terraform-providers/terraform-provider-openstack v0.0.0-20170616075611-4080a521c6ea/go.mod h1:2aQ6n/BtChAl1y2S60vebhyJyZXBsuAI5G4+lHrT1Ew=
|
github.com/terraform-providers/terraform-provider-openstack v1.15.0/go.mod h1:2aQ6n/BtChAl1y2S60vebhyJyZXBsuAI5G4+lHrT1Ew=
|
||||||
github.com/terraform-providers/terraform-provider-template v1.0.0 h1:g2pyFaAJu369iAb7qGWmVwtQ15/35lRAfW91Je8wLjE=
|
github.com/terraform-providers/terraform-provider-template v1.0.0 h1:g2pyFaAJu369iAb7qGWmVwtQ15/35lRAfW91Je8wLjE=
|
||||||
github.com/terraform-providers/terraform-provider-template v1.0.0/go.mod h1:/J+B8me5DCMa0rEBH5ic2aKPjhtpWNeScmxFJWxB1EU=
|
github.com/terraform-providers/terraform-provider-template v1.0.0/go.mod h1:/J+B8me5DCMa0rEBH5ic2aKPjhtpWNeScmxFJWxB1EU=
|
||||||
github.com/terraform-providers/terraform-provider-tls v1.2.0 h1:wcD0InKzNh8fanUYQwim62WCd4toeD9WJnPw/RjBI4o=
|
github.com/terraform-providers/terraform-provider-tls v1.2.0 h1:wcD0InKzNh8fanUYQwim62WCd4toeD9WJnPw/RjBI4o=
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
**/*.swp
|
**/*.swp
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
|
@ -7,13 +7,16 @@ install:
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
- go get golang.org/x/tools/cmd/goimports
|
- go get golang.org/x/tools/cmd/goimports
|
||||||
go:
|
go:
|
||||||
- 1.7
|
- "1.10"
|
||||||
- tip
|
- "tip"
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ="
|
- secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ="
|
||||||
|
before_script:
|
||||||
|
- go vet ./...
|
||||||
script:
|
script:
|
||||||
- ./script/coverage
|
- ./script/coverage
|
||||||
|
- ./script/unittest
|
||||||
- ./script/format
|
- ./script/format
|
||||||
after_success:
|
after_success:
|
||||||
- $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=cover.out
|
- $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=cover.out
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
- 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-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-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-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
|
||||||
|
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
|
||||||
|
periodic:
|
||||||
|
jobs:
|
||||||
|
- gophercloud-unittest
|
||||||
|
- gophercloud-acceptance-test
|
|
@ -1,148 +0,0 @@
|
||||||
# Tips
|
|
||||||
|
|
||||||
## Implementing default logging and re-authentication attempts
|
|
||||||
|
|
||||||
You can implement custom logging and/or limit re-auth attempts by creating a custom HTTP client
|
|
||||||
like the following and setting it as the provider client's HTTP Client (via the
|
|
||||||
`gophercloud.ProviderClient.HTTPClient` field):
|
|
||||||
|
|
||||||
```go
|
|
||||||
//...
|
|
||||||
|
|
||||||
// LogRoundTripper satisfies the http.RoundTripper interface and is used to
|
|
||||||
// customize the default Gophercloud RoundTripper to allow for logging.
|
|
||||||
type LogRoundTripper struct {
|
|
||||||
rt http.RoundTripper
|
|
||||||
numReauthAttempts int
|
|
||||||
}
|
|
||||||
|
|
||||||
// newHTTPClient return a custom HTTP client that allows for logging relevant
|
|
||||||
// information before and after the HTTP request.
|
|
||||||
func newHTTPClient() http.Client {
|
|
||||||
return http.Client{
|
|
||||||
Transport: &LogRoundTripper{
|
|
||||||
rt: http.DefaultTransport,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RoundTrip performs a round-trip HTTP request and logs relevant information about it.
|
|
||||||
func (lrt *LogRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
|
|
||||||
glog.Infof("Request URL: %s\n", request.URL)
|
|
||||||
|
|
||||||
response, err := lrt.rt.RoundTrip(request)
|
|
||||||
if response == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if response.StatusCode == http.StatusUnauthorized {
|
|
||||||
if lrt.numReauthAttempts == 3 {
|
|
||||||
return response, fmt.Errorf("Tried to re-authenticate 3 times with no success.")
|
|
||||||
}
|
|
||||||
lrt.numReauthAttempts++
|
|
||||||
}
|
|
||||||
|
|
||||||
glog.Debugf("Response Status: %s\n", response.Status)
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
endpoint := "https://127.0.0.1/auth"
|
|
||||||
pc := openstack.NewClient(endpoint)
|
|
||||||
pc.HTTPClient = newHTTPClient()
|
|
||||||
|
|
||||||
//...
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Implementing custom objects
|
|
||||||
|
|
||||||
OpenStack request/response objects may differ among variable names or types.
|
|
||||||
|
|
||||||
### Custom request objects
|
|
||||||
|
|
||||||
To pass custom options to a request, implement the desired `<ACTION>OptsBuilder` interface. For
|
|
||||||
example, to pass in
|
|
||||||
|
|
||||||
```go
|
|
||||||
type MyCreateServerOpts struct {
|
|
||||||
Name string
|
|
||||||
Size int
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
to `servers.Create`, simply implement the `servers.CreateOptsBuilder` interface:
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (o MyCreateServeropts) ToServerCreateMap() (map[string]interface{}, error) {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"name": o.Name,
|
|
||||||
"size": o.Size,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
create an instance of your custom options object, and pass it to `servers.Create`:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// ...
|
|
||||||
myOpts := MyCreateServerOpts{
|
|
||||||
Name: "s1",
|
|
||||||
Size: "100",
|
|
||||||
}
|
|
||||||
server, err := servers.Create(computeClient, myOpts).Extract()
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom response objects
|
|
||||||
|
|
||||||
Some OpenStack services have extensions. Extensions that are supported in Gophercloud can be
|
|
||||||
combined to create a custom object:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// ...
|
|
||||||
type MyVolume struct {
|
|
||||||
volumes.Volume
|
|
||||||
tenantattr.VolumeExt
|
|
||||||
}
|
|
||||||
|
|
||||||
var v struct {
|
|
||||||
MyVolume `json:"volume"`
|
|
||||||
}
|
|
||||||
|
|
||||||
err := volumes.Get(client, volID).ExtractInto(&v)
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Overriding default `UnmarshalJSON` method
|
|
||||||
|
|
||||||
For some response objects, a field may be a custom type or may be allowed to take on
|
|
||||||
different types. In these cases, overriding the default `UnmarshalJSON` method may be
|
|
||||||
necessary. To do this, declare the JSON `struct` field tag as "-" and create an `UnmarshalJSON`
|
|
||||||
method on the type:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// ...
|
|
||||||
type MyVolume struct {
|
|
||||||
ID string `json: "id"`
|
|
||||||
TimeCreated time.Time `json: "-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *MyVolume) UnmarshalJSON(b []byte) error {
|
|
||||||
type tmp MyVolume
|
|
||||||
var s struct {
|
|
||||||
tmp
|
|
||||||
TimeCreated gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
|
||||||
}
|
|
||||||
err := json.Unmarshal(b, &s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*r = Volume(s.tmp)
|
|
||||||
|
|
||||||
r.TimeCreated = time.Time(s.CreatedAt)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// ...
|
|
||||||
```
|
|
|
@ -1,32 +0,0 @@
|
||||||
# Compute
|
|
||||||
|
|
||||||
## Floating IPs
|
|
||||||
|
|
||||||
* `github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingip` is now `github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips`
|
|
||||||
* `floatingips.Associate` and `floatingips.Disassociate` have been removed.
|
|
||||||
* `floatingips.DisassociateOpts` is now required to disassociate a Floating IP.
|
|
||||||
|
|
||||||
## Security Groups
|
|
||||||
|
|
||||||
* `secgroups.AddServerToGroup` is now `secgroups.AddServer`.
|
|
||||||
* `secgroups.RemoveServerFromGroup` is now `secgroups.RemoveServer`.
|
|
||||||
|
|
||||||
## Servers
|
|
||||||
|
|
||||||
* `servers.Reboot` now requires a `servers.RebootOpts` struct:
|
|
||||||
|
|
||||||
```golang
|
|
||||||
rebootOpts := &servers.RebootOpts{
|
|
||||||
Type: servers.SoftReboot,
|
|
||||||
}
|
|
||||||
res := servers.Reboot(client, server.ID, rebootOpts)
|
|
||||||
```
|
|
||||||
|
|
||||||
# Identity
|
|
||||||
|
|
||||||
## V3
|
|
||||||
|
|
||||||
### Tokens
|
|
||||||
|
|
||||||
* `Token.ExpiresAt` is now of type `gophercloud.JSONRFC3339Milli` instead of
|
|
||||||
`time.Time`
|
|
|
@ -127,7 +127,7 @@ new resource in the `server` variable (a
|
||||||
|
|
||||||
## Advanced Usage
|
## Advanced Usage
|
||||||
|
|
||||||
Have a look at the [FAQ](./FAQ.md) for some tips on customizing the way Gophercloud works.
|
Have a look at the [FAQ](./docs/FAQ.md) for some tips on customizing the way Gophercloud works.
|
||||||
|
|
||||||
## Backwards-Compatibility Guarantees
|
## Backwards-Compatibility Guarantees
|
||||||
|
|
||||||
|
@ -140,4 +140,20 @@ See the [contributing guide](./.github/CONTRIBUTING.md).
|
||||||
## Help and feedback
|
## Help and feedback
|
||||||
|
|
||||||
If you're struggling with something or have spotted a potential bug, feel free
|
If you're struggling with something or have spotted a potential bug, feel free
|
||||||
to submit an issue to our [bug tracker](/issues).
|
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.
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
|
|
||||||
## On Pull Requests
|
|
||||||
|
|
||||||
- Before you start a PR there needs to be a Github issue and a discussion about it
|
|
||||||
on that issue with a core contributor, even if it's just a 'SGTM'.
|
|
||||||
|
|
||||||
- A PR's description must reference the issue it closes with a `For <ISSUE NUMBER>` (e.g. For #293).
|
|
||||||
|
|
||||||
- A PR's description must contain link(s) to the line(s) in the OpenStack
|
|
||||||
source code (on Github) that prove(s) the PR code to be valid. Links to documentation
|
|
||||||
are not good enough. The link(s) should be to a non-`master` branch. For example,
|
|
||||||
a pull request implementing the creation of a Neutron v2 subnet might put the
|
|
||||||
following link in the description:
|
|
||||||
|
|
||||||
https://github.com/openstack/neutron/blob/stable/mitaka/neutron/api/v2/attributes.py#L749
|
|
||||||
|
|
||||||
From that link, a reviewer (or user) can verify the fields in the request/response
|
|
||||||
objects in the PR.
|
|
||||||
|
|
||||||
- A PR that is in-progress should have `[wip]` in front of the PR's title. When
|
|
||||||
ready for review, remove the `[wip]` and ping a core contributor with an `@`.
|
|
||||||
|
|
||||||
- Forcing PRs to be small can have the effect of users submitting PRs in a hierarchical chain, with
|
|
||||||
one depending on the next. If a PR depends on another one, it should have a [Pending #PRNUM]
|
|
||||||
prefix in the PR title. In addition, it will be the PR submitter's responsibility to remove the
|
|
||||||
[Pending #PRNUM] tag once the PR has been updated with the merged, dependent PR. That will
|
|
||||||
let reviewers know it is ready to review.
|
|
||||||
|
|
||||||
- A PR should be small. Even if you intend on implementing an entire
|
|
||||||
service, a PR should only be one route of that service
|
|
||||||
(e.g. create server or get server, but not both).
|
|
||||||
|
|
||||||
- Unless explicitly asked, do not squash commits in the middle of a review; only
|
|
||||||
append. It makes it difficult for the reviewer to see what's changed from one
|
|
||||||
review to the next.
|
|
||||||
|
|
||||||
## On Code
|
|
||||||
|
|
||||||
- In re design: follow as closely as is reasonable the code already in the library.
|
|
||||||
Most operations (e.g. create, delete) admit the same design.
|
|
||||||
|
|
||||||
- Unit tests and acceptance (integration) tests must be written to cover each PR.
|
|
||||||
Tests for operations with several options (e.g. list, create) should include all
|
|
||||||
the options in the tests. This will allow users to verify an operation on their
|
|
||||||
own infrastructure and see an example of usage.
|
|
||||||
|
|
||||||
- If in doubt, ask in-line on the PR.
|
|
||||||
|
|
||||||
### File Structure
|
|
||||||
|
|
||||||
- The following should be used in most cases:
|
|
||||||
|
|
||||||
- `requests.go`: contains all the functions that make HTTP requests and the
|
|
||||||
types associated with the HTTP request (parameters for URL, body, etc)
|
|
||||||
- `results.go`: contains all the response objects and their methods
|
|
||||||
- `urls.go`: contains the endpoints to which the requests are made
|
|
||||||
|
|
||||||
### Naming
|
|
||||||
|
|
||||||
- For methods on a type in `response.go`, the receiver should be named `r` and the
|
|
||||||
variable into which it will be unmarshalled `s`.
|
|
||||||
|
|
||||||
- Functions in `requests.go`, with the exception of functions that return a
|
|
||||||
`pagination.Pager`, should be named returns of the name `r`.
|
|
||||||
|
|
||||||
- Functions in `requests.go` that accept request bodies should accept as their
|
|
||||||
last parameter an `interface` named `<Action>OptsBuilder` (eg `CreateOptsBuilder`).
|
|
||||||
This `interface` should have at the least a method named `To<Resource><Action>Map`
|
|
||||||
(eg `ToPortCreateMap`).
|
|
||||||
|
|
||||||
- Functions in `requests.go` that accept query strings should accept as their
|
|
||||||
last parameter an `interface` named `<Action>OptsBuilder` (eg `ListOptsBuilder`).
|
|
||||||
This `interface` should have at the least a method named `To<Resource><Action>Query`
|
|
||||||
(eg `ToServerListQuery`).
|
|
|
@ -9,25 +9,45 @@ ProviderClient representing an active session on that provider.
|
||||||
|
|
||||||
Its fields are the union of those recognized by each identity implementation and
|
Its fields are the union of those recognized by each identity implementation and
|
||||||
provider.
|
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 {
|
type AuthOptions struct {
|
||||||
// IdentityEndpoint specifies the HTTP endpoint that is required to work with
|
// IdentityEndpoint specifies the HTTP endpoint that is required to work with
|
||||||
// the Identity API of the appropriate version. While it's ultimately needed by
|
// 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
|
// all of the identity services, it will often be populated by a provider-level
|
||||||
// function.
|
// 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:"-"`
|
IdentityEndpoint string `json:"-"`
|
||||||
|
|
||||||
// Username is required if using Identity V2 API. Consult with your provider's
|
// 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
|
// control panel to discover your account's username. In Identity V3, either
|
||||||
// UserID or a combination of Username and DomainID or DomainName are needed.
|
// UserID or a combination of Username and DomainID or DomainName are needed.
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
UserID string `json:"id,omitempty"`
|
UserID string `json:"-"`
|
||||||
|
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
|
|
||||||
// At most one of DomainID and DomainName must be provided if using Username
|
// At most one of DomainID and DomainName must be provided if using Username
|
||||||
// with Identity V3. Otherwise, either are optional.
|
// with Identity V3. Otherwise, either are optional.
|
||||||
DomainID string `json:"id,omitempty"`
|
DomainID string `json:"-"`
|
||||||
DomainName string `json:"name,omitempty"`
|
DomainName string `json:"name,omitempty"`
|
||||||
|
|
||||||
// The TenantID and TenantName fields are optional for the Identity V2 API.
|
// The TenantID and TenantName fields are optional for the Identity V2 API.
|
||||||
|
@ -39,7 +59,7 @@ type AuthOptions struct {
|
||||||
// If DomainID or DomainName are provided, they will also apply to TenantName.
|
// If DomainID or DomainName are provided, they will also apply to TenantName.
|
||||||
// It is not currently possible to authenticate with Username and a Domain
|
// 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
|
// and scope to a Project in a different Domain by using TenantName. To
|
||||||
// accomplish that, the ProjectID will need to be provided to the TenantID
|
// accomplish that, the ProjectID will need to be provided as the TenantID
|
||||||
// option.
|
// option.
|
||||||
TenantID string `json:"tenantId,omitempty"`
|
TenantID string `json:"tenantId,omitempty"`
|
||||||
TenantName string `json:"tenantName,omitempty"`
|
TenantName string `json:"tenantName,omitempty"`
|
||||||
|
@ -50,15 +70,34 @@ type AuthOptions struct {
|
||||||
// false, it will not cache these settings, but re-authentication will not be
|
// false, it will not cache these settings, but re-authentication will not be
|
||||||
// possible. This setting defaults to false.
|
// possible. This setting defaults to false.
|
||||||
//
|
//
|
||||||
// NOTE: The reauth function will try to re-authenticate endlessly if left unchecked.
|
// NOTE: The reauth function will try to re-authenticate endlessly if left
|
||||||
// The way to limit the number of attempts is to provide a custom HTTP client to the provider client
|
// unchecked. The way to limit the number of attempts is to provide a custom
|
||||||
// and provide a transport that implements the RoundTripper interface and stores the number of failed retries.
|
// HTTP client to the provider client and provide a transport that implements
|
||||||
// For an example of this, see here: https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311
|
// 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:"-"`
|
AllowReauth bool `json:"-"`
|
||||||
|
|
||||||
// TokenID allows users to authenticate (possibly as another user) with an
|
// TokenID allows users to authenticate (possibly as another user) with an
|
||||||
// authentication token ID.
|
// authentication token ID.
|
||||||
TokenID string `json:"-"`
|
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
|
// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
|
||||||
|
@ -109,7 +148,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
type userReq struct {
|
type userReq struct {
|
||||||
ID *string `json:"id,omitempty"`
|
ID *string `json:"id,omitempty"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password,omitempty"`
|
||||||
Domain *domainReq `json:"domain,omitempty"`
|
Domain *domainReq `json:"domain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,10 +160,18 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
ID string `json:"id"`
|
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 {
|
type identityReq struct {
|
||||||
Methods []string `json:"methods"`
|
Methods []string `json:"methods"`
|
||||||
Password *passwordReq `json:"password,omitempty"`
|
Password *passwordReq `json:"password,omitempty"`
|
||||||
Token *tokenReq `json:"token,omitempty"`
|
Token *tokenReq `json:"token,omitempty"`
|
||||||
|
ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type authReq struct {
|
type authReq struct {
|
||||||
|
@ -161,8 +208,68 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
req.Auth.Identity.Token = &tokenReq{
|
req.Auth.Identity.Token = &tokenReq{
|
||||||
ID: opts.TokenID,
|
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 {
|
} else {
|
||||||
// If no password or token ID are available, authentication can't continue.
|
// If no password or token ID or ApplicationCredential are available, authentication can't continue.
|
||||||
return nil, ErrMissingPassword{}
|
return nil, ErrMissingPassword{}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -241,82 +348,85 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||||
|
// For backwards compatibility.
|
||||||
var scope struct {
|
// If AuthOptions.Scope was not set, try to determine it.
|
||||||
ProjectID string
|
// This works well for common scenarios.
|
||||||
ProjectName string
|
if opts.Scope == nil {
|
||||||
DomainID string
|
opts.Scope = new(AuthScope)
|
||||||
DomainName string
|
if opts.TenantID != "" {
|
||||||
}
|
opts.Scope.ProjectID = opts.TenantID
|
||||||
|
} else {
|
||||||
if opts.TenantID != "" {
|
if opts.TenantName != "" {
|
||||||
scope.ProjectID = opts.TenantID
|
opts.Scope.ProjectName = opts.TenantName
|
||||||
} else {
|
opts.Scope.DomainID = opts.DomainID
|
||||||
if opts.TenantName != "" {
|
opts.Scope.DomainName = opts.DomainName
|
||||||
scope.ProjectName = opts.TenantName
|
}
|
||||||
scope.DomainID = opts.DomainID
|
|
||||||
scope.DomainName = opts.DomainName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.ProjectName != "" {
|
if opts.Scope.ProjectName != "" {
|
||||||
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
||||||
// ProjectID may not be supplied.
|
// ProjectID may not be supplied.
|
||||||
if scope.DomainID == "" && scope.DomainName == "" {
|
if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" {
|
||||||
return nil, ErrScopeDomainIDOrDomainName{}
|
return nil, ErrScopeDomainIDOrDomainName{}
|
||||||
}
|
}
|
||||||
if scope.ProjectID != "" {
|
if opts.Scope.ProjectID != "" {
|
||||||
return nil, ErrScopeProjectIDOrProjectName{}
|
return nil, ErrScopeProjectIDOrProjectName{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.DomainID != "" {
|
if opts.Scope.DomainID != "" {
|
||||||
// ProjectName + DomainID
|
// ProjectName + DomainID
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"project": map[string]interface{}{
|
"project": map[string]interface{}{
|
||||||
"name": &scope.ProjectName,
|
"name": &opts.Scope.ProjectName,
|
||||||
"domain": map[string]interface{}{"id": &scope.DomainID},
|
"domain": map[string]interface{}{"id": &opts.Scope.DomainID},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.DomainName != "" {
|
if opts.Scope.DomainName != "" {
|
||||||
// ProjectName + DomainName
|
// ProjectName + DomainName
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"project": map[string]interface{}{
|
"project": map[string]interface{}{
|
||||||
"name": &scope.ProjectName,
|
"name": &opts.Scope.ProjectName,
|
||||||
"domain": map[string]interface{}{"name": &scope.DomainName},
|
"domain": map[string]interface{}{"name": &opts.Scope.DomainName},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
} else if scope.ProjectID != "" {
|
} else if opts.Scope.ProjectID != "" {
|
||||||
// ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
|
// ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
|
||||||
if scope.DomainID != "" {
|
if opts.Scope.DomainID != "" {
|
||||||
return nil, ErrScopeProjectIDAlone{}
|
return nil, ErrScopeProjectIDAlone{}
|
||||||
}
|
}
|
||||||
if scope.DomainName != "" {
|
if opts.Scope.DomainName != "" {
|
||||||
return nil, ErrScopeProjectIDAlone{}
|
return nil, ErrScopeProjectIDAlone{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProjectID
|
// ProjectID
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"project": map[string]interface{}{
|
"project": map[string]interface{}{
|
||||||
"id": &scope.ProjectID,
|
"id": &opts.Scope.ProjectID,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
} else if scope.DomainID != "" {
|
} else if opts.Scope.DomainID != "" {
|
||||||
// DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
|
// DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
|
||||||
if scope.DomainName != "" {
|
if opts.Scope.DomainName != "" {
|
||||||
return nil, ErrScopeDomainIDOrDomainName{}
|
return nil, ErrScopeDomainIDOrDomainName{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DomainID
|
// DomainID
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"domain": map[string]interface{}{
|
"domain": map[string]interface{}{
|
||||||
"id": &scope.DomainID,
|
"id": &opts.Scope.DomainID,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
} else if opts.Scope.DomainName != "" {
|
||||||
|
// DomainName
|
||||||
|
return map[string]interface{}{
|
||||||
|
"domain": map[string]interface{}{
|
||||||
|
"name": &opts.Scope.DomainName,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
} else if scope.DomainName != "" {
|
|
||||||
return nil, ErrScopeDomainName{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
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)
|
||||||
|
}
|
|
@ -3,11 +3,17 @@ Package gophercloud provides a multi-vendor interface to OpenStack-compatible
|
||||||
clouds. The library has a three-level hierarchy: providers, services, and
|
clouds. The library has a three-level hierarchy: providers, services, and
|
||||||
resources.
|
resources.
|
||||||
|
|
||||||
Provider structs represent the service providers that offer and manage a
|
Authenticating with Providers
|
||||||
collection of services. The IdentityEndpoint is typically refered to as
|
|
||||||
"auth_url" in information provided by the cloud operator. Additionally,
|
Provider structs represent the cloud providers that offer and manage a
|
||||||
the cloud may refer to TenantID or TenantName as project_id and project_name.
|
collection of services. You will generally want to create one Provider
|
||||||
These are defined like so:
|
client per OpenStack cloud.
|
||||||
|
|
||||||
|
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{
|
opts := gophercloud.AuthOptions{
|
||||||
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
||||||
|
@ -18,6 +24,16 @@ These are defined like so:
|
||||||
|
|
||||||
provider, err := openstack.AuthenticatedClient(opts)
|
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
|
Service structs are specific to a provider and handle all of the logic and
|
||||||
operations for a particular OpenStack service. Examples of services include:
|
operations for a particular OpenStack service. Examples of services include:
|
||||||
Compute, Object Storage, Block Storage. In order to define one, you need to
|
Compute, Object Storage, Block Storage. In order to define one, you need to
|
||||||
|
@ -25,7 +41,9 @@ pass in the parent provider, like so:
|
||||||
|
|
||||||
opts := gophercloud.EndpointOpts{Region: "RegionOne"}
|
opts := gophercloud.EndpointOpts{Region: "RegionOne"}
|
||||||
|
|
||||||
client := openstack.NewComputeV2(provider, opts)
|
client, err := openstack.NewComputeV2(provider, opts)
|
||||||
|
|
||||||
|
Resources
|
||||||
|
|
||||||
Resource structs are the domain models that services make use of in order
|
Resource structs are the domain models that services make use of in order
|
||||||
to work with and represent the state of API resources:
|
to work with and represent the state of API resources:
|
||||||
|
@ -62,6 +80,12 @@ of results:
|
||||||
return true, nil
|
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
|
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
|
throughout the provider and service packages. Of particular note for end users
|
||||||
are the AuthOptions and EndpointOpts structs.
|
are the AuthOptions and EndpointOpts structs.
|
||||||
|
|
|
@ -27,7 +27,7 @@ const (
|
||||||
// unambiguously identify one, and only one, endpoint within the catalog.
|
// unambiguously identify one, and only one, endpoint within the catalog.
|
||||||
//
|
//
|
||||||
// Usually, these are passed to service client factory functions in a provider
|
// Usually, these are passed to service client factory functions in a provider
|
||||||
// package, like "rackspace.NewComputeV2()".
|
// package, like "openstack.NewComputeV2()".
|
||||||
type EndpointOpts struct {
|
type EndpointOpts struct {
|
||||||
// Type [required] is the service type for the client (e.g., "compute",
|
// Type [required] is the service type for the client (e.g., "compute",
|
||||||
// "object-store"). Generally, this will be supplied by the service client
|
// "object-store"). Generally, this will be supplied by the service client
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package gophercloud
|
package gophercloud
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// BaseError is an error type that all other error types embed.
|
// BaseError is an error type that all other error types embed.
|
||||||
type BaseError struct {
|
type BaseError struct {
|
||||||
|
@ -43,6 +46,33 @@ func (e ErrInvalidInput) Error() string {
|
||||||
return e.choseErrString()
|
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
|
// ErrUnexpectedResponseCode is returned by the Request method when a response code other than
|
||||||
// those listed in OkCodes is encountered.
|
// those listed in OkCodes is encountered.
|
||||||
type ErrUnexpectedResponseCode struct {
|
type ErrUnexpectedResponseCode struct {
|
||||||
|
@ -72,6 +102,11 @@ type ErrDefault401 struct {
|
||||||
ErrUnexpectedResponseCode
|
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.
|
// ErrDefault404 is the default error type returned on a 404 HTTP response code.
|
||||||
type ErrDefault404 struct {
|
type ErrDefault404 struct {
|
||||||
ErrUnexpectedResponseCode
|
ErrUnexpectedResponseCode
|
||||||
|
@ -103,11 +138,22 @@ type ErrDefault503 struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e ErrDefault400) Error() string {
|
func (e ErrDefault400) Error() string {
|
||||||
return "Invalid request due to incorrect syntax or missing required parameters."
|
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 {
|
func (e ErrDefault401) Error() string {
|
||||||
return "Authentication failed"
|
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 {
|
func (e ErrDefault404) Error() string {
|
||||||
return "Resource not found"
|
return "Resource not found"
|
||||||
}
|
}
|
||||||
|
@ -141,6 +187,12 @@ type Err401er interface {
|
||||||
Error401(ErrUnexpectedResponseCode) error
|
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
|
// Err404er is the interface resource error types implement to override the error message
|
||||||
// from a 404 error.
|
// from a 404 error.
|
||||||
type Err404er interface {
|
type Err404er interface {
|
||||||
|
@ -393,16 +445,16 @@ func (e ErrScopeProjectIDAlone) Error() string {
|
||||||
return "ProjectID must be supplied alone in a Scope"
|
return "ProjectID must be supplied alone in a Scope"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrScopeDomainName indicates that a DomainName was provided alone in a Scope.
|
|
||||||
type ErrScopeDomainName struct{ BaseError }
|
|
||||||
|
|
||||||
func (e ErrScopeDomainName) Error() string {
|
|
||||||
return "DomainName must be supplied with a ProjectName or ProjectID in a Scope"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrScopeEmpty indicates that no credentials were provided in a Scope.
|
// ErrScopeEmpty indicates that no credentials were provided in a Scope.
|
||||||
type ErrScopeEmpty struct{ BaseError }
|
type ErrScopeEmpty struct{ BaseError }
|
||||||
|
|
||||||
func (e ErrScopeEmpty) Error() string {
|
func (e ErrScopeEmpty) Error() string {
|
||||||
return "You must provide either a Project or Domain in a Scope"
|
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"
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
package internal
|
|
@ -0,0 +1,34 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemainingKeys will inspect a struct and compare it to a map. Any struct
|
||||||
|
// field that does not have a JSON tag that matches a key in the map or
|
||||||
|
// a matching lower-case field in the map will be returned as an extra.
|
||||||
|
//
|
||||||
|
// This is useful for determining the extra fields returned in response bodies
|
||||||
|
// for resources that can contain an arbitrary or dynamic number of fields.
|
||||||
|
func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) {
|
||||||
|
extras = make(map[string]interface{})
|
||||||
|
for k, v := range m {
|
||||||
|
extras[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
valueOf := reflect.ValueOf(s)
|
||||||
|
typeOf := reflect.TypeOf(s)
|
||||||
|
for i := 0; i < valueOf.NumField(); i++ {
|
||||||
|
field := typeOf.Field(i)
|
||||||
|
|
||||||
|
lowerField := strings.ToLower(field.Name)
|
||||||
|
delete(extras, lowerField)
|
||||||
|
|
||||||
|
if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" {
|
||||||
|
delete(extras, tagValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -8,10 +8,27 @@ import (
|
||||||
|
|
||||||
var nilOptions = gophercloud.AuthOptions{}
|
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,
|
AuthOptionsFromEnv fills out an identity.AuthOptions structure with the
|
||||||
// OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME. Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must
|
settings found on the various OpenStack OS_* environment variables.
|
||||||
// have settings, or an error will result. OS_TENANT_ID and OS_TENANT_NAME are optional.
|
|
||||||
|
The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME,
|
||||||
|
OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME.
|
||||||
|
|
||||||
|
Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must have settings,
|
||||||
|
or an error will result. OS_TENANT_ID, OS_TENANT_NAME, OS_PROJECT_ID, and
|
||||||
|
OS_PROJECT_NAME are optional.
|
||||||
|
|
||||||
|
OS_TENANT_ID and OS_TENANT_NAME are mutually exclusive to OS_PROJECT_ID and
|
||||||
|
OS_PROJECT_NAME. If OS_PROJECT_ID and OS_PROJECT_NAME are set, they will
|
||||||
|
still be referred as "tenant" in Gophercloud.
|
||||||
|
|
||||||
|
To use this function, first set the OS_* environment variables (for example,
|
||||||
|
by sourcing an `openrc` file), then:
|
||||||
|
|
||||||
|
opts, err := openstack.AuthOptionsFromEnv()
|
||||||
|
provider, err := openstack.AuthenticatedClient(opts)
|
||||||
|
*/
|
||||||
func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
||||||
authURL := os.Getenv("OS_AUTH_URL")
|
authURL := os.Getenv("OS_AUTH_URL")
|
||||||
username := os.Getenv("OS_USERNAME")
|
username := os.Getenv("OS_USERNAME")
|
||||||
|
@ -21,31 +38,76 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
|
||||||
tenantName := os.Getenv("OS_TENANT_NAME")
|
tenantName := os.Getenv("OS_TENANT_NAME")
|
||||||
domainID := os.Getenv("OS_DOMAIN_ID")
|
domainID := os.Getenv("OS_DOMAIN_ID")
|
||||||
domainName := os.Getenv("OS_DOMAIN_NAME")
|
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 == "" {
|
if authURL == "" {
|
||||||
err := gophercloud.ErrMissingInput{Argument: "authURL"}
|
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||||
|
EnvironmentVariable: "OS_AUTH_URL",
|
||||||
|
}
|
||||||
return nilOptions, err
|
return nilOptions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if username == "" && userID == "" {
|
if userID == "" && username == "" {
|
||||||
err := gophercloud.ErrMissingInput{Argument: "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
|
return nilOptions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if password == "" {
|
if (applicationCredentialID != "" || applicationCredentialName != "") && applicationCredentialSecret == "" {
|
||||||
err := gophercloud.ErrMissingInput{Argument: "password"}
|
err := gophercloud.ErrMissingEnvironmentVariable{
|
||||||
|
EnvironmentVariable: "OS_APPLICATION_CREDENTIAL_SECRET",
|
||||||
|
}
|
||||||
return nilOptions, err
|
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{
|
ao := gophercloud.AuthOptions{
|
||||||
IdentityEndpoint: authURL,
|
IdentityEndpoint: authURL,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
TenantID: tenantID,
|
TenantID: tenantID,
|
||||||
TenantName: tenantName,
|
TenantName: tenantName,
|
||||||
DomainID: domainID,
|
DomainID: domainID,
|
||||||
DomainName: domainName,
|
DomainName: domainName,
|
||||||
|
ApplicationCredentialID: applicationCredentialID,
|
||||||
|
ApplicationCredentialName: applicationCredentialName,
|
||||||
|
ApplicationCredentialSecret: applicationCredentialSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ao, nil
|
return ao, nil
|
||||||
|
|
|
@ -1,5 +1,86 @@
|
||||||
// Package volumeactions provides information and interaction with volumes in the
|
/*
|
||||||
// OpenStack Block Storage service. A volume is a detachable block storage
|
Package volumeactions provides information and interaction with volumes in the
|
||||||
// device, akin to a USB hard drive. It can only be attached to one instance at
|
OpenStack Block Storage service. A volume is a detachable block storage
|
||||||
// a time.
|
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
|
package volumeactions
|
||||||
|
|
|
@ -13,7 +13,7 @@ type AttachOptsBuilder interface {
|
||||||
// AttachMode describes the attachment mode for volumes.
|
// AttachMode describes the attachment mode for volumes.
|
||||||
type AttachMode string
|
type AttachMode string
|
||||||
|
|
||||||
// These constants determine how a volume is attached
|
// These constants determine how a volume is attached.
|
||||||
const (
|
const (
|
||||||
ReadOnly AttachMode = "ro"
|
ReadOnly AttachMode = "ro"
|
||||||
ReadWrite AttachMode = "rw"
|
ReadWrite AttachMode = "rw"
|
||||||
|
@ -21,13 +21,16 @@ const (
|
||||||
|
|
||||||
// AttachOpts contains options for attaching a Volume.
|
// AttachOpts contains options for attaching a Volume.
|
||||||
type AttachOpts struct {
|
type AttachOpts struct {
|
||||||
// The mountpoint of this volume
|
// The mountpoint of this volume.
|
||||||
MountPoint string `json:"mountpoint,omitempty"`
|
MountPoint string `json:"mountpoint,omitempty"`
|
||||||
// The nova instance ID, can't set simultaneously with HostName
|
|
||||||
|
// The nova instance ID, can't set simultaneously with HostName.
|
||||||
InstanceUUID string `json:"instance_uuid,omitempty"`
|
InstanceUUID string `json:"instance_uuid,omitempty"`
|
||||||
// The hostname of baremetal host, can't set simultaneously with InstanceUUID
|
|
||||||
|
// The hostname of baremetal host, can't set simultaneously with InstanceUUID.
|
||||||
HostName string `json:"host_name,omitempty"`
|
HostName string `json:"host_name,omitempty"`
|
||||||
// Mount mode of this volume
|
|
||||||
|
// Mount mode of this volume.
|
||||||
Mode AttachMode `json:"mode,omitempty"`
|
Mode AttachMode `json:"mode,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,16 +47,16 @@ func Attach(client *gophercloud.ServiceClient, id string, opts AttachOptsBuilder
|
||||||
r.Err = err
|
r.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, r.Err = client.Post(attachURL(client, id), b, nil, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{202},
|
OkCodes: []int{202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeginDetach will mark the volume as detaching
|
// BeginDetach will mark the volume as detaching.
|
||||||
func BeginDetaching(client *gophercloud.ServiceClient, id string) (r BeginDetachingResult) {
|
func BeginDetaching(client *gophercloud.ServiceClient, id string) (r BeginDetachingResult) {
|
||||||
b := map[string]interface{}{"os-begin_detaching": make(map[string]interface{})}
|
b := map[string]interface{}{"os-begin_detaching": make(map[string]interface{})}
|
||||||
_, r.Err = client.Post(beginDetachingURL(client, id), b, nil, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{202},
|
OkCodes: []int{202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -65,7 +68,9 @@ type DetachOptsBuilder interface {
|
||||||
ToVolumeDetachMap() (map[string]interface{}, error)
|
ToVolumeDetachMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DetachOpts contains options for detaching a Volume.
|
||||||
type DetachOpts struct {
|
type DetachOpts struct {
|
||||||
|
// AttachmentID is the ID of the attachment between a volume and instance.
|
||||||
AttachmentID string `json:"attachment_id,omitempty"`
|
AttachmentID string `json:"attachment_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,32 +80,32 @@ func (opts DetachOpts) ToVolumeDetachMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "os-detach")
|
return gophercloud.BuildRequestBody(opts, "os-detach")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach will detach a volume based on volume id.
|
// Detach will detach a volume based on volume ID.
|
||||||
func Detach(client *gophercloud.ServiceClient, id string, opts DetachOptsBuilder) (r DetachResult) {
|
func Detach(client *gophercloud.ServiceClient, id string, opts DetachOptsBuilder) (r DetachResult) {
|
||||||
b, err := opts.ToVolumeDetachMap()
|
b, err := opts.ToVolumeDetachMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Err = err
|
r.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, r.Err = client.Post(detachURL(client, id), b, nil, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{202},
|
OkCodes: []int{202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve will reserve a volume based on volume id.
|
// Reserve will reserve a volume based on volume ID.
|
||||||
func Reserve(client *gophercloud.ServiceClient, id string) (r ReserveResult) {
|
func Reserve(client *gophercloud.ServiceClient, id string) (r ReserveResult) {
|
||||||
b := map[string]interface{}{"os-reserve": make(map[string]interface{})}
|
b := map[string]interface{}{"os-reserve": make(map[string]interface{})}
|
||||||
_, r.Err = client.Post(reserveURL(client, id), b, nil, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{200, 201, 202},
|
OkCodes: []int{200, 201, 202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unreserve will unreserve a volume based on volume id.
|
// Unreserve will unreserve a volume based on volume ID.
|
||||||
func Unreserve(client *gophercloud.ServiceClient, id string) (r UnreserveResult) {
|
func Unreserve(client *gophercloud.ServiceClient, id string) (r UnreserveResult) {
|
||||||
b := map[string]interface{}{"os-unreserve": make(map[string]interface{})}
|
b := map[string]interface{}{"os-unreserve": make(map[string]interface{})}
|
||||||
_, r.Err = client.Post(unreserveURL(client, id), b, nil, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{200, 201, 202},
|
OkCodes: []int{200, 201, 202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -113,6 +118,8 @@ type InitializeConnectionOptsBuilder interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitializeConnectionOpts hosts options for InitializeConnection.
|
// InitializeConnectionOpts hosts options for InitializeConnection.
|
||||||
|
// The fields are specific to the storage driver in use and the destination
|
||||||
|
// attachment.
|
||||||
type InitializeConnectionOpts struct {
|
type InitializeConnectionOpts struct {
|
||||||
IP string `json:"ip,omitempty"`
|
IP string `json:"ip,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
|
@ -131,14 +138,14 @@ func (opts InitializeConnectionOpts) ToVolumeInitializeConnectionMap() (map[stri
|
||||||
return map[string]interface{}{"os-initialize_connection": b}, err
|
return map[string]interface{}{"os-initialize_connection": b}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitializeConnection initializes iscsi connection.
|
// InitializeConnection initializes an iSCSI connection by volume ID.
|
||||||
func InitializeConnection(client *gophercloud.ServiceClient, id string, opts InitializeConnectionOptsBuilder) (r InitializeConnectionResult) {
|
func InitializeConnection(client *gophercloud.ServiceClient, id string, opts InitializeConnectionOptsBuilder) (r InitializeConnectionResult) {
|
||||||
b, err := opts.ToVolumeInitializeConnectionMap()
|
b, err := opts.ToVolumeInitializeConnectionMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Err = err
|
r.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, r.Err = client.Post(initializeConnectionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{200, 201, 202},
|
OkCodes: []int{200, 201, 202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -169,14 +176,14 @@ func (opts TerminateConnectionOpts) ToVolumeTerminateConnectionMap() (map[string
|
||||||
return map[string]interface{}{"os-terminate_connection": b}, err
|
return map[string]interface{}{"os-terminate_connection": b}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TerminateConnection terminates iscsi connection.
|
// TerminateConnection terminates an iSCSI connection by volume ID.
|
||||||
func TerminateConnection(client *gophercloud.ServiceClient, id string, opts TerminateConnectionOptsBuilder) (r TerminateConnectionResult) {
|
func TerminateConnection(client *gophercloud.ServiceClient, id string, opts TerminateConnectionOptsBuilder) (r TerminateConnectionResult) {
|
||||||
b, err := opts.ToVolumeTerminateConnectionMap()
|
b, err := opts.ToVolumeTerminateConnectionMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Err = err
|
r.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, r.Err = client.Post(teminateConnectionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{202},
|
OkCodes: []int{202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -188,10 +195,10 @@ type ExtendSizeOptsBuilder interface {
|
||||||
ToVolumeExtendSizeMap() (map[string]interface{}, error)
|
ToVolumeExtendSizeMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtendSizeOpts contain options for extending the size of an existing Volume. This object is passed
|
// ExtendSizeOpts contains options for extending the size of an existing Volume.
|
||||||
// to the volumes.ExtendSize function.
|
// This object is passed to the volumes.ExtendSize function.
|
||||||
type ExtendSizeOpts struct {
|
type ExtendSizeOpts struct {
|
||||||
// NewSize is the new size of the volume, in GB
|
// NewSize is the new size of the volume, in GB.
|
||||||
NewSize int `json:"new_size" required:"true"`
|
NewSize int `json:"new_size" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +216,7 @@ func ExtendSize(client *gophercloud.ServiceClient, id string, opts ExtendSizeOpt
|
||||||
r.Err = err
|
r.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, r.Err = client.Post(extendSizeURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{202},
|
OkCodes: []int{202},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -225,11 +232,14 @@ type UploadImageOptsBuilder interface {
|
||||||
type UploadImageOpts struct {
|
type UploadImageOpts struct {
|
||||||
// Container format, may be bare, ofv, ova, etc.
|
// Container format, may be bare, ofv, ova, etc.
|
||||||
ContainerFormat string `json:"container_format,omitempty"`
|
ContainerFormat string `json:"container_format,omitempty"`
|
||||||
|
|
||||||
// Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc.
|
// Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc.
|
||||||
DiskFormat string `json:"disk_format,omitempty"`
|
DiskFormat string `json:"disk_format,omitempty"`
|
||||||
// The name of image that will be stored in glance
|
|
||||||
|
// The name of image that will be stored in glance.
|
||||||
ImageName string `json:"image_name,omitempty"`
|
ImageName string `json:"image_name,omitempty"`
|
||||||
// Force image creation, usable if volume attached to instance
|
|
||||||
|
// Force image creation, usable if volume attached to instance.
|
||||||
Force bool `json:"force,omitempty"`
|
Force bool `json:"force,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,15 +249,21 @@ func (opts UploadImageOpts) ToVolumeUploadImageMap() (map[string]interface{}, er
|
||||||
return gophercloud.BuildRequestBody(opts, "os-volume_upload_image")
|
return gophercloud.BuildRequestBody(opts, "os-volume_upload_image")
|
||||||
}
|
}
|
||||||
|
|
||||||
// UploadImage will upload image base on the values in UploadImageOptsBuilder
|
// UploadImage will upload an image based on the values in UploadImageOptsBuilder.
|
||||||
func UploadImage(client *gophercloud.ServiceClient, id string, opts UploadImageOptsBuilder) (r UploadImageResult) {
|
func UploadImage(client *gophercloud.ServiceClient, id string, opts UploadImageOptsBuilder) (r UploadImageResult) {
|
||||||
b, err := opts.ToVolumeUploadImageMap()
|
b, err := opts.ToVolumeUploadImageMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Err = err
|
r.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, r.Err = client.Post(uploadURL(client, id), b, nil, &gophercloud.RequestOpts{
|
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
OkCodes: []int{202},
|
OkCodes: []int{202},
|
||||||
})
|
})
|
||||||
return
|
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,48 +1,68 @@
|
||||||
package volumeactions
|
package volumeactions
|
||||||
|
|
||||||
import "github.com/gophercloud/gophercloud"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
// AttachResult contains the response body and error from a Get request.
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AttachResult contains the response body and error from an Attach request.
|
||||||
type AttachResult struct {
|
type AttachResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeginDetachingResult contains the response body and error from a Get request.
|
// BeginDetachingResult contains the response body and error from a BeginDetach
|
||||||
|
// request.
|
||||||
type BeginDetachingResult struct {
|
type BeginDetachingResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DetachResult contains the response body and error from a Get request.
|
// DetachResult contains the response body and error from a Detach request.
|
||||||
type DetachResult struct {
|
type DetachResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// UploadImageResult contains the response body and error from a UploadImage request.
|
// UploadImageResult contains the response body and error from an UploadImage
|
||||||
|
// request.
|
||||||
type UploadImageResult struct {
|
type UploadImageResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReserveResult contains the response body and error from a Get request.
|
// ReserveResult contains the response body and error from a Reserve request.
|
||||||
type ReserveResult struct {
|
type ReserveResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnreserveResult contains the response body and error from a Get request.
|
// UnreserveResult contains the response body and error from an Unreserve
|
||||||
|
// request.
|
||||||
type UnreserveResult struct {
|
type UnreserveResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// TerminateConnectionResult contains the response body and error from a Get request.
|
// TerminateConnectionResult contains the response body and error from a
|
||||||
|
// TerminateConnection request.
|
||||||
type TerminateConnectionResult struct {
|
type TerminateConnectionResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
type commonResult struct {
|
// InitializeConnectionResult contains the response body and error from an
|
||||||
|
// InitializeConnection request.
|
||||||
|
type InitializeConnectionResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract will get the Volume object out of the commonResult object.
|
// ExtendSizeResult contains the response body and error from an ExtendSize request.
|
||||||
func (r commonResult) Extract() (map[string]interface{}, error) {
|
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 {
|
var s struct {
|
||||||
ConnectionInfo map[string]interface{} `json:"connection_info"`
|
ConnectionInfo map[string]interface{} `json:"connection_info"`
|
||||||
}
|
}
|
||||||
|
@ -50,12 +70,122 @@ func (r commonResult) Extract() (map[string]interface{}, error) {
|
||||||
return s.ConnectionInfo, err
|
return s.ConnectionInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitializeConnectionResult contains the response body and error from a Get request.
|
// ImageVolumeType contains volume type information obtained from UploadImage
|
||||||
type InitializeConnectionResult struct {
|
// action.
|
||||||
commonResult
|
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:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtendSizeResult contains the response body and error from an ExtendSize request.
|
func (r *ImageVolumeType) UnmarshalJSON(b []byte) error {
|
||||||
type ExtendSizeResult struct {
|
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
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,38 +2,6 @@ package volumeactions
|
||||||
|
|
||||||
import "github.com/gophercloud/gophercloud"
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
func attachURL(c *gophercloud.ServiceClient, id string) string {
|
func actionURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
return c.ServiceURL("volumes", id, "action")
|
return c.ServiceURL("volumes", id, "action")
|
||||||
}
|
}
|
||||||
|
|
||||||
func beginDetachingURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func detachURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func uploadURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func reserveURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func unreserveURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func initializeConnectionURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func teminateConnectionURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func extendSizeURL(c *gophercloud.ServiceClient, id string) string {
|
|
||||||
return attachURL(c, id)
|
|
||||||
}
|
|
||||||
|
|
11
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go
generated
vendored
11
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/requests.go
generated
vendored
|
@ -110,8 +110,8 @@ type UpdateOptsBuilder interface {
|
||||||
// to the volumes.Update function. For more information about the parameters, see
|
// to the volumes.Update function. For more information about the parameters, see
|
||||||
// the Volume object.
|
// the Volume object.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
Name string `json:"display_name,omitempty"`
|
Name *string `json:"display_name,omitempty"`
|
||||||
Description string `json:"display_description,omitempty"`
|
Description *string `json:"display_description,omitempty"`
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,12 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/results.go
generated
vendored
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/results.go
generated
vendored
|
@ -1,6 +1,9 @@
|
||||||
package volumes
|
package volumes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
@ -18,7 +21,7 @@ type Volume struct {
|
||||||
// Indicates whether this is a bootable volume.
|
// Indicates whether this is a bootable volume.
|
||||||
Bootable string `json:"bootable"`
|
Bootable string `json:"bootable"`
|
||||||
// The date when this volume was created.
|
// The date when this volume was created.
|
||||||
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
CreatedAt time.Time `json:"-"`
|
||||||
// Human-readable description for the volume.
|
// Human-readable description for the volume.
|
||||||
Description string `json:"display_description"`
|
Description string `json:"display_description"`
|
||||||
// The type of volume to create, either SATA or SSD.
|
// The type of volume to create, either SATA or SSD.
|
||||||
|
@ -35,6 +38,23 @@ type Volume struct {
|
||||||
Size int `json:"size"`
|
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.
|
// CreateResult contains the response body and error from a Create request.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
|
|
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/doc.go
generated
vendored
Normal file
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// Package snapshots provides information and interaction with snapshots in the
|
||||||
|
// OpenStack Block Storage service. A snapshot is a point in time copy of the
|
||||||
|
// data contained in an external storage volume, and can be controlled
|
||||||
|
// programmatically.
|
||||||
|
package snapshots
|
175
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/requests.go
generated
vendored
Normal file
175
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Create request.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToSnapshotCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts contains options for creating a Snapshot. This object is passed to
|
||||||
|
// the snapshots.Create function. For more information about these parameters,
|
||||||
|
// see the Snapshot object.
|
||||||
|
type CreateOpts struct {
|
||||||
|
VolumeID string `json:"volume_id" required:"true"`
|
||||||
|
Force bool `json:"force,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSnapshotCreateMap assembles a request body based on the contents of a
|
||||||
|
// CreateOpts.
|
||||||
|
func (opts CreateOpts) ToSnapshotCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "snapshot")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create will create a new Snapshot based on the values in CreateOpts. To
|
||||||
|
// extract the Snapshot object from the response, call the Extract method on the
|
||||||
|
// CreateResult.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToSnapshotCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{202},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete will delete the existing Snapshot 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 Snapshot with the provided ID. To extract the Snapshot
|
||||||
|
// 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 {
|
||||||
|
ToSnapshotListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts hold options for listing Snapshots. It is passed to the
|
||||||
|
// snapshots.List function.
|
||||||
|
type ListOpts struct {
|
||||||
|
// AllTenants will retrieve snapshots of all tenants/projects.
|
||||||
|
AllTenants bool `q:"all_tenants"`
|
||||||
|
|
||||||
|
// Name will filter by the specified snapshot 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 to use this.
|
||||||
|
TenantID string `q:"project_id"`
|
||||||
|
|
||||||
|
// VolumeID will filter by a specified volume ID.
|
||||||
|
VolumeID string `q:"volume_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSnapshotListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToSnapshotListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns Snapshots 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.ToSnapshotListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return SnapshotPage{pagination.SinglePageBase(r)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Update request.
|
||||||
|
type UpdateMetadataOptsBuilder interface {
|
||||||
|
ToSnapshotUpdateMetadataMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadataOpts contain options for updating an existing Snapshot. This
|
||||||
|
// object is passed to the snapshots.Update function. For more information
|
||||||
|
// about the parameters, see the Snapshot object.
|
||||||
|
type UpdateMetadataOpts struct {
|
||||||
|
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSnapshotUpdateMetadataMap assembles a request body based on the contents of
|
||||||
|
// an UpdateMetadataOpts.
|
||||||
|
func (opts UpdateMetadataOpts) ToSnapshotUpdateMetadataMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadata will update the Snapshot with provided information. To
|
||||||
|
// extract the updated Snapshot from the response, call the ExtractMetadata
|
||||||
|
// method on the UpdateMetadataResult.
|
||||||
|
func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) (r UpdateMetadataResult) {
|
||||||
|
b, err := opts.ToSnapshotUpdateMetadataMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Put(updateMetadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDFromName is a convienience function that returns a snapshot'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 := ExtractSnapshots(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: "snapshot"}
|
||||||
|
case 1:
|
||||||
|
return id, nil
|
||||||
|
default:
|
||||||
|
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "snapshot"}
|
||||||
|
}
|
||||||
|
}
|
120
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/results.go
generated
vendored
Normal file
120
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/results.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Snapshot contains all the information associated with a Cinder Snapshot.
|
||||||
|
type Snapshot struct {
|
||||||
|
// Unique identifier.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// Date created.
|
||||||
|
CreatedAt time.Time `json:"-"`
|
||||||
|
|
||||||
|
// Date updated.
|
||||||
|
UpdatedAt time.Time `json:"-"`
|
||||||
|
|
||||||
|
// Display name.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Display description.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// ID of the Volume from which this Snapshot was created.
|
||||||
|
VolumeID string `json:"volume_id"`
|
||||||
|
|
||||||
|
// Currect status of the Snapshot.
|
||||||
|
Status string `json:"status"`
|
||||||
|
|
||||||
|
// Size of the Snapshot, in GB.
|
||||||
|
Size int `json:"size"`
|
||||||
|
|
||||||
|
// User-defined key-value pairs.
|
||||||
|
Metadata map[string]string `json:"metadata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// SnapshotPage is a pagination.Pager that is returned from a call to the List function.
|
||||||
|
type SnapshotPage struct {
|
||||||
|
pagination.SinglePageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Snapshot) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Snapshot
|
||||||
|
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 = Snapshot(s.tmp)
|
||||||
|
|
||||||
|
r.CreatedAt = time.Time(s.CreatedAt)
|
||||||
|
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty returns true if a SnapshotPage contains no Snapshots.
|
||||||
|
func (r SnapshotPage) IsEmpty() (bool, error) {
|
||||||
|
volumes, err := ExtractSnapshots(r)
|
||||||
|
return len(volumes) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractSnapshots extracts and returns Snapshots. It is used while iterating over a snapshots.List call.
|
||||||
|
func ExtractSnapshots(r pagination.Page) ([]Snapshot, error) {
|
||||||
|
var s struct {
|
||||||
|
Snapshots []Snapshot `json:"snapshots"`
|
||||||
|
}
|
||||||
|
err := (r.(SnapshotPage)).ExtractInto(&s)
|
||||||
|
return s.Snapshots, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadataResult contains the response body and error from an UpdateMetadata request.
|
||||||
|
type UpdateMetadataResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractMetadata returns the metadata from a response from snapshots.UpdateMetadata.
|
||||||
|
func (r UpdateMetadataResult) ExtractMetadata() (map[string]interface{}, error) {
|
||||||
|
if r.Err != nil {
|
||||||
|
return nil, r.Err
|
||||||
|
}
|
||||||
|
m := r.Body.(map[string]interface{})["metadata"]
|
||||||
|
return m.(map[string]interface{}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type commonResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract will get the Snapshot object out of the commonResult object.
|
||||||
|
func (r commonResult) Extract() (*Snapshot, error) {
|
||||||
|
var s struct {
|
||||||
|
Snapshot *Snapshot `json:"snapshot"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Snapshot, err
|
||||||
|
}
|
27
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/urls.go
generated
vendored
Normal file
27
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func createURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return c.ServiceURL("snapshots")
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return c.ServiceURL("snapshots", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return deleteURL(c, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return createURL(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func metadataURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return c.ServiceURL("snapshots", id, "metadata")
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateMetadataURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return metadataURL(c, id)
|
||||||
|
}
|
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/util.go
generated
vendored
Normal file
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots/util.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
73
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go
generated
vendored
73
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/requests.go
generated
vendored
|
@ -61,9 +61,37 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
return
|
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.
|
// Delete will delete the existing Volume with the provided ID.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
func Delete(client *gophercloud.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,14 +111,34 @@ type ListOptsBuilder interface {
|
||||||
// ListOpts holds options for listing Volumes. It is passed to the volumes.List
|
// ListOpts holds options for listing Volumes. It is passed to the volumes.List
|
||||||
// function.
|
// function.
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
// admin-only option. Set it to true to see all tenant volumes.
|
// AllTenants will retrieve volumes of all tenants/projects.
|
||||||
AllTenants bool `q:"all_tenants"`
|
AllTenants bool `q:"all_tenants"`
|
||||||
// List only volumes that contain Metadata.
|
|
||||||
|
// Metadata will filter results based on specified metadata.
|
||||||
Metadata map[string]string `q:"metadata"`
|
Metadata map[string]string `q:"metadata"`
|
||||||
// List only volumes that have Name as the display name.
|
|
||||||
|
// Name will filter by the specified volume name.
|
||||||
Name string `q:"name"`
|
Name string `q:"name"`
|
||||||
// List only volumes that have a status of Status.
|
|
||||||
|
// Status will filter by the specified status.
|
||||||
Status string `q:"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.
|
// ToVolumeListQuery formats a ListOpts into a query string.
|
||||||
|
@ -111,7 +159,7 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa
|
||||||
}
|
}
|
||||||
|
|
||||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
return VolumePage{pagination.SinglePageBase(r)}
|
return VolumePage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +173,8 @@ type UpdateOptsBuilder interface {
|
||||||
// to the volumes.Update function. For more information about the parameters, see
|
// to the volumes.Update function. For more information about the parameters, see
|
||||||
// the Volume object.
|
// the Volume object.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +202,12 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
pages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
15
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
15
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
|
@ -98,7 +98,7 @@ func (r *Volume) UnmarshalJSON(b []byte) error {
|
||||||
|
|
||||||
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
||||||
type VolumePage struct {
|
type VolumePage struct {
|
||||||
pagination.SinglePageBase
|
pagination.LinkedPageBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if a ListResult contains no Volumes.
|
// IsEmpty returns true if a ListResult contains no Volumes.
|
||||||
|
@ -107,6 +107,19 @@ func (r VolumePage) IsEmpty() (bool, error) {
|
||||||
return len(volumes) == 0, err
|
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.
|
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
|
||||||
func ExtractVolumes(r pagination.Page) ([]Volume, error) {
|
func ExtractVolumes(r pagination.Page) ([]Volume, error) {
|
||||||
var s []Volume
|
var s []Volume
|
||||||
|
|
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/doc.go
generated
vendored
Normal file
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// Package snapshots provides information and interaction with snapshots in the
|
||||||
|
// OpenStack Block Storage service. A snapshot is a point in time copy of the
|
||||||
|
// data contained in an external storage volume, and can be controlled
|
||||||
|
// programmatically.
|
||||||
|
package snapshots
|
186
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/requests.go
generated
vendored
Normal file
186
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Create request.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToSnapshotCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts contains options for creating a Snapshot. This object is passed to
|
||||||
|
// the snapshots.Create function. For more information about these parameters,
|
||||||
|
// see the Snapshot object.
|
||||||
|
type CreateOpts struct {
|
||||||
|
VolumeID string `json:"volume_id" required:"true"`
|
||||||
|
Force bool `json:"force,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSnapshotCreateMap assembles a request body based on the contents of a
|
||||||
|
// CreateOpts.
|
||||||
|
func (opts CreateOpts) ToSnapshotCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "snapshot")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create will create a new Snapshot based on the values in CreateOpts. To
|
||||||
|
// extract the Snapshot object from the response, call the Extract method on the
|
||||||
|
// CreateResult.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToSnapshotCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{202},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete will delete the existing Snapshot 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 Snapshot with the provided ID. To extract the Snapshot
|
||||||
|
// 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 {
|
||||||
|
ToSnapshotListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListOpts struct {
|
||||||
|
// AllTenants will retrieve snapshots of all tenants/projects.
|
||||||
|
AllTenants bool `q:"all_tenants"`
|
||||||
|
|
||||||
|
// Name will filter by the specified snapshot 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 to use this.
|
||||||
|
TenantID string `q:"project_id"`
|
||||||
|
|
||||||
|
// VolumeID will filter by a specified volume ID.
|
||||||
|
VolumeID string `q:"volume_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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSnapshotListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToSnapshotListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns Snapshots 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.ToSnapshotListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return SnapshotPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Update request.
|
||||||
|
type UpdateMetadataOptsBuilder interface {
|
||||||
|
ToSnapshotUpdateMetadataMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadataOpts contain options for updating an existing Snapshot. This
|
||||||
|
// object is passed to the snapshots.Update function. For more information
|
||||||
|
// about the parameters, see the Snapshot object.
|
||||||
|
type UpdateMetadataOpts struct {
|
||||||
|
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSnapshotUpdateMetadataMap assembles a request body based on the contents of
|
||||||
|
// an UpdateMetadataOpts.
|
||||||
|
func (opts UpdateMetadataOpts) ToSnapshotUpdateMetadataMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadata will update the Snapshot with provided information. To
|
||||||
|
// extract the updated Snapshot from the response, call the ExtractMetadata
|
||||||
|
// method on the UpdateMetadataResult.
|
||||||
|
func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) (r UpdateMetadataResult) {
|
||||||
|
b, err := opts.ToSnapshotUpdateMetadataMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Put(updateMetadataURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDFromName is a convienience function that returns a snapshot'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 := ExtractSnapshots(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: "snapshot"}
|
||||||
|
case 1:
|
||||||
|
return id, nil
|
||||||
|
default:
|
||||||
|
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "snapshot"}
|
||||||
|
}
|
||||||
|
}
|
132
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/results.go
generated
vendored
Normal file
132
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/results.go
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Snapshot contains all the information associated with a Cinder Snapshot.
|
||||||
|
type Snapshot struct {
|
||||||
|
// Unique identifier.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// Date created.
|
||||||
|
CreatedAt time.Time `json:"-"`
|
||||||
|
|
||||||
|
// Date updated.
|
||||||
|
UpdatedAt time.Time `json:"-"`
|
||||||
|
|
||||||
|
// Display name.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Display description.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// ID of the Volume from which this Snapshot was created.
|
||||||
|
VolumeID string `json:"volume_id"`
|
||||||
|
|
||||||
|
// Currect status of the Snapshot.
|
||||||
|
Status string `json:"status"`
|
||||||
|
|
||||||
|
// Size of the Snapshot, in GB.
|
||||||
|
Size int `json:"size"`
|
||||||
|
|
||||||
|
// User-defined key-value pairs.
|
||||||
|
Metadata map[string]string `json:"metadata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// SnapshotPage is a pagination.Pager that is returned from a call to the List function.
|
||||||
|
type SnapshotPage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON converts our JSON API response into our snapshot struct
|
||||||
|
func (r *Snapshot) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Snapshot
|
||||||
|
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 = Snapshot(s.tmp)
|
||||||
|
|
||||||
|
r.CreatedAt = time.Time(s.CreatedAt)
|
||||||
|
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty returns true if a SnapshotPage contains no Snapshots.
|
||||||
|
func (r SnapshotPage) IsEmpty() (bool, error) {
|
||||||
|
volumes, err := ExtractSnapshots(r)
|
||||||
|
return len(volumes) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page SnapshotPage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Links []gophercloud.Link `json:"snapshots_links"`
|
||||||
|
}
|
||||||
|
err := page.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return gophercloud.ExtractNextURL(s.Links)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractSnapshots extracts and returns Snapshots. It is used while iterating over a snapshots.List call.
|
||||||
|
func ExtractSnapshots(r pagination.Page) ([]Snapshot, error) {
|
||||||
|
var s struct {
|
||||||
|
Snapshots []Snapshot `json:"snapshots"`
|
||||||
|
}
|
||||||
|
err := (r.(SnapshotPage)).ExtractInto(&s)
|
||||||
|
return s.Snapshots, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMetadataResult contains the response body and error from an UpdateMetadata request.
|
||||||
|
type UpdateMetadataResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractMetadata returns the metadata from a response from snapshots.UpdateMetadata.
|
||||||
|
func (r UpdateMetadataResult) ExtractMetadata() (map[string]interface{}, error) {
|
||||||
|
if r.Err != nil {
|
||||||
|
return nil, r.Err
|
||||||
|
}
|
||||||
|
m := r.Body.(map[string]interface{})["metadata"]
|
||||||
|
return m.(map[string]interface{}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type commonResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract will get the Snapshot object out of the commonResult object.
|
||||||
|
func (r commonResult) Extract() (*Snapshot, error) {
|
||||||
|
var s struct {
|
||||||
|
Snapshot *Snapshot `json:"snapshot"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Snapshot, err
|
||||||
|
}
|
27
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/urls.go
generated
vendored
Normal file
27
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func createURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return c.ServiceURL("snapshots")
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return c.ServiceURL("snapshots", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return deleteURL(c, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return createURL(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func metadataURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return c.ServiceURL("snapshots", id, "metadata")
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateMetadataURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return metadataURL(c, id)
|
||||||
|
}
|
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/util.go
generated
vendored
Normal file
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots/util.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package snapshots
|
||||||
|
|
||||||
|
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
Normal file
5
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// 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
Normal file
237
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
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"}
|
||||||
|
}
|
||||||
|
}
|
170
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go
generated
vendored
Normal file
170
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go
generated
vendored
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
Normal file
23
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
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
Normal file
22
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/util.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package openstack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
|
@ -12,43 +11,66 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
v20 = "v2.0"
|
// v2 represents Keystone v2.
|
||||||
v30 = "v3.0"
|
// 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.
|
NewClient prepares an unauthenticated ProviderClient instance.
|
||||||
// This is useful if you wish to explicitly control the version of the identity service that's used for authentication explicitly,
|
Most users will probably prefer using the AuthenticatedClient function
|
||||||
// for example.
|
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) {
|
func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
|
||||||
u, err := url.Parse(endpoint)
|
base, err := utils.BaseEndpoint(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hadPath := u.Path != ""
|
|
||||||
u.Path, u.RawQuery, u.Fragment = "", "", ""
|
|
||||||
base := u.String()
|
|
||||||
|
|
||||||
endpoint = gophercloud.NormalizeURL(endpoint)
|
endpoint = gophercloud.NormalizeURL(endpoint)
|
||||||
base = gophercloud.NormalizeURL(base)
|
base = gophercloud.NormalizeURL(base)
|
||||||
|
|
||||||
if hadPath {
|
p := new(gophercloud.ProviderClient)
|
||||||
return &gophercloud.ProviderClient{
|
p.IdentityBase = base
|
||||||
IdentityBase: base,
|
p.IdentityEndpoint = endpoint
|
||||||
IdentityEndpoint: endpoint,
|
p.UseTokenLock()
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &gophercloud.ProviderClient{
|
return p, nil
|
||||||
IdentityBase: base,
|
|
||||||
IdentityEndpoint: "",
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint specified by options, acquires a token, and
|
/*
|
||||||
// returns a Client instance that's ready to operate.
|
AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint
|
||||||
// It first queries the root identity endpoint to determine which versions of the identity service are supported, then chooses
|
specified by the options, acquires a token, and returns a Provider Client
|
||||||
// the most recent identity service available to proceed.
|
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) {
|
func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) {
|
||||||
client, err := NewClient(options.IdentityEndpoint)
|
client, err := NewClient(options.IdentityEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -62,11 +84,12 @@ func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.Provider
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate or re-authenticate against the most recent identity service supported at the provided endpoint.
|
// Authenticate or re-authenticate against the most recent identity service
|
||||||
|
// supported at the provided endpoint.
|
||||||
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
|
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
|
||||||
versions := []*utils.Version{
|
versions := []*utils.Version{
|
||||||
{ID: v20, Priority: 20, Suffix: "/v2.0/"},
|
{ID: v2, Priority: 20, Suffix: "/v2.0/"},
|
||||||
{ID: v30, Priority: 30, Suffix: "/v3/"},
|
{ID: v3, Priority: 30, Suffix: "/v3/"},
|
||||||
}
|
}
|
||||||
|
|
||||||
chosen, endpoint, err := utils.ChooseVersion(client, versions)
|
chosen, endpoint, err := utils.ChooseVersion(client, versions)
|
||||||
|
@ -75,9 +98,9 @@ func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOp
|
||||||
}
|
}
|
||||||
|
|
||||||
switch chosen.ID {
|
switch chosen.ID {
|
||||||
case v20:
|
case v2:
|
||||||
return v2auth(client, endpoint, options, gophercloud.EndpointOpts{})
|
return v2auth(client, endpoint, options, gophercloud.EndpointOpts{})
|
||||||
case v30:
|
case v3:
|
||||||
return v3auth(client, endpoint, &options, gophercloud.EndpointOpts{})
|
return v3auth(client, endpoint, &options, gophercloud.EndpointOpts{})
|
||||||
default:
|
default:
|
||||||
// The switch statement must be out of date from the versions list.
|
// The switch statement must be out of date from the versions list.
|
||||||
|
@ -112,7 +135,7 @@ func v2auth(client *gophercloud.ProviderClient, endpoint string, options gopherc
|
||||||
|
|
||||||
result := tokens2.Create(v2Client, v2Opts)
|
result := tokens2.Create(v2Client, v2Opts)
|
||||||
|
|
||||||
token, err := result.ExtractToken()
|
err = client.SetTokenAndAuthResult(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -123,12 +146,24 @@ func v2auth(client *gophercloud.ProviderClient, endpoint string, options gopherc
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.AllowReauth {
|
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 {
|
client.ReauthFunc = func() error {
|
||||||
client.TokenID = ""
|
err := v2auth(&tac, endpoint, tao, eo)
|
||||||
return v2auth(client, endpoint, options, eo)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client.CopyTokenFrom(&tac)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.TokenID = token.ID
|
|
||||||
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
|
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
|
||||||
return V2EndpointURL(catalog, opts)
|
return V2EndpointURL(catalog, opts)
|
||||||
}
|
}
|
||||||
|
@ -154,7 +189,7 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
|
||||||
|
|
||||||
result := tokens3.Create(v3Client, opts)
|
result := tokens3.Create(v3Client, opts)
|
||||||
|
|
||||||
token, err := result.ExtractToken()
|
err = client.SetTokenAndAuthResult(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -164,12 +199,34 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client.TokenID = token.ID
|
|
||||||
|
|
||||||
if opts.CanReauth() {
|
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 {
|
client.ReauthFunc = func() error {
|
||||||
client.TokenID = ""
|
err := v3auth(&tac, endpoint, tao, eo)
|
||||||
return v3auth(client, endpoint, opts, eo)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client.CopyTokenFrom(&tac)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
|
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
|
||||||
|
@ -179,12 +236,14 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIdentityV2 creates a ServiceClient that may be used to interact with the v2 identity service.
|
// 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) {
|
func NewIdentityV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
endpoint := client.IdentityBase + "v2.0/"
|
endpoint := client.IdentityBase + "v2.0/"
|
||||||
|
clientType := "identity"
|
||||||
var err error
|
var err error
|
||||||
if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
|
if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
|
||||||
eo.ApplyDefaults("identity")
|
eo.ApplyDefaults(clientType)
|
||||||
endpoint, err = client.EndpointLocator(eo)
|
endpoint, err = client.EndpointLocator(eo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -194,143 +253,174 @@ func NewIdentityV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOp
|
||||||
return &gophercloud.ServiceClient{
|
return &gophercloud.ServiceClient{
|
||||||
ProviderClient: client,
|
ProviderClient: client,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
|
Type: clientType,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIdentityV3 creates a ServiceClient that may be used to access the v3 identity service.
|
// 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) {
|
func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
endpoint := client.IdentityBase + "v3/"
|
endpoint := client.IdentityBase + "v3/"
|
||||||
|
clientType := "identity"
|
||||||
var err error
|
var err error
|
||||||
if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
|
if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
|
||||||
eo.ApplyDefaults("identity")
|
eo.ApplyDefaults(clientType)
|
||||||
endpoint, err = client.EndpointLocator(eo)
|
endpoint, err = client.EndpointLocator(eo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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{
|
return &gophercloud.ServiceClient{
|
||||||
ProviderClient: client,
|
ProviderClient: client,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
|
Type: clientType,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewObjectStorageV1 creates a ServiceClient that may be used with the v1 object storage package.
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("object-store")
|
return initClientOpts(client, eo, "object-store")
|
||||||
url, err := client.EndpointLocator(eo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewComputeV2 creates a ServiceClient that may be used with the v2 compute package.
|
// NewComputeV2 creates a ServiceClient that may be used with the v2 compute
|
||||||
|
// package.
|
||||||
func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("compute")
|
return initClientOpts(client, eo, "compute")
|
||||||
url, err := client.EndpointLocator(eo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNetworkV2 creates a ServiceClient that may be used with the v2 network package.
|
// NewNetworkV2 creates a ServiceClient that may be used with the v2 network
|
||||||
|
// package.
|
||||||
func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("network")
|
sc, err := initClientOpts(client, eo, "network")
|
||||||
url, err := client.EndpointLocator(eo)
|
sc.ResourceBase = sc.Endpoint + "v2.0/"
|
||||||
if err != nil {
|
return sc, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{
|
|
||||||
ProviderClient: client,
|
|
||||||
Endpoint: url,
|
|
||||||
ResourceBase: url + "v2.0/",
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 block storage service.
|
// 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) {
|
func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("volume")
|
return initClientOpts(client, eo, "volume")
|
||||||
url, err := client.EndpointLocator(eo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockStorageV2 creates a ServiceClient that may be used to access the v2 block storage service.
|
// 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) {
|
func NewBlockStorageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("volumev2")
|
return initClientOpts(client, eo, "volumev2")
|
||||||
url, err := client.EndpointLocator(eo)
|
}
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
// 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 &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
return initClientOpts(client, eo, "volumev3")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service.
|
// 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) {
|
func NewSharedFileSystemV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("sharev2")
|
return initClientOpts(client, eo, "sharev2")
|
||||||
url, err := client.EndpointLocator(eo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCDNV1 creates a ServiceClient that may be used to access the OpenStack v1
|
// NewCDNV1 creates a ServiceClient that may be used to access the OpenStack v1
|
||||||
// CDN service.
|
// CDN service.
|
||||||
func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("cdn")
|
return initClientOpts(client, eo, "cdn")
|
||||||
url, err := client.EndpointLocator(eo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 orchestration service.
|
// 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) {
|
func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("orchestration")
|
return initClientOpts(client, eo, "orchestration")
|
||||||
url, err := client.EndpointLocator(eo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDBV1 creates a ServiceClient that may be used to access the v1 DB service.
|
// 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) {
|
func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("database")
|
return initClientOpts(client, eo, "database")
|
||||||
url, err := client.EndpointLocator(eo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS service.
|
// 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) {
|
func NewDNSV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("dns")
|
sc, err := initClientOpts(client, eo, "dns")
|
||||||
url, err := client.EndpointLocator(eo)
|
sc.ResourceBase = sc.Endpoint + "v2/"
|
||||||
if err != nil {
|
return sc, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{
|
|
||||||
ProviderClient: client,
|
|
||||||
Endpoint: url,
|
|
||||||
ResourceBase: url + "v2/"}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewImageServiceV2 creates a ServiceClient that may be used to access the v2 image service.
|
// 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) {
|
func NewImageServiceV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
eo.ApplyDefaults("image")
|
sc, err := initClientOpts(client, eo, "image")
|
||||||
url, err := client.EndpointLocator(eo)
|
sc.ResourceBase = sc.Endpoint + "v2/"
|
||||||
if err != nil {
|
return sc, err
|
||||||
return nil, err
|
}
|
||||||
}
|
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client,
|
// NewLoadBalancerV2 creates a ServiceClient that may be used to access the v2
|
||||||
Endpoint: url,
|
// load balancer service.
|
||||||
ResourceBase: url + "v2/"}, nil
|
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/compute/v2/extensions/attachinterfaces/doc.go
generated
vendored
Normal file
52
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
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
|
72
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go
generated
vendored
Normal file
72
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
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
|
||||||
|
}
|
80
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go
generated
vendored
Normal file
80
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
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
|
||||||
|
}
|
18
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go
generated
vendored
Normal file
18
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
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)
|
||||||
|
}
|
61
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones/doc.go
generated
vendored
Normal file
61
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
Package availabilityzones provides the ability to get lists and detailed
|
||||||
|
availability zone information and to extend a server result with
|
||||||
|
availability zone information.
|
||||||
|
|
||||||
|
Example of Extend server result with Availability Zone Information:
|
||||||
|
|
||||||
|
type ServerWithAZ struct {
|
||||||
|
servers.Server
|
||||||
|
availabilityzones.ServerAvailabilityZoneExt
|
||||||
|
}
|
||||||
|
|
||||||
|
var allServers []ServerWithAZ
|
||||||
|
|
||||||
|
allPages, err := servers.List(client, nil).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic("Unable to retrieve servers: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = servers.ExtractServersInto(allPages, &allServers)
|
||||||
|
if err != nil {
|
||||||
|
panic("Unable to extract servers: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, server := range allServers {
|
||||||
|
fmt.Println(server.AvailabilityZone)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example of Get Availability Zone Information
|
||||||
|
|
||||||
|
allPages, err := availabilityzones.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, zoneInfo := range availabilityZoneInfo {
|
||||||
|
fmt.Printf("%+v\n", zoneInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example of Get Detailed Availability Zone Information
|
||||||
|
|
||||||
|
allPages, err := availabilityzones.ListDetail(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, zoneInfo := range availabilityZoneInfo {
|
||||||
|
fmt.Printf("%+v\n", zoneInfo)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package availabilityzones
|
20
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones/requests.go
generated
vendored
Normal file
20
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package availabilityzones
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// List will return the existing availability zones.
|
||||||
|
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
|
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
||||||
|
return AvailabilityZonePage{pagination.SinglePageBase(r)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListDetail will return the existing availability zones with detailed information.
|
||||||
|
func ListDetail(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
|
return pagination.NewPager(client, listDetailURL(client), func(r pagination.PageResult) pagination.Page {
|
||||||
|
return AvailabilityZonePage{pagination.SinglePageBase(r)}
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,12 +1,76 @@
|
||||||
package availabilityzones
|
package availabilityzones
|
||||||
|
|
||||||
// ServerExt is an extension to the base Server object
|
import (
|
||||||
type ServerExt struct {
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ServerAvailabilityZoneExt is an extension to the base Server object.
|
||||||
|
type ServerAvailabilityZoneExt struct {
|
||||||
// AvailabilityZone is the availabilty zone the server is in.
|
// AvailabilityZone is the availabilty zone the server is in.
|
||||||
AvailabilityZone string `json:"OS-EXT-AZ:availability_zone"`
|
AvailabilityZone string `json:"OS-EXT-AZ:availability_zone"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceState represents the state of a service in an AvailabilityZone.
|
||||||
|
type ServiceState struct {
|
||||||
|
Active bool `json:"active"`
|
||||||
|
Available bool `json:"available"`
|
||||||
|
UpdatedAt time.Time `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalJSON to override default
|
// UnmarshalJSON to override default
|
||||||
func (r *ServerExt) UnmarshalJSON(b []byte) error {
|
func (r *ServiceState) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp ServiceState
|
||||||
|
var s struct {
|
||||||
|
tmp
|
||||||
|
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*r = ServiceState(s.tmp)
|
||||||
|
|
||||||
|
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Services is a map of services contained in an AvailabilityZone.
|
||||||
|
type Services map[string]ServiceState
|
||||||
|
|
||||||
|
// Hosts is map of hosts/nodes contained in an AvailabilityZone.
|
||||||
|
// Each host can have multiple services.
|
||||||
|
type Hosts map[string]Services
|
||||||
|
|
||||||
|
// ZoneState represents the current state of the availability zone.
|
||||||
|
type ZoneState struct {
|
||||||
|
// Returns true if the availability zone is available
|
||||||
|
Available bool `json:"available"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AvailabilityZone contains all the information associated with an OpenStack
|
||||||
|
// AvailabilityZone.
|
||||||
|
type AvailabilityZone struct {
|
||||||
|
Hosts Hosts `json:"hosts"`
|
||||||
|
// The availability zone name
|
||||||
|
ZoneName string `json:"zoneName"`
|
||||||
|
ZoneState ZoneState `json:"zoneState"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AvailabilityZonePage struct {
|
||||||
|
pagination.SinglePageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractAvailabilityZones returns a slice of AvailabilityZones contained in a
|
||||||
|
// single page of results.
|
||||||
|
func ExtractAvailabilityZones(r pagination.Page) ([]AvailabilityZone, error) {
|
||||||
|
var s struct {
|
||||||
|
AvailabilityZoneInfo []AvailabilityZone `json:"availabilityZoneInfo"`
|
||||||
|
}
|
||||||
|
err := (r.(AvailabilityZonePage)).ExtractInto(&s)
|
||||||
|
return s.AvailabilityZoneInfo, err
|
||||||
|
}
|
||||||
|
|
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones/urls.go
generated
vendored
Normal file
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package availabilityzones
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func listURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return c.ServiceURL("os-availability-zone")
|
||||||
|
}
|
||||||
|
|
||||||
|
func listDetailURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return c.ServiceURL("os-availability-zone", "detail")
|
||||||
|
}
|
152
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/doc.go
generated
vendored
Normal file
152
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
Package bootfromvolume extends a server create request with the ability to
|
||||||
|
specify block device options. This can be used to boot a server from a block
|
||||||
|
storage volume as well as specify multiple ephemeral disks upon creation.
|
||||||
|
|
||||||
|
It is recommended to refer to the Block Device Mapping documentation to see
|
||||||
|
all possible ways to configure a server's block devices at creation time:
|
||||||
|
|
||||||
|
https://docs.openstack.org/nova/latest/user/block-device-mapping.html
|
||||||
|
|
||||||
|
Note that this package implements `block_device_mapping_v2`.
|
||||||
|
|
||||||
|
Example of Creating a Server From an Image
|
||||||
|
|
||||||
|
This example will boot a server from an image and use a standard ephemeral
|
||||||
|
disk as the server's root disk. This is virtually no different than creating
|
||||||
|
a server without using block device mappings.
|
||||||
|
|
||||||
|
blockDevices := []bootfromvolume.BlockDevice{
|
||||||
|
bootfromvolume.BlockDevice{
|
||||||
|
BootIndex: 0,
|
||||||
|
DeleteOnTermination: true,
|
||||||
|
DestinationType: bootfromvolume.DestinationLocal,
|
||||||
|
SourceType: bootfromvolume.SourceImage,
|
||||||
|
UUID: "image-uuid",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_name",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
ImageRef: "image-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := bootfromvolume.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
BlockDevice: blockDevices,
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := bootfromvolume.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example of Creating a Server From a New Volume
|
||||||
|
|
||||||
|
This example will create a block storage volume based on the given Image. The
|
||||||
|
server will use this volume as its root disk.
|
||||||
|
|
||||||
|
blockDevices := []bootfromvolume.BlockDevice{
|
||||||
|
bootfromvolume.BlockDevice{
|
||||||
|
DeleteOnTermination: true,
|
||||||
|
DestinationType: bootfromvolume.DestinationVolume,
|
||||||
|
SourceType: bootfromvolume.SourceImage,
|
||||||
|
UUID: "image-uuid",
|
||||||
|
VolumeSize: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_name",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := bootfromvolume.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
BlockDevice: blockDevices,
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := bootfromvolume.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example of Creating a Server From an Existing Volume
|
||||||
|
|
||||||
|
This example will create a server with an existing volume as its root disk.
|
||||||
|
|
||||||
|
blockDevices := []bootfromvolume.BlockDevice{
|
||||||
|
bootfromvolume.BlockDevice{
|
||||||
|
DeleteOnTermination: true,
|
||||||
|
DestinationType: bootfromvolume.DestinationVolume,
|
||||||
|
SourceType: bootfromvolume.SourceVolume,
|
||||||
|
UUID: "volume-uuid",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_name",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := bootfromvolume.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
BlockDevice: blockDevices,
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := bootfromvolume.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example of Creating a Server with Multiple Ephemeral Disks
|
||||||
|
|
||||||
|
This example will create a server with multiple ephemeral disks. The first
|
||||||
|
block device will be based off of an existing Image. Each additional
|
||||||
|
ephemeral disks must have an index of -1.
|
||||||
|
|
||||||
|
blockDevices := []bootfromvolume.BlockDevice{
|
||||||
|
bootfromvolume.BlockDevice{
|
||||||
|
BootIndex: 0,
|
||||||
|
DestinationType: bootfromvolume.DestinationLocal,
|
||||||
|
DeleteOnTermination: true,
|
||||||
|
SourceType: bootfromvolume.SourceImage,
|
||||||
|
UUID: "image-uuid",
|
||||||
|
VolumeSize: 5,
|
||||||
|
},
|
||||||
|
bootfromvolume.BlockDevice{
|
||||||
|
BootIndex: -1,
|
||||||
|
DestinationType: bootfromvolume.DestinationLocal,
|
||||||
|
DeleteOnTermination: true,
|
||||||
|
GuestFormat: "ext4",
|
||||||
|
SourceType: bootfromvolume.SourceBlank,
|
||||||
|
VolumeSize: 1,
|
||||||
|
},
|
||||||
|
bootfromvolume.BlockDevice{
|
||||||
|
BootIndex: -1,
|
||||||
|
DestinationType: bootfromvolume.DestinationLocal,
|
||||||
|
DeleteOnTermination: true,
|
||||||
|
GuestFormat: "ext4",
|
||||||
|
SourceType: bootfromvolume.SourceBlank,
|
||||||
|
VolumeSize: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_name",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
ImageRef: "image-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := bootfromvolume.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
BlockDevice: blockDevices,
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := bootfromvolume.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package bootfromvolume
|
|
@ -67,6 +67,14 @@ type BlockDevice struct {
|
||||||
// VolumeSize is the size of the volume to create (in gigabytes). This can be
|
// VolumeSize is the size of the volume to create (in gigabytes). This can be
|
||||||
// omitted for existing volumes.
|
// omitted for existing volumes.
|
||||||
VolumeSize int `json:"volume_size,omitempty"`
|
VolumeSize int `json:"volume_size,omitempty"`
|
||||||
|
|
||||||
|
// DeviceType specifies the device type of the block devices.
|
||||||
|
// Examples of this are disk, cdrom, floppy, lun, etc.
|
||||||
|
DeviceType string `json:"device_type,omitempty"`
|
||||||
|
|
||||||
|
// DiskBus is the bus type of the block devices.
|
||||||
|
// Examples of this are ide, usb, virtio, scsi, etc.
|
||||||
|
DiskBus string `json:"disk_bus,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptsExt is a structure that extends the server `CreateOpts` structure
|
// CreateOptsExt is a structure that extends the server `CreateOpts` structure
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateResult temporarily contains the response from a Create call.
|
// CreateResult temporarily contains the response from a Create call.
|
||||||
|
// It embeds the standard servers.CreateResults type and so can be used the
|
||||||
|
// same way as a standard server request result.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
os.CreateResult
|
os.CreateResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,68 @@
|
||||||
// Package floatingips provides the ability to manage floating ips through
|
/*
|
||||||
// nova-network
|
Package floatingips provides the ability to manage floating ips through the
|
||||||
|
Nova API.
|
||||||
|
|
||||||
|
This API has been deprecated and will be removed from a future release of the
|
||||||
|
Nova API service.
|
||||||
|
|
||||||
|
For environements that support this extension, this package can be used
|
||||||
|
regardless of if either Neutron or nova-network is used as the cloud's network
|
||||||
|
service.
|
||||||
|
|
||||||
|
Example to List Floating IPs
|
||||||
|
|
||||||
|
allPages, err := floatingips.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allFloatingIPs, err := floatingips.ExtractFloatingIPs(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fip := range allFloatingIPs {
|
||||||
|
fmt.Printf("%+v\n", fip)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Floating IP
|
||||||
|
|
||||||
|
createOpts := floatingips.CreateOpts{
|
||||||
|
Pool: "nova",
|
||||||
|
}
|
||||||
|
|
||||||
|
fip, err := floatingips.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Floating IP
|
||||||
|
|
||||||
|
err := floatingips.Delete(computeClient, "floatingip-id").ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Associate a Floating IP With a Server
|
||||||
|
|
||||||
|
associateOpts := floatingips.AssociateOpts{
|
||||||
|
FloatingIP: "10.10.10.2",
|
||||||
|
}
|
||||||
|
|
||||||
|
err := floatingips.AssociateInstance(computeClient, "server-id", associateOpts).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Disassociate a Floating IP From a Server
|
||||||
|
|
||||||
|
disassociateOpts := floatingips.DisassociateOpts{
|
||||||
|
FloatingIP: "10.10.10.2",
|
||||||
|
}
|
||||||
|
|
||||||
|
err := floatingips.DisassociateInstance(computeClient, "server-id", disassociateOpts).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package floatingips
|
package floatingips
|
||||||
|
|
|
@ -12,15 +12,15 @@ func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
// CreateOpts struct in this package does.
|
// Create request.
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToFloatingIPCreateMap() (map[string]interface{}, error)
|
ToFloatingIPCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOpts specifies a Floating IP allocation request
|
// CreateOpts specifies a Floating IP allocation request.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
// Pool is the pool of floating IPs to allocate one from
|
// Pool is the pool of Floating IPs to allocate one from.
|
||||||
Pool string `json:"pool" required:"true"`
|
Pool string `json:"pool" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "")
|
return gophercloud.BuildRequestBody(opts, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create requests the creation of a new floating IP
|
// Create requests the creation of a new Floating IP.
|
||||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
b, err := opts.ToFloatingIPCreateMap()
|
b, err := opts.ToFloatingIPCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -42,29 +42,30 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns data about a previously created FloatingIP.
|
// Get returns data about a previously created Floating IP.
|
||||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete requests the deletion of a previous allocated FloatingIP.
|
// Delete requests the deletion of a previous allocated Floating IP.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssociateOptsBuilder is the interface types must satfisfy to be used as
|
// AssociateOptsBuilder allows extensions to add additional parameters to the
|
||||||
// Associate options
|
// Associate request.
|
||||||
type AssociateOptsBuilder interface {
|
type AssociateOptsBuilder interface {
|
||||||
ToFloatingIPAssociateMap() (map[string]interface{}, error)
|
ToFloatingIPAssociateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssociateOpts specifies the required information to associate a floating IP with an instance
|
// AssociateOpts specifies the required information to associate a Floating IP with an instance
|
||||||
type AssociateOpts struct {
|
type AssociateOpts struct {
|
||||||
// FloatingIP is the floating IP to associate with an instance
|
// FloatingIP is the Floating IP to associate with an instance.
|
||||||
FloatingIP string `json:"address" required:"true"`
|
FloatingIP string `json:"address" required:"true"`
|
||||||
// FixedIP is an optional fixed IP address of the server
|
|
||||||
|
// FixedIP is an optional fixed IP address of the server.
|
||||||
FixedIP string `json:"fixed_address,omitempty"`
|
FixedIP string `json:"fixed_address,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ func (opts AssociateOpts) ToFloatingIPAssociateMap() (map[string]interface{}, er
|
||||||
return gophercloud.BuildRequestBody(opts, "addFloatingIp")
|
return gophercloud.BuildRequestBody(opts, "addFloatingIp")
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssociateInstance pairs an allocated floating IP with an instance.
|
// AssociateInstance pairs an allocated Floating IP with a server.
|
||||||
func AssociateInstance(client *gophercloud.ServiceClient, serverID string, opts AssociateOptsBuilder) (r AssociateResult) {
|
func AssociateInstance(client *gophercloud.ServiceClient, serverID string, opts AssociateOptsBuilder) (r AssociateResult) {
|
||||||
b, err := opts.ToFloatingIPAssociateMap()
|
b, err := opts.ToFloatingIPAssociateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -84,23 +85,24 @@ func AssociateInstance(client *gophercloud.ServiceClient, serverID string, opts
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisassociateOptsBuilder is the interface types must satfisfy to be used as
|
// DisassociateOptsBuilder allows extensions to add additional parameters to
|
||||||
// Disassociate options
|
// the Disassociate request.
|
||||||
type DisassociateOptsBuilder interface {
|
type DisassociateOptsBuilder interface {
|
||||||
ToFloatingIPDisassociateMap() (map[string]interface{}, error)
|
ToFloatingIPDisassociateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisassociateOpts specifies the required information to disassociate a floating IP with an instance
|
// DisassociateOpts specifies the required information to disassociate a
|
||||||
|
// Floating IP with a server.
|
||||||
type DisassociateOpts struct {
|
type DisassociateOpts struct {
|
||||||
FloatingIP string `json:"address" required:"true"`
|
FloatingIP string `json:"address" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToFloatingIPDisassociateMap constructs a request body from AssociateOpts.
|
// ToFloatingIPDisassociateMap constructs a request body from DisassociateOpts.
|
||||||
func (opts DisassociateOpts) ToFloatingIPDisassociateMap() (map[string]interface{}, error) {
|
func (opts DisassociateOpts) ToFloatingIPDisassociateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "removeFloatingIp")
|
return gophercloud.BuildRequestBody(opts, "removeFloatingIp")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisassociateInstance decouples an allocated floating IP from an instance
|
// DisassociateInstance decouples an allocated Floating IP from an instance
|
||||||
func DisassociateInstance(client *gophercloud.ServiceClient, serverID string, opts DisassociateOptsBuilder) (r DisassociateResult) {
|
func DisassociateInstance(client *gophercloud.ServiceClient, serverID string, opts DisassociateOptsBuilder) (r DisassociateResult) {
|
||||||
b, err := opts.ToFloatingIPDisassociateMap()
|
b, err := opts.ToFloatingIPDisassociateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -8,21 +8,21 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A FloatingIP is an IP that can be associated with an instance
|
// A FloatingIP is an IP that can be associated with a server.
|
||||||
type FloatingIP struct {
|
type FloatingIP struct {
|
||||||
// ID is a unique ID of the Floating IP
|
// ID is a unique ID of the Floating IP
|
||||||
ID string `json:"-"`
|
ID string `json:"-"`
|
||||||
|
|
||||||
// FixedIP is the IP of the instance related to the Floating IP
|
// FixedIP is a specific IP on the server to pair the Floating IP with.
|
||||||
FixedIP string `json:"fixed_ip,omitempty"`
|
FixedIP string `json:"fixed_ip,omitempty"`
|
||||||
|
|
||||||
// InstanceID is the ID of the instance that is using the Floating IP
|
// InstanceID is the ID of the server that is using the Floating IP.
|
||||||
InstanceID string `json:"instance_id"`
|
InstanceID string `json:"instance_id"`
|
||||||
|
|
||||||
// IP is the actual Floating IP
|
// IP is the actual Floating IP.
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
|
|
||||||
// Pool is the pool of floating IPs that this floating IP belongs to
|
// Pool is the pool of Floating IPs that this Floating IP belongs to.
|
||||||
Pool string `json:"pool"`
|
Pool string `json:"pool"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +49,7 @@ func (r *FloatingIP) UnmarshalJSON(b []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FloatingIPPage stores a single, only page of FloatingIPs
|
// FloatingIPPage stores a single page of FloatingIPs from a List call.
|
||||||
// results from a List call.
|
|
||||||
type FloatingIPPage struct {
|
type FloatingIPPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
@ -61,8 +60,7 @@ func (page FloatingIPPage) IsEmpty() (bool, error) {
|
||||||
return len(va) == 0, err
|
return len(va) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractFloatingIPs interprets a page of results as a slice of
|
// ExtractFloatingIPs interprets a page of results as a slice of FloatingIPs.
|
||||||
// FloatingIPs.
|
|
||||||
func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) {
|
func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
FloatingIPs []FloatingIP `json:"floating_ips"`
|
FloatingIPs []FloatingIP `json:"floating_ips"`
|
||||||
|
@ -86,32 +84,32 @@ func (r FloatingIPResult) Extract() (*FloatingIP, error) {
|
||||||
return s.FloatingIP, err
|
return s.FloatingIP, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
// as a FloatingIP.
|
// to interpret it as a FloatingIP.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
FloatingIPResult
|
FloatingIPResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult is the response from a Get operation. Call its Extract method to interpret it
|
// GetResult is the response from a Get operation. Call its Extract method to
|
||||||
// as a FloatingIP.
|
// interpret it as a FloatingIP.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
FloatingIPResult
|
FloatingIPResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult is the response from a Delete operation. Call its Extract method to determine if
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||||
// the call succeeded or failed.
|
// method to determine if the call succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssociateResult is the response from a Delete operation. Call its Extract method to determine if
|
// AssociateResult is the response from a Delete operation. Call its ExtractErr
|
||||||
// the call succeeded or failed.
|
// method to determine if the call succeeded or failed.
|
||||||
type AssociateResult struct {
|
type AssociateResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisassociateResult is the response from a Delete operation. Call its Extract method to determine if
|
// DisassociateResult is the response from a Delete operation. Call its
|
||||||
// the call succeeded or failed.
|
// ExtractErr method to determine if the call succeeded or failed.
|
||||||
type DisassociateResult struct {
|
type DisassociateResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,71 @@
|
||||||
// Package keypairs provides information and interaction with the Keypairs
|
/*
|
||||||
// extension for the OpenStack Compute service.
|
Package keypairs provides the ability to manage key pairs as well as create
|
||||||
|
servers with a specified key pair.
|
||||||
|
|
||||||
|
Example to List Key Pairs
|
||||||
|
|
||||||
|
allPages, err := keypairs.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allKeyPairs, err := keypairs.ExtractKeyPairs(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kp := range allKeyPairs {
|
||||||
|
fmt.Printf("%+v\n", kp)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Key Pair
|
||||||
|
|
||||||
|
createOpts := keypairs.CreateOpts{
|
||||||
|
Name: "keypair-name",
|
||||||
|
}
|
||||||
|
|
||||||
|
keypair, err := keypairs.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%+v", keypair)
|
||||||
|
|
||||||
|
Example to Import a Key Pair
|
||||||
|
|
||||||
|
createOpts := keypairs.CreateOpts{
|
||||||
|
Name: "keypair-name",
|
||||||
|
PublicKey: "public-key",
|
||||||
|
}
|
||||||
|
|
||||||
|
keypair, err := keypairs.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Key Pair
|
||||||
|
|
||||||
|
err := keypairs.Delete(computeClient, "keypair-name").ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Server With a Key Pair
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_name",
|
||||||
|
ImageRef: "image-uuid",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := keypairs.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
KeyName: "keypair-name",
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := servers.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package keypairs
|
package keypairs
|
||||||
|
|
|
@ -9,11 +9,12 @@ import (
|
||||||
// CreateOptsExt adds a KeyPair option to the base CreateOpts.
|
// CreateOptsExt adds a KeyPair option to the base CreateOpts.
|
||||||
type CreateOptsExt struct {
|
type CreateOptsExt struct {
|
||||||
servers.CreateOptsBuilder
|
servers.CreateOptsBuilder
|
||||||
|
|
||||||
|
// KeyName is the name of the key pair.
|
||||||
KeyName string `json:"key_name,omitempty"`
|
KeyName string `json:"key_name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToServerCreateMap adds the key_name and, optionally, key_data options to
|
// ToServerCreateMap adds the key_name to the base server creation options.
|
||||||
// the base server creation options.
|
|
||||||
func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
|
func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
|
||||||
base, err := opts.CreateOptsBuilder.ToServerCreateMap()
|
base, err := opts.CreateOptsBuilder.ToServerCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -37,18 +38,19 @@ func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
// CreateOpts struct in this package does.
|
// Create request.
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToKeyPairCreateMap() (map[string]interface{}, error)
|
ToKeyPairCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOpts specifies keypair creation or import parameters.
|
// CreateOpts specifies KeyPair creation or import parameters.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
// Name is a friendly name to refer to this KeyPair in other services.
|
// Name is a friendly name to refer to this KeyPair in other services.
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
// PublicKey [optional] is a pregenerated OpenSSH-formatted public key. If provided, this key
|
|
||||||
// will be imported and no new key will be created.
|
// PublicKey [optional] is a pregenerated OpenSSH-formatted public key.
|
||||||
|
// If provided, this key will be imported and no new key will be created.
|
||||||
PublicKey string `json:"public_key,omitempty"`
|
PublicKey string `json:"public_key,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +59,8 @@ func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "keypair")
|
return gophercloud.BuildRequestBody(opts, "keypair")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create requests the creation of a new keypair on the server, or to import a pre-existing
|
// Create requests the creation of a new KeyPair on the server, or to import a
|
||||||
// keypair.
|
// pre-existing keypair.
|
||||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
b, err := opts.ToKeyPairCreateMap()
|
b, err := opts.ToKeyPairCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,29 +5,33 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// KeyPair is an SSH key known to the OpenStack Cloud that is available to be injected into
|
// KeyPair is an SSH key known to the OpenStack Cloud that is available to be
|
||||||
// servers.
|
// injected into servers.
|
||||||
type KeyPair struct {
|
type KeyPair struct {
|
||||||
// Name is used to refer to this keypair from other services within this region.
|
// Name is used to refer to this keypair from other services within this
|
||||||
|
// region.
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
// Fingerprint is a short sequence of bytes that can be used to authenticate or validate a longer
|
// Fingerprint is a short sequence of bytes that can be used to authenticate
|
||||||
// public key.
|
// or validate a longer public key.
|
||||||
Fingerprint string `json:"fingerprint"`
|
Fingerprint string `json:"fingerprint"`
|
||||||
|
|
||||||
// PublicKey is the public key from this pair, in OpenSSH format. "ssh-rsa AAAAB3Nz..."
|
// PublicKey is the public key from this pair, in OpenSSH format.
|
||||||
|
// "ssh-rsa AAAAB3Nz..."
|
||||||
PublicKey string `json:"public_key"`
|
PublicKey string `json:"public_key"`
|
||||||
|
|
||||||
// PrivateKey is the private key from this pair, in PEM format.
|
// PrivateKey is the private key from this pair, in PEM format.
|
||||||
// "-----BEGIN RSA PRIVATE KEY-----\nMIICXA..." It is only present if this keypair was just
|
// "-----BEGIN RSA PRIVATE KEY-----\nMIICXA..."
|
||||||
// returned from a Create call
|
// It is only present if this KeyPair was just returned from a Create call.
|
||||||
PrivateKey string `json:"private_key"`
|
PrivateKey string `json:"private_key"`
|
||||||
|
|
||||||
// UserID is the user who owns this keypair.
|
// UserID is the user who owns this KeyPair.
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyPairPage stores a single, only page of KeyPair results from a List call.
|
// KeyPairPage stores a single page of all KeyPair results from a List call.
|
||||||
|
// Use the ExtractKeyPairs function to convert the results to a slice of
|
||||||
|
// KeyPairs.
|
||||||
type KeyPairPage struct {
|
type KeyPairPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
@ -58,7 +62,8 @@ type keyPairResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract is a method that attempts to interpret any KeyPair resource response as a KeyPair struct.
|
// Extract is a method that attempts to interpret any KeyPair resource response
|
||||||
|
// as a KeyPair struct.
|
||||||
func (r keyPairResult) Extract() (*KeyPair, error) {
|
func (r keyPairResult) Extract() (*KeyPair, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
KeyPair *KeyPair `json:"keypair"`
|
KeyPair *KeyPair `json:"keypair"`
|
||||||
|
@ -67,20 +72,20 @@ func (r keyPairResult) Extract() (*KeyPair, error) {
|
||||||
return s.KeyPair, err
|
return s.KeyPair, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
// as a KeyPair.
|
// to interpret it as a KeyPair.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
keyPairResult
|
keyPairResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult is the response from a Get operation. Call its Extract method to interpret it
|
// GetResult is the response from a Get operation. Call its Extract method to
|
||||||
// as a KeyPair.
|
// interpret it as a KeyPair.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
keyPairResult
|
keyPairResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult is the response from a Delete operation. Call its Extract method to determine if
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||||
// the call succeeded or failed.
|
// method to determine if the call succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,76 @@
|
||||||
// Package schedulerhints enables instances to provide the OpenStack scheduler
|
/*
|
||||||
// hints about where they should be placed in the cloud.
|
Package schedulerhints extends the server create request with the ability to
|
||||||
|
specify additional parameters which determine where the server will be
|
||||||
|
created in the OpenStack cloud.
|
||||||
|
|
||||||
|
Example to Add a Server to a Server Group
|
||||||
|
|
||||||
|
schedulerHints := schedulerhints.SchedulerHints{
|
||||||
|
Group: "servergroup-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_name",
|
||||||
|
ImageRef: "image-uuid",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := schedulerhints.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
SchedulerHints: schedulerHints,
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := servers.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Place Server B on a Different Host than Server A
|
||||||
|
|
||||||
|
schedulerHints := schedulerhints.SchedulerHints{
|
||||||
|
DifferentHost: []string{
|
||||||
|
"server-a-uuid",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_b",
|
||||||
|
ImageRef: "image-uuid",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := schedulerhints.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
SchedulerHints: schedulerHints,
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := servers.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Place Server B on the Same Host as Server A
|
||||||
|
|
||||||
|
schedulerHints := schedulerhints.SchedulerHints{
|
||||||
|
SameHost: []string{
|
||||||
|
"server-a-uuid",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCreateOpts := servers.CreateOpts{
|
||||||
|
Name: "server_b",
|
||||||
|
ImageRef: "image-uuid",
|
||||||
|
FlavorRef: "flavor-uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := schedulerhints.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: serverCreateOpts,
|
||||||
|
SchedulerHints: schedulerHints,
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := servers.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package schedulerhints
|
package schedulerhints
|
||||||
|
|
|
@ -10,23 +10,29 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// SchedulerHints represents a set of scheduling hints that are passed to the
|
// SchedulerHints represents a set of scheduling hints that are passed to the
|
||||||
// OpenStack scheduler
|
// OpenStack scheduler.
|
||||||
type SchedulerHints struct {
|
type SchedulerHints struct {
|
||||||
// Group specifies a Server Group to place the instance in.
|
// Group specifies a Server Group to place the instance in.
|
||||||
Group string
|
Group string
|
||||||
|
|
||||||
// DifferentHost will place the instance on a compute node that does not
|
// DifferentHost will place the instance on a compute node that does not
|
||||||
// host the given instances.
|
// host the given instances.
|
||||||
DifferentHost []string
|
DifferentHost []string
|
||||||
|
|
||||||
// SameHost will place the instance on a compute node that hosts the given
|
// SameHost will place the instance on a compute node that hosts the given
|
||||||
// instances.
|
// instances.
|
||||||
SameHost []string
|
SameHost []string
|
||||||
|
|
||||||
// Query is a conditional statement that results in compute nodes able to
|
// Query is a conditional statement that results in compute nodes able to
|
||||||
// host the instance.
|
// host the instance.
|
||||||
Query []interface{}
|
Query []interface{}
|
||||||
|
|
||||||
// TargetCell specifies a cell name where the instance will be placed.
|
// TargetCell specifies a cell name where the instance will be placed.
|
||||||
TargetCell string `json:"target_cell,omitempty"`
|
TargetCell string `json:"target_cell,omitempty"`
|
||||||
|
|
||||||
// BuildNearHostIP specifies a subnet of compute nodes to host the instance.
|
// BuildNearHostIP specifies a subnet of compute nodes to host the instance.
|
||||||
BuildNearHostIP string
|
BuildNearHostIP string
|
||||||
|
|
||||||
// AdditionalProperies are arbitrary key/values that are not validated by nova.
|
// AdditionalProperies are arbitrary key/values that are not validated by nova.
|
||||||
AdditionalProperties map[string]interface{}
|
AdditionalProperties map[string]interface{}
|
||||||
}
|
}
|
||||||
|
@ -79,8 +85,9 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
|
||||||
sh["same_host"] = opts.SameHost
|
sh["same_host"] = opts.SameHost
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query can be something simple like:
|
/*
|
||||||
[">=", "$free_ram_mb", 1024]
|
Query can be something simple like:
|
||||||
|
[">=", "$free_ram_mb", 1024]
|
||||||
|
|
||||||
Or more complex like:
|
Or more complex like:
|
||||||
['and',
|
['and',
|
||||||
|
@ -130,6 +137,7 @@ func (opts SchedulerHints) ToServerSchedulerHintsCreateMap() (map[string]interfa
|
||||||
// CreateOptsExt adds a SchedulerHints option to the base CreateOpts.
|
// CreateOptsExt adds a SchedulerHints option to the base CreateOpts.
|
||||||
type CreateOptsExt struct {
|
type CreateOptsExt struct {
|
||||||
servers.CreateOptsBuilder
|
servers.CreateOptsBuilder
|
||||||
|
|
||||||
// SchedulerHints provides a set of hints to the scheduler.
|
// SchedulerHints provides a set of hints to the scheduler.
|
||||||
SchedulerHints CreateOptsBuilder
|
SchedulerHints CreateOptsBuilder
|
||||||
}
|
}
|
||||||
|
|
111
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups/doc.go
generated
vendored
111
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups/doc.go
generated
vendored
|
@ -1 +1,112 @@
|
||||||
|
/*
|
||||||
|
Package secgroups provides the ability to manage security groups through the
|
||||||
|
Nova API.
|
||||||
|
|
||||||
|
This API has been deprecated and will be removed from a future release of the
|
||||||
|
Nova API service.
|
||||||
|
|
||||||
|
For environments that support this extension, this package can be used
|
||||||
|
regardless of if either Neutron or nova-network is used as the cloud's network
|
||||||
|
service.
|
||||||
|
|
||||||
|
Example to List Security Groups
|
||||||
|
|
||||||
|
allPages, err := secroups.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allSecurityGroups, err := secgroups.ExtractSecurityGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sg := range allSecurityGroups {
|
||||||
|
fmt.Printf("%+v\n", sg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to List Security Groups by Server
|
||||||
|
|
||||||
|
serverID := "aab3ad01-9956-4623-a29b-24afc89a7d36"
|
||||||
|
|
||||||
|
allPages, err := secroups.ListByServer(computeClient, serverID).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allSecurityGroups, err := secgroups.ExtractSecurityGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sg := range allSecurityGroups {
|
||||||
|
fmt.Printf("%+v\n", sg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Security Group
|
||||||
|
|
||||||
|
createOpts := secgroups.CreateOpts{
|
||||||
|
Name: "group_name",
|
||||||
|
Description: "A Security Group",
|
||||||
|
}
|
||||||
|
|
||||||
|
sg, err := secgroups.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Security Group Rule
|
||||||
|
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
|
||||||
|
createOpts := secgroups.CreateRuleOpts{
|
||||||
|
ParentGroupID: sgID,
|
||||||
|
FromPort: 22,
|
||||||
|
ToPort: 22,
|
||||||
|
IPProtocol: "tcp",
|
||||||
|
CIDR: "0.0.0.0/0",
|
||||||
|
}
|
||||||
|
|
||||||
|
rule, err := secgroups.CreateRule(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Add a Security Group to a Server
|
||||||
|
|
||||||
|
serverID := "aab3ad01-9956-4623-a29b-24afc89a7d36"
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
|
||||||
|
err := secgroups.AddServer(computeClient, serverID, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Remove a Security Group from a Server
|
||||||
|
|
||||||
|
serverID := "aab3ad01-9956-4623-a29b-24afc89a7d36"
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
|
||||||
|
err := secgroups.RemoveServer(computeClient, serverID, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Security Group
|
||||||
|
|
||||||
|
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
err := secgroups.Delete(computeClient, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Security Group Rule
|
||||||
|
|
||||||
|
ruleID := "6221fe3e-383d-46c9-a3a6-845e66c1e8b4"
|
||||||
|
err := secgroups.DeleteRule(computeClient, ruleID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package secgroups
|
package secgroups
|
||||||
|
|
|
@ -23,25 +23,21 @@ func ListByServer(client *gophercloud.ServiceClient, serverID string) pagination
|
||||||
return commonList(client, listByServerURL(client, serverID))
|
return commonList(client, listByServerURL(client, serverID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GroupOpts is the underlying struct responsible for creating or updating
|
// CreateOpts is the struct responsible for creating a security group.
|
||||||
// security groups. It therefore represents the mutable attributes of a
|
type CreateOpts struct {
|
||||||
// security group.
|
|
||||||
type GroupOpts struct {
|
|
||||||
// the name of your security group.
|
// the name of your security group.
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
// the description of your security group.
|
// the description of your security group.
|
||||||
Description string `json:"description" required:"true"`
|
Description string `json:"description,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOpts is the struct responsible for creating a security group.
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
type CreateOpts GroupOpts
|
// Create request.
|
||||||
|
|
||||||
// CreateOptsBuilder builds the create options into a serializable format.
|
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToSecGroupCreateMap() (map[string]interface{}, error)
|
ToSecGroupCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToSecGroupCreateMap builds the create options into a serializable format.
|
// ToSecGroupCreateMap builds a request body from CreateOpts.
|
||||||
func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) {
|
func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "security_group")
|
return gophercloud.BuildRequestBody(opts, "security_group")
|
||||||
}
|
}
|
||||||
|
@ -60,14 +56,20 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOpts is the struct responsible for updating an existing security group.
|
// UpdateOpts is the struct responsible for updating an existing security group.
|
||||||
type UpdateOpts GroupOpts
|
type UpdateOpts struct {
|
||||||
|
// the name of your security group.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
// the description of your security group.
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateOptsBuilder builds the update options into a serializable format.
|
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Update request.
|
||||||
type UpdateOptsBuilder interface {
|
type UpdateOptsBuilder interface {
|
||||||
ToSecGroupUpdateMap() (map[string]interface{}, error)
|
ToSecGroupUpdateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToSecGroupUpdateMap builds the update options into a serializable format.
|
// ToSecGroupUpdateMap builds a request body from UpdateOpts.
|
||||||
func (opts UpdateOpts) ToSecGroupUpdateMap() (map[string]interface{}, error) {
|
func (opts UpdateOpts) ToSecGroupUpdateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "security_group")
|
return gophercloud.BuildRequestBody(opts, "security_group")
|
||||||
}
|
}
|
||||||
|
@ -93,7 +95,7 @@ func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete will permanently delete a security group from the project.
|
// Delete will permanently delete a security group from the project.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(resourceURL(client, id), nil)
|
_, r.Err = client.Delete(resourceURL(client, id), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -101,31 +103,41 @@ func Delete(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResu
|
||||||
// CreateRuleOpts represents the configuration for adding a new rule to an
|
// CreateRuleOpts represents the configuration for adding a new rule to an
|
||||||
// existing security group.
|
// existing security group.
|
||||||
type CreateRuleOpts struct {
|
type CreateRuleOpts struct {
|
||||||
// the ID of the group that this rule will be added to.
|
// ID is the ID of the group that this rule will be added to.
|
||||||
ParentGroupID string `json:"parent_group_id" required:"true"`
|
ParentGroupID string `json:"parent_group_id" required:"true"`
|
||||||
// the lower bound of the port range that will be opened.
|
|
||||||
|
// FromPort is the lower bound of the port range that will be opened.
|
||||||
|
// Use -1 to allow all ICMP traffic.
|
||||||
FromPort int `json:"from_port"`
|
FromPort int `json:"from_port"`
|
||||||
// the upper bound of the port range that will be opened.
|
|
||||||
|
// ToPort is the upper bound of the port range that will be opened.
|
||||||
|
// Use -1 to allow all ICMP traffic.
|
||||||
ToPort int `json:"to_port"`
|
ToPort int `json:"to_port"`
|
||||||
// the protocol type that will be allowed, e.g. TCP.
|
|
||||||
|
// IPProtocol the protocol type that will be allowed, e.g. TCP.
|
||||||
IPProtocol string `json:"ip_protocol" required:"true"`
|
IPProtocol string `json:"ip_protocol" required:"true"`
|
||||||
// ONLY required if FromGroupID is blank. This represents the IP range that
|
|
||||||
// will be the source of network traffic to your security group. Use
|
// CIDR is the network CIDR to allow traffic from.
|
||||||
// 0.0.0.0/0 to allow all IP addresses.
|
// This is ONLY required if FromGroupID is blank. This represents the IP
|
||||||
|
// range that will be the source of network traffic to your security group.
|
||||||
|
// Use 0.0.0.0/0 to allow all IP addresses.
|
||||||
CIDR string `json:"cidr,omitempty" or:"FromGroupID"`
|
CIDR string `json:"cidr,omitempty" or:"FromGroupID"`
|
||||||
// ONLY required if CIDR is blank. This value represents the ID of a group
|
|
||||||
// that forwards traffic to the parent group. So, instead of accepting
|
// FromGroupID represents another security group to allow access.
|
||||||
|
// This is ONLY required if CIDR is blank. This value represents the ID of a
|
||||||
|
// group that forwards traffic to the parent group. So, instead of accepting
|
||||||
// network traffic from an entire IP range, you can instead refine the
|
// network traffic from an entire IP range, you can instead refine the
|
||||||
// inbound source by an existing security group.
|
// inbound source by an existing security group.
|
||||||
FromGroupID string `json:"group_id,omitempty" or:"CIDR"`
|
FromGroupID string `json:"group_id,omitempty" or:"CIDR"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRuleOptsBuilder builds the create rule options into a serializable format.
|
// CreateRuleOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// CreateRule request.
|
||||||
type CreateRuleOptsBuilder interface {
|
type CreateRuleOptsBuilder interface {
|
||||||
ToRuleCreateMap() (map[string]interface{}, error)
|
ToRuleCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToRuleCreateMap builds the create rule options into a serializable format.
|
// ToRuleCreateMap builds a request body from CreateRuleOpts.
|
||||||
func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
|
func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "security_group_rule")
|
return gophercloud.BuildRequestBody(opts, "security_group_rule")
|
||||||
}
|
}
|
||||||
|
@ -146,7 +158,7 @@ func CreateRule(client *gophercloud.ServiceClient, opts CreateRuleOptsBuilder) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRule will permanently delete a rule from a security group.
|
// DeleteRule will permanently delete a rule from a security group.
|
||||||
func DeleteRule(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func DeleteRule(client *gophercloud.ServiceClient, id string) (r DeleteRuleResult) {
|
||||||
_, r.Err = client.Delete(resourceRuleURL(client, id), nil)
|
_, r.Err = client.Delete(resourceRuleURL(client, id), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -159,13 +171,13 @@ func actionMap(prefix, groupName string) map[string]map[string]string {
|
||||||
|
|
||||||
// AddServer will associate a server and a security group, enforcing the
|
// AddServer will associate a server and a security group, enforcing the
|
||||||
// rules of the group on the server.
|
// rules of the group on the server.
|
||||||
func AddServer(client *gophercloud.ServiceClient, serverID, groupName string) (r gophercloud.ErrResult) {
|
func AddServer(client *gophercloud.ServiceClient, serverID, groupName string) (r AddServerResult) {
|
||||||
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("add", groupName), &r.Body, nil)
|
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("add", groupName), nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveServer will disassociate a server from a security group.
|
// RemoveServer will disassociate a server from a security group.
|
||||||
func RemoveServer(client *gophercloud.ServiceClient, serverID, groupName string) (r gophercloud.ErrResult) {
|
func RemoveServer(client *gophercloud.ServiceClient, serverID, groupName string) (r RemoveServerResult) {
|
||||||
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("remove", groupName), &r.Body, nil)
|
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("remove", groupName), nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,20 +59,20 @@ type Rule struct {
|
||||||
// numeric ID. For the sake of consistency, we always cast it to a string.
|
// numeric ID. For the sake of consistency, we always cast it to a string.
|
||||||
ID string `json:"-"`
|
ID string `json:"-"`
|
||||||
|
|
||||||
// The lower bound of the port range which this security group should open up
|
// The lower bound of the port range which this security group should open up.
|
||||||
FromPort int `json:"from_port"`
|
FromPort int `json:"from_port"`
|
||||||
|
|
||||||
// The upper bound of the port range which this security group should open up
|
// The upper bound of the port range which this security group should open up.
|
||||||
ToPort int `json:"to_port"`
|
ToPort int `json:"to_port"`
|
||||||
|
|
||||||
// The IP protocol (e.g. TCP) which the security group accepts
|
// The IP protocol (e.g. TCP) which the security group accepts.
|
||||||
IPProtocol string `json:"ip_protocol"`
|
IPProtocol string `json:"ip_protocol"`
|
||||||
|
|
||||||
// The CIDR IP range whose traffic can be received
|
// The CIDR IP range whose traffic can be received.
|
||||||
IPRange IPRange `json:"ip_range"`
|
IPRange IPRange `json:"ip_range"`
|
||||||
|
|
||||||
// The security group ID to which this rule belongs
|
// The security group ID to which this rule belongs.
|
||||||
ParentGroupID string `json:"parent_group_id"`
|
ParentGroupID string `json:"-"`
|
||||||
|
|
||||||
// Not documented.
|
// Not documented.
|
||||||
Group Group
|
Group Group
|
||||||
|
@ -126,13 +126,15 @@ type SecurityGroupPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty determines whether or not a page of Security Groups contains any results.
|
// IsEmpty determines whether or not a page of Security Groups contains any
|
||||||
|
// results.
|
||||||
func (page SecurityGroupPage) IsEmpty() (bool, error) {
|
func (page SecurityGroupPage) IsEmpty() (bool, error) {
|
||||||
users, err := ExtractSecurityGroups(page)
|
users, err := ExtractSecurityGroups(page)
|
||||||
return len(users) == 0, err
|
return len(users) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractSecurityGroups returns a slice of SecurityGroups contained in a single page of results.
|
// ExtractSecurityGroups returns a slice of SecurityGroups contained in a
|
||||||
|
// single page of results.
|
||||||
func ExtractSecurityGroups(r pagination.Page) ([]SecurityGroup, error) {
|
func ExtractSecurityGroups(r pagination.Page) ([]SecurityGroup, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
SecurityGroups []SecurityGroup `json:"security_groups"`
|
SecurityGroups []SecurityGroup `json:"security_groups"`
|
||||||
|
@ -145,17 +147,20 @@ type commonResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult represents the result of a create operation.
|
// CreateResult represents the result of a create operation. Call its Extract
|
||||||
|
// method to interpret the result as a SecurityGroup.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult represents the result of a get operation.
|
// GetResult represents the result of a get operation. Call its Extract
|
||||||
|
// method to interpret the result as a SecurityGroup.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateResult represents the result of an update operation.
|
// UpdateResult represents the result of an update operation. Call its Extract
|
||||||
|
// method to interpret the result as a SecurityGroup.
|
||||||
type UpdateResult struct {
|
type UpdateResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
@ -170,6 +175,7 @@ func (r commonResult) Extract() (*SecurityGroup, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRuleResult represents the result when adding rules to a security group.
|
// CreateRuleResult represents the result when adding rules to a security group.
|
||||||
|
// Call its Extract method to interpret the result as a Rule.
|
||||||
type CreateRuleResult struct {
|
type CreateRuleResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
@ -182,3 +188,27 @@ func (r CreateRuleResult) Extract() (*Rule, error) {
|
||||||
err := r.ExtractInto(&s)
|
err := r.ExtractInto(&s)
|
||||||
return s.Rule, err
|
return s.Rule, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the response from delete operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRuleResult is the response from a DeleteRule operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type DeleteRuleResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddServerResult is the response from an AddServer operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type AddServerResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveServerResult is the response from a RemoveServer operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type RemoveServerResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,40 @@
|
||||||
// Package servergroups provides the ability to manage server groups
|
/*
|
||||||
|
Package servergroups provides the ability to manage server groups.
|
||||||
|
|
||||||
|
Example to List Server Groups
|
||||||
|
|
||||||
|
allpages, err := servergroups.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allServerGroups, err := servergroups.ExtractServerGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sg := range allServerGroups {
|
||||||
|
fmt.Printf("%#v\n", sg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Server Group
|
||||||
|
|
||||||
|
createOpts := servergroups.CreateOpts{
|
||||||
|
Name: "my_sg",
|
||||||
|
Policies: []string{"anti-affinity"},
|
||||||
|
}
|
||||||
|
|
||||||
|
sg, err := servergroups.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Server Group
|
||||||
|
|
||||||
|
sgID := "7a6f29ad-e34d-4368-951a-58a08f11cfb7"
|
||||||
|
err := servergroups.Delete(computeClient, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package servergroups
|
package servergroups
|
||||||
|
|
|
@ -5,23 +5,25 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// List returns a Pager that allows you to iterate over a collection of ServerGroups.
|
// List returns a Pager that allows you to iterate over a collection of
|
||||||
|
// ServerGroups.
|
||||||
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
||||||
return ServerGroupPage{pagination.SinglePageBase(r)}
|
return ServerGroupPage{pagination.SinglePageBase(r)}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notably, the
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
// CreateOpts struct in this package does.
|
// Create request.
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToServerGroupCreateMap() (map[string]interface{}, error)
|
ToServerGroupCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOpts specifies a Server Group allocation request
|
// CreateOpts specifies Server Group creation parameters.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
// Name is the name of the server group
|
// Name is the name of the server group
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
|
|
||||||
// Policies are the server group policies
|
// Policies are the server group policies
|
||||||
Policies []string `json:"policies" required:"true"`
|
Policies []string `json:"policies" required:"true"`
|
||||||
}
|
}
|
||||||
|
@ -31,7 +33,7 @@ func (opts CreateOpts) ToServerGroupCreateMap() (map[string]interface{}, error)
|
||||||
return gophercloud.BuildRequestBody(opts, "server_group")
|
return gophercloud.BuildRequestBody(opts, "server_group")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create requests the creation of a new Server Group
|
// Create requests the creation of a new Server Group.
|
||||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
b, err := opts.ToServerGroupCreateMap()
|
b, err := opts.ToServerGroupCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A ServerGroup creates a policy for instance placement in the cloud
|
// A ServerGroup creates a policy for instance placement in the cloud.
|
||||||
type ServerGroup struct {
|
type ServerGroup struct {
|
||||||
// ID is the unique ID of the Server Group.
|
// ID is the unique ID of the Server Group.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
@ -14,17 +14,26 @@ type ServerGroup struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
// Polices are the group policies.
|
// Polices are the group policies.
|
||||||
|
//
|
||||||
|
// Normally a single policy is applied:
|
||||||
|
//
|
||||||
|
// "affinity" will place all servers within the server group on the
|
||||||
|
// same compute node.
|
||||||
|
//
|
||||||
|
// "anti-affinity" will place servers within the server group on different
|
||||||
|
// compute nodes.
|
||||||
Policies []string `json:"policies"`
|
Policies []string `json:"policies"`
|
||||||
|
|
||||||
// Members are the members of the server group.
|
// Members are the members of the server group.
|
||||||
Members []string `json:"members"`
|
Members []string `json:"members"`
|
||||||
|
|
||||||
// Metadata includes a list of all user-specified key-value pairs attached to the Server Group.
|
// Metadata includes a list of all user-specified key-value pairs attached
|
||||||
|
// to the Server Group.
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerGroupPage stores a single, only page of ServerGroups
|
// ServerGroupPage stores a single page of all ServerGroups results from a
|
||||||
// results from a List call.
|
// List call.
|
||||||
type ServerGroupPage struct {
|
type ServerGroupPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
@ -59,20 +68,20 @@ func (r ServerGroupResult) Extract() (*ServerGroup, error) {
|
||||||
return s.ServerGroup, err
|
return s.ServerGroup, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
// as a ServerGroup.
|
// to interpret it as a ServerGroup.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
ServerGroupResult
|
ServerGroupResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult is the response from a Get operation. Call its Extract method to interpret it
|
// GetResult is the response from a Get operation. Call its Extract method to
|
||||||
// as a ServerGroup.
|
// interpret it as a ServerGroup.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
ServerGroupResult
|
ServerGroupResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult is the response from a Delete operation. Call its Extract method to determine if
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||||
// the call succeeded or failed.
|
// method to determine if the call succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
/*
|
/*
|
||||||
Package startstop provides functionality to start and stop servers that have
|
Package startstop provides functionality to start and stop servers that have
|
||||||
been provisioned by the OpenStack Compute service.
|
been provisioned by the OpenStack Compute service.
|
||||||
|
|
||||||
|
Example to Stop and Start a Server
|
||||||
|
|
||||||
|
serverID := "47b6b7b7-568d-40e4-868c-d5c41735532e"
|
||||||
|
|
||||||
|
err := startstop.Stop(computeClient, serverID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := startstop.Start(computeClient, serverID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
package startstop
|
package startstop
|
||||||
|
|
|
@ -7,13 +7,13 @@ func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start is the operation responsible for starting a Compute server.
|
// Start is the operation responsible for starting a Compute server.
|
||||||
func Start(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Start(client *gophercloud.ServiceClient, id string) (r StartResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-start": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-start": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop is the operation responsible for stopping a Compute server.
|
// Stop is the operation responsible for stopping a Compute server.
|
||||||
func Stop(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Stop(client *gophercloud.ServiceClient, id string) (r StopResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-stop": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-stop": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop/results.go
generated
vendored
Normal file
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop/results.go
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package startstop
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
// StartResult is the response from a Start operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type StartResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopResult is the response from Stop operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type StopResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
|
@ -1,2 +1,26 @@
|
||||||
// Package tenantnetworks provides the ability for tenants to see information about the networks they have access to
|
/*
|
||||||
|
Package tenantnetworks provides the ability for tenants to see information
|
||||||
|
about the networks they have access to.
|
||||||
|
|
||||||
|
This is a deprecated API and will be removed from the Nova API service in a
|
||||||
|
future version.
|
||||||
|
|
||||||
|
This API works in both Neutron and nova-network based OpenStack clouds.
|
||||||
|
|
||||||
|
Example to List Networks Available to a Tenant
|
||||||
|
|
||||||
|
allPages, err := tenantnetworks.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allNetworks, err := tenantnetworks.ExtractNetworks(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, network := range allNetworks {
|
||||||
|
fmt.Printf("%+v\n", network)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package tenantnetworks
|
package tenantnetworks
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// List returns a Pager that allows you to iterate over a collection of Network.
|
// List returns a Pager that allows you to iterate over a collection of Networks.
|
||||||
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
||||||
return NetworkPage{pagination.SinglePageBase(r)}
|
return NetworkPage{pagination.SinglePageBase(r)}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Network represents a nova-network that an instance communicates on
|
// A Network represents a network that a server communicates on.
|
||||||
type Network struct {
|
type Network struct {
|
||||||
// CIDR is the IPv4 subnet.
|
// CIDR is the IPv4 subnet.
|
||||||
CIDR string `json:"cidr"`
|
CIDR string `json:"cidr"`
|
||||||
|
@ -17,8 +17,7 @@ type Network struct {
|
||||||
Name string `json:"label"`
|
Name string `json:"label"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkPage stores a single, only page of Networks
|
// NetworkPage stores a single page of all Networks results from a List call.
|
||||||
// results from a List call.
|
|
||||||
type NetworkPage struct {
|
type NetworkPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
@ -29,7 +28,7 @@ func (page NetworkPage) IsEmpty() (bool, error) {
|
||||||
return len(va) == 0, err
|
return len(va) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractNetworks interprets a page of results as a slice of Networks
|
// ExtractNetworks interprets a page of results as a slice of Network.
|
||||||
func ExtractNetworks(r pagination.Page) ([]Network, error) {
|
func ExtractNetworks(r pagination.Page) ([]Network, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Networks []Network `json:"networks"`
|
Networks []Network `json:"networks"`
|
||||||
|
@ -42,8 +41,8 @@ type NetworkResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract is a method that attempts to interpret any Network resource
|
// Extract is a method that attempts to interpret any Network resource response
|
||||||
// response as a Network struct.
|
// as a Network struct.
|
||||||
func (r NetworkResult) Extract() (*Network, error) {
|
func (r NetworkResult) Extract() (*Network, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Network *Network `json:"network"`
|
Network *Network `json:"network"`
|
||||||
|
@ -52,8 +51,8 @@ func (r NetworkResult) Extract() (*Network, error) {
|
||||||
return s.Network, err
|
return s.Network, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult is the response from a Get operation. Call its Extract method to interpret it
|
// GetResult is the response from a Get operation. Call its Extract method to
|
||||||
// as a Network.
|
// interpret it as a Network.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
NetworkResult
|
NetworkResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,30 @@
|
||||||
// Package volumeattach provides the ability to attach and detach volumes
|
/*
|
||||||
// to instances
|
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
|
package volumeattach
|
||||||
|
|
|
@ -5,24 +5,26 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// List returns a Pager that allows you to iterate over a collection of VolumeAttachments.
|
// List returns a Pager that allows you to iterate over a collection of
|
||||||
|
// VolumeAttachments.
|
||||||
func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
|
func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
|
||||||
return pagination.NewPager(client, listURL(client, serverID), func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, listURL(client, serverID), func(r pagination.PageResult) pagination.Page {
|
||||||
return VolumeAttachmentPage{pagination.SinglePageBase(r)}
|
return VolumeAttachmentPage{pagination.SinglePageBase(r)}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the
|
// CreateOptsBuilder allows extensions to add parameters to the Create request.
|
||||||
// CreateOpts struct in this package does.
|
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToVolumeAttachmentCreateMap() (map[string]interface{}, error)
|
ToVolumeAttachmentCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOpts specifies volume attachment creation or import parameters.
|
// CreateOpts specifies volume attachment creation or import parameters.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
// Device is the device that the volume will attach to the instance as. Omit for "auto"
|
// Device is the device that the volume will attach to the instance as.
|
||||||
|
// Omit for "auto".
|
||||||
Device string `json:"device,omitempty"`
|
Device string `json:"device,omitempty"`
|
||||||
// VolumeID is the ID of the volume to attach to the instance
|
|
||||||
|
// VolumeID is the ID of the volume to attach to the instance.
|
||||||
VolumeID string `json:"volumeId" required:"true"`
|
VolumeID string `json:"volumeId" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +33,7 @@ func (opts CreateOpts) ToVolumeAttachmentCreateMap() (map[string]interface{}, er
|
||||||
return gophercloud.BuildRequestBody(opts, "volumeAttachment")
|
return gophercloud.BuildRequestBody(opts, "volumeAttachment")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create requests the creation of a new volume attachment on the server
|
// Create requests the creation of a new volume attachment on the server.
|
||||||
func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) {
|
func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
b, err := opts.ToVolumeAttachmentCreateMap()
|
b, err := opts.ToVolumeAttachmentCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,7 +52,8 @@ func Get(client *gophercloud.ServiceClient, serverID, attachmentID string) (r Ge
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete requests the deletion of a previous stored VolumeAttachment from the server.
|
// Delete requests the deletion of a previous stored VolumeAttachment from
|
||||||
|
// the server.
|
||||||
func Delete(client *gophercloud.ServiceClient, serverID, attachmentID string) (r DeleteResult) {
|
func Delete(client *gophercloud.ServiceClient, serverID, attachmentID string) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(deleteURL(client, serverID, attachmentID), nil)
|
_, r.Err = client.Delete(deleteURL(client, serverID, attachmentID), nil)
|
||||||
return
|
return
|
||||||
|
|
|
@ -5,35 +5,36 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VolumeAttachment controls the attachment of a volume to an instance.
|
// VolumeAttachment contains attachment information between a volume
|
||||||
|
// and server.
|
||||||
type VolumeAttachment struct {
|
type VolumeAttachment struct {
|
||||||
// ID is a unique id of the attachment
|
// ID is a unique id of the attachment.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
||||||
// Device is what device the volume is attached as
|
// Device is what device the volume is attached as.
|
||||||
Device string `json:"device"`
|
Device string `json:"device"`
|
||||||
|
|
||||||
// VolumeID is the ID of the attached volume
|
// VolumeID is the ID of the attached volume.
|
||||||
VolumeID string `json:"volumeId"`
|
VolumeID string `json:"volumeId"`
|
||||||
|
|
||||||
// ServerID is the ID of the instance that has the volume attached
|
// ServerID is the ID of the instance that has the volume attached.
|
||||||
ServerID string `json:"serverId"`
|
ServerID string `json:"serverId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VolumeAttachmentPage stores a single, only page of VolumeAttachments
|
// VolumeAttachmentPage stores a single page all of VolumeAttachment
|
||||||
// results from a List call.
|
// results from a List call.
|
||||||
type VolumeAttachmentPage struct {
|
type VolumeAttachmentPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty determines whether or not a VolumeAttachmentsPage is empty.
|
// IsEmpty determines whether or not a VolumeAttachmentPage is empty.
|
||||||
func (page VolumeAttachmentPage) IsEmpty() (bool, error) {
|
func (page VolumeAttachmentPage) IsEmpty() (bool, error) {
|
||||||
va, err := ExtractVolumeAttachments(page)
|
va, err := ExtractVolumeAttachments(page)
|
||||||
return len(va) == 0, err
|
return len(va) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractVolumeAttachments interprets a page of results as a slice of
|
// ExtractVolumeAttachments interprets a page of results as a slice of
|
||||||
// VolumeAttachments.
|
// VolumeAttachment.
|
||||||
func ExtractVolumeAttachments(r pagination.Page) ([]VolumeAttachment, error) {
|
func ExtractVolumeAttachments(r pagination.Page) ([]VolumeAttachment, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
VolumeAttachments []VolumeAttachment `json:"volumeAttachments"`
|
VolumeAttachments []VolumeAttachment `json:"volumeAttachments"`
|
||||||
|
@ -57,20 +58,20 @@ func (r VolumeAttachmentResult) Extract() (*VolumeAttachment, error) {
|
||||||
return s.VolumeAttachment, err
|
return s.VolumeAttachment, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
// as a VolumeAttachment.
|
// to interpret it as a VolumeAttachment.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
VolumeAttachmentResult
|
VolumeAttachmentResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult is the response from a Get operation. Call its Extract method to interpret it
|
// GetResult is the response from a Get operation. Call its Extract method to
|
||||||
// as a VolumeAttachment.
|
// interpret it as a VolumeAttachment.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
VolumeAttachmentResult
|
VolumeAttachmentResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult is the response from a Delete operation. Call its Extract method to determine if
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||||
// the call succeeded or failed.
|
// method to determine if the call succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
142
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go
generated
vendored
142
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go
generated
vendored
|
@ -1,7 +1,137 @@
|
||||||
// Package flavors provides information and interaction with the flavor API
|
/*
|
||||||
// resource in the OpenStack Compute service.
|
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
|
A flavor is an available hardware configuration for a server. Each flavor
|
||||||
// time.
|
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
|
package flavors
|
||||||
|
|
270
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
270
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
generated
vendored
|
@ -11,24 +11,66 @@ type ListOptsBuilder interface {
|
||||||
ToFlavorListQuery() (string, error)
|
ToFlavorListQuery() (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListOpts helps control 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.
|
AccessType maps to OpenStack's Flavor.is_public field. Although the is_public
|
||||||
// Typically, software will use the last ID of the previous call to List to set the Marker for the current call.
|
field is boolean, the request options are ternary, which is why AccessType is
|
||||||
type ListOpts struct {
|
a string. The following values are allowed:
|
||||||
|
|
||||||
// ChangesSince, if provided, instructs List to return only those things which have changed since the timestamp provided.
|
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"`
|
ChangesSince string `q:"changes-since"`
|
||||||
|
|
||||||
// MinDisk and MinRAM, if provided, elides flavors which do not meet your criteria.
|
// MinDisk and MinRAM, if provided, elides flavors which do not meet your
|
||||||
|
// criteria.
|
||||||
MinDisk int `q:"minDisk"`
|
MinDisk int `q:"minDisk"`
|
||||||
MinRAM int `q:"minRam"`
|
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 and Limit control paging.
|
||||||
// Marker instructs List where to start listing from.
|
// Marker instructs List where to start listing from.
|
||||||
Marker string `q:"marker"`
|
Marker string `q:"marker"`
|
||||||
|
|
||||||
// Limit instructs List to refrain from sending excessively large lists of flavors.
|
// Limit instructs List to refrain from sending excessively large lists of
|
||||||
|
// flavors.
|
||||||
Limit int `q:"limit"`
|
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.
|
// ToFlavorListQuery formats a ListOpts into a query string.
|
||||||
|
@ -38,8 +80,8 @@ func (opts ListOpts) ToFlavorListQuery() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListDetail instructs OpenStack to provide a list of flavors.
|
// ListDetail instructs OpenStack to provide a list of flavors.
|
||||||
// You may provide criteria by which List curtails its results for easier processing.
|
// You may provide criteria by which List curtails its results for easier
|
||||||
// See ListOpts for more details.
|
// processing.
|
||||||
func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
url := listURL(client)
|
url := listURL(client)
|
||||||
if opts != nil {
|
if opts != nil {
|
||||||
|
@ -58,31 +100,42 @@ type CreateOptsBuilder interface {
|
||||||
ToFlavorCreateMap() (map[string]interface{}, error)
|
ToFlavorCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOpts is passed to Create to create a flavor
|
// CreateOpts specifies parameters used for creating a flavor.
|
||||||
// Source:
|
|
||||||
// https://github.com/openstack/nova/blob/stable/newton/nova/api/openstack/compute/schemas/flavor_manage.py#L20
|
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
|
// Name is the name of the flavor.
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
// memory size, in MBs
|
|
||||||
RAM int `json:"ram" 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"`
|
VCPUs int `json:"vcpus" required:"true"`
|
||||||
// disk size, in GBs
|
|
||||||
Disk *int `json:"disk" required:"true"`
|
// Disk the amount of root disk space, measured in GB.
|
||||||
ID string `json:"id,omitempty"`
|
Disk *int `json:"disk" required:"true"`
|
||||||
// non-zero, positive
|
|
||||||
Swap *int `json:"swap,omitempty"`
|
// 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"`
|
RxTxFactor float64 `json:"rxtx_factor,omitempty"`
|
||||||
IsPublic *bool `json:"os-flavor-access:is_public,omitempty"`
|
|
||||||
// ephemeral disk size, in GBs, non-zero, positive
|
// 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"`
|
Ephemeral *int `json:"OS-FLV-EXT-DATA:ephemeral,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToFlavorCreateMap satisfies the CreateOptsBuilder interface
|
// ToFlavorCreateMap constructs a request body from CreateOpts.
|
||||||
func (opts *CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) {
|
func (opts CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "flavor")
|
return gophercloud.BuildRequestBody(opts, "flavor")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a flavor
|
// Create requests the creation of a new flavor.
|
||||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
b, err := opts.ToFlavorCreateMap()
|
b, err := opts.ToFlavorCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -95,14 +148,177 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get instructs OpenStack to provide details on a single flavor, identified by its ID.
|
// Get retrieves details of a single flavor. Use ExtractFlavor to convert its
|
||||||
// Use ExtractFlavor to convert its result into a Flavor.
|
// result into a Flavor.
|
||||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDFromName is a convienience function that returns a flavor's ID given its name.
|
// 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) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
|
|
171
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go
generated
vendored
171
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go
generated
vendored
|
@ -12,16 +12,26 @@ type commonResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateResult is the response of a Get operations. Call its Extract method to
|
||||||
|
// interpret it as a Flavor.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult temporarily holds the response from a Get call.
|
// GetResult is the response of a Get operations. Call its Extract method to
|
||||||
|
// interpret it as a Flavor.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract provides access to the individual Flavor returned by the Get and Create functions.
|
// 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) {
|
func (r commonResult) Extract() (*Flavor, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Flavor *Flavor `json:"flavor"`
|
Flavor *Flavor `json:"flavor"`
|
||||||
|
@ -30,22 +40,35 @@ func (r commonResult) Extract() (*Flavor, error) {
|
||||||
return s.Flavor, err
|
return s.Flavor, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flavor records represent (virtual) hardware configurations for server resources in a region.
|
// Flavor represent (virtual) hardware configurations for server resources
|
||||||
|
// in a region.
|
||||||
type Flavor struct {
|
type Flavor struct {
|
||||||
// The Id field contains the flavor's unique identifier.
|
// ID is the flavor's unique ID.
|
||||||
// For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance.
|
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
// The Disk and RA< fields provide a measure of storage space offered by the flavor, in GB and MB, respectively.
|
|
||||||
|
// Disk is the amount of root disk, measured in GB.
|
||||||
Disk int `json:"disk"`
|
Disk int `json:"disk"`
|
||||||
RAM int `json:"ram"`
|
|
||||||
// The Name field provides a human-readable moniker for the flavor.
|
// RAM is the amount of memory, measured in MB.
|
||||||
Name string `json:"name"`
|
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"`
|
RxTxFactor float64 `json:"rxtx_factor"`
|
||||||
// Swap indicates how much space is reserved for swap.
|
|
||||||
// If not provided, this field will be set to 0.
|
// Swap is the amount of swap space, measured in MB.
|
||||||
Swap int `json:"swap"`
|
Swap int `json:"-"`
|
||||||
|
|
||||||
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
|
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
|
||||||
VCPUs int `json:"vcpus"`
|
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 {
|
func (r *Flavor) UnmarshalJSON(b []byte) error {
|
||||||
|
@ -80,18 +103,19 @@ func (r *Flavor) UnmarshalJSON(b []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlavorPage contains a single page of the response from a List call.
|
// FlavorPage contains a single page of all flavors from a ListDetails call.
|
||||||
type FlavorPage struct {
|
type FlavorPage struct {
|
||||||
pagination.LinkedPageBase
|
pagination.LinkedPageBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty determines if a page contains any results.
|
// IsEmpty determines if a FlavorPage contains any results.
|
||||||
func (page FlavorPage) IsEmpty() (bool, error) {
|
func (page FlavorPage) IsEmpty() (bool, error) {
|
||||||
flavors, err := ExtractFlavors(page)
|
flavors, err := ExtractFlavors(page)
|
||||||
return len(flavors) == 0, err
|
return len(flavors) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
|
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||||
|
// next page of results.
|
||||||
func (page FlavorPage) NextPageURL() (string, error) {
|
func (page FlavorPage) NextPageURL() (string, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Links []gophercloud.Link `json:"flavors_links"`
|
Links []gophercloud.Link `json:"flavors_links"`
|
||||||
|
@ -103,7 +127,8 @@ func (page FlavorPage) NextPageURL() (string, error) {
|
||||||
return gophercloud.ExtractNextURL(s.Links)
|
return gophercloud.ExtractNextURL(s.Links)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractFlavors provides access to the list of flavors in a page acquired from the List operation.
|
// ExtractFlavors provides access to the list of flavors in a page acquired
|
||||||
|
// from the ListDetail operation.
|
||||||
func ExtractFlavors(r pagination.Page) ([]Flavor, error) {
|
func ExtractFlavors(r pagination.Page) ([]Flavor, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Flavors []Flavor `json:"flavors"`
|
Flavors []Flavor `json:"flavors"`
|
||||||
|
@ -111,3 +136,117 @@ func ExtractFlavors(r pagination.Page) ([]Flavor, error) {
|
||||||
err := (r.(FlavorPage)).ExtractInto(&s)
|
err := (r.(FlavorPage)).ExtractInto(&s)
|
||||||
return s.Flavors, err
|
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
|
||||||
|
}
|
||||||
|
|
32
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go
generated
vendored
32
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go
generated
vendored
|
@ -15,3 +15,35 @@ func listURL(client *gophercloud.ServiceClient) string {
|
||||||
func createURL(client *gophercloud.ServiceClient) string {
|
func createURL(client *gophercloud.ServiceClient) string {
|
||||||
return client.ServiceURL("flavors")
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,32 @@
|
||||||
// Package images provides information and interaction with the image API
|
/*
|
||||||
// resource in the OpenStack Compute service.
|
Package images provides information and interaction with the images through
|
||||||
//
|
the OpenStack Compute 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
|
This API is deprecated and will be removed from a future version of the Nova
|
||||||
// create custom images from cloud servers you have launched.
|
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
|
package images
|
||||||
|
|
31
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/requests.go
generated
vendored
31
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/requests.go
generated
vendored
|
@ -6,26 +6,33 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListOptsBuilder allows extensions to add additional parameters to the
|
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||||
// List request.
|
// ListDetail request.
|
||||||
type ListOptsBuilder interface {
|
type ListOptsBuilder interface {
|
||||||
ToImageListQuery() (string, error)
|
ToImageListQuery() (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListOpts contain options for limiting the number of Images returned from a call to ListDetail.
|
// ListOpts contain options filtering Images returned from a call to ListDetail.
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
// When the image last changed status (in date-time format).
|
// ChangesSince filters Images based on the last changed status (in date-time
|
||||||
|
// format).
|
||||||
ChangesSince string `q:"changes-since"`
|
ChangesSince string `q:"changes-since"`
|
||||||
// The number of Images to return.
|
|
||||||
|
// Limit limits the number of Images to return.
|
||||||
Limit int `q:"limit"`
|
Limit int `q:"limit"`
|
||||||
// UUID of the Image at which to set a marker.
|
|
||||||
|
// Mark is an Image UUID at which to set a marker.
|
||||||
Marker string `q:"marker"`
|
Marker string `q:"marker"`
|
||||||
// The name of the Image.
|
|
||||||
|
// Name is the name of the Image.
|
||||||
Name string `q:"name"`
|
Name string `q:"name"`
|
||||||
// The name of the Server (in URL format).
|
|
||||||
|
// Server is the name of the Server (in URL format).
|
||||||
Server string `q:"server"`
|
Server string `q:"server"`
|
||||||
// The current status of the Image.
|
|
||||||
|
// Status is the current status of the Image.
|
||||||
Status string `q:"status"`
|
Status string `q:"status"`
|
||||||
// The value of the type of image (e.g. BASE, SERVER, ALL)
|
|
||||||
|
// Type is the type of image (e.g. BASE, SERVER, ALL).
|
||||||
Type string `q:"type"`
|
Type string `q:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +57,7 @@ func ListDetail(client *gophercloud.ServiceClient, opts ListOptsBuilder) paginat
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get acquires additional detail about a specific image by ID.
|
// Get returns data about a specific image by its ID.
|
||||||
// Use ExtractImage() to interpret the result as an openstack Image.
|
|
||||||
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||||
return
|
return
|
||||||
|
@ -63,7 +69,8 @@ func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDFromName is a convienience function that returns an image's ID given its name.
|
// IDFromName is a convienience function that returns an image's ID given its
|
||||||
|
// name.
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
|
|
40
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/results.go
generated
vendored
40
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/results.go
generated
vendored
|
@ -5,12 +5,14 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetResult temporarily stores a Get response.
|
// GetResult is the response from a Get operation. Call its Extract method to
|
||||||
|
// interpret it as an Image.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult represents the result of an image.Delete operation.
|
// DeleteResult is the result from a Delete operation. Call its ExtractErr
|
||||||
|
// method to determine if the call succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
@ -24,44 +26,53 @@ func (r GetResult) Extract() (*Image, error) {
|
||||||
return s.Image, err
|
return s.Image, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image is used for JSON (un)marshalling.
|
// Image represents an Image returned by the Compute API.
|
||||||
// It provides a description of an OS image.
|
|
||||||
type Image struct {
|
type Image struct {
|
||||||
// ID contains the image's unique identifier.
|
// ID is the unique ID of an image.
|
||||||
ID string
|
ID string
|
||||||
|
|
||||||
|
// Created is the date when the image was created.
|
||||||
Created string
|
Created string
|
||||||
|
|
||||||
// MinDisk and MinRAM specify the minimum resources a server must provide to be able to install the image.
|
// 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
|
MinDisk int
|
||||||
MinRAM 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 provides a human-readable moniker for the OS image.
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
// The Progress and Status fields indicate image-creation status.
|
// The Progress and Status fields indicate image-creation status.
|
||||||
// Any usable image will have 100% progress.
|
|
||||||
Progress int
|
Progress int
|
||||||
Status string
|
|
||||||
|
|
||||||
|
// Status is the current status of the image.
|
||||||
|
Status string
|
||||||
|
|
||||||
|
// Update is the date when the image was updated.
|
||||||
Updated string
|
Updated string
|
||||||
|
|
||||||
|
// Metadata provides free-form key/value pairs that further describe the
|
||||||
|
// image.
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImagePage contains a single page of results from a List operation.
|
// ImagePage contains a single page of all Images returne from a ListDetail
|
||||||
// Use ExtractImages to convert it into a slice of usable structs.
|
// operation. Use ExtractImages to convert it into a slice of usable structs.
|
||||||
type ImagePage struct {
|
type ImagePage struct {
|
||||||
pagination.LinkedPageBase
|
pagination.LinkedPageBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if a page contains no Image results.
|
// IsEmpty returns true if an ImagePage contains no Image results.
|
||||||
func (page ImagePage) IsEmpty() (bool, error) {
|
func (page ImagePage) IsEmpty() (bool, error) {
|
||||||
images, err := ExtractImages(page)
|
images, err := ExtractImages(page)
|
||||||
return len(images) == 0, err
|
return len(images) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
|
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||||
|
// next page of results.
|
||||||
func (page ImagePage) NextPageURL() (string, error) {
|
func (page ImagePage) NextPageURL() (string, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Links []gophercloud.Link `json:"images_links"`
|
Links []gophercloud.Link `json:"images_links"`
|
||||||
|
@ -73,7 +84,8 @@ func (page ImagePage) NextPageURL() (string, error) {
|
||||||
return gophercloud.ExtractNextURL(s.Links)
|
return gophercloud.ExtractNextURL(s.Links)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractImages converts a page of List results into a slice of usable Image structs.
|
// ExtractImages converts a page of List results into a slice of usable Image
|
||||||
|
// structs.
|
||||||
func ExtractImages(r pagination.Page) ([]Image, error) {
|
func ExtractImages(r pagination.Page) ([]Image, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Images []Image `json:"images"`
|
Images []Image `json:"images"`
|
||||||
|
|
119
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/doc.go
generated
vendored
119
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/doc.go
generated
vendored
|
@ -1,6 +1,115 @@
|
||||||
// Package servers provides information and interaction with the server API
|
/*
|
||||||
// resource in the OpenStack Compute service.
|
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.
|
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
|
package servers
|
||||||
|
|
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/microversions.go
generated
vendored
Normal file
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/microversions.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
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
|
||||||
|
}
|
311
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
311
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
generated
vendored
|
@ -21,13 +21,13 @@ type ListOptsBuilder interface {
|
||||||
// the server attributes you want to see returned. Marker and Limit are used
|
// the server attributes you want to see returned. Marker and Limit are used
|
||||||
// for pagination.
|
// for pagination.
|
||||||
type ListOpts struct {
|
type ListOpts struct {
|
||||||
// A time/date stamp for when the server last changed status.
|
// ChangesSince is a time/date stamp for when the server last changed status.
|
||||||
ChangesSince string `q:"changes-since"`
|
ChangesSince string `q:"changes-since"`
|
||||||
|
|
||||||
// Name of the image in URL format.
|
// Image is the name of the image in URL format.
|
||||||
Image string `q:"image"`
|
Image string `q:"image"`
|
||||||
|
|
||||||
// Name of the flavor in URL format.
|
// Flavor is the name of the flavor in URL format.
|
||||||
Flavor string `q:"flavor"`
|
Flavor string `q:"flavor"`
|
||||||
|
|
||||||
// Name of the server as a string; can be queried with regular expressions.
|
// Name of the server as a string; can be queried with regular expressions.
|
||||||
|
@ -36,20 +36,25 @@ type ListOpts struct {
|
||||||
// underlying database server implemented for Compute.
|
// underlying database server implemented for Compute.
|
||||||
Name string `q:"name"`
|
Name string `q:"name"`
|
||||||
|
|
||||||
// Value of the status of the server so that you can filter on "ACTIVE" for example.
|
// Status is the value of the status of the server so that you can filter on
|
||||||
|
// "ACTIVE" for example.
|
||||||
Status string `q:"status"`
|
Status string `q:"status"`
|
||||||
|
|
||||||
// Name of the host as a string.
|
// Host is the name of the host as a string.
|
||||||
Host string `q:"host"`
|
Host string `q:"host"`
|
||||||
|
|
||||||
// UUID of the server at which you want to set a marker.
|
// Marker is a UUID of the server at which you want to set a marker.
|
||||||
Marker string `q:"marker"`
|
Marker string `q:"marker"`
|
||||||
|
|
||||||
// Integer value for the limit of values to return.
|
// Limit is an integer value for the limit of values to return.
|
||||||
Limit int `q:"limit"`
|
Limit int `q:"limit"`
|
||||||
|
|
||||||
// Bool to show all tenants
|
// AllTenants is a bool to show all tenants.
|
||||||
AllTenants bool `q:"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.
|
// ToServerListQuery formats a ListOpts into a query string.
|
||||||
|
@ -73,15 +78,16 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call.
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
// The CreateOpts struct in this package does.
|
// Create request.
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToServerCreateMap() (map[string]interface{}, error)
|
ToServerCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network is used within CreateOpts to control a new server's network attachments.
|
// Network is used within CreateOpts to control a new server's network
|
||||||
|
// attachments.
|
||||||
type Network struct {
|
type Network struct {
|
||||||
// UUID of a nova-network to attach to the newly provisioned server.
|
// UUID of a network to attach to the newly provisioned server.
|
||||||
// Required unless Port is provided.
|
// Required unless Port is provided.
|
||||||
UUID string
|
UUID string
|
||||||
|
|
||||||
|
@ -89,19 +95,21 @@ type Network struct {
|
||||||
// Required unless UUID is provided.
|
// Required unless UUID is provided.
|
||||||
Port string
|
Port string
|
||||||
|
|
||||||
// FixedIP [optional] specifies a fixed IPv4 address to be used on this network.
|
// FixedIP specifies a fixed IPv4 address to be used on this network.
|
||||||
FixedIP string
|
FixedIP string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Personality is an array of files that are injected into the server at launch.
|
// Personality is an array of files that are injected into the server at launch.
|
||||||
type Personality []*File
|
type Personality []*File
|
||||||
|
|
||||||
// File is used within CreateOpts and RebuildOpts to inject a file into the server at launch.
|
// File is used within CreateOpts and RebuildOpts to inject a file into the
|
||||||
// File implements the json.Marshaler interface, so when a Create or Rebuild operation is requested,
|
// server at launch.
|
||||||
// json.Marshal will call File's MarshalJSON method.
|
// 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 {
|
type File struct {
|
||||||
// Path of the file
|
// Path of the file.
|
||||||
Path string
|
Path string
|
||||||
|
|
||||||
// Contents of the file. Maximum content size is 255 bytes.
|
// Contents of the file. Maximum content size is 255 bytes.
|
||||||
Contents []byte
|
Contents []byte
|
||||||
}
|
}
|
||||||
|
@ -123,13 +131,13 @@ type CreateOpts struct {
|
||||||
// Name is the name to assign to the newly launched server.
|
// Name is the name to assign to the newly launched server.
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
|
|
||||||
// ImageRef [optional; required if ImageName is not provided] is the ID or full
|
// ImageRef [optional; required if ImageName is not provided] is the ID or
|
||||||
// URL to the image that contains the server's OS and initial state.
|
// full URL to the image that contains the server's OS and initial state.
|
||||||
// Also optional if using the boot-from-volume extension.
|
// Also optional if using the boot-from-volume extension.
|
||||||
ImageRef string `json:"imageRef"`
|
ImageRef string `json:"imageRef"`
|
||||||
|
|
||||||
// ImageName [optional; required if ImageRef is not provided] is the name of the
|
// ImageName [optional; required if ImageRef is not provided] is the name of
|
||||||
// image that contains the server's OS and initial state.
|
// the image that contains the server's OS and initial state.
|
||||||
// Also optional if using the boot-from-volume extension.
|
// Also optional if using the boot-from-volume extension.
|
||||||
ImageName string `json:"-"`
|
ImageName string `json:"-"`
|
||||||
|
|
||||||
|
@ -141,7 +149,8 @@ type CreateOpts struct {
|
||||||
// the flavor that describes the server's specs.
|
// the flavor that describes the server's specs.
|
||||||
FlavorName string `json:"-"`
|
FlavorName string `json:"-"`
|
||||||
|
|
||||||
// SecurityGroups lists the names of the security groups to which this server should belong.
|
// SecurityGroups lists the names of the security groups to which this server
|
||||||
|
// should belong.
|
||||||
SecurityGroups []string `json:"-"`
|
SecurityGroups []string `json:"-"`
|
||||||
|
|
||||||
// UserData contains configuration information or scripts to use upon launch.
|
// UserData contains configuration information or scripts to use upon launch.
|
||||||
|
@ -152,10 +161,12 @@ type CreateOpts struct {
|
||||||
AvailabilityZone string `json:"availability_zone,omitempty"`
|
AvailabilityZone string `json:"availability_zone,omitempty"`
|
||||||
|
|
||||||
// Networks dictates how this server will be attached to available networks.
|
// 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.
|
// By default, the server will be attached to all isolated networks for the
|
||||||
|
// tenant.
|
||||||
Networks []Network `json:"-"`
|
Networks []Network `json:"-"`
|
||||||
|
|
||||||
// Metadata contains key-value pairs (up to 255 bytes each) to attach to the server.
|
// Metadata contains key-value pairs (up to 255 bytes each) to attach to the
|
||||||
|
// server.
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
|
|
||||||
// Personality includes files to inject into the server at launch.
|
// Personality includes files to inject into the server at launch.
|
||||||
|
@ -166,7 +177,7 @@ type CreateOpts struct {
|
||||||
ConfigDrive *bool `json:"config_drive,omitempty"`
|
ConfigDrive *bool `json:"config_drive,omitempty"`
|
||||||
|
|
||||||
// AdminPass sets the root user password. If not set, a randomly-generated
|
// AdminPass sets the root user password. If not set, a randomly-generated
|
||||||
// password will be created and returned in the rponse.
|
// password will be created and returned in the response.
|
||||||
AdminPass string `json:"adminPass,omitempty"`
|
AdminPass string `json:"adminPass,omitempty"`
|
||||||
|
|
||||||
// AccessIPv4 specifies an IPv4 address for the instance.
|
// AccessIPv4 specifies an IPv4 address for the instance.
|
||||||
|
@ -178,9 +189,14 @@ type CreateOpts struct {
|
||||||
// ServiceClient will allow calls to be made to retrieve an image or
|
// ServiceClient will allow calls to be made to retrieve an image or
|
||||||
// flavor ID by name.
|
// flavor ID by name.
|
||||||
ServiceClient *gophercloud.ServiceClient `json:"-"`
|
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.
|
// ToServerCreateMap assembles a request body based on the contents of a
|
||||||
|
// CreateOpts.
|
||||||
func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
|
func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) {
|
||||||
sc := opts.ServiceClient
|
sc := opts.ServiceClient
|
||||||
opts.ServiceClient = nil
|
opts.ServiceClient = nil
|
||||||
|
@ -274,13 +290,14 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete requests that a server previously provisioned be removed from your account.
|
// Delete requests that a server previously provisioned be removed from your
|
||||||
|
// account.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
_, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceDelete forces the deletion of a server
|
// ForceDelete forces the deletion of a server.
|
||||||
func ForceDelete(client *gophercloud.ServiceClient, id string) (r ActionResult) {
|
func ForceDelete(client *gophercloud.ServiceClient, id string) (r ActionResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"forceDelete": ""}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"forceDelete": ""}, nil, nil)
|
||||||
return
|
return
|
||||||
|
@ -294,12 +311,14 @@ func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOptsBuilder allows extensions to add additional attributes to the Update request.
|
// UpdateOptsBuilder allows extensions to add additional attributes to the
|
||||||
|
// Update request.
|
||||||
type UpdateOptsBuilder interface {
|
type UpdateOptsBuilder interface {
|
||||||
ToServerUpdateMap() (map[string]interface{}, error)
|
ToServerUpdateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOpts specifies the base attributes that may be updated on an existing server.
|
// UpdateOpts specifies the base attributes that may be updated on an existing
|
||||||
|
// server.
|
||||||
type UpdateOpts struct {
|
type UpdateOpts struct {
|
||||||
// Name changes the displayed name of the server.
|
// Name changes the displayed name of the server.
|
||||||
// The server host name will *not* change.
|
// The server host name will *not* change.
|
||||||
|
@ -331,7 +350,8 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeAdminPassword alters the administrator or root password for a specified server.
|
// ChangeAdminPassword alters the administrator or root password for a specified
|
||||||
|
// server.
|
||||||
func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) (r ActionResult) {
|
func ChangeAdminPassword(client *gophercloud.ServiceClient, id, newPassword string) (r ActionResult) {
|
||||||
b := map[string]interface{}{
|
b := map[string]interface{}{
|
||||||
"changePassword": map[string]string{
|
"changePassword": map[string]string{
|
||||||
|
@ -354,33 +374,38 @@ const (
|
||||||
PowerCycle = HardReboot
|
PowerCycle = HardReboot
|
||||||
)
|
)
|
||||||
|
|
||||||
// RebootOptsBuilder is an interface that options must satisfy in order to be
|
// RebootOptsBuilder allows extensions to add additional parameters to the
|
||||||
// used when rebooting a server instance
|
// reboot request.
|
||||||
type RebootOptsBuilder interface {
|
type RebootOptsBuilder interface {
|
||||||
ToServerRebootMap() (map[string]interface{}, error)
|
ToServerRebootMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RebootOpts satisfies the RebootOptsBuilder interface
|
// RebootOpts provides options to the reboot request.
|
||||||
type RebootOpts struct {
|
type RebootOpts struct {
|
||||||
|
// Type is the type of reboot to perform on the server.
|
||||||
Type RebootMethod `json:"type" required:"true"`
|
Type RebootMethod `json:"type" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToServerRebootMap allows RebootOpts to satisfiy the RebootOptsBuilder
|
// ToServerRebootMap builds a body for the reboot request.
|
||||||
// interface
|
func (opts RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
|
||||||
func (opts *RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
|
|
||||||
return gophercloud.BuildRequestBody(opts, "reboot")
|
return gophercloud.BuildRequestBody(opts, "reboot")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reboot requests that a given server reboot.
|
/*
|
||||||
// Two methods exist for rebooting a server:
|
Reboot requests that a given server reboot.
|
||||||
//
|
|
||||||
// HardReboot (aka PowerCycle) starts the server instance by physically cutting power to the machine, or if a VM,
|
Two methods exist for rebooting a server:
|
||||||
// terminating it at the hypervisor level.
|
|
||||||
// It's done. Caput. Full stop.
|
HardReboot (aka PowerCycle) starts the server instance by physically cutting
|
||||||
// Then, after a brief while, power is rtored or the VM instance rtarted.
|
power to the machine, or if a VM, terminating it at the hypervisor level.
|
||||||
//
|
It's done. Caput. Full stop.
|
||||||
// SoftReboot (aka OSReboot) simply tells the OS to rtart under its own procedur.
|
Then, after a brief while, power is rtored or the VM instance restarted.
|
||||||
// E.g., in Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to rtart the machine.
|
|
||||||
|
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) {
|
func Reboot(client *gophercloud.ServiceClient, id string, opts RebootOptsBuilder) (r ActionResult) {
|
||||||
b, err := opts.ToServerRebootMap()
|
b, err := opts.ToServerRebootMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -391,31 +416,43 @@ func Reboot(client *gophercloud.ServiceClient, id string, opts RebootOptsBuilder
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RebuildOptsBuilder is an interface that allows extensions to override the
|
// RebuildOptsBuilder allows extensions to provide additional parameters to the
|
||||||
// default behaviour of rebuild options
|
// rebuild request.
|
||||||
type RebuildOptsBuilder interface {
|
type RebuildOptsBuilder interface {
|
||||||
ToServerRebuildMap() (map[string]interface{}, error)
|
ToServerRebuildMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RebuildOpts represents the configuration options used in a server rebuild
|
// RebuildOpts represents the configuration options used in a server rebuild
|
||||||
// operation
|
// operation.
|
||||||
type RebuildOpts struct {
|
type RebuildOpts struct {
|
||||||
// The server's admin password
|
// AdminPass is the server's admin password
|
||||||
AdminPass string `json:"adminPass,omitempty"`
|
AdminPass string `json:"adminPass,omitempty"`
|
||||||
// The ID of the image you want your server to be provisioned on
|
|
||||||
ImageID string `json:"imageRef"`
|
// 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:"-"`
|
ImageName string `json:"-"`
|
||||||
|
|
||||||
// Name to set the server to
|
// Name to set the server to
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
// AccessIPv4 [optional] provides a new IPv4 address for the instance.
|
// AccessIPv4 [optional] provides a new IPv4 address for the instance.
|
||||||
AccessIPv4 string `json:"accessIPv4,omitempty"`
|
AccessIPv4 string `json:"accessIPv4,omitempty"`
|
||||||
|
|
||||||
// AccessIPv6 [optional] provides a new IPv6 address for the instance.
|
// AccessIPv6 [optional] provides a new IPv6 address for the instance.
|
||||||
AccessIPv6 string `json:"accessIPv6,omitempty"`
|
AccessIPv6 string `json:"accessIPv6,omitempty"`
|
||||||
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server.
|
|
||||||
|
// Metadata [optional] contains key-value pairs (up to 255 bytes each)
|
||||||
|
// to attach to the server.
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
|
|
||||||
// Personality [optional] includes files to inject into the server at launch.
|
// Personality [optional] includes files to inject into the server at launch.
|
||||||
// Rebuild will base64-encode file contents for you.
|
// Rebuild will base64-encode file contents for you.
|
||||||
Personality Personality `json:"personality,omitempty"`
|
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:"-"`
|
ServiceClient *gophercloud.ServiceClient `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,31 +495,34 @@ func Rebuild(client *gophercloud.ServiceClient, id string, opts RebuildOptsBuild
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResizeOptsBuilder is an interface that allows extensions to override the default structure of
|
// ResizeOptsBuilder allows extensions to add additional parameters to the
|
||||||
// a Resize request.
|
// resize request.
|
||||||
type ResizeOptsBuilder interface {
|
type ResizeOptsBuilder interface {
|
||||||
ToServerResizeMap() (map[string]interface{}, error)
|
ToServerResizeMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResizeOpts represents the configuration options used to control a Resize operation.
|
// ResizeOpts represents the configuration options used to control a Resize
|
||||||
|
// operation.
|
||||||
type ResizeOpts struct {
|
type ResizeOpts struct {
|
||||||
// FlavorRef is the ID of the flavor you wish your server to become.
|
// FlavorRef is the ID of the flavor you wish your server to become.
|
||||||
FlavorRef string `json:"flavorRef" required:"true"`
|
FlavorRef string `json:"flavorRef" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON request body for the
|
// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON
|
||||||
// Resize request.
|
// request body for the Resize request.
|
||||||
func (opts ResizeOpts) ToServerResizeMap() (map[string]interface{}, error) {
|
func (opts ResizeOpts) ToServerResizeMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "resize")
|
return gophercloud.BuildRequestBody(opts, "resize")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize instructs the provider to change the flavor of the server.
|
// Resize instructs the provider to change the flavor of the server.
|
||||||
|
//
|
||||||
// Note that this implies rebuilding it.
|
// Note that this implies rebuilding it.
|
||||||
|
//
|
||||||
// Unfortunately, one cannot pass rebuild parameters to the resize function.
|
// Unfortunately, one cannot pass rebuild parameters to the resize function.
|
||||||
// When the resize completes, the server will be in RESIZE_VERIFY state.
|
// 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.
|
// While in this state, you can explore the use of the new server's
|
||||||
// If you like it, call ConfirmResize() to commit the resize permanently.
|
// configuration. If you like it, call ConfirmResize() to commit the resize
|
||||||
// Otherwise, call RevertResize() to restore the old configuration.
|
// permanently. Otherwise, call RevertResize() to restore the old configuration.
|
||||||
func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) (r ActionResult) {
|
func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) (r ActionResult) {
|
||||||
b, err := opts.ToServerResizeMap()
|
b, err := opts.ToServerResizeMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -509,41 +549,8 @@ func RevertResize(client *gophercloud.ServiceClient, id string) (r ActionResult)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RescueOptsBuilder is an interface that allows extensions to override the
|
// ResetMetadataOptsBuilder allows extensions to add additional parameters to
|
||||||
// default structure of a Rescue request.
|
// the Reset request.
|
||||||
type RescueOptsBuilder interface {
|
|
||||||
ToServerRescueMap() (map[string]interface{}, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RescueOpts represents the configuration options used to control a Rescue
|
|
||||||
// option.
|
|
||||||
type RescueOpts struct {
|
|
||||||
// AdminPass is the desired administrative password for the instance in
|
|
||||||
// RESCUE mode. If it's left blank, the server will generate a password.
|
|
||||||
AdminPass string `json:"adminPass,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToServerRescueMap formats a RescueOpts as a map that can be used as a JSON
|
|
||||||
// request body for the Rescue request.
|
|
||||||
func (opts RescueOpts) ToServerRescueMap() (map[string]interface{}, error) {
|
|
||||||
return gophercloud.BuildRequestBody(opts, "rescue")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rescue instructs the provider to place the server into RESCUE mode.
|
|
||||||
func Rescue(client *gophercloud.ServiceClient, id string, opts RescueOptsBuilder) (r RescueResult) {
|
|
||||||
b, err := opts.ToServerRescueMap()
|
|
||||||
if err != nil {
|
|
||||||
r.Err = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
|
||||||
OkCodes: []int{200},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResetMetadataOptsBuilder allows extensions to add additional parameters to the
|
|
||||||
// Reset request.
|
|
||||||
type ResetMetadataOptsBuilder interface {
|
type ResetMetadataOptsBuilder interface {
|
||||||
ToMetadataResetMap() (map[string]interface{}, error)
|
ToMetadataResetMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
@ -551,20 +558,23 @@ type ResetMetadataOptsBuilder interface {
|
||||||
// MetadataOpts is a map that contains key-value pairs.
|
// MetadataOpts is a map that contains key-value pairs.
|
||||||
type MetadataOpts map[string]string
|
type MetadataOpts map[string]string
|
||||||
|
|
||||||
// ToMetadataResetMap assembles a body for a Reset request based on the contents of a MetadataOpts.
|
// ToMetadataResetMap assembles a body for a Reset request based on the contents
|
||||||
|
// of a MetadataOpts.
|
||||||
func (opts MetadataOpts) ToMetadataResetMap() (map[string]interface{}, error) {
|
func (opts MetadataOpts) ToMetadataResetMap() (map[string]interface{}, error) {
|
||||||
return map[string]interface{}{"metadata": opts}, nil
|
return map[string]interface{}{"metadata": opts}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToMetadataUpdateMap assembles a body for an Update request based on the contents of a MetadataOpts.
|
// ToMetadataUpdateMap assembles a body for an Update request based on the
|
||||||
|
// contents of a MetadataOpts.
|
||||||
func (opts MetadataOpts) ToMetadataUpdateMap() (map[string]interface{}, error) {
|
func (opts MetadataOpts) ToMetadataUpdateMap() (map[string]interface{}, error) {
|
||||||
return map[string]interface{}{"metadata": opts}, nil
|
return map[string]interface{}{"metadata": opts}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetMetadata will create multiple new key-value pairs for the given server ID.
|
// ResetMetadata will create multiple new key-value pairs for the given server
|
||||||
// Note: Using this operation will erase any already-existing metadata and create
|
// ID.
|
||||||
// the new metadata provided. To keep any already-existing metadata, use the
|
// Note: Using this operation will erase any already-existing metadata and
|
||||||
// UpdateMetadatas or UpdateMetadata function.
|
// 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) {
|
func ResetMetadata(client *gophercloud.ServiceClient, id string, opts ResetMetadataOptsBuilder) (r ResetMetadataResult) {
|
||||||
b, err := opts.ToMetadataResetMap()
|
b, err := opts.ToMetadataResetMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -583,15 +593,15 @@ func Metadata(client *gophercloud.ServiceClient, id string) (r GetMetadataResult
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMetadataOptsBuilder allows extensions to add additional parameters to the
|
// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
|
||||||
// Create request.
|
// the Create request.
|
||||||
type UpdateMetadataOptsBuilder interface {
|
type UpdateMetadataOptsBuilder interface {
|
||||||
ToMetadataUpdateMap() (map[string]interface{}, error)
|
ToMetadataUpdateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMetadata updates (or creates) all the metadata specified by opts for the given server ID.
|
// UpdateMetadata updates (or creates) all the metadata specified by opts for
|
||||||
// This operation does not affect already-existing metadata that is not specified
|
// the given server ID. This operation does not affect already-existing metadata
|
||||||
// by opts.
|
// that is not specified by opts.
|
||||||
func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) (r UpdateMetadataResult) {
|
func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) (r UpdateMetadataResult) {
|
||||||
b, err := opts.ToMetadataUpdateMap()
|
b, err := opts.ToMetadataUpdateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -613,7 +623,8 @@ type MetadatumOptsBuilder interface {
|
||||||
// MetadatumOpts is a map of length one that contains a key-value pair.
|
// MetadatumOpts is a map of length one that contains a key-value pair.
|
||||||
type MetadatumOpts map[string]string
|
type MetadatumOpts map[string]string
|
||||||
|
|
||||||
// ToMetadatumCreateMap assembles a body for a Create request based on the contents of a MetadataumOpts.
|
// ToMetadatumCreateMap assembles a body for a Create request based on the
|
||||||
|
// contents of a MetadataumOpts.
|
||||||
func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string, error) {
|
func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string, error) {
|
||||||
if len(opts) != 1 {
|
if len(opts) != 1 {
|
||||||
err := gophercloud.ErrInvalidInput{}
|
err := gophercloud.ErrInvalidInput{}
|
||||||
|
@ -629,7 +640,8 @@ func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string
|
||||||
return metadatum, key, nil
|
return metadatum, key, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMetadatum will create or update the key-value pair with the given key for the given server ID.
|
// 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) {
|
func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts MetadatumOptsBuilder) (r CreateMetadatumResult) {
|
||||||
b, key, err := opts.ToMetadatumCreateMap()
|
b, key, err := opts.ToMetadatumCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -642,53 +654,60 @@ func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts Metadatu
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadatum requests the key-value pair with the given key for the given server ID.
|
// 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) {
|
func Metadatum(client *gophercloud.ServiceClient, id, key string) (r GetMetadatumResult) {
|
||||||
_, r.Err = client.Get(metadatumURL(client, id, key), &r.Body, nil)
|
_, r.Err = client.Get(metadatumURL(client, id, key), &r.Body, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMetadatum will delete the key-value pair with the given key for the given server ID.
|
// 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) {
|
func DeleteMetadatum(client *gophercloud.ServiceClient, id, key string) (r DeleteMetadatumResult) {
|
||||||
_, r.Err = client.Delete(metadatumURL(client, id, key), nil)
|
_, r.Err = client.Delete(metadatumURL(client, id, key), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListAddresses makes a request against the API to list the servers IP addresses.
|
// ListAddresses makes a request against the API to list the servers IP
|
||||||
|
// addresses.
|
||||||
func ListAddresses(client *gophercloud.ServiceClient, id string) pagination.Pager {
|
func ListAddresses(client *gophercloud.ServiceClient, id string) pagination.Pager {
|
||||||
return pagination.NewPager(client, listAddressesURL(client, id), func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, listAddressesURL(client, id), func(r pagination.PageResult) pagination.Page {
|
||||||
return AddressPage{pagination.SinglePageBase(r)}
|
return AddressPage{pagination.SinglePageBase(r)}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListAddressesByNetwork makes a request against the API to list the servers IP addresses
|
// ListAddressesByNetwork makes a request against the API to list the servers IP
|
||||||
// for the given network.
|
// addresses for the given network.
|
||||||
func ListAddressesByNetwork(client *gophercloud.ServiceClient, id, network string) pagination.Pager {
|
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 pagination.NewPager(client, listAddressesByNetworkURL(client, id, network), func(r pagination.PageResult) pagination.Page {
|
||||||
return NetworkAddressPage{pagination.SinglePageBase(r)}
|
return NetworkAddressPage{pagination.SinglePageBase(r)}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateImageOptsBuilder is the interface types must satisfy in order to be
|
// CreateImageOptsBuilder allows extensions to add additional parameters to the
|
||||||
// used as CreateImage options
|
// CreateImage request.
|
||||||
type CreateImageOptsBuilder interface {
|
type CreateImageOptsBuilder interface {
|
||||||
ToServerCreateImageMap() (map[string]interface{}, error)
|
ToServerCreateImageMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateImageOpts satisfies the CreateImageOptsBuilder
|
// CreateImageOpts provides options to pass to the CreateImage request.
|
||||||
type CreateImageOpts struct {
|
type CreateImageOpts struct {
|
||||||
// Name of the image/snapshot
|
// Name of the image/snapshot.
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
// Metadata contains key-value pairs (up to 255 bytes each) to attach to the created image.
|
|
||||||
|
// Metadata contains key-value pairs (up to 255 bytes each) to attach to
|
||||||
|
// the created image.
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToServerCreateImageMap formats a CreateImageOpts structure into a request body.
|
// ToServerCreateImageMap formats a CreateImageOpts structure into a request
|
||||||
|
// body.
|
||||||
func (opts CreateImageOpts) ToServerCreateImageMap() (map[string]interface{}, error) {
|
func (opts CreateImageOpts) ToServerCreateImageMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "createImage")
|
return gophercloud.BuildRequestBody(opts, "createImage")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateImage makes a request against the nova API to schedule an image to be created of the server
|
// 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) {
|
func CreateImage(client *gophercloud.ServiceClient, id string, opts CreateImageOptsBuilder) (r CreateImageResult) {
|
||||||
b, err := opts.ToServerCreateImageMap()
|
b, err := opts.ToServerCreateImageMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -703,11 +722,17 @@ func CreateImage(client *gophercloud.ServiceClient, id string, opts CreateImageO
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDFromName is a convienience function that returns a server's ID given its name.
|
// IDFromName is a convienience function that returns a server's ID given its
|
||||||
|
// name.
|
||||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||||
count := 0
|
count := 0
|
||||||
id := ""
|
id := ""
|
||||||
allPages, err := List(client, nil).AllPages()
|
|
||||||
|
listOpts := ListOpts{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := List(client, listOpts).AllPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -734,8 +759,40 @@ func IDFromName(client *gophercloud.ServiceClient, name string) (string, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPassword makes a request against the nova API to get the encrypted administrative password.
|
// GetPassword makes a request against the nova API to get the encrypted
|
||||||
|
// administrative password.
|
||||||
func GetPassword(client *gophercloud.ServiceClient, serverId string) (r GetPasswordResult) {
|
func GetPassword(client *gophercloud.ServiceClient, serverId string) (r GetPasswordResult) {
|
||||||
_, r.Err = client.Get(passwordURL(client, serverId), &r.Body, nil)
|
_, r.Err = client.Get(passwordURL(client, serverId), &r.Body, nil)
|
||||||
return
|
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
|
||||||
|
}
|
||||||
|
|
182
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
182
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
|
@ -32,54 +32,73 @@ func ExtractServersInto(r pagination.Page, v interface{}) error {
|
||||||
return r.(ServerPage).Result.ExtractIntoSlicePtr(v, "servers")
|
return r.(ServerPage).Result.ExtractIntoSlicePtr(v, "servers")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult temporarily contains the response from a Create call.
|
// CreateResult is the response from a Create operation. Call its Extract
|
||||||
|
// method to interpret it as a Server.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
serverResult
|
serverResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult temporarily contains the response from a Get call.
|
// GetResult is the response from a Get operation. Call its Extract
|
||||||
|
// method to interpret it as a Server.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
serverResult
|
serverResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateResult temporarily contains the response from an Update call.
|
// UpdateResult is the response from an Update operation. Call its Extract
|
||||||
|
// method to interpret it as a Server.
|
||||||
type UpdateResult struct {
|
type UpdateResult struct {
|
||||||
serverResult
|
serverResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult temporarily contains the response from a Delete call.
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||||
|
// method to determine if the call succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// RebuildResult temporarily contains the response from a Rebuild call.
|
// RebuildResult is the response from a Rebuild operation. Call its Extract
|
||||||
|
// method to interpret it as a Server.
|
||||||
type RebuildResult struct {
|
type RebuildResult struct {
|
||||||
serverResult
|
serverResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionResult represents the result of server action operations, like reboot
|
// 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 {
|
type ActionResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// RescueResult represents the result of a server rescue operation
|
// CreateImageResult is the response from a CreateImage operation. Call its
|
||||||
type RescueResult struct {
|
// ExtractImageID method to retrieve the ID of the newly created image.
|
||||||
ActionResult
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateImageResult represents the result of an image creation operation
|
|
||||||
type CreateImageResult struct {
|
type CreateImageResult struct {
|
||||||
gophercloud.Result
|
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.
|
// GetPasswordResult represent the result of a get os-server-password operation.
|
||||||
|
// Call its ExtractPassword method to retrieve the password.
|
||||||
type GetPasswordResult struct {
|
type GetPasswordResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractPassword gets the encrypted password.
|
// ExtractPassword gets the encrypted password.
|
||||||
// If privateKey != nil the password is decrypted with the private key.
|
// If privateKey != nil the password is decrypted with the private key.
|
||||||
// If privateKey == nil the encrypted password is returned and can be decrypted with:
|
// If privateKey == nil the encrypted password is returned and can be decrypted
|
||||||
|
// with:
|
||||||
// echo '<pwd>' | base64 -D | openssl rsautl -decrypt -inkey <private_key>
|
// echo '<pwd>' | base64 -D | openssl rsautl -decrypt -inkey <private_key>
|
||||||
func (r GetPasswordResult) ExtractPassword(privateKey *rsa.PrivateKey) (string, error) {
|
func (r GetPasswordResult) ExtractPassword(privateKey *rsa.PrivateKey) (string, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
|
@ -107,7 +126,7 @@ func decryptPassword(encryptedPassword string, privateKey *rsa.PrivateKey) (stri
|
||||||
return string(password), nil
|
return string(password), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractImageID gets the ID of the newly created server image from the header
|
// ExtractImageID gets the ID of the newly created server image from the header.
|
||||||
func (r CreateImageResult) ExtractImageID() (string, error) {
|
func (r CreateImageResult) ExtractImageID() (string, error) {
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
return "", r.Err
|
return "", r.Err
|
||||||
|
@ -124,54 +143,84 @@ func (r CreateImageResult) ExtractImageID() (string, error) {
|
||||||
return imageID, nil
|
return imageID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract interprets any RescueResult as an AdminPass, if possible.
|
// Server represents a server/instance in the OpenStack cloud.
|
||||||
func (r RescueResult) Extract() (string, error) {
|
|
||||||
var s struct {
|
|
||||||
AdminPass string `json:"adminPass"`
|
|
||||||
}
|
|
||||||
err := r.ExtractInto(&s)
|
|
||||||
return s.AdminPass, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server exposes only the standard OpenStack fields corresponding to a given server on the user's account.
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// ID uniquely identifies this server amongst all other servers, including those not accessible to the current tenant.
|
// ID uniquely identifies this server amongst all other servers,
|
||||||
|
// including those not accessible to the current tenant.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
||||||
// TenantID identifies the tenant owning this server resource.
|
// TenantID identifies the tenant owning this server resource.
|
||||||
TenantID string `json:"tenant_id"`
|
TenantID string `json:"tenant_id"`
|
||||||
|
|
||||||
// UserID uniquely identifies the user account owning the tenant.
|
// UserID uniquely identifies the user account owning the tenant.
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
|
|
||||||
// Name contains the human-readable name for the server.
|
// Name contains the human-readable name for the server.
|
||||||
Name string `json:"name"`
|
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 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"`
|
Updated time.Time `json:"updated"`
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
HostID string `json:"hostid"`
|
|
||||||
// Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
|
// 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"`
|
Status string `json:"status"`
|
||||||
|
|
||||||
// Progress ranges from 0..100.
|
// Progress ranges from 0..100.
|
||||||
// A request made against the server completes only once Progress reaches 100.
|
// A request made against the server completes only once Progress reaches 100.
|
||||||
Progress int `json:"progress"`
|
Progress int `json:"progress"`
|
||||||
// AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration.
|
|
||||||
|
// AccessIPv4 and AccessIPv6 contain the IP addresses of the server,
|
||||||
|
// suitable for remote access for administration.
|
||||||
AccessIPv4 string `json:"accessIPv4"`
|
AccessIPv4 string `json:"accessIPv4"`
|
||||||
AccessIPv6 string `json:"accessIPv6"`
|
AccessIPv6 string `json:"accessIPv6"`
|
||||||
// Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
|
|
||||||
|
// Image refers to a JSON object, which itself indicates the OS image used to
|
||||||
|
// deploy the server.
|
||||||
Image map[string]interface{} `json:"-"`
|
Image map[string]interface{} `json:"-"`
|
||||||
// Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server.
|
|
||||||
|
// Flavor refers to a JSON object, which itself indicates the hardware
|
||||||
|
// configuration of the deployed server.
|
||||||
Flavor map[string]interface{} `json:"flavor"`
|
Flavor map[string]interface{} `json:"flavor"`
|
||||||
// Addresses includes a list of all IP addresses assigned to the server, keyed by pool.
|
|
||||||
|
// Addresses includes a list of all IP addresses assigned to the server,
|
||||||
|
// keyed by pool.
|
||||||
Addresses map[string]interface{} `json:"addresses"`
|
Addresses map[string]interface{} `json:"addresses"`
|
||||||
// Metadata includes a list of all user-specified key-value pairs attached to the server.
|
|
||||||
|
// Metadata includes a list of all user-specified key-value pairs attached
|
||||||
|
// to the server.
|
||||||
Metadata map[string]string `json:"metadata"`
|
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 includes HTTP references to the itself, useful for passing along to
|
||||||
|
// other APIs that might want a server reference.
|
||||||
Links []interface{} `json:"links"`
|
Links []interface{} `json:"links"`
|
||||||
|
|
||||||
// KeyName indicates which public key was injected into the server on launch.
|
// KeyName indicates which public key was injected into the server on launch.
|
||||||
KeyName string `json:"key_name"`
|
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.
|
|
||||||
|
// 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.
|
// Note that this is the ONLY time this field will be valid.
|
||||||
AdminPass string `json:"adminPass"`
|
AdminPass string `json:"adminPass"`
|
||||||
// SecurityGroups includes the security groups that this instance has applied to it
|
|
||||||
|
// SecurityGroups includes the security groups that this instance has applied
|
||||||
|
// to it.
|
||||||
SecurityGroups []map[string]interface{} `json:"security_groups"`
|
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 {
|
func (r *Server) UnmarshalJSON(b []byte) error {
|
||||||
|
@ -200,9 +249,10 @@ func (r *Server) UnmarshalJSON(b []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerPage abstracts the raw results of making a List() request against the API.
|
// ServerPage abstracts the raw results of making a List() request against
|
||||||
// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the
|
// the API. As OpenStack extensions may freely alter the response bodies of
|
||||||
// data provided through the ExtractServers call.
|
// structures returned to the client, you may only safely access the data
|
||||||
|
// provided through the ExtractServers call.
|
||||||
type ServerPage struct {
|
type ServerPage struct {
|
||||||
pagination.LinkedPageBase
|
pagination.LinkedPageBase
|
||||||
}
|
}
|
||||||
|
@ -213,7 +263,8 @@ func (r ServerPage) IsEmpty() (bool, error) {
|
||||||
return len(s) == 0, err
|
return len(s) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
|
// NextPageURL uses the response's embedded link reference to navigate to the
|
||||||
|
// next page of results.
|
||||||
func (r ServerPage) NextPageURL() (string, error) {
|
func (r ServerPage) NextPageURL() (string, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Links []gophercloud.Link `json:"servers_links"`
|
Links []gophercloud.Link `json:"servers_links"`
|
||||||
|
@ -225,49 +276,59 @@ func (r ServerPage) NextPageURL() (string, error) {
|
||||||
return gophercloud.ExtractNextURL(s.Links)
|
return gophercloud.ExtractNextURL(s.Links)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities.
|
// 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) {
|
func ExtractServers(r pagination.Page) ([]Server, error) {
|
||||||
var s []Server
|
var s []Server
|
||||||
err := ExtractServersInto(r, &s)
|
err := ExtractServersInto(r, &s)
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetadataResult contains the result of a call for (potentially) multiple key-value pairs.
|
// 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 {
|
type MetadataResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetadataResult temporarily contains the response from a metadata Get call.
|
// GetMetadataResult contains the result of a Get operation. Call its Extract
|
||||||
|
// method to interpret it as a map[string]interface.
|
||||||
type GetMetadataResult struct {
|
type GetMetadataResult struct {
|
||||||
MetadataResult
|
MetadataResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetMetadataResult temporarily contains the response from a metadata Reset call.
|
// ResetMetadataResult contains the result of a Reset operation. Call its
|
||||||
|
// Extract method to interpret it as a map[string]interface.
|
||||||
type ResetMetadataResult struct {
|
type ResetMetadataResult struct {
|
||||||
MetadataResult
|
MetadataResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMetadataResult temporarily contains the response from a metadata Update call.
|
// UpdateMetadataResult contains the result of an Update operation. Call its
|
||||||
|
// Extract method to interpret it as a map[string]interface.
|
||||||
type UpdateMetadataResult struct {
|
type UpdateMetadataResult struct {
|
||||||
MetadataResult
|
MetadataResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetadatumResult contains the result of a call for individual a single key-value pair.
|
// MetadatumResult contains the result of a call for individual a single
|
||||||
|
// key-value pair.
|
||||||
type MetadatumResult struct {
|
type MetadatumResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetadatumResult temporarily contains the response from a metadatum Get call.
|
// GetMetadatumResult contains the result of a Get operation. Call its Extract
|
||||||
|
// method to interpret it as a map[string]interface.
|
||||||
type GetMetadatumResult struct {
|
type GetMetadatumResult struct {
|
||||||
MetadatumResult
|
MetadatumResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMetadatumResult temporarily contains the response from a metadatum Create call.
|
// CreateMetadatumResult contains the result of a Create operation. Call its
|
||||||
|
// Extract method to interpret it as a map[string]interface.
|
||||||
type CreateMetadatumResult struct {
|
type CreateMetadatumResult struct {
|
||||||
MetadatumResult
|
MetadatumResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMetadatumResult temporarily contains the response from a metadatum Delete call.
|
// DeleteMetadatumResult contains the result of a Delete operation. Call its
|
||||||
|
// ExtractErr method to determine if the call succeeded or failed.
|
||||||
type DeleteMetadatumResult struct {
|
type DeleteMetadatumResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
@ -296,9 +357,10 @@ type Address struct {
|
||||||
Address string `json:"addr"`
|
Address string `json:"addr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressPage abstracts the raw results of making a ListAddresses() request against the API.
|
// AddressPage abstracts the raw results of making a ListAddresses() request
|
||||||
// As OpenStack extensions may freely alter the response bodies of structures returned
|
// against the API. As OpenStack extensions may freely alter the response bodies
|
||||||
// to the client, you may only safely access the data provided through the ExtractAddresses call.
|
// of structures returned to the client, you may only safely access the data
|
||||||
|
// provided through the ExtractAddresses call.
|
||||||
type AddressPage struct {
|
type AddressPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
@ -309,8 +371,8 @@ func (r AddressPage) IsEmpty() (bool, error) {
|
||||||
return len(addresses) == 0, err
|
return len(addresses) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractAddresses interprets the results of a single page from a ListAddresses() call,
|
// ExtractAddresses interprets the results of a single page from a
|
||||||
// producing a map of addresses.
|
// ListAddresses() call, producing a map of addresses.
|
||||||
func ExtractAddresses(r pagination.Page) (map[string][]Address, error) {
|
func ExtractAddresses(r pagination.Page) (map[string][]Address, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
Addresses map[string][]Address `json:"addresses"`
|
Addresses map[string][]Address `json:"addresses"`
|
||||||
|
@ -319,9 +381,11 @@ func ExtractAddresses(r pagination.Page) (map[string][]Address, error) {
|
||||||
return s.Addresses, err
|
return s.Addresses, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkAddressPage abstracts the raw results of making a ListAddressesByNetwork() request against the API.
|
// NetworkAddressPage abstracts the raw results of making a
|
||||||
// As OpenStack extensions may freely alter the response bodies of structures returned
|
// ListAddressesByNetwork() request against the API.
|
||||||
// to the client, you may only safely access the data provided through the ExtractAddresses call.
|
// 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 {
|
type NetworkAddressPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
@ -332,8 +396,8 @@ func (r NetworkAddressPage) IsEmpty() (bool, error) {
|
||||||
return len(addresses) == 0, err
|
return len(addresses) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractNetworkAddresses interprets the results of a single page from a ListAddressesByNetwork() call,
|
// ExtractNetworkAddresses interprets the results of a single page from a
|
||||||
// producing a slice of addresses.
|
// ListAddressesByNetwork() call, producing a slice of addresses.
|
||||||
func ExtractNetworkAddresses(r pagination.Page) ([]Address, error) {
|
func ExtractNetworkAddresses(r pagination.Page) ([]Address, error) {
|
||||||
var s map[string][]Address
|
var s map[string][]Address
|
||||||
err := (r.(NetworkAddressPage)).ExtractInto(&s)
|
err := (r.(NetworkAddressPage)).ExtractInto(&s)
|
||||||
|
|
|
@ -2,8 +2,9 @@ package servers
|
||||||
|
|
||||||
import "github.com/gophercloud/gophercloud"
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
// WaitForStatus will continually poll a server until it successfully transitions to a specified
|
// WaitForStatus will continually poll a server until it successfully
|
||||||
// status. It will do this for at most the number of seconds specified.
|
// 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 {
|
func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error {
|
||||||
return gophercloud.WaitFor(secs, func() (bool, error) {
|
return gophercloud.WaitFor(secs, func() (bool, error) {
|
||||||
current, err := Get(c, id).Extract()
|
current, err := Get(c, id).Extract()
|
||||||
|
|
101
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/doc.go
generated
vendored
Normal file
101
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
Package clusters contains functionality for working with Magnum Cluster resources.
|
||||||
|
|
||||||
|
Example to Create a Cluster
|
||||||
|
|
||||||
|
masterCount := 1
|
||||||
|
nodeCount := 1
|
||||||
|
createTimeout := 30
|
||||||
|
opts := clusters.CreateOpts{
|
||||||
|
ClusterTemplateID: "0562d357-8641-4759-8fed-8173f02c9633",
|
||||||
|
CreateTimeout: &createTimeout,
|
||||||
|
DiscoveryURL: "",
|
||||||
|
FlavorID: "m1.small",
|
||||||
|
KeyPair: "my_keypair",
|
||||||
|
Labels: map[string]string{},
|
||||||
|
MasterCount: &masterCount,
|
||||||
|
MasterFlavorID: "m1.small",
|
||||||
|
Name: "k8s",
|
||||||
|
NodeCount: &nodeCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster, err := clusters.Create(serviceClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Get a Cluster
|
||||||
|
|
||||||
|
clusterName := "cluster123"
|
||||||
|
cluster, err := clusters.Get(serviceClient, clusterName).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("%+v\n", cluster)
|
||||||
|
|
||||||
|
Example to List Clusters
|
||||||
|
|
||||||
|
listOpts := clusters.ListOpts{
|
||||||
|
Limit: 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := clusters.List(serviceClient, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allClusters, err := clusters.ExtractClusters(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cluster := range allClusters {
|
||||||
|
fmt.Printf("%+v\n", cluster)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to List Clusters with detailed information
|
||||||
|
|
||||||
|
allPagesDetail, err := clusters.ListDetail(serviceClient, clusters.ListOpts{}).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allClustersDetail, err := clusters.ExtractClusters(allPagesDetail)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, clusterDetail := range allClustersDetail {
|
||||||
|
fmt.Printf("%+v\n", clusterDetail)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Update a Cluster
|
||||||
|
|
||||||
|
updateOpts := []clusters.UpdateOptsBuilder{
|
||||||
|
clusters.UpdateOpts{
|
||||||
|
Op: clusters.ReplaceOp,
|
||||||
|
Path: "/master_lb_enabled",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
clusters.UpdateOpts{
|
||||||
|
Op: clusters.ReplaceOp,
|
||||||
|
Path: "/registry_enabled",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
clusterUUID, err := clusters.Update(serviceClient, clusterUUID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\n", clusterUUID)
|
||||||
|
|
||||||
|
Example to Delete a Cluster
|
||||||
|
|
||||||
|
clusterUUID := "dc6d336e3fc4c0a951b5698cd1236ee"
|
||||||
|
err := clusters.Delete(serviceClient, clusterUUID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
package clusters
|
177
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/requests.go
generated
vendored
Normal file
177
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
package clusters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateOptsBuilder Builder.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToClusterCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts params
|
||||||
|
type CreateOpts struct {
|
||||||
|
ClusterTemplateID string `json:"cluster_template_id" required:"true"`
|
||||||
|
CreateTimeout *int `json:"create_timeout"`
|
||||||
|
DiscoveryURL string `json:"discovery_url,omitempty"`
|
||||||
|
DockerVolumeSize *int `json:"docker_volume_size,omitempty"`
|
||||||
|
FlavorID string `json:"flavor_id,omitempty"`
|
||||||
|
Keypair string `json:"keypair,omitempty"`
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
|
MasterCount *int `json:"master_count,omitempty"`
|
||||||
|
MasterFlavorID string `json:"master_flavor_id,omitempty"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
NodeCount *int `json:"node_count,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToClusterCreateMap constructs a request body from CreateOpts.
|
||||||
|
func (opts CreateOpts) ToClusterCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create requests the creation of a new cluster.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToClusterCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{202},
|
||||||
|
})
|
||||||
|
|
||||||
|
if r.Err == nil {
|
||||||
|
r.Header = result.Header
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a specific clusters based on its unique ID.
|
||||||
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Get(getURL(client, id), &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
|
||||||
|
if r.Err == nil {
|
||||||
|
r.Header = result.Header
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes the specified cluster ID.
|
||||||
|
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||||
|
r.Header = result.Header
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// List request.
|
||||||
|
type ListOptsBuilder interface {
|
||||||
|
ToClustersListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts allows the sorting of paginated collections through
|
||||||
|
// the API. SortKey allows you to sort by a particular cluster attribute.
|
||||||
|
// SortDir sets the direction, and is either `asc' or `desc'.
|
||||||
|
// Marker and Limit are used for pagination.
|
||||||
|
type ListOpts struct {
|
||||||
|
Marker string `q:"marker"`
|
||||||
|
Limit int `q:"limit"`
|
||||||
|
SortKey string `q:"sort_key"`
|
||||||
|
SortDir string `q:"sort_dir"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToClustersListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToClustersListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a Pager which allows you to iterate over a collection of
|
||||||
|
// clusters. It accepts a ListOptsBuilder, which allows you to sort
|
||||||
|
// the returned collection for greater efficiency.
|
||||||
|
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := listURL(c)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToClustersListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return ClusterPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListDetail returns a Pager which allows you to iterate over a collection of
|
||||||
|
// clusters with detailed information.
|
||||||
|
// It accepts a ListOptsBuilder, which allows you to sort the returned
|
||||||
|
// collection for greater efficiency.
|
||||||
|
func ListDetail(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := listDetailURL(c)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToClustersListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return ClusterPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateOp string
|
||||||
|
|
||||||
|
const (
|
||||||
|
AddOp UpdateOp = "add"
|
||||||
|
RemoveOp UpdateOp = "remove"
|
||||||
|
ReplaceOp UpdateOp = "replace"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateOpts struct {
|
||||||
|
Op UpdateOp `json:"op" required:"true"`
|
||||||
|
Path string `json:"path" required:"true"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Update request.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToClustersUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToClusterUpdateMap assembles a request body based on the contents of
|
||||||
|
// UpdateOpts.
|
||||||
|
func (opts UpdateOpts) ToClustersUpdateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update implements cluster updated request.
|
||||||
|
func Update(client *gophercloud.ServiceClient, id string, opts []UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
var o []map[string]interface{}
|
||||||
|
for _, opt := range opts {
|
||||||
|
b, err := opt.ToClustersUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
o = append(o, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Patch(updateURL(client, id), o, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200, 202},
|
||||||
|
})
|
||||||
|
|
||||||
|
if r.Err == nil {
|
||||||
|
r.Header = result.Header
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
114
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/results.go
generated
vendored
Normal file
114
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/results.go
generated
vendored
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
package clusters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
type commonResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult is the response of a Create operations.
|
||||||
|
type CreateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the result from a Delete operation. Call its Extract or ExtractErr
|
||||||
|
// method to determine if the call succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResult represents the result of a get operation.
|
||||||
|
type GetResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract is a function that accepts a result and extracts a cluster resource.
|
||||||
|
func (r commonResult) Extract() (*Cluster, error) {
|
||||||
|
var s *Cluster
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult is the response of a Update operations.
|
||||||
|
type UpdateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r CreateResult) Extract() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
UUID string
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.UUID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r UpdateResult) Extract() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
UUID string
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.UUID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type Cluster struct {
|
||||||
|
APIAddress string `json:"api_address"`
|
||||||
|
COEVersion string `json:"coe_version"`
|
||||||
|
ClusterTemplateID string `json:"cluster_template_id"`
|
||||||
|
ContainerVersion string `json:"container_version"`
|
||||||
|
CreateTimeout int `json:"create_timeout"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
DiscoveryURL string `json:"discovery_url"`
|
||||||
|
DockerVolumeSize int `json:"docker_volume_size"`
|
||||||
|
Faults map[string]string `json:"faults"`
|
||||||
|
FlavorID string `json:"flavor_id"`
|
||||||
|
KeyPair string `json:"keypair"`
|
||||||
|
Labels map[string]string `json:"labels"`
|
||||||
|
Links []gophercloud.Link `json:"links"`
|
||||||
|
MasterFlavorID string `json:"master_flavor_id"`
|
||||||
|
MasterAddresses []string `json:"master_addresses"`
|
||||||
|
MasterCount int `json:"master_count"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
NodeAddresses []string `json:"node_addresses"`
|
||||||
|
NodeCount int `json:"node_count"`
|
||||||
|
ProjectID string `json:"project_id"`
|
||||||
|
StackID string `json:"stack_id"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
StatusReason string `json:"status_reason"`
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClusterPage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ClusterPage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Next string `json:"next"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return s.Next, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty checks whether a ClusterPage struct is empty.
|
||||||
|
func (r ClusterPage) IsEmpty() (bool, error) {
|
||||||
|
is, err := ExtractClusters(r)
|
||||||
|
return len(is) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtractClusters(r pagination.Page) ([]Cluster, error) {
|
||||||
|
var s struct {
|
||||||
|
Clusters []Cluster `json:"clusters"`
|
||||||
|
}
|
||||||
|
err := (r.(ClusterPage)).ExtractInto(&s)
|
||||||
|
return s.Clusters, err
|
||||||
|
}
|
39
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/urls.go
generated
vendored
Normal file
39
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package clusters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
var apiName = "clusters"
|
||||||
|
|
||||||
|
func commonURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL(apiName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func idURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return client.ServiceURL(apiName, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return commonURL(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return idURL(client, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getURL(c *gophercloud.ServiceClient, id string) string {
|
||||||
|
return c.ServiceURL("clusters", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL("clusters")
|
||||||
|
}
|
||||||
|
|
||||||
|
func listDetailURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL("clusters", "detail")
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return idURL(client, id)
|
||||||
|
}
|
90
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/doc.go
generated
vendored
Normal file
90
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
// Package clustertemplates contains functionality for working with Magnum Cluster Templates
|
||||||
|
// resources.
|
||||||
|
/*
|
||||||
|
Package clustertemplates provides information and interaction with the cluster-templates through
|
||||||
|
the OpenStack Container Infra service.
|
||||||
|
|
||||||
|
Example to Create Cluster Template
|
||||||
|
|
||||||
|
boolFalse := false
|
||||||
|
boolTrue := true
|
||||||
|
createOpts := clustertemplates.CreateOpts{
|
||||||
|
Name: "test-cluster-template",
|
||||||
|
Labels: map[string]string{},
|
||||||
|
FixedSubnet: "",
|
||||||
|
MasterFlavorID: "",
|
||||||
|
NoProxy: "10.0.0.0/8,172.0.0.0/8,192.0.0.0/8,localhost",
|
||||||
|
HTTPSProxy: "http://10.164.177.169:8080",
|
||||||
|
TLSDisabled: &boolFalse,
|
||||||
|
KeyPairID: "kp",
|
||||||
|
Public: &boolFalse,
|
||||||
|
HTTPProxy: "http://10.164.177.169:8080",
|
||||||
|
ServerType: "vm",
|
||||||
|
ExternalNetworkID: "public",
|
||||||
|
ImageID: "fedora-atomic-latest",
|
||||||
|
VolumeDriver: "cinder",
|
||||||
|
RegistryEnabled: &boolFalse,
|
||||||
|
DockerStorageDriver: "devicemapper",
|
||||||
|
NetworkDriver: "flannel",
|
||||||
|
FixedNetwork: "",
|
||||||
|
COE: "kubernetes",
|
||||||
|
FlavorID: "m1.small",
|
||||||
|
MasterLBEnabled: &boolTrue,
|
||||||
|
DNSNameServer: "8.8.8.8",
|
||||||
|
}
|
||||||
|
|
||||||
|
clustertemplate, err := clustertemplates.Create(serviceClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete Cluster Template
|
||||||
|
|
||||||
|
clusterTemplateID := "dc6d336e3fc4c0a951b5698cd1236ee"
|
||||||
|
err := clustertemplates.Delete(serviceClient, clusterTemplateID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to List Clusters Templates
|
||||||
|
|
||||||
|
listOpts := clustertemplates.ListOpts{
|
||||||
|
Limit: 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := clustertemplates.List(serviceClient, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allClusterTemplates, err := clusters.ExtractClusterTemplates(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, clusterTemplate := range allClusterTemplates {
|
||||||
|
fmt.Printf("%+v\n", clusterTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Update Cluster Template
|
||||||
|
|
||||||
|
updateOpts := []clustertemplates.UpdateOptsBuilder{
|
||||||
|
clustertemplates.UpdateOpts{
|
||||||
|
Op: clustertemplates.ReplaceOp,
|
||||||
|
Path: "/master_lb_enabled",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
clustertemplates.UpdateOpts{
|
||||||
|
Op: clustertemplates.ReplaceOp,
|
||||||
|
Path: "/registry_enabled",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
clustertemplate, err := clustertemplates.Update(serviceClient, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
package clustertemplates
|
178
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/requests.go
generated
vendored
Normal file
178
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
package clustertemplates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateOptsBuilder Builder.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToClusterCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts params
|
||||||
|
type CreateOpts struct {
|
||||||
|
APIServerPort *int `json:"apiserver_port,omitempty"`
|
||||||
|
COE string `json:"coe" required:"true"`
|
||||||
|
DNSNameServer string `json:"dns_nameserver,omitempty"`
|
||||||
|
DockerStorageDriver string `json:"docker_storage_driver,omitempty"`
|
||||||
|
DockerVolumeSize *int `json:"docker_volume_size,omitempty"`
|
||||||
|
ExternalNetworkID string `json:"external_network_id,omitempty"`
|
||||||
|
FixedNetwork string `json:"fixed_network,omitempty"`
|
||||||
|
FixedSubnet string `json:"fixed_subnet,omitempty"`
|
||||||
|
FlavorID string `json:"flavor_id,omitempty"`
|
||||||
|
FloatingIPEnabled *bool `json:"floating_ip_enabled,omitempty"`
|
||||||
|
HTTPProxy string `json:"http_proxy,omitempty"`
|
||||||
|
HTTPSProxy string `json:"https_proxy,omitempty"`
|
||||||
|
ImageID string `json:"image_id" required:"true"`
|
||||||
|
InsecureRegistry string `json:"insecure_registry,omitempty"`
|
||||||
|
KeyPairID string `json:"keypair_id,omitempty"`
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
|
MasterFlavorID string `json:"master_flavor_id,omitempty"`
|
||||||
|
MasterLBEnabled *bool `json:"master_lb_enabled,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkDriver string `json:"network_driver,omitempty"`
|
||||||
|
NoProxy string `json:"no_proxy,omitempty"`
|
||||||
|
Public *bool `json:"public,omitempty"`
|
||||||
|
RegistryEnabled *bool `json:"registry_enabled,omitempty"`
|
||||||
|
ServerType string `json:"server_type,omitempty"`
|
||||||
|
TLSDisabled *bool `json:"tls_disabled,omitempty"`
|
||||||
|
VolumeDriver string `json:"volume_driver,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToClusterCreateMap constructs a request body from CreateOpts.
|
||||||
|
func (opts CreateOpts) ToClusterCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create requests the creation of a new cluster.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToClusterCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{201},
|
||||||
|
})
|
||||||
|
|
||||||
|
if r.Err == nil {
|
||||||
|
r.Header = result.Header
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes the specified cluster ID.
|
||||||
|
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Delete(deleteURL(client, id), nil)
|
||||||
|
r.Header = result.Header
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// List request.
|
||||||
|
type ListOptsBuilder interface {
|
||||||
|
ToClusterTemplateListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts allows the sorting of paginated collections through
|
||||||
|
// the API. SortKey allows you to sort by a particular cluster templates attribute.
|
||||||
|
// SortDir sets the direction, and is either `asc' or `desc'.
|
||||||
|
// Marker and Limit are used for pagination.
|
||||||
|
type ListOpts struct {
|
||||||
|
Marker string `q:"marker"`
|
||||||
|
Limit int `q:"limit"`
|
||||||
|
SortKey string `q:"sort_key"`
|
||||||
|
SortDir string `q:"sort_dir"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToClusterTemplateListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToClusterTemplateListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a Pager which allows you to iterate over a collection of
|
||||||
|
// cluster-templates. It accepts a ListOptsBuilder, which allows you to sort
|
||||||
|
// the returned collection for greater efficiency.
|
||||||
|
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := listURL(client)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToClusterTemplateListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return ClusterTemplatePage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a specific cluster-template based on its unique ID.
|
||||||
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Get(getURL(client, id), &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
|
||||||
|
if r.Err == nil {
|
||||||
|
r.Header = result.Header
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateOp string
|
||||||
|
|
||||||
|
const (
|
||||||
|
AddOp UpdateOp = "add"
|
||||||
|
RemoveOp UpdateOp = "remove"
|
||||||
|
ReplaceOp UpdateOp = "replace"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateOpts struct {
|
||||||
|
Op UpdateOp `json:"op" required:"true"`
|
||||||
|
Path string `json:"path" required:"true"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Update request.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToClusterTemplateUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToClusterUpdateMap assembles a request body based on the contents of
|
||||||
|
// UpdateOpts.
|
||||||
|
func (opts UpdateOpts) ToClusterTemplateUpdateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update implements cluster updated request.
|
||||||
|
func Update(client *gophercloud.ServiceClient, id string, opts []UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
var o []map[string]interface{}
|
||||||
|
for _, opt := range opts {
|
||||||
|
b, err := opt.ToClusterTemplateUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
o = append(o, b)
|
||||||
|
}
|
||||||
|
var result *http.Response
|
||||||
|
result, r.Err = client.Patch(updateURL(client, id), o, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200, 202},
|
||||||
|
})
|
||||||
|
|
||||||
|
if r.Err == nil {
|
||||||
|
r.Header = result.Header
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
114
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/results.go
generated
vendored
Normal file
114
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/results.go
generated
vendored
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
package clustertemplates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
type commonResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult is the response of a Create operations.
|
||||||
|
type CreateResult 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResult is the response of a Get operations.
|
||||||
|
type GetResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult is the response of a Update operations.
|
||||||
|
type UpdateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract is a function that accepts a result and extracts a cluster-template resource.
|
||||||
|
func (r commonResult) Extract() (*ClusterTemplate, error) {
|
||||||
|
var s *ClusterTemplate
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Represents a template for a Cluster Template
|
||||||
|
type ClusterTemplate struct {
|
||||||
|
APIServerPort int `json:"apiserver_port"`
|
||||||
|
COE string `json:"coe"`
|
||||||
|
ClusterDistro string `json:"cluster_distro"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
DNSNameServer string `json:"dns_nameserver"`
|
||||||
|
DockerStorageDriver string `json:"docker_storage_driver"`
|
||||||
|
DockerVolumeSize int `json:"docker_volume_size"`
|
||||||
|
ExternalNetworkID string `json:"external_network_id"`
|
||||||
|
FixedNetwork string `json:"fixed_network"`
|
||||||
|
FixedSubnet string `json:"fixed_subnet"`
|
||||||
|
FlavorID string `json:"flavor_id"`
|
||||||
|
FloatingIPEnabled bool `json:"floating_ip_enabled"`
|
||||||
|
HTTPProxy string `json:"http_proxy"`
|
||||||
|
HTTPSProxy string `json:"https_proxy"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
InsecureRegistry string `json:"insecure_registry"`
|
||||||
|
KeyPairID string `json:"keypair_id"`
|
||||||
|
Labels map[string]string `json:"labels"`
|
||||||
|
Links []gophercloud.Link `json:"links"`
|
||||||
|
MasterFlavorID string `json:"master_flavor_id"`
|
||||||
|
MasterLBEnabled bool `json:"master_lb_enabled"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
NetworkDriver string `json:"network_driver"`
|
||||||
|
NoProxy string `json:"no_proxy"`
|
||||||
|
ProjectID string `json:"project_id"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
RegistryEnabled bool `json:"registry_enabled"`
|
||||||
|
ServerType string `json:"server_type"`
|
||||||
|
TLSDisabled bool `json:"tls_disabled"`
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
VolumeDriver string `json:"volume_driver"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClusterTemplatePage is the page returned by a pager when traversing over a
|
||||||
|
// collection of cluster-templates.
|
||||||
|
type ClusterTemplatePage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextPageURL is invoked when a paginated collection of cluster template 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 ClusterTemplatePage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Next string `json:"next"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return s.Next, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty checks whether a ClusterTemplatePage struct is empty.
|
||||||
|
func (r ClusterTemplatePage) IsEmpty() (bool, error) {
|
||||||
|
is, err := ExtractClusterTemplates(r)
|
||||||
|
return len(is) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractClusterTemplates accepts a Page struct, specifically a ClusterTemplatePage struct,
|
||||||
|
// and extracts the elements into a slice of cluster templates structs. In other words,
|
||||||
|
// a generic collection is mapped into a relevant slice.
|
||||||
|
func ExtractClusterTemplates(r pagination.Page) ([]ClusterTemplate, error) {
|
||||||
|
var s struct {
|
||||||
|
ClusterTemplates []ClusterTemplate `json:"clustertemplates"`
|
||||||
|
}
|
||||||
|
err := (r.(ClusterTemplatePage)).ExtractInto(&s)
|
||||||
|
return s.ClusterTemplates, err
|
||||||
|
}
|
35
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/urls.go
generated
vendored
Normal file
35
vendor/github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package clustertemplates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
var apiName = "clustertemplates"
|
||||||
|
|
||||||
|
func commonURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL(apiName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func idURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return client.ServiceURL(apiName, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return commonURL(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return idURL(client, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return commonURL(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return idURL(client, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return idURL(client, id)
|
||||||
|
}
|
11
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/doc.go
generated
vendored
Normal file
11
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Package configurations provides information and interaction with the
|
||||||
|
// configuration API resource in the Rackspace Database service.
|
||||||
|
//
|
||||||
|
// A configuration group is a collection of key/value pairs which define how a
|
||||||
|
// particular database operates. These key/value pairs are specific to each
|
||||||
|
// datastore type and serve like settings. Some directives are capable of being
|
||||||
|
// applied dynamically, while other directives require a server restart to take
|
||||||
|
// effect. The configuration group can be applied to an instance at creation or
|
||||||
|
// applied to an existing instance to modify the behavior of the running
|
||||||
|
// datastore on the instance.
|
||||||
|
package configurations
|
167
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/requests.go
generated
vendored
Normal file
167
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
package configurations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/instances"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// List will list all of the available configurations.
|
||||||
|
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
|
return pagination.NewPager(client, baseURL(client), func(r pagination.PageResult) pagination.Page {
|
||||||
|
return ConfigPage{pagination.SinglePageBase(r)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOptsBuilder is a top-level interface which renders a JSON map.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToConfigCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DatastoreOpts is the primary options struct for creating and modifying
|
||||||
|
// how configuration resources are associated with datastores.
|
||||||
|
type DatastoreOpts struct {
|
||||||
|
// The type of datastore. Defaults to "MySQL".
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
// The specific version of a datastore. Defaults to "5.6".
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts is the struct responsible for configuring new configurations.
|
||||||
|
type CreateOpts struct {
|
||||||
|
// The configuration group name
|
||||||
|
Name string `json:"name" required:"true"`
|
||||||
|
// A map of user-defined configuration settings that will define
|
||||||
|
// how each associated datastore works. Each key/value pair is specific to a
|
||||||
|
// datastore type.
|
||||||
|
Values map[string]interface{} `json:"values" required:"true"`
|
||||||
|
// Associates the configuration group with a particular datastore.
|
||||||
|
Datastore *DatastoreOpts `json:"datastore,omitempty"`
|
||||||
|
// A human-readable explanation for the group.
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToConfigCreateMap casts a CreateOpts struct into a JSON map.
|
||||||
|
func (opts CreateOpts) ToConfigCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create will create a new configuration group.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToConfigCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get will retrieve the details for a specified configuration group.
|
||||||
|
func Get(client *gophercloud.ServiceClient, configID string) (r GetResult) {
|
||||||
|
_, r.Err = client.Get(resourceURL(client, configID), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder is the top-level interface for casting update options into
|
||||||
|
// JSON maps.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToConfigUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOpts is the struct responsible for modifying existing configurations.
|
||||||
|
type UpdateOpts struct {
|
||||||
|
// The configuration group name
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
// A map of user-defined configuration settings that will define
|
||||||
|
// how each associated datastore works. Each key/value pair is specific to a
|
||||||
|
// datastore type.
|
||||||
|
Values map[string]interface{} `json:"values,omitempty"`
|
||||||
|
// Associates the configuration group with a particular datastore.
|
||||||
|
Datastore *DatastoreOpts `json:"datastore,omitempty"`
|
||||||
|
// A human-readable explanation for the group.
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToConfigUpdateMap will cast an UpdateOpts struct into a JSON map.
|
||||||
|
func (opts UpdateOpts) ToConfigUpdateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update will modify an existing configuration group by performing a merge
|
||||||
|
// between new and existing values. If the key already exists, the new value
|
||||||
|
// will overwrite. All other keys will remain unaffected.
|
||||||
|
func Update(client *gophercloud.ServiceClient, configID string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
b, err := opts.ToConfigUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Patch(resourceURL(client, configID), &b, nil, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace will modify an existing configuration group by overwriting the
|
||||||
|
// entire parameter group with the new values provided. Any existing keys not
|
||||||
|
// included in UpdateOptsBuilder will be deleted.
|
||||||
|
func Replace(client *gophercloud.ServiceClient, configID string, opts UpdateOptsBuilder) (r ReplaceResult) {
|
||||||
|
b, err := opts.ToConfigUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Put(resourceURL(client, configID), &b, nil, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete will permanently delete a configuration group. Please note that
|
||||||
|
// config groups cannot be deleted whilst still attached to running instances -
|
||||||
|
// you must detach and then delete them.
|
||||||
|
func Delete(client *gophercloud.ServiceClient, configID string) (r DeleteResult) {
|
||||||
|
_, r.Err = client.Delete(resourceURL(client, configID), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListInstances will list all the instances associated with a particular
|
||||||
|
// configuration group.
|
||||||
|
func ListInstances(client *gophercloud.ServiceClient, configID string) pagination.Pager {
|
||||||
|
return pagination.NewPager(client, instancesURL(client, configID), func(r pagination.PageResult) pagination.Page {
|
||||||
|
return instances.InstancePage{LinkedPageBase: pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListDatastoreParams will list all the available and supported parameters
|
||||||
|
// that can be used for a particular datastore ID and a particular version.
|
||||||
|
// For example, if you are wondering how you can configure a MySQL 5.6 instance,
|
||||||
|
// you can use this operation (you will need to retrieve the MySQL datastore ID
|
||||||
|
// by using the datastores API).
|
||||||
|
func ListDatastoreParams(client *gophercloud.ServiceClient, datastoreID, versionID string) pagination.Pager {
|
||||||
|
return pagination.NewPager(client, listDSParamsURL(client, datastoreID, versionID), func(r pagination.PageResult) pagination.Page {
|
||||||
|
return ParamPage{pagination.SinglePageBase(r)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDatastoreParam will retrieve information about a specific configuration
|
||||||
|
// parameter. For example, you can use this operation to understand more about
|
||||||
|
// "innodb_file_per_table" configuration param for MySQL datastores. You will
|
||||||
|
// need the param's ID first, which can be attained by using the ListDatastoreParams
|
||||||
|
// operation.
|
||||||
|
func GetDatastoreParam(client *gophercloud.ServiceClient, datastoreID, versionID, paramID string) (r ParamResult) {
|
||||||
|
_, r.Err = client.Get(getDSParamURL(client, datastoreID, versionID, paramID), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListGlobalParams is similar to ListDatastoreParams but does not require a
|
||||||
|
// DatastoreID.
|
||||||
|
func ListGlobalParams(client *gophercloud.ServiceClient, versionID string) pagination.Pager {
|
||||||
|
return pagination.NewPager(client, listGlobalParamsURL(client, versionID), func(r pagination.PageResult) pagination.Page {
|
||||||
|
return ParamPage{pagination.SinglePageBase(r)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlobalParam is similar to GetDatastoreParam but does not require a
|
||||||
|
// DatastoreID.
|
||||||
|
func GetGlobalParam(client *gophercloud.ServiceClient, versionID, paramID string) (r ParamResult) {
|
||||||
|
_, r.Err = client.Get(getGlobalParamURL(client, versionID, paramID), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
141
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/results.go
generated
vendored
Normal file
141
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/results.go
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
package configurations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config represents a configuration group API resource.
|
||||||
|
type Config struct {
|
||||||
|
Created time.Time `json:"-"`
|
||||||
|
Updated time.Time `json:"-"`
|
||||||
|
DatastoreName string `json:"datastore_name"`
|
||||||
|
DatastoreVersionID string `json:"datastore_version_id"`
|
||||||
|
DatastoreVersionName string `json:"datastore_version_name"`
|
||||||
|
Description string
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
Values map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Config) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Config
|
||||||
|
var s struct {
|
||||||
|
tmp
|
||||||
|
Created gophercloud.JSONRFC3339NoZ `json:"created"`
|
||||||
|
Updated gophercloud.JSONRFC3339NoZ `json:"updated"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*r = Config(s.tmp)
|
||||||
|
|
||||||
|
r.Created = time.Time(s.Created)
|
||||||
|
r.Updated = time.Time(s.Updated)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigPage contains a page of Config resources in a paginated collection.
|
||||||
|
type ConfigPage struct {
|
||||||
|
pagination.SinglePageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty indicates whether a ConfigPage is empty.
|
||||||
|
func (r ConfigPage) IsEmpty() (bool, error) {
|
||||||
|
is, err := ExtractConfigs(r)
|
||||||
|
return len(is) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractConfigs will retrieve a slice of Config structs from a page.
|
||||||
|
func ExtractConfigs(r pagination.Page) ([]Config, error) {
|
||||||
|
var s struct {
|
||||||
|
Configs []Config `json:"configurations"`
|
||||||
|
}
|
||||||
|
err := (r.(ConfigPage)).ExtractInto(&s)
|
||||||
|
return s.Configs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type commonResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract will retrieve a Config resource from an operation result.
|
||||||
|
func (r commonResult) Extract() (*Config, error) {
|
||||||
|
var s struct {
|
||||||
|
Config *Config `json:"configuration"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Config, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResult represents the result of a Get operation.
|
||||||
|
type GetResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult represents the result of a Create operation.
|
||||||
|
type CreateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult represents the result of an Update operation.
|
||||||
|
type UpdateResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceResult represents the result of a Replace operation.
|
||||||
|
type ReplaceResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResult represents the result of a Delete operation.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param represents a configuration parameter API resource.
|
||||||
|
type Param struct {
|
||||||
|
Max float64
|
||||||
|
Min float64
|
||||||
|
Name string
|
||||||
|
RestartRequired bool `json:"restart_required"`
|
||||||
|
Type string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamPage contains a page of Param resources in a paginated collection.
|
||||||
|
type ParamPage struct {
|
||||||
|
pagination.SinglePageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty indicates whether a ParamPage is empty.
|
||||||
|
func (r ParamPage) IsEmpty() (bool, error) {
|
||||||
|
is, err := ExtractParams(r)
|
||||||
|
return len(is) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractParams will retrieve a slice of Param structs from a page.
|
||||||
|
func ExtractParams(r pagination.Page) ([]Param, error) {
|
||||||
|
var s struct {
|
||||||
|
Params []Param `json:"configuration-parameters"`
|
||||||
|
}
|
||||||
|
err := (r.(ParamPage)).ExtractInto(&s)
|
||||||
|
return s.Params, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamResult represents the result of an operation which retrieves details
|
||||||
|
// about a particular configuration param.
|
||||||
|
type ParamResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract will retrieve a param from an operation result.
|
||||||
|
func (r ParamResult) Extract() (*Param, error) {
|
||||||
|
var s *Param
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s, err
|
||||||
|
}
|
31
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/urls.go
generated
vendored
Normal file
31
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/configurations/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package configurations
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func baseURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return c.ServiceURL("configurations")
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceURL(c *gophercloud.ServiceClient, configID string) string {
|
||||||
|
return c.ServiceURL("configurations", configID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func instancesURL(c *gophercloud.ServiceClient, configID string) string {
|
||||||
|
return c.ServiceURL("configurations", configID, "instances")
|
||||||
|
}
|
||||||
|
|
||||||
|
func listDSParamsURL(c *gophercloud.ServiceClient, datastoreID, versionID string) string {
|
||||||
|
return c.ServiceURL("datastores", datastoreID, "versions", versionID, "parameters")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDSParamURL(c *gophercloud.ServiceClient, datastoreID, versionID, paramID string) string {
|
||||||
|
return c.ServiceURL("datastores", datastoreID, "versions", versionID, "parameters", paramID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listGlobalParamsURL(c *gophercloud.ServiceClient, versionID string) string {
|
||||||
|
return c.ServiceURL("datastores", "versions", versionID, "parameters")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getGlobalParamURL(c *gophercloud.ServiceClient, versionID, paramID string) string {
|
||||||
|
return c.ServiceURL("datastores", "versions", versionID, "parameters", paramID)
|
||||||
|
}
|
6
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/databases/doc.go
generated
vendored
Normal file
6
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/databases/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// Package flavors provides information and interaction with the database API
|
||||||
|
// resource in the OpenStack Database service.
|
||||||
|
//
|
||||||
|
// A database, when referred to here, refers to the database engine running on
|
||||||
|
// an instance.
|
||||||
|
package databases
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue