vendor: Updating Gophercloud for OpenStack Provider
This commit is contained in:
parent
c5b1eed7e5
commit
986b9fcc53
|
@ -74,7 +74,7 @@ import (
|
||||||
|
|
||||||
// Option 1: Pass in the values yourself
|
// Option 1: Pass in the values yourself
|
||||||
opts := gophercloud.AuthOptions{
|
opts := gophercloud.AuthOptions{
|
||||||
IdentityEndpoint: "https://my-openstack.com:5000/v2.0",
|
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
||||||
Username: "{username}",
|
Username: "{username}",
|
||||||
Password: "{password}",
|
Password: "{password}",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package gophercloud
|
package gophercloud
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AuthOptions stores information needed to authenticate to an OpenStack cluster.
|
AuthOptions stores information needed to authenticate to an OpenStack Cloud.
|
||||||
You can populate one manually, or use a provider's AuthOptionsFromEnv() function
|
You can populate one manually, or use a provider's AuthOptionsFromEnv() function
|
||||||
to read relevant information from the standard environment variables. Pass one
|
to read relevant information from the standard environment variables. Pass one
|
||||||
to a provider's AuthenticatedClient function to authenticate and obtain a
|
to a provider's AuthenticatedClient function to authenticate and obtain a
|
||||||
|
@ -31,9 +31,16 @@ type AuthOptions struct {
|
||||||
DomainName string `json:"name,omitempty"`
|
DomainName string `json:"name,omitempty"`
|
||||||
|
|
||||||
// The TenantID and TenantName fields are optional for the Identity V2 API.
|
// The TenantID and TenantName fields are optional for the Identity V2 API.
|
||||||
|
// The same fields are known as project_id and project_name in the Identity
|
||||||
|
// V3 API, but are collected as TenantID and TenantName here in both cases.
|
||||||
// Some providers allow you to specify a TenantName instead of the TenantId.
|
// Some providers allow you to specify a TenantName instead of the TenantId.
|
||||||
// Some require both. Your provider's authentication policies will determine
|
// Some require both. Your provider's authentication policies will determine
|
||||||
// how these fields influence authentication.
|
// how these fields influence authentication.
|
||||||
|
// If DomainID or DomainName are provided, they will also apply to TenantName.
|
||||||
|
// It is not currently possible to authenticate with Username and a Domain
|
||||||
|
// and scope to a Project in a different Domain by using TenantName. To
|
||||||
|
// accomplish that, the ProjectID will need to be provided to the TenantID
|
||||||
|
// option.
|
||||||
TenantID string `json:"tenantId,omitempty"`
|
TenantID string `json:"tenantId,omitempty"`
|
||||||
TenantName string `json:"tenantName,omitempty"`
|
TenantName string `json:"tenantName,omitempty"`
|
||||||
|
|
||||||
|
@ -132,14 +139,6 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
||||||
// if insufficient or incompatible information is present.
|
// if insufficient or incompatible information is present.
|
||||||
var req request
|
var req request
|
||||||
|
|
||||||
// Test first for unrecognized arguments.
|
|
||||||
if opts.TenantID != "" {
|
|
||||||
return nil, ErrTenantIDProvided{}
|
|
||||||
}
|
|
||||||
if opts.TenantName != "" {
|
|
||||||
return nil, ErrTenantNameProvided{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Password == "" {
|
if opts.Password == "" {
|
||||||
if opts.TokenID != "" {
|
if opts.TokenID != "" {
|
||||||
// Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
|
// Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
|
||||||
|
@ -252,15 +251,12 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
|
||||||
|
|
||||||
if opts.TenantID != "" {
|
if opts.TenantID != "" {
|
||||||
scope.ProjectID = opts.TenantID
|
scope.ProjectID = opts.TenantID
|
||||||
opts.TenantID = ""
|
|
||||||
opts.TenantName = ""
|
|
||||||
} else {
|
} else {
|
||||||
if opts.TenantName != "" {
|
if opts.TenantName != "" {
|
||||||
scope.ProjectName = opts.TenantName
|
scope.ProjectName = opts.TenantName
|
||||||
scope.DomainID = opts.DomainID
|
scope.DomainID = opts.DomainID
|
||||||
scope.DomainName = opts.DomainName
|
scope.DomainName = opts.DomainName
|
||||||
}
|
}
|
||||||
opts.TenantName = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.ProjectName != "" {
|
if scope.ProjectName != "" {
|
||||||
|
|
|
@ -4,11 +4,13 @@ clouds. The library has a three-level hierarchy: providers, services, and
|
||||||
resources.
|
resources.
|
||||||
|
|
||||||
Provider structs represent the service providers that offer and manage a
|
Provider structs represent the service providers that offer and manage a
|
||||||
collection of services. Examples of providers include: OpenStack, Rackspace,
|
collection of services. The IdentityEndpoint is typically refered to as
|
||||||
HP. These are defined like so:
|
"auth_url" in information provided by the cloud operator. Additionally,
|
||||||
|
the cloud may refer to TenantID or TenantName as project_id and project_name.
|
||||||
|
These are defined like so:
|
||||||
|
|
||||||
opts := gophercloud.AuthOptions{
|
opts := gophercloud.AuthOptions{
|
||||||
IdentityEndpoint: "https://my-openstack.com:5000/v2.0",
|
IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
|
||||||
Username: "{username}",
|
Username: "{username}",
|
||||||
Password: "{password}",
|
Password: "{password}",
|
||||||
TenantID: "{tenant_id}",
|
TenantID: "{tenant_id}",
|
||||||
|
|
6
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/doc.go
generated
vendored
Normal file
6
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// Package tokens provides information and interaction with the zone API
|
||||||
|
// resource for the OpenStack DNS service.
|
||||||
|
//
|
||||||
|
// For more information, see:
|
||||||
|
// http://developer.openstack.org/api-ref/dns/#zone
|
||||||
|
package zones
|
162
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/requests.go
generated
vendored
Normal file
162
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
package zones
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListOptsBuilder interface {
|
||||||
|
ToZoneListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts allows the filtering and sorting of paginated collections through
|
||||||
|
// the API. Filtering is achieved by passing in struct field values that map to
|
||||||
|
// the server attributes you want to see returned. Marker and Limit are used
|
||||||
|
// for pagination.
|
||||||
|
// https://developer.openstack.org/api-ref/dns/
|
||||||
|
type ListOpts struct {
|
||||||
|
// Integer value for the limit of values to return.
|
||||||
|
Limit int `q:"limit"`
|
||||||
|
|
||||||
|
// UUID of the zone at which you want to set a marker.
|
||||||
|
Marker string `q:"marker"`
|
||||||
|
|
||||||
|
Description string `q:"description"`
|
||||||
|
Email string `q:"email"`
|
||||||
|
Name string `q:"name"`
|
||||||
|
SortDir string `q:"sort_dir"`
|
||||||
|
SortKey string `q:"sort_key"`
|
||||||
|
Status string `q:"status"`
|
||||||
|
TTL int `q:"ttl"`
|
||||||
|
Type string `q:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts ListOpts) ToZoneListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := baseURL(client)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToZoneListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return ZonePage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns additional information about a zone, given its ID.
|
||||||
|
func Get(client *gophercloud.ServiceClient, zoneID string) (r GetResult) {
|
||||||
|
_, r.Err = client.Get(zoneURL(client, zoneID), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOptsBuilder allows extensions to add additional attributes to the Update request.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToZoneCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts specifies the base attributes used to create a zone.
|
||||||
|
type CreateOpts struct {
|
||||||
|
// Attributes are settings that supply hints and filters for the zone.
|
||||||
|
Attributes map[string]string `json:"attributes,omitempty"`
|
||||||
|
|
||||||
|
// Email contact of the zone.
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
|
||||||
|
// Description of the zone.
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// Name of the zone.
|
||||||
|
Name string `json:"name,required"`
|
||||||
|
|
||||||
|
// Masters specifies zone masters if this is a secondary zone.
|
||||||
|
Masters []string `json:"masters,omitempty"`
|
||||||
|
|
||||||
|
// TTL is the time to live of the zone.
|
||||||
|
TTL int `json:"-"`
|
||||||
|
|
||||||
|
// Type specifies if this is a primary or secondary zone.
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToZoneCreateMap formats an CreateOpts structure into a request body.
|
||||||
|
func (opts CreateOpts) ToZoneCreateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.TTL > 0 {
|
||||||
|
b["ttl"] = opts.TTL
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a zone
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToZoneCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{201, 202},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder allows extensions to add additional attributes to the Update request.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToZoneUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOpts specifies the base attributes to update a zone.
|
||||||
|
type UpdateOpts struct {
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
TTL int `json:"-"`
|
||||||
|
Masters []string `json:"masters,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToZoneUpdateMap formats an UpdateOpts structure into a request body.
|
||||||
|
func (opts UpdateOpts) ToZoneUpdateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.TTL > 0 {
|
||||||
|
b["ttl"] = opts.TTL
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update a zone.
|
||||||
|
func Update(client *gophercloud.ServiceClient, zoneID string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
b, err := opts.ToZoneUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Patch(zoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200, 202},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a zone.
|
||||||
|
func Delete(client *gophercloud.ServiceClient, zoneID string) (r DeleteResult) {
|
||||||
|
_, r.Err = client.Delete(zoneURL(client, zoneID), &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{202},
|
||||||
|
JSONResponse: &r.Body,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
159
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/results.go
generated
vendored
Normal file
159
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/results.go
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
package zones
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
type commonResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Zone.
|
||||||
|
// An error is returned if the original call or the extraction failed.
|
||||||
|
func (r commonResult) Extract() (*Zone, error) {
|
||||||
|
var s *Zone
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult is the deferred result of a Create call.
|
||||||
|
type CreateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResult is the deferred result of a Get call.
|
||||||
|
type GetResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult is the deferred result of an Update call.
|
||||||
|
type UpdateResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the deferred result of an Delete call.
|
||||||
|
type DeleteResult struct {
|
||||||
|
commonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// ZonePage is a single page of Zone results.
|
||||||
|
type ZonePage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty returns true if the page contains no results.
|
||||||
|
func (r ZonePage) IsEmpty() (bool, error) {
|
||||||
|
s, err := ExtractZones(r)
|
||||||
|
return len(s) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractZones extracts a slice of Services from a Collection acquired from List.
|
||||||
|
func ExtractZones(r pagination.Page) ([]Zone, error) {
|
||||||
|
var s struct {
|
||||||
|
Zones []Zone `json:"zones"`
|
||||||
|
}
|
||||||
|
err := (r.(ZonePage)).ExtractInto(&s)
|
||||||
|
return s.Zones, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zone represents a DNS zone.
|
||||||
|
type Zone struct {
|
||||||
|
// ID uniquely identifies this zone amongst all other zones, including those not accessible to the current tenant.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// PoolID is the ID for the pool hosting this zone.
|
||||||
|
PoolID string `json:"pool_id"`
|
||||||
|
|
||||||
|
// ProjectID identifies the project/tenant owning this resource.
|
||||||
|
ProjectID string `json:"project_id"`
|
||||||
|
|
||||||
|
// Name is the DNS Name for the zone.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Email for the zone. Used in SOA records for the zone.
|
||||||
|
Email string `json:"email"`
|
||||||
|
|
||||||
|
// Description for this zone.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// TTL is the Time to Live for the zone.
|
||||||
|
TTL int `json:"ttl"`
|
||||||
|
|
||||||
|
// Serial is the current serial number for the zone.
|
||||||
|
Serial int `json:"-"`
|
||||||
|
|
||||||
|
// Status is the status of the resource.
|
||||||
|
Status string `json:"status"`
|
||||||
|
|
||||||
|
// Action is the current action in progress on the resource.
|
||||||
|
Action string `json:"action"`
|
||||||
|
|
||||||
|
// Version of the resource.
|
||||||
|
Version int `json:"version"`
|
||||||
|
|
||||||
|
// Attributes for the zone.
|
||||||
|
Attributes map[string]string `json:"attributes"`
|
||||||
|
|
||||||
|
// Type of zone. Primary is controlled by Designate.
|
||||||
|
// Secondary zones are slaved from another DNS Server.
|
||||||
|
// Defaults to Primary.
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Masters is the servers for slave servers to get DNS information from.
|
||||||
|
Masters []string `json:"masters"`
|
||||||
|
|
||||||
|
// CreatedAt is the date when the zone was created.
|
||||||
|
CreatedAt time.Time `json:"-"`
|
||||||
|
|
||||||
|
// UpdatedAt is the date when the last change was made to the zone.
|
||||||
|
UpdatedAt time.Time `json:"-"`
|
||||||
|
|
||||||
|
// TransferredAt is the last time an update was retrieved from the master servers.
|
||||||
|
TransferredAt time.Time `json:"-"`
|
||||||
|
|
||||||
|
// Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference.
|
||||||
|
Links map[string]interface{} `json:"links"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Zone) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Zone
|
||||||
|
var s struct {
|
||||||
|
tmp
|
||||||
|
CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
|
||||||
|
UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
|
||||||
|
TransferredAt gophercloud.JSONRFC3339MilliNoZ `json:"transferred_at"`
|
||||||
|
Serial interface{} `json:"serial"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*r = Zone(s.tmp)
|
||||||
|
|
||||||
|
r.CreatedAt = time.Time(s.CreatedAt)
|
||||||
|
r.UpdatedAt = time.Time(s.UpdatedAt)
|
||||||
|
r.TransferredAt = time.Time(s.TransferredAt)
|
||||||
|
|
||||||
|
switch t := s.Serial.(type) {
|
||||||
|
case float64:
|
||||||
|
r.Serial = int(t)
|
||||||
|
case string:
|
||||||
|
switch t {
|
||||||
|
case "":
|
||||||
|
r.Serial = 0
|
||||||
|
default:
|
||||||
|
serial, err := strconv.ParseFloat(t, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.Serial = int(serial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
11
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/urls.go
generated
vendored
Normal file
11
vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package zones
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func baseURL(c *gophercloud.ServiceClient) string {
|
||||||
|
return c.ServiceURL("zones")
|
||||||
|
}
|
||||||
|
|
||||||
|
func zoneURL(c *gophercloud.ServiceClient, zoneID string) string {
|
||||||
|
return c.ServiceURL("zones", zoneID)
|
||||||
|
}
|
|
@ -1605,10 +1605,10 @@
|
||||||
"revisionTime": "2016-11-07T00:24:06Z"
|
"revisionTime": "2016-11-07T00:24:06Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "xKB/9qxVhWxAERkjZLYfuUBR4P8=",
|
"checksumSHA1": "cuTQkSEiIoMhDhB7xCbYDwDhrgw=",
|
||||||
"path": "github.com/gophercloud/gophercloud",
|
"path": "github.com/gophercloud/gophercloud",
|
||||||
"revision": "0f64da0e36de86a0ca1a8f2fc1b0570a0d3f7504",
|
"revision": "c5dfe1bc7b150a98b1578bb32f7c138ff9568f1d",
|
||||||
"revisionTime": "2017-03-10T01:59:53Z"
|
"revisionTime": "2017-05-15T02:07:51Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "0KdIjTH5IO8hlIl8kdfI6313GiY=",
|
"checksumSHA1": "0KdIjTH5IO8hlIl8kdfI6313GiY=",
|
||||||
|
@ -1712,6 +1712,12 @@
|
||||||
"revision": "0f64da0e36de86a0ca1a8f2fc1b0570a0d3f7504",
|
"revision": "0f64da0e36de86a0ca1a8f2fc1b0570a0d3f7504",
|
||||||
"revisionTime": "2017-03-10T01:59:53Z"
|
"revisionTime": "2017-03-10T01:59:53Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "OGb3suDcMij0bnu0r/eQgWAX5Ho=",
|
||||||
|
"path": "github.com/gophercloud/gophercloud/openstack/dns/v2/zones",
|
||||||
|
"revision": "c5dfe1bc7b150a98b1578bb32f7c138ff9568f1d",
|
||||||
|
"revisionTime": "2017-05-15T02:07:51Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "1sVqsZBZBNhDXLY9XzjMkcOkcbg=",
|
"checksumSHA1": "1sVqsZBZBNhDXLY9XzjMkcOkcbg=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
"path": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
||||||
|
|
Loading…
Reference in New Issue