vendor: Updating Gophercloud for OpenStack Provider (#11191)
This commit is contained in:
parent
a2c0b85b2d
commit
7b168604a1
|
@ -1,235 +0,0 @@
|
||||||
# Contributing to Gophercloud
|
|
||||||
|
|
||||||
- [Getting started](#getting-started)
|
|
||||||
- [Tests](#tests)
|
|
||||||
- [Style guide](#basic-style-guide)
|
|
||||||
- [3 ways to get involved](#5-ways-to-get-involved)
|
|
||||||
|
|
||||||
## Setting up your git workspace
|
|
||||||
|
|
||||||
As a contributor you will need to setup your workspace in a slightly different
|
|
||||||
way than just downloading it. Here are the basic installation instructions:
|
|
||||||
|
|
||||||
1. Configure your `$GOPATH` and run `go get` as described in the main
|
|
||||||
[README](/README.md#how-to-install) but add `-tags "fixtures acceptance"` to
|
|
||||||
get dependencies for unit and acceptance tests.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get -tags "fixtures acceptance" github.com/gophercloud/gophercloud
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Move into the directory that houses your local repository:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ${GOPATH}/src/github.com/gophercloud/gophercloud
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Fork the `gophercloud/gophercloud` repository and update your remote refs. You
|
|
||||||
will need to rename the `origin` remote branch to `upstream`, and add your
|
|
||||||
fork as `origin` instead:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git remote rename origin upstream
|
|
||||||
git remote add origin git@github.com:<my_username>/gophercloud.git
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Checkout the latest development branch:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git checkout master
|
|
||||||
```
|
|
||||||
|
|
||||||
5. If you're working on something (discussed more in detail below), you will
|
|
||||||
need to checkout a new feature branch:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git checkout -b my-new-feature
|
|
||||||
```
|
|
||||||
|
|
||||||
Another thing to bear in mind is that you will need to add a few extra
|
|
||||||
environment variables for acceptance tests - this is documented in our
|
|
||||||
[acceptance tests readme](/acceptance).
|
|
||||||
|
|
||||||
## Tests
|
|
||||||
|
|
||||||
When working on a new or existing feature, testing will be the backbone of your
|
|
||||||
work since it helps uncover and prevent regressions in the codebase. There are
|
|
||||||
two types of test we use in Gophercloud: unit tests and acceptance tests, which
|
|
||||||
are both described below.
|
|
||||||
|
|
||||||
### Unit tests
|
|
||||||
|
|
||||||
Unit tests are the fine-grained tests that establish and ensure the behavior
|
|
||||||
of individual units of functionality. We usually test on an
|
|
||||||
operation-by-operation basis (an operation typically being an API action) with
|
|
||||||
the use of mocking to set up explicit expectations. Each operation will set up
|
|
||||||
its HTTP response expectation, and then test how the system responds when fed
|
|
||||||
this controlled, pre-determined input.
|
|
||||||
|
|
||||||
To make life easier, we've introduced a bunch of test helpers to simplify the
|
|
||||||
process of testing expectations with assertions:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud/testhelper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSomething(t *testing.T) {
|
|
||||||
result, err := Operation()
|
|
||||||
|
|
||||||
testhelper.AssertEquals(t, "foo", result.Bar)
|
|
||||||
testhelper.AssertNoErr(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSomethingElse(t *testing.T) {
|
|
||||||
testhelper.CheckEquals(t, "expected", "actual")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`AssertEquals` and `AssertNoErr` will throw a fatal error if a value does not
|
|
||||||
match an expected value or if an error has been declared, respectively. You can
|
|
||||||
also use `CheckEquals` and `CheckNoErr` for the same purpose; the only difference
|
|
||||||
being that `t.Errorf` is raised rather than `t.Fatalf`.
|
|
||||||
|
|
||||||
Here is a truncated example of mocked HTTP responses:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
th "github.com/gophercloud/gophercloud/testhelper"
|
|
||||||
fake "github.com/gophercloud/gophercloud/testhelper/client"
|
|
||||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGet(t *testing.T) {
|
|
||||||
// Setup the HTTP request multiplexer and server
|
|
||||||
th.SetupHTTP()
|
|
||||||
defer th.TeardownHTTP()
|
|
||||||
|
|
||||||
th.Mux.HandleFunc("/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// Test we're using the correct HTTP method
|
|
||||||
th.TestMethod(t, r, "GET")
|
|
||||||
|
|
||||||
// Test we're setting the auth token
|
|
||||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
|
||||||
|
|
||||||
// Set the appropriate headers for our mocked response
|
|
||||||
w.Header().Add("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
|
|
||||||
// Set the HTTP body
|
|
||||||
fmt.Fprintf(w, `
|
|
||||||
{
|
|
||||||
"network": {
|
|
||||||
"status": "ACTIVE",
|
|
||||||
"name": "private-network",
|
|
||||||
"admin_state_up": true,
|
|
||||||
"tenant_id": "4fd44f30292945e481c7b8a0c8908869",
|
|
||||||
"shared": true,
|
|
||||||
"id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Call our API operation
|
|
||||||
network, err := networks.Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
|
|
||||||
|
|
||||||
// Assert no errors and equality
|
|
||||||
th.AssertNoErr(t, err)
|
|
||||||
th.AssertEquals(t, n.Status, "ACTIVE")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Acceptance tests
|
|
||||||
|
|
||||||
As we've already mentioned, unit tests have a very narrow and confined focus -
|
|
||||||
they test small units of behavior. Acceptance tests on the other hand have a
|
|
||||||
far larger scope: they are fully functional tests that test the entire API of a
|
|
||||||
service in one fell swoop. They don't care about unit isolation or mocking
|
|
||||||
expectations, they instead do a full run-through and consequently test how the
|
|
||||||
entire system _integrates_ together. When an API satisfies expectations, it
|
|
||||||
proves by default that the requirements for a contract have been met.
|
|
||||||
|
|
||||||
Please be aware that acceptance tests will hit a live API - and may incur
|
|
||||||
service charges from your provider. Although most tests handle their own
|
|
||||||
teardown procedures, it is always worth manually checking that resources are
|
|
||||||
deleted after the test suite finishes.
|
|
||||||
|
|
||||||
### Running tests
|
|
||||||
|
|
||||||
To run all tests:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go test -tags fixtures ./...
|
|
||||||
```
|
|
||||||
|
|
||||||
To run all tests with verbose output:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go test -v -tags fixtures ./...
|
|
||||||
```
|
|
||||||
|
|
||||||
To run tests that match certain [build tags]():
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go test -tags "fixtures foo bar" ./...
|
|
||||||
```
|
|
||||||
|
|
||||||
To run tests for a particular sub-package:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ./path/to/package && go test -tags fixtures .
|
|
||||||
```
|
|
||||||
|
|
||||||
## Style guide
|
|
||||||
|
|
||||||
See [here](/STYLEGUIDE.md)
|
|
||||||
|
|
||||||
## 3 ways to get involved
|
|
||||||
|
|
||||||
There are five main ways you can get involved in our open-source project, and
|
|
||||||
each is described briefly below. Once you've made up your mind and decided on
|
|
||||||
your fix, you will need to follow the same basic steps that all submissions are
|
|
||||||
required to adhere to:
|
|
||||||
|
|
||||||
1. [fork](https://help.github.com/articles/fork-a-repo/) the `gophercloud/gophercloud` repository
|
|
||||||
2. checkout a [new branch](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches)
|
|
||||||
3. submit your branch as a [pull request](https://help.github.com/articles/creating-a-pull-request/)
|
|
||||||
|
|
||||||
### 1. Fixing bugs
|
|
||||||
|
|
||||||
If you want to start fixing open bugs, we'd really appreciate that! Bug fixing
|
|
||||||
is central to any project. The best way to get started is by heading to our
|
|
||||||
[bug tracker](https://github.com/gophercloud/gophercloud/issues) and finding open
|
|
||||||
bugs that you think nobody is working on. It might be useful to comment on the
|
|
||||||
thread to see the current state of the issue and if anybody has made any
|
|
||||||
breakthroughs on it so far.
|
|
||||||
|
|
||||||
### 2. Improving documentation
|
|
||||||
The best source of documentation is on [godoc.org](http://godoc.org). It is
|
|
||||||
automatically generated from the source code.
|
|
||||||
|
|
||||||
If you feel that a certain section could be improved - whether it's to clarify
|
|
||||||
ambiguity, correct a technical mistake, or to fix a grammatical error - please
|
|
||||||
feel entitled to do so! We welcome doc pull requests with the same childlike
|
|
||||||
enthusiasm as any other contribution!
|
|
||||||
|
|
||||||
###3. Working on a new feature
|
|
||||||
|
|
||||||
If you've found something we've left out, definitely feel free to start work on
|
|
||||||
introducing that feature. It's always useful to open an issue or submit a pull
|
|
||||||
request early on to indicate your intent to a core contributor - this enables
|
|
||||||
quick/early feedback and can help steer you in the right direction by avoiding
|
|
||||||
known issues. It might also help you avoid losing time implementing something
|
|
||||||
that might not ever work. One tip is to prefix your Pull Request issue title
|
|
||||||
with [wip] - then people know it's a work in progress.
|
|
||||||
|
|
||||||
You must ensure that all of your work is well tested - both in terms of unit
|
|
||||||
and acceptance tests. Untested code will not be merged because it introduces
|
|
||||||
too much of a risk to end-users.
|
|
||||||
|
|
||||||
Happy hacking!
|
|
|
@ -131,7 +131,7 @@ None. Vendor it and write tests covering the parts you use.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
See the [contributing guide](./CONTRIBUTING.md).
|
See the [contributing guide](./.github/CONTRIBUTING.md).
|
||||||
|
|
||||||
## Help and feedback
|
## Help and feedback
|
||||||
|
|
||||||
|
|
75
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
75
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes/results.go
generated
vendored
|
@ -1,12 +1,15 @@
|
||||||
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"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Attachment struct {
|
type Attachment struct {
|
||||||
AttachedAt gophercloud.JSONRFC3339MilliNoZ `json:"attached_at"`
|
AttachedAt time.Time `json:"-"`
|
||||||
AttachmentID string `json:"attachment_id"`
|
AttachmentID string `json:"attachment_id"`
|
||||||
Device string `json:"device"`
|
Device string `json:"device"`
|
||||||
HostName string `json:"host_name"`
|
HostName string `json:"host_name"`
|
||||||
|
@ -15,6 +18,23 @@ type Attachment struct {
|
||||||
VolumeID string `json:"volume_id"`
|
VolumeID string `json:"volume_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Attachment) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Attachment
|
||||||
|
var s struct {
|
||||||
|
tmp
|
||||||
|
AttachedAt gophercloud.JSONRFC3339MilliNoZ `json:"attached_at"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*r = Attachment(s.tmp)
|
||||||
|
|
||||||
|
r.AttachedAt = time.Time(s.AttachedAt)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Volume contains all the information associated with an OpenStack Volume.
|
// Volume contains all the information associated with an OpenStack Volume.
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
// Unique identifier for the volume.
|
// Unique identifier for the volume.
|
||||||
|
@ -26,9 +46,9 @@ type Volume struct {
|
||||||
// AvailabilityZone is which availability zone the volume is in.
|
// AvailabilityZone is which availability zone the volume is in.
|
||||||
AvailabilityZone string `json:"availability_zone"`
|
AvailabilityZone string `json:"availability_zone"`
|
||||||
// The date when this volume was created.
|
// The date when this volume was created.
|
||||||
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
CreatedAt time.Time `json:"-"`
|
||||||
// The date when this volume was last updated
|
// The date when this volume was last updated
|
||||||
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
UpdatedAt time.Time `json:"-"`
|
||||||
// Instances onto which the volume is attached.
|
// Instances onto which the volume is attached.
|
||||||
Attachments []Attachment `json:"attachments"`
|
Attachments []Attachment `json:"attachments"`
|
||||||
// Human-readable display name for the volume.
|
// Human-readable display name for the volume.
|
||||||
|
@ -57,15 +77,24 @@ type Volume struct {
|
||||||
Multiattach bool `json:"multiattach"`
|
Multiattach bool `json:"multiattach"`
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func (r *Volume) UnmarshalJSON(b []byte) error {
|
||||||
THESE BELONG IN EXTENSIONS:
|
type tmp Volume
|
||||||
// ReplicationDriverData contains data about the replication driver.
|
var s struct {
|
||||||
ReplicationDriverData string `json:"os-volume-replication:driver_data"`
|
tmp
|
||||||
// ReplicationExtendedStatus contains extended status about replication.
|
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
||||||
ReplicationExtendedStatus string `json:"os-volume-replication:extended_status"`
|
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
||||||
// TenantID is the id of the project that owns the volume.
|
}
|
||||||
TenantID string `json:"os-vol-tenant-attr:tenant_id"`
|
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.
|
// VolumePage is a pagination.pager that is returned from a call to the List function.
|
||||||
type VolumePage struct {
|
type VolumePage struct {
|
||||||
|
@ -80,11 +109,9 @@ func (r VolumePage) IsEmpty() (bool, error) {
|
||||||
|
|
||||||
// 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 struct {
|
var s []Volume
|
||||||
Volumes []Volume `json:"volumes"`
|
err := ExtractVolumesInto(r, &s)
|
||||||
}
|
return s, err
|
||||||
err := (r.(VolumePage)).ExtractInto(&s)
|
|
||||||
return s.Volumes, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type commonResult struct {
|
type commonResult struct {
|
||||||
|
@ -93,11 +120,17 @@ type commonResult struct {
|
||||||
|
|
||||||
// Extract will get the Volume object out of the commonResult object.
|
// Extract will get the Volume object out of the commonResult object.
|
||||||
func (r commonResult) Extract() (*Volume, error) {
|
func (r commonResult) Extract() (*Volume, error) {
|
||||||
var s struct {
|
var s Volume
|
||||||
Volume *Volume `json:"volume"`
|
|
||||||
}
|
|
||||||
err := r.ExtractInto(&s)
|
err := r.ExtractInto(&s)
|
||||||
return s.Volume, err
|
return &s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commonResult) ExtractInto(v interface{}) error {
|
||||||
|
return r.Result.ExtractIntoStructPtr(v, "volume")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtractVolumesInto(r pagination.Page, v interface{}) error {
|
||||||
|
return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult contains the response body and error from a Create request.
|
// CreateResult contains the response body and error from a Create request.
|
||||||
|
|
|
@ -309,3 +309,15 @@ func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*
|
||||||
}
|
}
|
||||||
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
eo.ApplyDefaults("image")
|
||||||
|
url, err := client.EndpointLocator(eo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &gophercloud.ServiceClient{ProviderClient: client,
|
||||||
|
Endpoint: url,
|
||||||
|
ResourceBase: url + "v2/"}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package secgroups
|
package secgroups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
@ -10,28 +13,51 @@ type SecurityGroup struct {
|
||||||
// The unique ID of the group. If Neutron is installed, this ID will be
|
// The unique ID of the group. If Neutron is installed, this ID will be
|
||||||
// represented as a string UUID; if Neutron is not installed, it will be a
|
// represented as a string UUID; if Neutron is not installed, it will be a
|
||||||
// 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
|
ID string `json:"-"`
|
||||||
|
|
||||||
// The human-readable name of the group, which needs to be unique.
|
// The human-readable name of the group, which needs to be unique.
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
|
|
||||||
// The human-readable description of the group.
|
// The human-readable description of the group.
|
||||||
Description string
|
Description string `json:"description"`
|
||||||
|
|
||||||
// The rules which determine how this security group operates.
|
// The rules which determine how this security group operates.
|
||||||
Rules []Rule
|
Rules []Rule `json:"rules"`
|
||||||
|
|
||||||
// The ID of the tenant to which this security group belongs.
|
// The ID of the tenant to which this security group belongs.
|
||||||
TenantID string `json:"tenant_id"`
|
TenantID string `json:"tenant_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *SecurityGroup) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp SecurityGroup
|
||||||
|
var s struct {
|
||||||
|
tmp
|
||||||
|
ID interface{} `json:"id"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*r = SecurityGroup(s.tmp)
|
||||||
|
|
||||||
|
switch t := s.ID.(type) {
|
||||||
|
case float64:
|
||||||
|
r.ID = strconv.FormatFloat(t, 'f', -1, 64)
|
||||||
|
case string:
|
||||||
|
r.ID = t
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Rule represents a security group rule, a policy which determines how a
|
// Rule represents a security group rule, a policy which determines how a
|
||||||
// security group operates and what inbound traffic it allows in.
|
// security group operates and what inbound traffic it allows in.
|
||||||
type Rule struct {
|
type Rule struct {
|
||||||
// The unique ID. If Neutron is installed, this ID will be
|
// The unique ID. If Neutron is installed, this ID will be
|
||||||
// represented as a string UUID; if Neutron is not installed, it will be a
|
// represented as a string UUID; if Neutron is not installed, it will be a
|
||||||
// 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
|
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"`
|
||||||
|
@ -52,6 +78,37 @@ type Rule struct {
|
||||||
Group Group
|
Group Group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Rule) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Rule
|
||||||
|
var s struct {
|
||||||
|
tmp
|
||||||
|
ID interface{} `json:"id"`
|
||||||
|
ParentGroupID interface{} `json:"parent_group_id"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*r = Rule(s.tmp)
|
||||||
|
|
||||||
|
switch t := s.ID.(type) {
|
||||||
|
case float64:
|
||||||
|
r.ID = strconv.FormatFloat(t, 'f', -1, 64)
|
||||||
|
case string:
|
||||||
|
r.ID = t
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t := s.ParentGroupID.(type) {
|
||||||
|
case float64:
|
||||||
|
r.ParentGroupID = strconv.FormatFloat(t, 'f', -1, 64)
|
||||||
|
case string:
|
||||||
|
r.ParentGroupID = t
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// IPRange represents the IP range whose traffic will be accepted by the
|
// IPRange represents the IP range whose traffic will be accepted by the
|
||||||
// security group.
|
// security group.
|
||||||
type IPRange struct {
|
type IPRange struct {
|
||||||
|
|
60
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
60
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
@ -101,12 +102,12 @@ func decryptPassword(encryptedPassword string, privateKey *rsa.PrivateKey) (stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (res CreateImageResult) ExtractImageID() (string, error) {
|
func (r CreateImageResult) ExtractImageID() (string, error) {
|
||||||
if res.Err != nil {
|
if r.Err != nil {
|
||||||
return "", res.Err
|
return "", r.Err
|
||||||
}
|
}
|
||||||
// Get the image id from the header
|
// Get the image id from the header
|
||||||
u, err := url.ParseRequestURI(res.Header.Get("Location"))
|
u, err := url.ParseRequestURI(r.Header.Get("Location"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -137,26 +138,27 @@ type Server struct {
|
||||||
// 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 string
|
Updated time.Time `json:"updated"`
|
||||||
Created string
|
Created time.Time `json:"created"`
|
||||||
HostID string
|
HostID string `json:"hostid"`
|
||||||
// Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
|
// Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
|
||||||
Status string
|
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
|
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, AccessIPv6 string
|
AccessIPv4 string `json:"accessIPv4"`
|
||||||
|
AccessIPv6 string `json:"accessIPv6"`
|
||||||
// Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
|
// Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
|
||||||
Image map[string]interface{}
|
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{}
|
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{}
|
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
|
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{}
|
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.
|
||||||
|
@ -166,30 +168,30 @@ type Server struct {
|
||||||
SecurityGroups []map[string]interface{} `json:"security_groups"`
|
SecurityGroups []map[string]interface{} `json:"security_groups"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UnmarshalJSON(b []byte) error {
|
func (r *Server) UnmarshalJSON(b []byte) error {
|
||||||
type tmp Server
|
type tmp Server
|
||||||
var server *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
Image interface{}
|
Image interface{} `json:"image"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &server)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*s = Server(server.tmp)
|
*r = Server(s.tmp)
|
||||||
|
|
||||||
switch t := server.Image.(type) {
|
switch t := s.Image.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
s.Image = t
|
r.Image = t
|
||||||
case string:
|
case string:
|
||||||
switch t {
|
switch t {
|
||||||
case "":
|
case "":
|
||||||
s.Image = nil
|
r.Image = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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 the API.
|
||||||
|
@ -200,17 +202,17 @@ type ServerPage struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if a page contains no Server results.
|
// IsEmpty returns true if a page contains no Server results.
|
||||||
func (page ServerPage) IsEmpty() (bool, error) {
|
func (r ServerPage) IsEmpty() (bool, error) {
|
||||||
servers, err := ExtractServers(page)
|
s, err := ExtractServers(r)
|
||||||
return len(servers) == 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 (page 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"`
|
||||||
}
|
}
|
||||||
err := page.ExtractInto(&s)
|
err := r.ExtractInto(&s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
5
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go
generated
vendored
5
vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go
generated
vendored
|
@ -132,11 +132,6 @@ func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
|
||||||
return &ServiceCatalog{Entries: s.Access.Entries}, err
|
return &ServiceCatalog{Entries: s.Access.Entries}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// createErr quickly packs an error in a CreateResult.
|
|
||||||
func createErr(err error) CreateResult {
|
|
||||||
return CreateResult{gophercloud.Result{Err: err}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractUser returns the User from a GetResult.
|
// ExtractUser returns the User from a GetResult.
|
||||||
func (r GetResult) ExtractUser() (*User, error) {
|
func (r GetResult) ExtractUser() (*User, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
|
|
43
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
generated
vendored
43
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
generated
vendored
|
@ -1,7 +1,10 @@
|
||||||
package tokens
|
package tokens
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
import "github.com/gophercloud/gophercloud"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
// Endpoint represents a single API endpoint offered by a service.
|
// Endpoint represents a single API endpoint offered by a service.
|
||||||
// It matches either a public, internal or admin URL.
|
// It matches either a public, internal or admin URL.
|
||||||
|
@ -35,7 +38,7 @@ type CatalogEntry struct {
|
||||||
|
|
||||||
// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
|
// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
|
||||||
type ServiceCatalog struct {
|
type ServiceCatalog struct {
|
||||||
Entries []CatalogEntry
|
Entries []CatalogEntry `json:"catalog"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// commonResult is the deferred result of a Create or a Get call.
|
// commonResult is the deferred result of a Create or a Get call.
|
||||||
|
@ -51,34 +54,23 @@ func (r commonResult) Extract() (*Token, error) {
|
||||||
|
|
||||||
// ExtractToken interprets a commonResult as a Token.
|
// ExtractToken interprets a commonResult as a Token.
|
||||||
func (r commonResult) ExtractToken() (*Token, error) {
|
func (r commonResult) ExtractToken() (*Token, error) {
|
||||||
var s struct {
|
var s Token
|
||||||
Token *Token `json:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
err := r.ExtractInto(&s)
|
err := r.ExtractInto(&s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Token == nil {
|
|
||||||
return nil, errors.New("'token' missing in JSON response")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the token itself from the stored headers.
|
// Parse the token itself from the stored headers.
|
||||||
s.Token.ID = r.Header.Get("X-Subject-Token")
|
s.ID = r.Header.Get("X-Subject-Token")
|
||||||
|
|
||||||
return s.Token, err
|
return &s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
|
// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
|
||||||
func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
|
func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
|
||||||
var s struct {
|
var s ServiceCatalog
|
||||||
Token struct {
|
|
||||||
Entries []CatalogEntry `json:"catalog"`
|
|
||||||
} `json:"token"`
|
|
||||||
}
|
|
||||||
err := r.ExtractInto(&s)
|
err := r.ExtractInto(&s)
|
||||||
return &ServiceCatalog{Entries: s.Token.Entries}, err
|
return &s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult defers the interpretation of a created token.
|
// CreateResult defers the interpretation of a created token.
|
||||||
|
@ -87,13 +79,6 @@ type CreateResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// createErr quickly creates a CreateResult that reports an error.
|
|
||||||
func createErr(err error) CreateResult {
|
|
||||||
return CreateResult{
|
|
||||||
commonResult: commonResult{Result: gophercloud.Result{Err: err}},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetResult is the deferred response from a Get call.
|
// GetResult is the deferred response from a Get call.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
|
@ -110,5 +95,9 @@ type Token struct {
|
||||||
// ID is the issued token.
|
// ID is the issued token.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
// ExpiresAt is the timestamp at which this token will no longer be accepted.
|
// ExpiresAt is the timestamp at which this token will no longer be accepted.
|
||||||
ExpiresAt gophercloud.JSONRFC3339Milli `json:"expires_at"`
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commonResult) ExtractInto(v interface{}) error {
|
||||||
|
return r.ExtractIntoStructPtr(v, "token")
|
||||||
}
|
}
|
||||||
|
|
75
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts/results.go
generated
vendored
75
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts/results.go
generated
vendored
|
@ -2,9 +2,9 @@ package accounts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
)
|
)
|
||||||
|
@ -19,41 +19,44 @@ type UpdateHeader struct {
|
||||||
ContentLength int64 `json:"-"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UpdateHeader) UnmarshalJSON(b []byte) error {
|
func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp UpdateHeader
|
type tmp UpdateHeader
|
||||||
var updateHeader *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &updateHeader)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = UpdateHeader(updateHeader.tmp)
|
*r = UpdateHeader(s.tmp)
|
||||||
|
|
||||||
switch updateHeader.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(updateHeader.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
r.Date = time.Time(s.Date)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract will return a struct of headers returned from a call to Get. To obtain
|
// Extract will return a struct of headers returned from a call to Get. To obtain
|
||||||
// a map of headers, call the ExtractHeader method on the GetResult.
|
// a map of headers, call the ExtractHeader method on the GetResult.
|
||||||
func (ur UpdateResult) Extract() (*UpdateHeader, error) {
|
func (r UpdateResult) Extract() (*UpdateHeader, error) {
|
||||||
var uh *UpdateHeader
|
var s *UpdateHeader
|
||||||
err := ur.ExtractInto(&uh)
|
err := r.ExtractInto(&s)
|
||||||
return uh, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeader represents the headers returned in the response from a Get request.
|
// GetHeader represents the headers returned in the response from a Get request.
|
||||||
|
@ -66,67 +69,71 @@ type GetHeader struct {
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
TempURLKey string `json:"X-Account-Meta-Temp-URL-Key"`
|
TempURLKey string `json:"X-Account-Meta-Temp-URL-Key"`
|
||||||
TempURLKey2 string `json:"X-Account-Meta-Temp-URL-Key-2"`
|
TempURLKey2 string `json:"X-Account-Meta-Temp-URL-Key-2"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *GetHeader) UnmarshalJSON(b []byte) error {
|
func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp GetHeader
|
type tmp GetHeader
|
||||||
var getHeader *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
BytesUsed string `json:"X-Account-Bytes-Used"`
|
BytesUsed string `json:"X-Account-Bytes-Used"`
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
ContainerCount string `json:"X-Account-Container-Count"`
|
ContainerCount string `json:"X-Account-Container-Count"`
|
||||||
ObjectCount string `json:"X-Account-Object-Count"`
|
ObjectCount string `json:"X-Account-Object-Count"`
|
||||||
|
Date string `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &getHeader)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = GetHeader(getHeader.tmp)
|
*r = GetHeader(s.tmp)
|
||||||
|
|
||||||
switch getHeader.BytesUsed {
|
switch s.BytesUsed {
|
||||||
case "":
|
case "":
|
||||||
h.BytesUsed = 0
|
r.BytesUsed = 0
|
||||||
default:
|
default:
|
||||||
h.BytesUsed, err = strconv.ParseInt(getHeader.BytesUsed, 10, 64)
|
r.BytesUsed, err = strconv.ParseInt(s.BytesUsed, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("getHeader: ", getHeader.ContentLength)
|
switch s.ContentLength {
|
||||||
switch getHeader.ContentLength {
|
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(getHeader.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch getHeader.ObjectCount {
|
switch s.ObjectCount {
|
||||||
case "":
|
case "":
|
||||||
h.ObjectCount = 0
|
r.ObjectCount = 0
|
||||||
default:
|
default:
|
||||||
h.ObjectCount, err = strconv.ParseInt(getHeader.ObjectCount, 10, 64)
|
r.ObjectCount, err = strconv.ParseInt(s.ObjectCount, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch getHeader.ContainerCount {
|
switch s.ContainerCount {
|
||||||
case "":
|
case "":
|
||||||
h.ContainerCount = 0
|
r.ContainerCount = 0
|
||||||
default:
|
default:
|
||||||
h.ContainerCount, err = strconv.ParseInt(getHeader.ContainerCount, 10, 64)
|
r.ContainerCount, err = strconv.ParseInt(s.ContainerCount, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if s.Date != "" {
|
||||||
|
r.Date, err = time.Parse(time.RFC1123, s.Date)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult is returned from a call to the Get function.
|
// GetResult is returned from a call to the Get function.
|
||||||
|
@ -142,7 +149,7 @@ func (r GetResult) Extract() (*GetHeader, error) {
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
|
// ExtractMetadata is a function that takes a GetResult (of type *htts.Response)
|
||||||
// and returns the custom metatdata associated with the account.
|
// and returns the custom metatdata associated with the account.
|
||||||
func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
|
|
103
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers/results.go
generated
vendored
103
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers/results.go
generated
vendored
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
@ -92,7 +93,7 @@ type GetHeader struct {
|
||||||
BytesUsed int64 `json:"-"`
|
BytesUsed int64 `json:"-"`
|
||||||
ContentLength int64 `json:"-"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
ObjectCount int64 `json:"-"`
|
ObjectCount int64 `json:"-"`
|
||||||
Read []string `json:"-"`
|
Read []string `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
|
@ -100,57 +101,60 @@ type GetHeader struct {
|
||||||
Write []string `json:"-"`
|
Write []string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *GetHeader) UnmarshalJSON(b []byte) error {
|
func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp GetHeader
|
type tmp GetHeader
|
||||||
var getHeader *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
BytesUsed string `json:"X-Container-Bytes-Used"`
|
BytesUsed string `json:"X-Container-Bytes-Used"`
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
ObjectCount string `json:"X-Container-Object-Count"`
|
ObjectCount string `json:"X-Container-Object-Count"`
|
||||||
Write string `json:"X-Container-Write"`
|
Write string `json:"X-Container-Write"`
|
||||||
Read string `json:"X-Container-Read"`
|
Read string `json:"X-Container-Read"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &getHeader)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = GetHeader(getHeader.tmp)
|
*r = GetHeader(s.tmp)
|
||||||
|
|
||||||
switch getHeader.BytesUsed {
|
switch s.BytesUsed {
|
||||||
case "":
|
case "":
|
||||||
h.BytesUsed = 0
|
r.BytesUsed = 0
|
||||||
default:
|
default:
|
||||||
h.BytesUsed, err = strconv.ParseInt(getHeader.BytesUsed, 10, 64)
|
r.BytesUsed, err = strconv.ParseInt(s.BytesUsed, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch getHeader.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(getHeader.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch getHeader.ObjectCount {
|
switch s.ObjectCount {
|
||||||
case "":
|
case "":
|
||||||
h.ObjectCount = 0
|
r.ObjectCount = 0
|
||||||
default:
|
default:
|
||||||
h.ObjectCount, err = strconv.ParseInt(getHeader.ObjectCount, 10, 64)
|
r.ObjectCount, err = strconv.ParseInt(s.ObjectCount, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Read = strings.Split(getHeader.Read, ",")
|
r.Read = strings.Split(s.Read, ",")
|
||||||
h.Write = strings.Split(getHeader.Write, ",")
|
r.Write = strings.Split(s.Write, ",")
|
||||||
|
|
||||||
return nil
|
r.Date = time.Time(s.Date)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult represents the result of a get operation.
|
// GetResult represents the result of a get operation.
|
||||||
|
@ -166,7 +170,7 @@ func (r GetResult) Extract() (*GetHeader, error) {
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
|
// ExtractMetadata is a function that takes a GetResult (of type *stts.Response)
|
||||||
// and returns the custom metadata associated with the container.
|
// and returns the custom metadata associated with the container.
|
||||||
func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
|
@ -186,34 +190,37 @@ func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
||||||
type CreateHeader struct {
|
type CreateHeader struct {
|
||||||
ContentLength int64 `json:"-"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CreateHeader) UnmarshalJSON(b []byte) error {
|
func (r *CreateHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp CreateHeader
|
type tmp CreateHeader
|
||||||
var header *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &header)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = CreateHeader(header.tmp)
|
*r = CreateHeader(s.tmp)
|
||||||
|
|
||||||
switch header.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(header.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
r.Date = time.Time(s.Date)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult represents the result of a create operation. To extract the
|
// CreateResult represents the result of a create operation. To extract the
|
||||||
|
@ -235,34 +242,37 @@ func (r CreateResult) Extract() (*CreateHeader, error) {
|
||||||
type UpdateHeader struct {
|
type UpdateHeader struct {
|
||||||
ContentLength int64 `json:"-"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UpdateHeader) UnmarshalJSON(b []byte) error {
|
func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp UpdateHeader
|
type tmp UpdateHeader
|
||||||
var header *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &header)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = UpdateHeader(header.tmp)
|
*r = UpdateHeader(s.tmp)
|
||||||
|
|
||||||
switch header.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(header.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
r.Date = time.Time(s.Date)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateResult represents the result of an update operation. To extract the
|
// UpdateResult represents the result of an update operation. To extract the
|
||||||
|
@ -284,34 +294,37 @@ func (r UpdateResult) Extract() (*UpdateHeader, error) {
|
||||||
type DeleteHeader struct {
|
type DeleteHeader struct {
|
||||||
ContentLength int64 `json:"-"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *DeleteHeader) UnmarshalJSON(b []byte) error {
|
func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp DeleteHeader
|
type tmp DeleteHeader
|
||||||
var header *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &header)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = DeleteHeader(header.tmp)
|
*r = DeleteHeader(s.tmp)
|
||||||
|
|
||||||
switch header.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(header.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
r.Date = time.Time(s.Date)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult represents the result of a delete operation. To extract the
|
// DeleteResult represents the result of a delete operation. To extract the
|
||||||
|
|
178
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/results.go
generated
vendored
178
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects/results.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
@ -23,15 +24,34 @@ type Object struct {
|
||||||
// Hash represents the MD5 checksum value of the object's content.
|
// Hash represents the MD5 checksum value of the object's content.
|
||||||
Hash string `json:"hash"`
|
Hash string `json:"hash"`
|
||||||
|
|
||||||
// LastModified is the RFC3339Milli time the object was last modified, represented
|
// LastModified is the time the object was last modified, represented
|
||||||
// as a string. For any given object (obj), this value may be parsed to a time.Time:
|
// as a string.
|
||||||
// lastModified, err := time.Parse(gophercloud.RFC3339Milli, obj.LastModified)
|
LastModified time.Time `json:"-"`
|
||||||
LastModified gophercloud.JSONRFC3339MilliNoZ `json:"last_modified"`
|
|
||||||
|
|
||||||
// Name is the unique name for the object.
|
// Name is the unique name for the object.
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Object) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Object
|
||||||
|
var s *struct {
|
||||||
|
tmp
|
||||||
|
LastModified gophercloud.JSONRFC3339MilliNoZ `json:"last_modified"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*r = Object(s.tmp)
|
||||||
|
|
||||||
|
r.LastModified = time.Time(s.LastModified)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// ObjectPage is a single page of objects that is returned from a call to the
|
// ObjectPage is a single page of objects that is returned from a call to the
|
||||||
// List function.
|
// List function.
|
||||||
type ObjectPage struct {
|
type ObjectPage struct {
|
||||||
|
@ -105,38 +125,45 @@ type DownloadHeader struct {
|
||||||
ContentEncoding string `json:"Content-Encoding"`
|
ContentEncoding string `json:"Content-Encoding"`
|
||||||
ContentLength int64 `json:"-"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
|
DeleteAt time.Time `json:"-"`
|
||||||
ETag string `json:"Etag"`
|
ETag string `json:"Etag"`
|
||||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
LastModified time.Time `json:"-"`
|
||||||
ObjectManifest string `json:"X-Object-Manifest"`
|
ObjectManifest string `json:"X-Object-Manifest"`
|
||||||
StaticLargeObject bool `json:"X-Static-Large-Object"`
|
StaticLargeObject bool `json:"X-Static-Large-Object"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *DownloadHeader) UnmarshalJSON(b []byte) error {
|
func (r *DownloadHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp DownloadHeader
|
type tmp DownloadHeader
|
||||||
var hTmp *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
|
DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
|
||||||
|
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &hTmp)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = DownloadHeader(hTmp.tmp)
|
*r = DownloadHeader(s.tmp)
|
||||||
|
|
||||||
switch hTmp.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Date = time.Time(s.Date)
|
||||||
|
r.DeleteAt = time.Time(s.DeleteAt)
|
||||||
|
r.LastModified = time.Time(s.LastModified)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,40 +203,47 @@ func (r *DownloadResult) ExtractContent() ([]byte, error) {
|
||||||
type GetHeader struct {
|
type GetHeader struct {
|
||||||
ContentDisposition string `json:"Content-Disposition"`
|
ContentDisposition string `json:"Content-Disposition"`
|
||||||
ContentEncoding string `json:"Content-Encoding"`
|
ContentEncoding string `json:"Content-Encoding"`
|
||||||
ContentLength int64 `json:"Content-Length"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
|
DeleteAt time.Time `json:"-"`
|
||||||
ETag string `json:"Etag"`
|
ETag string `json:"Etag"`
|
||||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
LastModified time.Time `json:"-"`
|
||||||
ObjectManifest string `json:"X-Object-Manifest"`
|
ObjectManifest string `json:"X-Object-Manifest"`
|
||||||
StaticLargeObject bool `json:"X-Static-Large-Object"`
|
StaticLargeObject bool `json:"X-Static-Large-Object"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *GetHeader) UnmarshalJSON(b []byte) error {
|
func (r *GetHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp GetHeader
|
type tmp GetHeader
|
||||||
var hTmp *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
|
DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
|
||||||
|
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &hTmp)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = GetHeader(hTmp.tmp)
|
*r = GetHeader(s.tmp)
|
||||||
|
|
||||||
switch hTmp.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Date = time.Time(s.Date)
|
||||||
|
r.DeleteAt = time.Time(s.DeleteAt)
|
||||||
|
r.LastModified = time.Time(s.LastModified)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,37 +278,42 @@ func (r GetResult) ExtractMetadata() (map[string]string, error) {
|
||||||
|
|
||||||
// CreateHeader represents the headers returned in the response from a Create request.
|
// CreateHeader represents the headers returned in the response from a Create request.
|
||||||
type CreateHeader struct {
|
type CreateHeader struct {
|
||||||
ContentLength int64 `json:"Content-Length"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
ETag string `json:"Etag"`
|
ETag string `json:"Etag"`
|
||||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
LastModified time.Time `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CreateHeader) UnmarshalJSON(b []byte) error {
|
func (r *CreateHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp CreateHeader
|
type tmp CreateHeader
|
||||||
var hTmp *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
|
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &hTmp)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = CreateHeader(hTmp.tmp)
|
*r = CreateHeader(s.tmp)
|
||||||
|
|
||||||
switch hTmp.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Date = time.Time(s.Date)
|
||||||
|
r.LastModified = time.Time(s.LastModified)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,35 +336,38 @@ func (r CreateResult) Extract() (*CreateHeader, error) {
|
||||||
|
|
||||||
// UpdateHeader represents the headers returned in the response from a Update request.
|
// UpdateHeader represents the headers returned in the response from a Update request.
|
||||||
type UpdateHeader struct {
|
type UpdateHeader struct {
|
||||||
ContentLength int64 `json:"Content-Length"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UpdateHeader) UnmarshalJSON(b []byte) error {
|
func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp UpdateHeader
|
type tmp UpdateHeader
|
||||||
var hTmp *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &hTmp)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = UpdateHeader(hTmp.tmp)
|
*r = UpdateHeader(s.tmp)
|
||||||
|
|
||||||
switch hTmp.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Date = time.Time(s.Date)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,33 +388,36 @@ func (r UpdateResult) Extract() (*UpdateHeader, error) {
|
||||||
type DeleteHeader struct {
|
type DeleteHeader struct {
|
||||||
ContentLength int64 `json:"Content-Length"`
|
ContentLength int64 `json:"Content-Length"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *DeleteHeader) UnmarshalJSON(b []byte) error {
|
func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp DeleteHeader
|
type tmp DeleteHeader
|
||||||
var hTmp *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &hTmp)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = DeleteHeader(hTmp.tmp)
|
*r = DeleteHeader(s.tmp)
|
||||||
|
|
||||||
switch hTmp.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Date = time.Time(s.Date)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,39 +436,46 @@ func (r DeleteResult) Extract() (*DeleteHeader, error) {
|
||||||
|
|
||||||
// CopyHeader represents the headers returned in the response from a Copy request.
|
// CopyHeader represents the headers returned in the response from a Copy request.
|
||||||
type CopyHeader struct {
|
type CopyHeader struct {
|
||||||
ContentLength int64 `json:"Content-Length"`
|
ContentLength int64 `json:"-"`
|
||||||
ContentType string `json:"Content-Type"`
|
ContentType string `json:"Content-Type"`
|
||||||
CopiedFrom string `json:"X-Copied-From"`
|
CopiedFrom string `json:"X-Copied-From"`
|
||||||
CopiedFromLastModified gophercloud.JSONRFC1123 `json:"X-Copied-From-Last-Modified"`
|
CopiedFromLastModified time.Time `json:"-"`
|
||||||
Date gophercloud.JSONRFC1123 `json:"Date"`
|
Date time.Time `json:"-"`
|
||||||
ETag string `json:"Etag"`
|
ETag string `json:"Etag"`
|
||||||
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
LastModified time.Time `json:"-"`
|
||||||
TransID string `json:"X-Trans-Id"`
|
TransID string `json:"X-Trans-Id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CopyHeader) UnmarshalJSON(b []byte) error {
|
func (r *CopyHeader) UnmarshalJSON(b []byte) error {
|
||||||
type tmp CopyHeader
|
type tmp CopyHeader
|
||||||
var hTmp *struct {
|
var s struct {
|
||||||
tmp
|
tmp
|
||||||
ContentLength string `json:"Content-Length"`
|
ContentLength string `json:"Content-Length"`
|
||||||
|
CopiedFromLastModified gophercloud.JSONRFC1123 `json:"X-Copied-From-Last-Modified"`
|
||||||
|
Date gophercloud.JSONRFC1123 `json:"Date"`
|
||||||
|
LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(b, &hTmp)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*h = CopyHeader(hTmp.tmp)
|
*r = CopyHeader(s.tmp)
|
||||||
|
|
||||||
switch hTmp.ContentLength {
|
switch s.ContentLength {
|
||||||
case "":
|
case "":
|
||||||
h.ContentLength = 0
|
r.ContentLength = 0
|
||||||
default:
|
default:
|
||||||
h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
|
r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Date = time.Time(s.Date)
|
||||||
|
r.CopiedFromLastModified = time.Time(s.CopiedFromLastModified)
|
||||||
|
r.LastModified = time.Time(s.LastModified)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ func isZero(v reflect.Value) bool {
|
||||||
if v.IsNil() {
|
if v.IsNil() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return isZero(v.Elem())
|
return false
|
||||||
case reflect.Func, reflect.Map, reflect.Slice:
|
case reflect.Func, reflect.Map, reflect.Slice:
|
||||||
return v.IsNil()
|
return v.IsNil()
|
||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
|
@ -307,7 +307,11 @@ func BuildQueryString(opts interface{}) (*url.URL, error) {
|
||||||
|
|
||||||
// if the field is set, add it to the slice of query pieces
|
// if the field is set, add it to the slice of query pieces
|
||||||
if !isZero(v) {
|
if !isZero(v) {
|
||||||
|
loop:
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
v = v.Elem()
|
||||||
|
goto loop
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
params.Add(tags[0], v.String())
|
params.Add(tags[0], v.String())
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
|
|
|
@ -3,8 +3,10 @@ package gophercloud
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -60,6 +62,78 @@ func (r Result) ExtractInto(to interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r Result) extractIntoPtr(to interface{}, label string) error {
|
||||||
|
if label == "" {
|
||||||
|
return r.ExtractInto(&to)
|
||||||
|
}
|
||||||
|
|
||||||
|
var m map[string]interface{}
|
||||||
|
err := r.ExtractInto(&m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(m[label])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(b, &to)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractIntoStructPtr will unmarshal the Result (r) into the provided
|
||||||
|
// interface{} (to).
|
||||||
|
//
|
||||||
|
// NOTE: For internal use only
|
||||||
|
//
|
||||||
|
// `to` must be a pointer to an underlying struct type
|
||||||
|
//
|
||||||
|
// If provided, `label` will be filtered out of the response
|
||||||
|
// body prior to `r` being unmarshalled into `to`.
|
||||||
|
func (r Result) ExtractIntoStructPtr(to interface{}, label string) error {
|
||||||
|
if r.Err != nil {
|
||||||
|
return r.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := reflect.TypeOf(to)
|
||||||
|
if k := t.Kind(); k != reflect.Ptr {
|
||||||
|
return fmt.Errorf("Expected pointer, got %v", k)
|
||||||
|
}
|
||||||
|
switch t.Elem().Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
return r.extractIntoPtr(to, label)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Expected pointer to struct, got: %v", t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractIntoSlicePtr will unmarshal the Result (r) into the provided
|
||||||
|
// interface{} (to).
|
||||||
|
//
|
||||||
|
// NOTE: For internal use only
|
||||||
|
//
|
||||||
|
// `to` must be a pointer to an underlying slice type
|
||||||
|
//
|
||||||
|
// If provided, `label` will be filtered out of the response
|
||||||
|
// body prior to `r` being unmarshalled into `to`.
|
||||||
|
func (r Result) ExtractIntoSlicePtr(to interface{}, label string) error {
|
||||||
|
if r.Err != nil {
|
||||||
|
return r.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := reflect.TypeOf(to)
|
||||||
|
if k := t.Kind(); k != reflect.Ptr {
|
||||||
|
return fmt.Errorf("Expected pointer, got %v", k)
|
||||||
|
}
|
||||||
|
switch t.Elem().Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
return r.extractIntoPtr(to, label)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Expected pointer to slice, got: %v", t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PrettyPrintJSON creates a string containing the full response body as
|
// PrettyPrintJSON creates a string containing the full response body as
|
||||||
// pretty-printed JSON. It's useful for capturing test fixtures and for
|
// pretty-printed JSON. It's useful for capturing test fixtures and for
|
||||||
// debugging extraction bugs. If you include its output in an issue related to
|
// debugging extraction bugs. If you include its output in an issue related to
|
||||||
|
|
|
@ -1282,268 +1282,268 @@
|
||||||
"revision": "2a60fc2ba6c19de80291203597d752e9ba58e4c0"
|
"revision": "2a60fc2ba6c19de80291203597d752e9ba58e4c0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "WJ/6nt4LiRCzFQcaxfc/iodURPM=",
|
"checksumSHA1": "DkbpYqirk9i+2YDR5Ujzpot/oAg=",
|
||||||
"path": "github.com/gophercloud/gophercloud",
|
"path": "github.com/gophercloud/gophercloud",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "KHRGRGaThzPw7fpZ+h6enJbSyDY=",
|
"checksumSHA1": "S3zTth9INyj1RfyHkQEvJAvRWvw=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack",
|
"path": "github.com/gophercloud/gophercloud/openstack",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "XAKLUSwXSMGtbp+U874qU4MzT/A=",
|
"checksumSHA1": "XAKLUSwXSMGtbp+U874qU4MzT/A=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions",
|
"path": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions",
|
||||||
"revision": "d5eda9707e146108e4d424062b602fd97a71c2e6",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-11-14T18:28:31Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "PFD8SEqhArAy/6jRbIlYb5lp64k=",
|
"checksumSHA1": "PFD8SEqhArAy/6jRbIlYb5lp64k=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes",
|
"path": "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "Ucc8dbvgihRt/2YqLhBkBYXF8v0=",
|
"checksumSHA1": "B4IXSmq364HcBruvvV0QjDFxZgc=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
|
"path": "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "w2wHF5eEBE89ZYlkS9GAJsSIq9U=",
|
"checksumSHA1": "w2wHF5eEBE89ZYlkS9GAJsSIq9U=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "pUlKsepGmWDd4PqPaK4W85pHsRU=",
|
"checksumSHA1": "pUlKsepGmWDd4PqPaK4W85pHsRU=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "RWwUliHD65cWApdEo4ckOcPSArg=",
|
"checksumSHA1": "RWwUliHD65cWApdEo4ckOcPSArg=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "tOmntqlmZ/r8aObUChNloddLhwk=",
|
"checksumSHA1": "tOmntqlmZ/r8aObUChNloddLhwk=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "IZQJSUx3hRGbhGrkm9Vtk1GP5XY=",
|
"checksumSHA1": "jNrUTQf+9dYfaD7YqvKwC+kGvyY=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "ci4gzd7Uy9JC4NcQ2ms19pjtW6s=",
|
"checksumSHA1": "ci4gzd7Uy9JC4NcQ2ms19pjtW6s=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "qBpGbX7LQMPATdO8XyQmU7IXDiI=",
|
"checksumSHA1": "qBpGbX7LQMPATdO8XyQmU7IXDiI=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "5JuziAp9BSRA/z+8pTjVLTWeTw4=",
|
"checksumSHA1": "5JuziAp9BSRA/z+8pTjVLTWeTw4=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/tenantnetworks",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/tenantnetworks",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "2VNgU0F9PDax5VKClvMLmbzuksw=",
|
"checksumSHA1": "2VNgU0F9PDax5VKClvMLmbzuksw=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "a9xDFPigDjHlPlthknKlBduGvKY=",
|
"checksumSHA1": "a9xDFPigDjHlPlthknKlBduGvKY=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "UGeqrw3KdPNRwDxl315MAYyy/uY=",
|
"checksumSHA1": "UGeqrw3KdPNRwDxl315MAYyy/uY=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/images",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "8rOLNDSqwz/DSKL1BoPqjtWSWAE=",
|
"checksumSHA1": "efmzF4m/gZ8nKJ5B9RcdQfgCy/o=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers",
|
"path": "github.com/gophercloud/gophercloud/openstack/compute/v2/servers",
|
||||||
"revision": "21a44e132331d6d46ab4187411c85ced6b1a9963",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-11-08T07:34:31Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "1sVqsZBZBNhDXLY9XzjMkcOkcbg=",
|
"checksumSHA1": "1sVqsZBZBNhDXLY9XzjMkcOkcbg=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
"path": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "q1VGeltZl57OidZ5UDxbMsnyV2g=",
|
"checksumSHA1": "AvUU5En9YpG25iLlcAPDgcQODjI=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
"path": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "6M6ofb8ri5G+sZ8OiExLi7irdx8=",
|
"checksumSHA1": "ZKyEbJuIlvuZ9aUushINCXJHF4w=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
"path": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "aTHxjMlfNXFJ3l2TZyvIwqt/3kM=",
|
"checksumSHA1": "aTHxjMlfNXFJ3l2TZyvIwqt/3kM=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "14ZhP0wE/WCL/6oujcML755AaH4=",
|
"checksumSHA1": "14ZhP0wE/WCL/6oujcML755AaH4=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/policies",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/policies",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "sYET5A7WTyJ7dpuxR/VXYoReldw=",
|
"checksumSHA1": "sYET5A7WTyJ7dpuxR/VXYoReldw=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/rules",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/rules",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "0UcU/7oQbhlnYKoT+I+T403U8MQ=",
|
"checksumSHA1": "0UcU/7oQbhlnYKoT+I+T403U8MQ=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "Mjt7GwFygyqPxygY8xZZnUasHmk=",
|
"checksumSHA1": "Mjt7GwFygyqPxygY8xZZnUasHmk=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "mCTz2rnyVfhjJ+AD/WihCNcYWiY=",
|
"checksumSHA1": "mCTz2rnyVfhjJ+AD/WihCNcYWiY=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/members",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/members",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "B2mtHvADREtFLam72wyijyQh/Ds=",
|
"checksumSHA1": "B2mtHvADREtFLam72wyijyQh/Ds=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/monitors",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/monitors",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "pTr22CKKJ26yvhgd0SRxFF4jkEs=",
|
"checksumSHA1": "pTr22CKKJ26yvhgd0SRxFF4jkEs=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/pools",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/pools",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "E7/Z7g5O9o+ge+8YklheTpKgWNw=",
|
"checksumSHA1": "E7/Z7g5O9o+ge+8YklheTpKgWNw=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/vips",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/vips",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "mhpwj5tPv7Uw5aUfC55fhLPBcKo=",
|
"checksumSHA1": "mhpwj5tPv7Uw5aUfC55fhLPBcKo=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "5efJz6UH7JCFeav5ZCCzicXCFTU=",
|
"checksumSHA1": "5efJz6UH7JCFeav5ZCCzicXCFTU=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "TVFgBTz7B6bb1R4TWdgAkbE1/fk=",
|
"checksumSHA1": "TVFgBTz7B6bb1R4TWdgAkbE1/fk=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "xirjw9vJIN6rmkT3T56bfPfOLUM=",
|
"checksumSHA1": "xirjw9vJIN6rmkT3T56bfPfOLUM=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "FKwSMrpQf7b3TcCOQfh+ovoBShA=",
|
"checksumSHA1": "FKwSMrpQf7b3TcCOQfh+ovoBShA=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "CsS/kI3VeLcSHzMKviFVDwqwgvk=",
|
"checksumSHA1": "CsS/kI3VeLcSHzMKviFVDwqwgvk=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "zKOhFTL5BDZPMC58ZzZkryjskno=",
|
"checksumSHA1": "zKOhFTL5BDZPMC58ZzZkryjskno=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "BE+CO3QrEGpIgv3Ee2ANZp1WtSo=",
|
"checksumSHA1": "BE+CO3QrEGpIgv3Ee2ANZp1WtSo=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "wY0MY7RpX0Z2Y0rMmrAuYS6cHYA=",
|
"checksumSHA1": "wY0MY7RpX0Z2Y0rMmrAuYS6cHYA=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets",
|
"path": "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "yIerdfSMJRUnjh2EZikMhWcgwlY=",
|
"checksumSHA1": "LtdQKIKKRKe6FOGdBvrBz/bg1Gc=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts",
|
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts",
|
||||||
"revision": "45720eeefeeeba03b2d7da500297ec68eeee51af",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-31T15:28:56Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "5XMyCSYDLmv/b54K3HNNNCJdnBk=",
|
"checksumSHA1": "1lwXcRrM5A7iCfekbn3bpfNLe3g=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers",
|
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "CRiIA3oRRlKRDF2ZYnZT8rTlJBU=",
|
"checksumSHA1": "dotTh+ZsNiyv8e9Z4e0chPEZDKE=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects",
|
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects",
|
||||||
"revision": "45720eeefeeeba03b2d7da500297ec68eeee51af",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-31T15:28:56Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "roxPPVwS2CjJhf0CApHNQxAX7EA=",
|
"checksumSHA1": "roxPPVwS2CjJhf0CApHNQxAX7EA=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth",
|
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth",
|
||||||
"revision": "d5eda9707e146108e4d424062b602fd97a71c2e6",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-11-14T18:28:31Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "TDOZnaS0TO0NirpxV1QwPerAQTY=",
|
"checksumSHA1": "TDOZnaS0TO0NirpxV1QwPerAQTY=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/utils",
|
"path": "github.com/gophercloud/gophercloud/openstack/utils",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "pmpLcbUZ+EgLUmTbzMtGRq3haOU=",
|
"checksumSHA1": "pmpLcbUZ+EgLUmTbzMtGRq3haOU=",
|
||||||
"path": "github.com/gophercloud/gophercloud/pagination",
|
"path": "github.com/gophercloud/gophercloud/pagination",
|
||||||
"revision": "e3d6384a3714b335d075862e6eb0a681180643df",
|
"revision": "368deee20062b2c7a043f792d7d998abe621872e",
|
||||||
"revisionTime": "2016-10-25T18:03:21Z"
|
"revisionTime": "2017-01-12T21:19:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "6tvhO5ieOvX9R6o0vtl19s0lr8E=",
|
"checksumSHA1": "6tvhO5ieOvX9R6o0vtl19s0lr8E=",
|
||||||
|
|
Loading…
Reference in New Issue