mirror of https://github.com/kubernetes/kops.git
update gophercloud to newest version
This commit is contained in:
parent
b02c3a269c
commit
41b8f21ce5
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2bf16b94fdd9b01557c4d076e567fe5cbbe5a961
|
Subproject commit c7551a666c4fee120cc314dce91ba3d0663a86f3
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
**/*.swp
|
**/*.swp
|
||||||
|
.idea
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ go:
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ="
|
- secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ="
|
||||||
|
before_script:
|
||||||
|
- go vet ./...
|
||||||
script:
|
script:
|
||||||
- ./script/coverage
|
- ./script/coverage
|
||||||
- ./script/format
|
- ./script/format
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,26 @@ to a remote API.
|
||||||
> be certain cases where this does not happen; always double-check to make sure
|
> be certain cases where this does not happen; always double-check to make sure
|
||||||
> you have no stragglers left behind.
|
> you have no stragglers left behind.
|
||||||
|
|
||||||
### Step 1. Set environment variables
|
### Step 1. Creating a Testing Environment
|
||||||
|
|
||||||
|
Running tests on an existing OpenStack cloud can be risky. Malformed tests,
|
||||||
|
especially ones which require Admin privileges, can cause damage to the
|
||||||
|
environment. Additionally, you may incur bandwidth and service charges for
|
||||||
|
the resources used, as mentioned in the note above.
|
||||||
|
|
||||||
|
Therefore, it is usually best to first practice running acceptance tests in
|
||||||
|
an isolated test environment. Two options to easily create a testing
|
||||||
|
environment are [DevStack](https://docs.openstack.org/devstack/latest/)
|
||||||
|
and [PackStack](https://www.rdoproject.org/install/packstack/).
|
||||||
|
|
||||||
|
The following blog posts detail how to create reusable PackStack environments.
|
||||||
|
These posts were written with Gophercloud in mind:
|
||||||
|
|
||||||
|
* http://terrarum.net/blog/building-openstack-environments.html
|
||||||
|
* http://terrarum.net/blog/building-openstack-environments-2.html
|
||||||
|
* http://terrarum.net/blog/building-openstack-environments-3.html
|
||||||
|
|
||||||
|
### Step 2. Set environment variables
|
||||||
|
|
||||||
A lot of tests rely on environment variables for configuration - so you will need
|
A lot of tests rely on environment variables for configuration - so you will need
|
||||||
to set them before running the suite. If you're testing against pure OpenStack APIs,
|
to set them before running the suite. If you're testing against pure OpenStack APIs,
|
||||||
|
|
@ -43,14 +62,22 @@ to set them manually.
|
||||||
|`OS_FLAVOR_ID`|The ID of the flavor you want your server to be based on|
|
|`OS_FLAVOR_ID`|The ID of the flavor you want your server to be based on|
|
||||||
|`OS_FLAVOR_ID_RESIZE`|The ID of the flavor you want your server to be resized to|
|
|`OS_FLAVOR_ID_RESIZE`|The ID of the flavor you want your server to be resized to|
|
||||||
|`OS_POOL_NAME`|The Pool from where to obtain Floating IPs|
|
|`OS_POOL_NAME`|The Pool from where to obtain Floating IPs|
|
||||||
|`OS_NETWORK_NAME`|The network to launch instances on|
|
|`OS_NETWORK_NAME`|The internal/private network to launch instances on|
|
||||||
|
|`OS_EXTGW_ID`|The external/public network|
|
||||||
|
|
||||||
|
#### Database
|
||||||
|
|
||||||
|
|Name|Description|
|
||||||
|
|---|---|
|
||||||
|
|`OS_DB_DATASTORE_TYPE`|The Datastore type to use. Example: `mariadb`|
|
||||||
|
|`OS_DB_DATASTORE_VERSION`|The Datastore version to use. Example: `mariadb-10`|
|
||||||
|
|
||||||
#### Shared file systems
|
#### Shared file systems
|
||||||
|Name|Description|
|
|Name|Description|
|
||||||
|---|---|
|
|---|---|
|
||||||
|`OS_SHARE_NETWORK_ID`| The share network ID to use when creating shares|
|
|`OS_SHARE_NETWORK_ID`| The share network ID to use when creating shares|
|
||||||
|
|
||||||
### 2. Run the test suite
|
### 3. Run the test suite
|
||||||
|
|
||||||
From the root directory, run:
|
From the root directory, run:
|
||||||
|
|
||||||
|
|
@ -78,7 +105,7 @@ $ gophercloudtest TestFlavors compute/v2
|
||||||
$ gophercloudtest Test compute/v2
|
$ gophercloudtest Test compute/v2
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Notes
|
### 4. Notes
|
||||||
|
|
||||||
#### Compute Tests
|
#### Compute Tests
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/openstack"
|
"github.com/gophercloud/gophercloud/openstack"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/blockstorage/noauth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AcceptanceTestChoices contains image and flavor selections for use by the acceptance tests.
|
// AcceptanceTestChoices contains image and flavor selections for use by the acceptance tests.
|
||||||
|
|
@ -35,6 +36,12 @@ type AcceptanceTestChoices struct {
|
||||||
|
|
||||||
// ShareNetworkID is the Manila Share network ID
|
// ShareNetworkID is the Manila Share network ID
|
||||||
ShareNetworkID string
|
ShareNetworkID string
|
||||||
|
|
||||||
|
// DBDatastoreType is the datastore type for DB tests.
|
||||||
|
DBDatastoreType string
|
||||||
|
|
||||||
|
// DBDatastoreTypeID is the datastore type version for DB tests.
|
||||||
|
DBDatastoreVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptanceTestChoicesFromEnv populates a ComputeChoices struct from environment variables.
|
// AcceptanceTestChoicesFromEnv populates a ComputeChoices struct from environment variables.
|
||||||
|
|
@ -47,6 +54,8 @@ func AcceptanceTestChoicesFromEnv() (*AcceptanceTestChoices, error) {
|
||||||
floatingIPPoolName := os.Getenv("OS_POOL_NAME")
|
floatingIPPoolName := os.Getenv("OS_POOL_NAME")
|
||||||
externalNetworkID := os.Getenv("OS_EXTGW_ID")
|
externalNetworkID := os.Getenv("OS_EXTGW_ID")
|
||||||
shareNetworkID := os.Getenv("OS_SHARE_NETWORK_ID")
|
shareNetworkID := os.Getenv("OS_SHARE_NETWORK_ID")
|
||||||
|
dbDatastoreType := os.Getenv("OS_DB_DATASTORE_TYPE")
|
||||||
|
dbDatastoreVersion := os.Getenv("OS_DB_DATASTORE_VERSION")
|
||||||
|
|
||||||
missing := make([]string, 0, 3)
|
missing := make([]string, 0, 3)
|
||||||
if imageID == "" {
|
if imageID == "" {
|
||||||
|
|
@ -95,6 +104,8 @@ func AcceptanceTestChoicesFromEnv() (*AcceptanceTestChoices, error) {
|
||||||
NetworkName: networkName,
|
NetworkName: networkName,
|
||||||
ExternalNetworkID: externalNetworkID,
|
ExternalNetworkID: externalNetworkID,
|
||||||
ShareNetworkID: shareNetworkID,
|
ShareNetworkID: shareNetworkID,
|
||||||
|
DBDatastoreType: dbDatastoreType,
|
||||||
|
DBDatastoreVersion: dbDatastoreVersion,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,22 +147,20 @@ func NewBlockStorageV2Client() (*gophercloud.ServiceClient, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSharedFileSystemV2Client returns a *ServiceClient for making calls
|
// NewBlockStorageV2NoAuthClient returns a noauth *ServiceClient for
|
||||||
// to the OpenStack Shared File System v2 API. An error will be returned
|
// making calls to the OpenStack Block Storage v2 API. An error will be
|
||||||
// if authentication or client creation was not possible.
|
// returned if client creation was not possible.
|
||||||
func NewSharedFileSystemV2Client() (*gophercloud.ServiceClient, error) {
|
func NewBlockStorageV2NoAuthClient() (*gophercloud.ServiceClient, error) {
|
||||||
ao, err := openstack.AuthOptionsFromEnv()
|
client, err := noauth.NewClient(gophercloud.AuthOptions{
|
||||||
|
Username: os.Getenv("OS_USERNAME"),
|
||||||
|
TenantName: os.Getenv("OS_TENANT_NAME"),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := openstack.AuthenticatedClient(ao)
|
return noauth.NewBlockStorageV2(client, noauth.EndpointOpts{
|
||||||
if err != nil {
|
CinderEndpoint: os.Getenv("CINDER_ENDPOINT"),
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return openstack.NewSharedFileSystemV2(client, gophercloud.EndpointOpts{
|
|
||||||
Region: os.Getenv("OS_REGION_NAME"),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,6 +183,25 @@ func NewComputeV2Client() (*gophercloud.ServiceClient, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDBV1Client returns a *ServiceClient for making calls
|
||||||
|
// to the OpenStack Database v1 API. An error will be returned
|
||||||
|
// if authentication or client creation was not possible.
|
||||||
|
func NewDBV1Client() (*gophercloud.ServiceClient, error) {
|
||||||
|
ao, err := openstack.AuthOptionsFromEnv()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := openstack.AuthenticatedClient(ao)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return openstack.NewDBV1(client, gophercloud.EndpointOpts{
|
||||||
|
Region: os.Getenv("OS_REGION_NAME"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// NewDNSV2Client returns a *ServiceClient for making calls
|
// NewDNSV2Client returns a *ServiceClient for making calls
|
||||||
// to the OpenStack Compute v2 API. An error will be returned
|
// to the OpenStack Compute v2 API. An error will be returned
|
||||||
// if authentication or client creation was not possible.
|
// if authentication or client creation was not possible.
|
||||||
|
|
@ -341,3 +369,22 @@ func NewObjectStorageV1Client() (*gophercloud.ServiceClient, error) {
|
||||||
Region: os.Getenv("OS_REGION_NAME"),
|
Region: os.Getenv("OS_REGION_NAME"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewSharedFileSystemV2Client returns a *ServiceClient for making calls
|
||||||
|
// to the OpenStack Shared File System v2 API. An error will be returned
|
||||||
|
// if authentication or client creation was not possible.
|
||||||
|
func NewSharedFileSystemV2Client() (*gophercloud.ServiceClient, error) {
|
||||||
|
ao, err := openstack.AuthOptionsFromEnv()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := openstack.AuthenticatedClient(ao)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return openstack.NewSharedFileSystemV2(client, gophercloud.EndpointOpts{
|
||||||
|
Region: os.Getenv("OS_REGION_NAME"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
142
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/blockstorage.go
generated
vendored
Normal file
142
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/blockstorage.go
generated
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
// Package noauth contains common functions for creating block storage based
|
||||||
|
// resources for use in acceptance tests. See the `*_test.go` files for
|
||||||
|
// example usages.
|
||||||
|
package noauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateVolume will create a volume with a random name and size of 1GB. An
|
||||||
|
// error will be returned if the volume was unable to be created.
|
||||||
|
func CreateVolume(t *testing.T, client *gophercloud.ServiceClient) (*volumes.Volume, error) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping test that requires volume creation in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeName := tools.RandomString("ACPTTEST", 16)
|
||||||
|
t.Logf("Attempting to create volume: %s", volumeName)
|
||||||
|
|
||||||
|
createOpts := volumes.CreateOpts{
|
||||||
|
Size: 1,
|
||||||
|
Name: volumeName,
|
||||||
|
}
|
||||||
|
|
||||||
|
volume, err := volumes.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return volume, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = volumes.WaitForStatus(client, volume.ID, "available", 60)
|
||||||
|
if err != nil {
|
||||||
|
return volume, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return volume, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateVolumeFromImage will create a volume from with a random name and size of
|
||||||
|
// 1GB. An error will be returned if the volume was unable to be created.
|
||||||
|
func CreateVolumeFromImage(t *testing.T, client *gophercloud.ServiceClient) (*volumes.Volume, error) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping test that requires volume creation in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
choices, err := clients.AcceptanceTestChoicesFromEnv()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeName := tools.RandomString("ACPTTEST", 16)
|
||||||
|
t.Logf("Attempting to create volume: %s", volumeName)
|
||||||
|
|
||||||
|
createOpts := volumes.CreateOpts{
|
||||||
|
Size: 1,
|
||||||
|
Name: volumeName,
|
||||||
|
ImageID: choices.ImageID,
|
||||||
|
}
|
||||||
|
|
||||||
|
volume, err := volumes.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return volume, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = volumes.WaitForStatus(client, volume.ID, "available", 60)
|
||||||
|
if err != nil {
|
||||||
|
return volume, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return volume, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteVolume will delete a volume. A fatal error will occur if the volume
|
||||||
|
// failed to be deleted. This works best when used as a deferred function.
|
||||||
|
func DeleteVolume(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.Volume) {
|
||||||
|
err := volumes.Delete(client, volume.ID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete volume %s: %v", volume.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted volume: %s", volume.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshot will create a snapshot of the specified volume.
|
||||||
|
// Snapshot will be assigned a random name and description.
|
||||||
|
func CreateSnapshot(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.Volume) (*snapshots.Snapshot, error) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping test that requires snapshot creation in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshotName := tools.RandomString("ACPTTEST", 16)
|
||||||
|
snapshotDescription := tools.RandomString("ACPTTEST", 16)
|
||||||
|
t.Logf("Attempting to create snapshot: %s", snapshotName)
|
||||||
|
|
||||||
|
createOpts := snapshots.CreateOpts{
|
||||||
|
VolumeID: volume.ID,
|
||||||
|
Name: snapshotName,
|
||||||
|
Description: snapshotDescription,
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot, err := snapshots.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return snapshot, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = snapshots.WaitForStatus(client, snapshot.ID, "available", 60)
|
||||||
|
if err != nil {
|
||||||
|
return snapshot, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return snapshot, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSnapshot will delete a snapshot. A fatal error will occur if the
|
||||||
|
// snapshot failed to be deleted.
|
||||||
|
func DeleteSnapshot(t *testing.T, client *gophercloud.ServiceClient, snapshot *snapshots.Snapshot) {
|
||||||
|
err := snapshots.Delete(client, snapshot.ID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete snapshot %s: %+v", snapshot.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volumes can't be deleted until their snapshots have been,
|
||||||
|
// so block up to 120 seconds for the snapshot to delete.
|
||||||
|
err = gophercloud.WaitFor(120, func() (bool, error) {
|
||||||
|
_, err := snapshots.Get(client, snapshot.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error waiting for snapshot to delete: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted snapshot: %s", snapshot.ID)
|
||||||
|
}
|
||||||
3
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/pkg.go
generated
vendored
Normal file
3
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/pkg.go
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// The noauth package contains acceptance tests for the Openstack Cinder standalone service.
|
||||||
|
|
||||||
|
package noauth
|
||||||
58
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/snapshots_test.go
generated
vendored
Normal file
58
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/snapshots_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
// +build acceptance blockstorage
|
||||||
|
|
||||||
|
package noauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/snapshots"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSnapshotsList(t *testing.T) {
|
||||||
|
client, err := clients.NewBlockStorageV2NoAuthClient()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a blockstorage client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := snapshots.List(client, snapshots.ListOpts{}).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to retrieve snapshots: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allSnapshots, err := snapshots.ExtractSnapshots(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract snapshots: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, snapshot := range allSnapshots {
|
||||||
|
tools.PrintResource(t, snapshot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSnapshotsCreateDelete(t *testing.T) {
|
||||||
|
client, err := clients.NewBlockStorageV2NoAuthClient()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a blockstorage client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
volume, err := CreateVolume(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create volume: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteVolume(t, client, volume)
|
||||||
|
|
||||||
|
snapshot, err := CreateSnapshot(t, client, volume)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create snapshot: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteSnapshot(t, client, snapshot)
|
||||||
|
|
||||||
|
newSnapshot, err := snapshots.Get(client, snapshot.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to retrieve snapshot: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, newSnapshot)
|
||||||
|
}
|
||||||
52
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/volumes_test.go
generated
vendored
Normal file
52
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/blockstorage/noauth/volumes_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
// +build acceptance blockstorage
|
||||||
|
|
||||||
|
package noauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVolumesList(t *testing.T) {
|
||||||
|
client, err := clients.NewBlockStorageV2NoAuthClient()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a blockstorage client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := volumes.List(client, volumes.ListOpts{}).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to retrieve volumes: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allVolumes, err := volumes.ExtractVolumes(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract volumes: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, volume := range allVolumes {
|
||||||
|
tools.PrintResource(t, volume)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVolumesCreateDestroy(t *testing.T) {
|
||||||
|
client, err := clients.NewBlockStorageV2NoAuthClient()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create blockstorage client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
volume, err := CreateVolume(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create volume: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteVolume(t, client, volume)
|
||||||
|
|
||||||
|
newVolume, err := volumes.Get(client, volume.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to retrieve volume: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, newVolume)
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/acceptance/tools"
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces"
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces"
|
||||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones"
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock"
|
||||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/pauseunpause"
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/pauseunpause"
|
||||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/suspendresume"
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/suspendresume"
|
||||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||||
|
|
@ -479,3 +480,39 @@ func TestServersActionSuspend(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServersActionLock(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
client, err := clients.NewComputeV2Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a compute client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := CreateServer(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer DeleteServer(t, client, server)
|
||||||
|
|
||||||
|
t.Logf("Attempting to Lock server %s", server.ID)
|
||||||
|
err = lockunlock.Lock(client, server.ID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = servers.Delete(client, server.ID).ExtractErr()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Should not have been able to delete the server")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = lockunlock.Unlock(client, server.ID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = WaitForComputeStatus(client, server, "ACTIVE")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
70
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/common.go
generated
vendored
70
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/common.go
generated
vendored
|
|
@ -1,70 +0,0 @@
|
||||||
// +build acceptance db
|
|
||||||
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
|
||||||
"github.com/gophercloud/gophercloud/openstack"
|
|
||||||
"github.com/gophercloud/gophercloud/openstack/db/v1/instances"
|
|
||||||
th "github.com/gophercloud/gophercloud/testhelper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newClient(t *testing.T) *gophercloud.ServiceClient {
|
|
||||||
ao, err := openstack.AuthOptionsFromEnv()
|
|
||||||
th.AssertNoErr(t, err)
|
|
||||||
|
|
||||||
client, err := openstack.AuthenticatedClient(ao)
|
|
||||||
th.AssertNoErr(t, err)
|
|
||||||
|
|
||||||
c, err := openstack.NewDBV1(client, gophercloud.EndpointOpts{
|
|
||||||
Region: os.Getenv("OS_REGION_NAME"),
|
|
||||||
})
|
|
||||||
th.AssertNoErr(t, err)
|
|
||||||
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
type context struct {
|
|
||||||
test *testing.T
|
|
||||||
client *gophercloud.ServiceClient
|
|
||||||
instanceID string
|
|
||||||
DBIDs []string
|
|
||||||
users []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newContext(t *testing.T) context {
|
|
||||||
return context{
|
|
||||||
test: t,
|
|
||||||
client: newClient(t),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) Logf(msg string, args ...interface{}) {
|
|
||||||
if len(args) > 0 {
|
|
||||||
c.test.Logf(msg, args...)
|
|
||||||
} else {
|
|
||||||
c.test.Log(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) AssertNoErr(err error) {
|
|
||||||
th.AssertNoErr(c.test, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) WaitUntilActive(id string) {
|
|
||||||
err := gophercloud.WaitFor(60, func() (bool, error) {
|
|
||||||
inst, err := instances.Get(c.client, id).Extract()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if inst.Status == "ACTIVE" {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
}
|
|
||||||
45
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/database_test.go
generated
vendored
45
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/database_test.go
generated
vendored
|
|
@ -1,45 +0,0 @@
|
||||||
// +build acceptance db
|
|
||||||
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
db "github.com/gophercloud/gophercloud/openstack/db/v1/databases"
|
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c context) createDBs() {
|
|
||||||
opts := db.BatchCreateOpts{
|
|
||||||
db.CreateOpts{Name: "db1"},
|
|
||||||
db.CreateOpts{Name: "db2"},
|
|
||||||
db.CreateOpts{Name: "db3"},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := db.Create(c.client, c.instanceID, opts).ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Created three databases on instance %s: db1, db2, db3", c.instanceID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) listDBs() {
|
|
||||||
c.Logf("Listing databases on instance %s", c.instanceID)
|
|
||||||
|
|
||||||
err := db.List(c.client, c.instanceID).EachPage(func(page pagination.Page) (bool, error) {
|
|
||||||
dbList, err := db.ExtractDBs(page)
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
|
|
||||||
for _, db := range dbList {
|
|
||||||
c.Logf("DB: %#v", db)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) deleteDBs() {
|
|
||||||
for _, id := range []string{"db1", "db2", "db3"} {
|
|
||||||
err := db.Delete(c.client, c.instanceID, id).ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Deleted DB %s", id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
55
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/databases_test.go
generated
vendored
Normal file
55
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/databases_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
// +build acceptance db
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/databases"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Because it takes so long to create an instance,
|
||||||
|
// all tests will be housed in a single function.
|
||||||
|
func TestDatabases(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := clients.NewDBV1Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a DB client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and Get an instance.
|
||||||
|
instance, err := CreateInstance(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create instance: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteInstance(t, client, instance.ID)
|
||||||
|
|
||||||
|
// Create a database.
|
||||||
|
err = CreateDatabase(t, client, instance.ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create database: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List all databases.
|
||||||
|
allPages, err := databases.List(client, instance.ID).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list databases: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allDatabases, err := databases.ExtractDBs(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract databases: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, db := range allDatabases {
|
||||||
|
tools.PrintResource(t, db)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer DeleteDatabase(t, client, instance.ID, allDatabases[0].Name)
|
||||||
|
|
||||||
|
}
|
||||||
145
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/db.go
generated
vendored
Normal file
145
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/db.go
generated
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
// Package v2 contains common functions for creating db resources for use
|
||||||
|
// in acceptance tests. See the `*_test.go` files for example usages.
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/databases"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/instances"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/users"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateDatabase will create a database with a randomly generated name.
|
||||||
|
// An error will be returned if the database was unable to be created.
|
||||||
|
func CreateDatabase(t *testing.T, client *gophercloud.ServiceClient, instanceID string) error {
|
||||||
|
name := tools.RandomString("ACPTTEST", 8)
|
||||||
|
t.Logf("Attempting to create database: %s", name)
|
||||||
|
|
||||||
|
createOpts := databases.BatchCreateOpts{
|
||||||
|
databases.CreateOpts{
|
||||||
|
Name: name,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return databases.Create(client, instanceID, createOpts).ExtractErr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateInstance will create an instance with a randomly generated name.
|
||||||
|
// The flavor of the instance will be the value of the OS_FLAVOR_ID
|
||||||
|
// environment variable. The Datastore will be pulled from the
|
||||||
|
// OS_DATASTORE_TYPE_ID environment variable.
|
||||||
|
// An error will be returned if the instance was unable to be created.
|
||||||
|
func CreateInstance(t *testing.T, client *gophercloud.ServiceClient) (*instances.Instance, error) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping test that requires instance creation in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
choices, err := clients.AcceptanceTestChoicesFromEnv()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
name := tools.RandomString("ACPTTEST", 8)
|
||||||
|
t.Logf("Attempting to create instance: %s", name)
|
||||||
|
|
||||||
|
createOpts := instances.CreateOpts{
|
||||||
|
FlavorRef: choices.FlavorID,
|
||||||
|
Size: 1,
|
||||||
|
Name: name,
|
||||||
|
Datastore: &instances.DatastoreOpts{
|
||||||
|
Type: choices.DBDatastoreType,
|
||||||
|
Version: choices.DBDatastoreVersion,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
instance, err := instances.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return instance, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := WaitForInstanceStatus(client, instance, "ACTIVE"); err != nil {
|
||||||
|
return instance, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return instances.Get(client, instance.ID).Extract()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateUser will create a user with a randomly generated name.
|
||||||
|
// An error will be returned if the user was unable to be created.
|
||||||
|
func CreateUser(t *testing.T, client *gophercloud.ServiceClient, instanceID string) error {
|
||||||
|
name := tools.RandomString("ACPTTEST", 8)
|
||||||
|
password := tools.RandomString("", 8)
|
||||||
|
t.Logf("Attempting to create user: %s", name)
|
||||||
|
|
||||||
|
createOpts := users.BatchCreateOpts{
|
||||||
|
users.CreateOpts{
|
||||||
|
Name: name,
|
||||||
|
Password: password,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return users.Create(client, instanceID, createOpts).ExtractErr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteDatabase deletes a database. A fatal error will occur if the database
|
||||||
|
// failed to delete. This works best when used as a deferred function.
|
||||||
|
func DeleteDatabase(t *testing.T, client *gophercloud.ServiceClient, instanceID, name string) {
|
||||||
|
t.Logf("Attempting to delete database: %s", name)
|
||||||
|
err := databases.Delete(client, instanceID, name).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete database %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted database: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInstance deletes an instance. A fatal error will occur if the instance
|
||||||
|
// failed to delete. This works best when used as a deferred function.
|
||||||
|
func DeleteInstance(t *testing.T, client *gophercloud.ServiceClient, id string) {
|
||||||
|
t.Logf("Attempting to delete instance: %s", id)
|
||||||
|
err := instances.Delete(client, id).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete instance %s: %s", id, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted instance: %s", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteUser deletes a user. A fatal error will occur if the user
|
||||||
|
// failed to delete. This works best when used as a deferred function.
|
||||||
|
func DeleteUser(t *testing.T, client *gophercloud.ServiceClient, instanceID, name string) {
|
||||||
|
t.Logf("Attempting to delete user: %s", name)
|
||||||
|
err := users.Delete(client, instanceID, name).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete users %s: %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted users: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForInstanceState will poll an instance's status until it either matches
|
||||||
|
// the specified status or the status becomes ERROR.
|
||||||
|
func WaitForInstanceStatus(
|
||||||
|
client *gophercloud.ServiceClient, instance *instances.Instance, status string) error {
|
||||||
|
return tools.WaitFor(func() (bool, error) {
|
||||||
|
latest, err := instances.Get(client, instance.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if latest.Status == status {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if latest.Status == "ERROR" {
|
||||||
|
return false, fmt.Errorf("Instance in ERROR state")
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
31
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/flavor_test.go
generated
vendored
31
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/flavor_test.go
generated
vendored
|
|
@ -1,31 +0,0 @@
|
||||||
// +build acceptance db
|
|
||||||
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gophercloud/gophercloud/openstack/db/v1/flavors"
|
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c context) listFlavors() {
|
|
||||||
c.Logf("Listing flavors")
|
|
||||||
|
|
||||||
err := flavors.List(c.client).EachPage(func(page pagination.Page) (bool, error) {
|
|
||||||
flavorList, err := flavors.ExtractFlavors(page)
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
|
|
||||||
for _, f := range flavorList {
|
|
||||||
c.Logf("Flavor: ID [%s] Name [%s] RAM [%d]", f.ID, f.Name, f.RAM)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) getFlavor() {
|
|
||||||
flavor, err := flavors.Get(c.client, "1").Extract()
|
|
||||||
c.Logf("Getting flavor %s", flavor.ID)
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
}
|
|
||||||
58
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/flavors_test.go
generated
vendored
Normal file
58
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/flavors_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
// +build acceptance db
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/flavors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFlavorsList(t *testing.T) {
|
||||||
|
client, err := clients.NewDBV1Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a DB client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := flavors.List(client).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to retrieve flavors: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allFlavors, err := flavors.ExtractFlavors(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract flavors: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, flavor := range allFlavors {
|
||||||
|
tools.PrintResource(t, &flavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFlavorsGet(t *testing.T) {
|
||||||
|
client, err := clients.NewDBV1Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a DB client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := flavors.List(client).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to retrieve flavors: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allFlavors, err := flavors.ExtractFlavors(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract flavors: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(allFlavors) > 0 {
|
||||||
|
flavor, err := flavors.Get(client, allFlavors[0].StrID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get flavor: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, flavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
138
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/instance_test.go
generated
vendored
138
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/instance_test.go
generated
vendored
|
|
@ -1,138 +0,0 @@
|
||||||
// +build acceptance db
|
|
||||||
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud/acceptance/tools"
|
|
||||||
"github.com/gophercloud/gophercloud/openstack/db/v1/instances"
|
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
|
||||||
th "github.com/gophercloud/gophercloud/testhelper"
|
|
||||||
)
|
|
||||||
|
|
||||||
const envDSType = "DATASTORE_TYPE_ID"
|
|
||||||
|
|
||||||
func TestRunner(t *testing.T) {
|
|
||||||
c := newContext(t)
|
|
||||||
|
|
||||||
// FLAVOR tests
|
|
||||||
c.listFlavors()
|
|
||||||
c.getFlavor()
|
|
||||||
|
|
||||||
// INSTANCE tests
|
|
||||||
c.createInstance()
|
|
||||||
c.listInstances()
|
|
||||||
c.getInstance()
|
|
||||||
c.isRootEnabled()
|
|
||||||
c.enableRootUser()
|
|
||||||
c.isRootEnabled()
|
|
||||||
c.restartInstance()
|
|
||||||
//c.resizeInstance()
|
|
||||||
//c.resizeVol()
|
|
||||||
|
|
||||||
// DATABASE tests
|
|
||||||
c.createDBs()
|
|
||||||
c.listDBs()
|
|
||||||
|
|
||||||
// USER tests
|
|
||||||
c.createUsers()
|
|
||||||
c.listUsers()
|
|
||||||
|
|
||||||
// TEARDOWN
|
|
||||||
c.deleteUsers()
|
|
||||||
c.deleteDBs()
|
|
||||||
c.deleteInstance()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) createInstance() {
|
|
||||||
if os.Getenv(envDSType) == "" {
|
|
||||||
c.test.Fatalf("%s must be set as an environment var", envDSType)
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := instances.CreateOpts{
|
|
||||||
FlavorRef: "2",
|
|
||||||
Size: 5,
|
|
||||||
Name: tools.RandomString("gopher_db", 5),
|
|
||||||
Datastore: &instances.DatastoreOpts{Type: os.Getenv(envDSType)},
|
|
||||||
}
|
|
||||||
|
|
||||||
instance, err := instances.Create(c.client, opts).Extract()
|
|
||||||
th.AssertNoErr(c.test, err)
|
|
||||||
|
|
||||||
c.Logf("Restarting %s. Waiting...", instance.ID)
|
|
||||||
c.WaitUntilActive(instance.ID)
|
|
||||||
c.Logf("Created Instance %s", instance.ID)
|
|
||||||
|
|
||||||
c.instanceID = instance.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) listInstances() {
|
|
||||||
c.Logf("Listing instances")
|
|
||||||
|
|
||||||
err := instances.List(c.client).EachPage(func(page pagination.Page) (bool, error) {
|
|
||||||
instanceList, err := instances.ExtractInstances(page)
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
|
|
||||||
for _, i := range instanceList {
|
|
||||||
c.Logf("Instance: ID [%s] Name [%s] Status [%s] VolSize [%d] Datastore Type [%s]",
|
|
||||||
i.ID, i.Name, i.Status, i.Volume.Size, i.Datastore.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) getInstance() {
|
|
||||||
instance, err := instances.Get(c.client, c.instanceID).Extract()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Getting instance: %s", instance.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) deleteInstance() {
|
|
||||||
err := instances.Delete(c.client, c.instanceID).ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Deleted instance %s", c.instanceID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) enableRootUser() {
|
|
||||||
_, err := instances.EnableRootUser(c.client, c.instanceID).Extract()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Enabled root user on %s", c.instanceID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) isRootEnabled() {
|
|
||||||
enabled, err := instances.IsRootEnabled(c.client, c.instanceID)
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Is root enabled? %d", enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) restartInstance() {
|
|
||||||
id := c.instanceID
|
|
||||||
err := instances.Restart(c.client, id).ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Restarting %s. Waiting...", id)
|
|
||||||
c.WaitUntilActive(id)
|
|
||||||
c.Logf("Restarted %s", id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) resizeInstance() {
|
|
||||||
id := c.instanceID
|
|
||||||
err := instances.Resize(c.client, id, "3").ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Resizing %s. Waiting...", id)
|
|
||||||
c.WaitUntilActive(id)
|
|
||||||
c.Logf("Resized %s with flavorRef %s", id, "2")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) resizeVol() {
|
|
||||||
id := c.instanceID
|
|
||||||
err := instances.ResizeVolume(c.client, id, 4).ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Resizing volume of %s. Waiting...", id)
|
|
||||||
c.WaitUntilActive(id)
|
|
||||||
c.Logf("Resized the volume of %s to %d GB", id, 2)
|
|
||||||
}
|
|
||||||
71
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/instances_test.go
generated
vendored
Normal file
71
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/instances_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
// +build acceptance db
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/instances"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Because it takes so long to create an instance,
|
||||||
|
// all tests will be housed in a single function.
|
||||||
|
func TestInstances(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := clients.NewDBV1Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a DB client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and Get an instance.
|
||||||
|
instance, err := CreateInstance(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create instance: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteInstance(t, client, instance.ID)
|
||||||
|
tools.PrintResource(t, &instance)
|
||||||
|
|
||||||
|
// List all instances.
|
||||||
|
allPages, err := instances.List(client).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list instances: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allInstances, err := instances.ExtractInstances(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract instances: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, instance := range allInstances {
|
||||||
|
tools.PrintResource(t, instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable root user.
|
||||||
|
_, err = instances.EnableRootUser(client, instance.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to enable root user: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled, err := instances.IsRootEnabled(client, instance.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to check if root user is enabled: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Root user is enabled: %t", enabled)
|
||||||
|
|
||||||
|
// Restart
|
||||||
|
err = instances.Restart(client, instance.ID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to restart instance: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = WaitForInstanceStatus(client, instance, "ACTIVE")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to restart instance: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
70
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/user_test.go
generated
vendored
70
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/user_test.go
generated
vendored
|
|
@ -1,70 +0,0 @@
|
||||||
// +build acceptance db
|
|
||||||
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gophercloud/gophercloud/acceptance/tools"
|
|
||||||
db "github.com/gophercloud/gophercloud/openstack/db/v1/databases"
|
|
||||||
u "github.com/gophercloud/gophercloud/openstack/db/v1/users"
|
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c context) createUsers() {
|
|
||||||
users := []string{
|
|
||||||
tools.RandomString("user_", 5),
|
|
||||||
tools.RandomString("user_", 5),
|
|
||||||
tools.RandomString("user_", 5),
|
|
||||||
}
|
|
||||||
|
|
||||||
db1 := db.CreateOpts{Name: "db1"}
|
|
||||||
db2 := db.CreateOpts{Name: "db2"}
|
|
||||||
db3 := db.CreateOpts{Name: "db3"}
|
|
||||||
|
|
||||||
opts := u.BatchCreateOpts{
|
|
||||||
u.CreateOpts{
|
|
||||||
Name: users[0],
|
|
||||||
Password: tools.RandomString("", 5),
|
|
||||||
Databases: db.BatchCreateOpts{db1, db2, db3},
|
|
||||||
},
|
|
||||||
u.CreateOpts{
|
|
||||||
Name: users[1],
|
|
||||||
Password: tools.RandomString("", 5),
|
|
||||||
Databases: db.BatchCreateOpts{db1, db2},
|
|
||||||
},
|
|
||||||
u.CreateOpts{
|
|
||||||
Name: users[2],
|
|
||||||
Password: tools.RandomString("", 5),
|
|
||||||
Databases: db.BatchCreateOpts{db3},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := u.Create(c.client, c.instanceID, opts).ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Created three users on instance %s: %s, %s, %s", c.instanceID, users[0], users[1], users[2])
|
|
||||||
c.users = users
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) listUsers() {
|
|
||||||
c.Logf("Listing databases on instance %s", c.instanceID)
|
|
||||||
|
|
||||||
err := db.List(c.client, c.instanceID).EachPage(func(page pagination.Page) (bool, error) {
|
|
||||||
dbList, err := db.ExtractDBs(page)
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
|
|
||||||
for _, db := range dbList {
|
|
||||||
c.Logf("DB: %#v", db)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c context) deleteUsers() {
|
|
||||||
for _, id := range c.DBIDs {
|
|
||||||
err := db.Delete(c.client, c.instanceID, id).ExtractErr()
|
|
||||||
c.AssertNoErr(err)
|
|
||||||
c.Logf("Deleted DB %s", id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
54
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/users_test.go
generated
vendored
Normal file
54
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/db/v1/users_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
// +build acceptance db
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/db/v1/users"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Because it takes so long to create an instance,
|
||||||
|
// all tests will be housed in a single function.
|
||||||
|
func TestUsers(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := clients.NewDBV1Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create a DB client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and Get an instance.
|
||||||
|
instance, err := CreateInstance(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create instance: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteInstance(t, client, instance.ID)
|
||||||
|
|
||||||
|
// Create a user.
|
||||||
|
err = CreateUser(t, client, instance.ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create user: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List all users.
|
||||||
|
allPages, err := users.List(client, instance.ID).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list users: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allUsers, err := users.ExtractUsers(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract users: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range allUsers {
|
||||||
|
tools.PrintResource(t, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer DeleteUser(t, client, instance.ID, allUsers[0].Name)
|
||||||
|
}
|
||||||
96
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/domains_test.go
generated
vendored
Normal file
96
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/domains_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
// +build acceptance
|
||||||
|
|
||||||
|
package v3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/domains"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDomainsList(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var iTrue bool = true
|
||||||
|
listOpts := domains.ListOpts{
|
||||||
|
Enabled: &iTrue,
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := domains.List(client, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list domains: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allDomains, err := domains.ExtractDomains(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract domains: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, domain := range allDomains {
|
||||||
|
tools.PrintResource(t, domain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDomainsGet(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := domains.List(client, nil).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list domains: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allDomains, err := domains.ExtractDomains(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract domains: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
domain := allDomains[0]
|
||||||
|
p, err := domains.Get(client, domain.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get domain: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDomainsCRUD(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var iTrue bool = true
|
||||||
|
createOpts := domains.CreateOpts{
|
||||||
|
Description: "Testing Domain",
|
||||||
|
Enabled: &iTrue,
|
||||||
|
}
|
||||||
|
|
||||||
|
domain, err := CreateDomain(t, client, &createOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create domain: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteDomain(t, client, domain.ID)
|
||||||
|
|
||||||
|
tools.PrintResource(t, domain)
|
||||||
|
|
||||||
|
var iFalse bool = false
|
||||||
|
updateOpts := domains.UpdateOpts{
|
||||||
|
Description: "Staging Test Domain",
|
||||||
|
Enabled: &iFalse,
|
||||||
|
}
|
||||||
|
|
||||||
|
newDomain, err := domains.Update(client, domain.ID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to update domain: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, newDomain)
|
||||||
|
}
|
||||||
79
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/groups_test.go
generated
vendored
Normal file
79
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/groups_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
// +build acceptance
|
||||||
|
|
||||||
|
package v3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGroupCRUD(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := groups.CreateOpts{
|
||||||
|
Name: "testgroup",
|
||||||
|
DomainID: "default",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "testgroup@example.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Group in the default domain
|
||||||
|
group, err := CreateGroup(t, client, &createOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create group: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteGroup(t, client, group.ID)
|
||||||
|
|
||||||
|
tools.PrintResource(t, group)
|
||||||
|
tools.PrintResource(t, group.Extra)
|
||||||
|
|
||||||
|
updateOpts := groups.UpdateOpts{
|
||||||
|
Description: "Test Users",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "thetestgroup@example.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
newGroup, err := groups.Update(client, group.ID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to update group: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, newGroup)
|
||||||
|
tools.PrintResource(t, newGroup.Extra)
|
||||||
|
|
||||||
|
listOpts := groups.ListOpts{
|
||||||
|
DomainID: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
// List all Groups in default domain
|
||||||
|
allPages, err := groups.List(client, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list groups: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allGroups, err := groups.ExtractGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract groups: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, g := range allGroups {
|
||||||
|
tools.PrintResource(t, g)
|
||||||
|
tools.PrintResource(t, g.Extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the recently created group by ID
|
||||||
|
p, err := groups.Get(client, group.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get group: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, p)
|
||||||
|
}
|
||||||
164
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/identity.go
generated
vendored
164
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/identity.go
generated
vendored
|
|
@ -5,7 +5,10 @@ import (
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/acceptance/tools"
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/domains"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/roles"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -36,7 +39,7 @@ func CreateProject(t *testing.T, client *gophercloud.ServiceClient, c *projects.
|
||||||
return project, nil
|
return project, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser will create a project with a random name.
|
// CreateUser will create a user with a random name.
|
||||||
// It takes an optional createOpts parameter since creating a user
|
// It takes an optional createOpts parameter since creating a user
|
||||||
// has so many options. An error will be returned if the user was
|
// has so many options. An error will be returned if the user was
|
||||||
// unable to be created.
|
// unable to be created.
|
||||||
|
|
@ -63,6 +66,87 @@ func CreateUser(t *testing.T, client *gophercloud.ServiceClient, c *users.Create
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateGroup will create a group with a random name.
|
||||||
|
// It takes an optional createOpts parameter since creating a group
|
||||||
|
// has so many options. An error will be returned if the group was
|
||||||
|
// unable to be created.
|
||||||
|
func CreateGroup(t *testing.T, client *gophercloud.ServiceClient, c *groups.CreateOpts) (*groups.Group, error) {
|
||||||
|
name := tools.RandomString("ACPTTEST", 8)
|
||||||
|
t.Logf("Attempting to create group: %s", name)
|
||||||
|
|
||||||
|
var createOpts groups.CreateOpts
|
||||||
|
if c != nil {
|
||||||
|
createOpts = *c
|
||||||
|
} else {
|
||||||
|
createOpts = groups.CreateOpts{}
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts.Name = name
|
||||||
|
|
||||||
|
group, err := groups.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return group, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Successfully created group %s with ID %s", name, group.ID)
|
||||||
|
|
||||||
|
return group, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDomain will create a domain with a random name.
|
||||||
|
// It takes an optional createOpts parameter since creating a domain
|
||||||
|
// has many options. An error will be returned if the domain was
|
||||||
|
// unable to be created.
|
||||||
|
func CreateDomain(t *testing.T, client *gophercloud.ServiceClient, c *domains.CreateOpts) (*domains.Domain, error) {
|
||||||
|
name := tools.RandomString("ACPTTEST", 8)
|
||||||
|
t.Logf("Attempting to create domain: %s", name)
|
||||||
|
|
||||||
|
var createOpts domains.CreateOpts
|
||||||
|
if c != nil {
|
||||||
|
createOpts = *c
|
||||||
|
} else {
|
||||||
|
createOpts = domains.CreateOpts{}
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts.Name = name
|
||||||
|
|
||||||
|
domain, err := domains.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return domain, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Successfully created domain %s with ID %s", name, domain.ID)
|
||||||
|
|
||||||
|
return domain, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRole will create a role with a random name.
|
||||||
|
// It takes an optional createOpts parameter since creating a role
|
||||||
|
// has so many options. An error will be returned if the role was
|
||||||
|
// unable to be created.
|
||||||
|
func CreateRole(t *testing.T, client *gophercloud.ServiceClient, c *roles.CreateOpts) (*roles.Role, error) {
|
||||||
|
name := tools.RandomString("ACPTTEST", 8)
|
||||||
|
t.Logf("Attempting to create role: %s", name)
|
||||||
|
|
||||||
|
var createOpts roles.CreateOpts
|
||||||
|
if c != nil {
|
||||||
|
createOpts = *c
|
||||||
|
} else {
|
||||||
|
createOpts = roles.CreateOpts{}
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts.Name = name
|
||||||
|
|
||||||
|
role, err := roles.Create(client, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return role, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Successfully created role %s with ID %s", name, role.ID)
|
||||||
|
|
||||||
|
return role, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteProject will delete a project by ID. A fatal error will occur if
|
// DeleteProject will delete a project by ID. A fatal error will occur if
|
||||||
// the project ID failed to be deleted. This works best when using it as
|
// the project ID failed to be deleted. This works best when using it as
|
||||||
// a deferred function.
|
// a deferred function.
|
||||||
|
|
@ -81,8 +165,82 @@ func DeleteProject(t *testing.T, client *gophercloud.ServiceClient, projectID st
|
||||||
func DeleteUser(t *testing.T, client *gophercloud.ServiceClient, userID string) {
|
func DeleteUser(t *testing.T, client *gophercloud.ServiceClient, userID string) {
|
||||||
err := users.Delete(client, userID).ExtractErr()
|
err := users.Delete(client, userID).ExtractErr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to delete user %s: %v", userID, err)
|
t.Fatalf("Unable to delete user with ID %s: %v", userID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("Deleted user: %s", userID)
|
t.Logf("Deleted user with ID: %s", userID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteGroup will delete a group by ID. A fatal error will occur if
|
||||||
|
// the group failed to be deleted. This works best when using it as
|
||||||
|
// a deferred function.
|
||||||
|
func DeleteGroup(t *testing.T, client *gophercloud.ServiceClient, groupID string) {
|
||||||
|
err := groups.Delete(client, groupID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete group %s: %v", groupID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted group: %s", groupID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteDomain will delete a domain by ID. A fatal error will occur if
|
||||||
|
// the project ID failed to be deleted. This works best when using it as
|
||||||
|
// a deferred function.
|
||||||
|
func DeleteDomain(t *testing.T, client *gophercloud.ServiceClient, domainID string) {
|
||||||
|
err := domains.Delete(client, domainID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete domain %s: %v", domainID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted domain: %s", domainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRole will delete a role by ID. A fatal error will occur if
|
||||||
|
// the role failed to be deleted. This works best when using it as
|
||||||
|
// a deferred function.
|
||||||
|
func DeleteRole(t *testing.T, client *gophercloud.ServiceClient, roleID string) {
|
||||||
|
err := roles.Delete(client, roleID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to delete role %s: %v", roleID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Deleted role: %s", roleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnassignRole will delete a role assigned to a user/group on a project/domain
|
||||||
|
// A fatal error will occur if it fails to delete the assignment.
|
||||||
|
// This works best when using it as a deferred function.
|
||||||
|
func UnassignRole(t *testing.T, client *gophercloud.ServiceClient, roleID string, opts *roles.UnassignOpts) {
|
||||||
|
err := roles.Unassign(client, roleID, *opts).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to unassign a role %v on context %+v: %v", roleID, *opts, err)
|
||||||
|
}
|
||||||
|
t.Logf("Unassigned the role %v on context %+v", roleID, *opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindRole finds all roles that the current authenticated client has access
|
||||||
|
// to and returns the first one found. An error will be returned if the lookup
|
||||||
|
// was unsuccessful.
|
||||||
|
func FindRole(t *testing.T, client *gophercloud.ServiceClient) (*roles.Role, error) {
|
||||||
|
t.Log("Attempting to find a role")
|
||||||
|
var role *roles.Role
|
||||||
|
|
||||||
|
allPages, err := roles.List(client, nil).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoles, err := roles.ExtractRoles(allPages)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range allRoles {
|
||||||
|
role = &r
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Successfully found a role %s with ID %s", role.Name, role.ID)
|
||||||
|
|
||||||
|
return role, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
328
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/roles_test.go
generated
vendored
Normal file
328
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/roles_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,328 @@
|
||||||
|
// +build acceptance
|
||||||
|
|
||||||
|
package v3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/domains"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/roles"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRolesList(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
listOpts := roles.ListOpts{
|
||||||
|
DomainID: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := roles.List(client, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list roles: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoles, err := roles.ExtractRoles(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract roles: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, role := range allRoles {
|
||||||
|
tools.PrintResource(t, role)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRolesGet(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
role, err := FindRole(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to find a role: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := roles.Get(client, role.ID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get role: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoleCRUD(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := roles.CreateOpts{
|
||||||
|
Name: "testrole",
|
||||||
|
DomainID: "default",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"description": "test role description",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Role in the default domain
|
||||||
|
role, err := CreateRole(t, client, &createOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create role: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteRole(t, client, role.ID)
|
||||||
|
|
||||||
|
tools.PrintResource(t, role)
|
||||||
|
tools.PrintResource(t, role.Extra)
|
||||||
|
|
||||||
|
updateOpts := roles.UpdateOpts{
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"description": "updated test role description",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
newRole, err := roles.Update(client, role.ID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to update role: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.PrintResource(t, newRole)
|
||||||
|
tools.PrintResource(t, newRole.Extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoleAssignToUserOnProject(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an indentity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := CreateProject(t, client, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to create a project")
|
||||||
|
}
|
||||||
|
defer DeleteProject(t, client, project.ID)
|
||||||
|
|
||||||
|
role, err := FindRole(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get a role: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := CreateUser(t, client, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create user: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteUser(t, client, user.ID)
|
||||||
|
|
||||||
|
t.Logf("Attempting to assign a role %s to a user %s on a project %s", role.Name, user.Name, project.Name)
|
||||||
|
err = roles.Assign(client, role.ID, roles.AssignOpts{
|
||||||
|
UserID: user.ID,
|
||||||
|
ProjectID: project.ID,
|
||||||
|
}).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to assign a role to a user on a project: %v", err)
|
||||||
|
}
|
||||||
|
t.Logf("Successfully assigned a role %s to a user %s on a project %s", role.Name, user.Name, project.Name)
|
||||||
|
defer UnassignRole(t, client, role.ID, &roles.UnassignOpts{
|
||||||
|
UserID: user.ID,
|
||||||
|
ProjectID: project.ID,
|
||||||
|
})
|
||||||
|
|
||||||
|
allPages, err := roles.ListAssignments(client, roles.ListAssignmentsOpts{
|
||||||
|
RoleID: role.ID,
|
||||||
|
ScopeProjectID: project.ID,
|
||||||
|
UserID: user.ID,
|
||||||
|
}).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoleAssignments, err := roles.ExtractRoleAssignments(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Role assignments of user %s on project %s:", user.Name, project.Name)
|
||||||
|
for _, roleAssignment := range allRoleAssignments {
|
||||||
|
tools.PrintResource(t, roleAssignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoleAssignToUserOnDomain(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an indentity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
domain, err := CreateDomain(t, client, &domains.CreateOpts{
|
||||||
|
Enabled: gophercloud.Disabled,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to create a domain")
|
||||||
|
}
|
||||||
|
defer DeleteDomain(t, client, domain.ID)
|
||||||
|
|
||||||
|
role, err := FindRole(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get a role: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := CreateUser(t, client, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create user: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteUser(t, client, user.ID)
|
||||||
|
|
||||||
|
t.Logf("Attempting to assign a role %s to a user %s on a domain %s", role.Name, user.Name, domain.Name)
|
||||||
|
err = roles.Assign(client, role.ID, roles.AssignOpts{
|
||||||
|
UserID: user.ID,
|
||||||
|
DomainID: domain.ID,
|
||||||
|
}).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to assign a role to a user on a domain: %v", err)
|
||||||
|
}
|
||||||
|
t.Logf("Successfully assigned a role %s to a user %s on a domain %s", role.Name, user.Name, domain.Name)
|
||||||
|
defer UnassignRole(t, client, role.ID, &roles.UnassignOpts{
|
||||||
|
UserID: user.ID,
|
||||||
|
DomainID: domain.ID,
|
||||||
|
})
|
||||||
|
|
||||||
|
allPages, err := roles.ListAssignments(client, roles.ListAssignmentsOpts{
|
||||||
|
RoleID: role.ID,
|
||||||
|
ScopeDomainID: domain.ID,
|
||||||
|
UserID: user.ID,
|
||||||
|
}).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoleAssignments, err := roles.ExtractRoleAssignments(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Role assignments of user %s on domain %s:", user.Name, domain.Name)
|
||||||
|
for _, roleAssignment := range allRoleAssignments {
|
||||||
|
tools.PrintResource(t, roleAssignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoleAssignToGroupOnDomain(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an indentity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
domain, err := CreateDomain(t, client, &domains.CreateOpts{
|
||||||
|
Enabled: gophercloud.Disabled,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to create a domain")
|
||||||
|
}
|
||||||
|
defer DeleteDomain(t, client, domain.ID)
|
||||||
|
|
||||||
|
role, err := FindRole(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get a role: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := CreateGroup(t, client, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create group: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteGroup(t, client, group.ID)
|
||||||
|
|
||||||
|
t.Logf("Attempting to assign a role %s to a group %s on a domain %s", role.Name, group.Name, domain.Name)
|
||||||
|
err = roles.Assign(client, role.ID, roles.AssignOpts{
|
||||||
|
GroupID: group.ID,
|
||||||
|
DomainID: domain.ID,
|
||||||
|
}).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to assign a role to a group on a domain: %v", err)
|
||||||
|
}
|
||||||
|
t.Logf("Successfully assigned a role %s to a group %s on a domain %s", role.Name, group.Name, domain.Name)
|
||||||
|
defer UnassignRole(t, client, role.ID, &roles.UnassignOpts{
|
||||||
|
GroupID: group.ID,
|
||||||
|
DomainID: domain.ID,
|
||||||
|
})
|
||||||
|
|
||||||
|
allPages, err := roles.ListAssignments(client, roles.ListAssignmentsOpts{
|
||||||
|
RoleID: role.ID,
|
||||||
|
ScopeDomainID: domain.ID,
|
||||||
|
GroupID: group.ID,
|
||||||
|
}).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoleAssignments, err := roles.ExtractRoleAssignments(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Role assignments of group %s on domain %s:", group.Name, domain.Name)
|
||||||
|
for _, roleAssignment := range allRoleAssignments {
|
||||||
|
tools.PrintResource(t, roleAssignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoleAssignToGroupOnProject(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an indentity client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := CreateProject(t, client, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to create a project")
|
||||||
|
}
|
||||||
|
defer DeleteProject(t, client, project.ID)
|
||||||
|
|
||||||
|
role, err := FindRole(t, client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to get a role: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := CreateGroup(t, client, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create group: %v", err)
|
||||||
|
}
|
||||||
|
defer DeleteGroup(t, client, group.ID)
|
||||||
|
|
||||||
|
t.Logf("Attempting to assign a role %s to a group %s on a project %s", role.Name, group.Name, project.Name)
|
||||||
|
err = roles.Assign(client, role.ID, roles.AssignOpts{
|
||||||
|
GroupID: group.ID,
|
||||||
|
ProjectID: project.ID,
|
||||||
|
}).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to assign a role to a group on a project: %v", err)
|
||||||
|
}
|
||||||
|
t.Logf("Successfully assigned a role %s to a group %s on a project %s", role.Name, group.Name, project.Name)
|
||||||
|
defer UnassignRole(t, client, role.ID, &roles.UnassignOpts{
|
||||||
|
GroupID: group.ID,
|
||||||
|
ProjectID: project.ID,
|
||||||
|
})
|
||||||
|
|
||||||
|
allPages, err := roles.ListAssignments(client, roles.ListAssignmentsOpts{
|
||||||
|
RoleID: role.ID,
|
||||||
|
ScopeProjectID: project.ID,
|
||||||
|
GroupID: group.ID,
|
||||||
|
}).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoleAssignments, err := roles.ExtractRoleAssignments(allPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract role assignments: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Role assignments of group %s on project %s:", group.Name, project.Name)
|
||||||
|
for _, roleAssignment := range allRoleAssignments {
|
||||||
|
tools.PrintResource(t, roleAssignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
66
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/users_test.go
generated
vendored
66
vendor/github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3/users_test.go
generated
vendored
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/acceptance/clients"
|
"github.com/gophercloud/gophercloud/acceptance/clients"
|
||||||
"github.com/gophercloud/gophercloud/acceptance/tools"
|
"github.com/gophercloud/gophercloud/acceptance/tools"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -154,3 +155,68 @@ func TestUsersListGroups(t *testing.T) {
|
||||||
tools.PrintResource(t, group.Extra)
|
tools.PrintResource(t, group.Extra)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUsersListProjects(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
allUserPages, err := users.List(client, nil).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list users: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allUsers, err := users.ExtractUsers(allUserPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract users: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
user := allUsers[0]
|
||||||
|
|
||||||
|
allProjectPages, err := users.ListProjects(client, user.ID).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list projects: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allProjects, err := projects.ExtractProjects(allProjectPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract projects: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, project := range allProjects {
|
||||||
|
tools.PrintResource(t, project)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUsersListInGroup(t *testing.T) {
|
||||||
|
client, err := clients.NewIdentityV3Client()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to obtain an identity client: %v", err)
|
||||||
|
}
|
||||||
|
allGroupPages, err := groups.List(client, nil).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list groups: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allGroups, err := groups.ExtractGroups(allGroupPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract groups: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
group := allGroups[0]
|
||||||
|
|
||||||
|
allUserPages, err := users.ListInGroup(client, group.ID, nil).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to list users: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allUsers, err := users.ExtractUsers(allUserPages)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to extract users: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range allUsers {
|
||||||
|
tools.PrintResource(t, user)
|
||||||
|
tools.PrintResource(t, user.Extra)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ func CreateExternalNetwork(t *testing.T, client *gophercloud.ServiceClient) (*ne
|
||||||
}
|
}
|
||||||
|
|
||||||
createOpts := external.CreateOptsExt{
|
createOpts := external.CreateOptsExt{
|
||||||
networkCreateOpts,
|
CreateOptsBuilder: networkCreateOpts,
|
||||||
&isExternal,
|
External: &isExternal,
|
||||||
}
|
}
|
||||||
|
|
||||||
network, err := networks.Create(client, createOpts).Extract()
|
network, err := networks.Create(client, createOpts).Extract()
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,10 @@ func CreateExternalRouter(t *testing.T, client *gophercloud.ServiceClient) (*rou
|
||||||
t.Logf("Attempting to create external router: %s", routerName)
|
t.Logf("Attempting to create external router: %s", routerName)
|
||||||
|
|
||||||
adminStateUp := true
|
adminStateUp := true
|
||||||
|
enableSNAT := false
|
||||||
gatewayInfo := routers.GatewayInfo{
|
gatewayInfo := routers.GatewayInfo{
|
||||||
NetworkID: choices.ExternalNetworkID,
|
NetworkID: choices.ExternalNetworkID,
|
||||||
|
EnableSNAT: &enableSNAT,
|
||||||
}
|
}
|
||||||
|
|
||||||
createOpts := routers.CreateOpts{
|
createOpts := routers.CreateOpts{
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ func TestLayer3RouterList(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLayer3RouterCreateDelete(t *testing.T) {
|
func TestLayer3ExternalRouterCreateDelete(t *testing.T) {
|
||||||
client, err := clients.NewNetworkV2Client()
|
client, err := clients.NewNetworkV2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to create a network client: %v", err)
|
t.Fatalf("Unable to create a network client: %v", err)
|
||||||
|
|
|
||||||
26
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumetenants/doc.go
generated
vendored
Normal file
26
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumetenants/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
Package volumetenants provides the ability to extend a volume result with
|
||||||
|
tenant/project information. Example:
|
||||||
|
|
||||||
|
type VolumeWithTenant struct {
|
||||||
|
volumes.Volume
|
||||||
|
volumetenants.VolumeTenantExt
|
||||||
|
}
|
||||||
|
|
||||||
|
var allVolumes []VolumeWithTenant
|
||||||
|
|
||||||
|
allPages, err := volumes.List(client, nil).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic("Unable to retrieve volumes: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = volumes.ExtractVolumesInto(allPages, &allVolumes)
|
||||||
|
if err != nil {
|
||||||
|
panic("Unable to extract volumes: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, volume := range allVolumes {
|
||||||
|
fmt.Println(volume.TenantID)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package volumetenants
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
package volumetenants
|
package volumetenants
|
||||||
|
|
||||||
// VolumeExt is an extension to the base Volume object
|
// VolumeTenantExt is an extension to the base Volume object
|
||||||
type VolumeExt struct {
|
type VolumeTenantExt struct {
|
||||||
// TenantID is the id of the project that owns the volume.
|
// TenantID is the id of the project that owns the volume.
|
||||||
TenantID string `json:"os-vol-tenant-attr:tenant_id"`
|
TenantID string `json:"os-vol-tenant-attr:tenant_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON to override default
|
|
||||||
func (r *VolumeExt) UnmarshalJSON(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
17
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/doc.go
generated
vendored
Normal file
17
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
Package noauth creates a "noauth" *gophercloud.ServiceClient for use in Cinder
|
||||||
|
environments configured with the noauth authentication middleware.
|
||||||
|
|
||||||
|
Example of Creating a noauth Service Client
|
||||||
|
|
||||||
|
provider, err := noauth.NewClient(gophercloud.AuthOptions{
|
||||||
|
Username: os.Getenv("OS_USERNAME"),
|
||||||
|
TenantName: os.Getenv("OS_TENANT_NAME"),
|
||||||
|
})
|
||||||
|
client, err := noauth.NewBlockStorageV2(provider, noauth.EndpointOpts{
|
||||||
|
CinderEndpoint: os.Getenv("CINDER_ENDPOINT"),
|
||||||
|
})
|
||||||
|
|
||||||
|
An example of a CinderEndpoint would be: http://example.com:8776/v2,
|
||||||
|
*/
|
||||||
|
package noauth
|
||||||
55
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/requests.go
generated
vendored
Normal file
55
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/requests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
package noauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EndpointOpts specifies a "noauth" Cinder Endpoint.
|
||||||
|
type EndpointOpts struct {
|
||||||
|
// CinderEndpoint [required] is currently only used with "noauth" Cinder.
|
||||||
|
// A cinder endpoint with "auth_strategy=noauth" is necessary, for example:
|
||||||
|
// http://example.com:8776/v2.
|
||||||
|
CinderEndpoint string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient prepares an unauthenticated ProviderClient instance.
|
||||||
|
func NewClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) {
|
||||||
|
if options.Username == "" {
|
||||||
|
options.Username = "admin"
|
||||||
|
}
|
||||||
|
if options.TenantName == "" {
|
||||||
|
options.TenantName = "admin"
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &gophercloud.ProviderClient{
|
||||||
|
TokenID: fmt.Sprintf("%s:%s", options.Username, options.TenantName),
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func initClientOpts(client *gophercloud.ProviderClient, eo EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
sc := new(gophercloud.ServiceClient)
|
||||||
|
if eo.CinderEndpoint == "" {
|
||||||
|
return nil, fmt.Errorf("CinderEndpoint is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
token := strings.Split(client.TokenID, ":")
|
||||||
|
if len(token) != 2 {
|
||||||
|
return nil, fmt.Errorf("Malformed noauth token")
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint := fmt.Sprintf("%s%s", gophercloud.NormalizeURL(eo.CinderEndpoint), token[1])
|
||||||
|
sc.Endpoint = gophercloud.NormalizeURL(endpoint)
|
||||||
|
sc.ProviderClient = client
|
||||||
|
return sc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBlockStorageV2 creates a ServiceClient that may be used to access a
|
||||||
|
// "noauth" block storage service.
|
||||||
|
func NewBlockStorageV2(client *gophercloud.ProviderClient, eo EndpointOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
return initClientOpts(client, eo)
|
||||||
|
}
|
||||||
2
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/testing/doc.go
generated
vendored
Normal file
2
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/testing/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// noauth unit tests
|
||||||
|
package testing
|
||||||
19
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/testing/fixtures.go
generated
vendored
Normal file
19
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/testing/fixtures.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
// NoAuthResult is the expected result of the noauth Service Client
|
||||||
|
type NoAuthResult struct {
|
||||||
|
TokenID string
|
||||||
|
Endpoint string
|
||||||
|
}
|
||||||
|
|
||||||
|
var naTestResult = NoAuthResult{
|
||||||
|
TokenID: "user:test",
|
||||||
|
Endpoint: "http://cinder:8776/v2/test/",
|
||||||
|
}
|
||||||
|
|
||||||
|
var naResult = NoAuthResult{
|
||||||
|
TokenID: "admin:admin",
|
||||||
|
Endpoint: "http://cinder:8776/v2/admin/",
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorResult = "CinderEndpoint is required"
|
||||||
38
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/testing/requests_test.go
generated
vendored
Normal file
38
vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/noauth/testing/requests_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/blockstorage/noauth"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNoAuth(t *testing.T) {
|
||||||
|
ao := gophercloud.AuthOptions{
|
||||||
|
Username: "user",
|
||||||
|
TenantName: "test",
|
||||||
|
}
|
||||||
|
provider, err := noauth.NewClient(ao)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
noauthClient, err := noauth.NewBlockStorageV2(provider, noauth.EndpointOpts{
|
||||||
|
CinderEndpoint: "http://cinder:8776/v2",
|
||||||
|
})
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.AssertEquals(t, naTestResult.Endpoint, noauthClient.Endpoint)
|
||||||
|
th.AssertEquals(t, naTestResult.TokenID, noauthClient.TokenID)
|
||||||
|
|
||||||
|
ao2 := gophercloud.AuthOptions{}
|
||||||
|
provider2, err := noauth.NewClient(ao2)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
noauthClient2, err := noauth.NewBlockStorageV2(provider2, noauth.EndpointOpts{
|
||||||
|
CinderEndpoint: "http://cinder:8776/v2/",
|
||||||
|
})
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.AssertEquals(t, naResult.Endpoint, noauthClient2.Endpoint)
|
||||||
|
th.AssertEquals(t, naResult.TokenID, noauthClient2.TokenID)
|
||||||
|
|
||||||
|
errTest, err := noauth.NewBlockStorageV2(provider2, noauth.EndpointOpts{})
|
||||||
|
_ = errTest
|
||||||
|
th.AssertEquals(t, errorResult, err.Error())
|
||||||
|
}
|
||||||
|
|
@ -102,7 +102,7 @@ func TestListAllWithExtensions(t *testing.T) {
|
||||||
|
|
||||||
type VolumeWithExt struct {
|
type VolumeWithExt struct {
|
||||||
volumes.Volume
|
volumes.Volume
|
||||||
volumetenants.VolumeExt
|
volumetenants.VolumeTenantExt
|
||||||
}
|
}
|
||||||
|
|
||||||
allPages, err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).AllPages()
|
allPages, err := volumes.List(client.ServiceClient(), &volumes.ListOpts{}).AllPages()
|
||||||
|
|
@ -244,7 +244,7 @@ func TestGetWithExtensions(t *testing.T) {
|
||||||
|
|
||||||
var s struct {
|
var s struct {
|
||||||
volumes.Volume
|
volumes.Volume
|
||||||
volumetenants.VolumeExt
|
volumetenants.VolumeTenantExt
|
||||||
}
|
}
|
||||||
err := volumes.Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s)
|
err := volumes.Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractInto(&s)
|
||||||
th.AssertNoErr(t, err)
|
th.AssertNoErr(t, err)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
|
||||||
|
|
@ -12,8 +14,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
v20 = "v2.0"
|
// v2 represents Keystone v2.
|
||||||
v30 = "v3.0"
|
// It should never increase beyond 2.0.
|
||||||
|
v2 = "v2.0"
|
||||||
|
|
||||||
|
// v3 represents Keystone v3.
|
||||||
|
// The version can be anything from v3 to v3.x.
|
||||||
|
v3 = "v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -35,24 +42,25 @@ func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hadPath := u.Path != ""
|
|
||||||
u.Path, u.RawQuery, u.Fragment = "", "", ""
|
u.RawQuery, u.Fragment = "", ""
|
||||||
base := u.String()
|
|
||||||
|
var base string
|
||||||
|
versionRe := regexp.MustCompile("v[0-9.]+/?")
|
||||||
|
if version := versionRe.FindString(u.Path); version != "" {
|
||||||
|
base = strings.Replace(u.String(), version, "", -1)
|
||||||
|
} else {
|
||||||
|
base = u.String()
|
||||||
|
}
|
||||||
|
|
||||||
endpoint = gophercloud.NormalizeURL(endpoint)
|
endpoint = gophercloud.NormalizeURL(endpoint)
|
||||||
base = gophercloud.NormalizeURL(base)
|
base = gophercloud.NormalizeURL(base)
|
||||||
|
|
||||||
if hadPath {
|
|
||||||
return &gophercloud.ProviderClient{
|
|
||||||
IdentityBase: base,
|
|
||||||
IdentityEndpoint: endpoint,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &gophercloud.ProviderClient{
|
return &gophercloud.ProviderClient{
|
||||||
IdentityBase: base,
|
IdentityBase: base,
|
||||||
IdentityEndpoint: "",
|
IdentityEndpoint: endpoint,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -92,8 +100,8 @@ func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.Provider
|
||||||
// supported at the provided endpoint.
|
// supported at the provided endpoint.
|
||||||
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
|
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
|
||||||
versions := []*utils.Version{
|
versions := []*utils.Version{
|
||||||
{ID: v20, Priority: 20, Suffix: "/v2.0/"},
|
{ID: v2, Priority: 20, Suffix: "/v2.0/"},
|
||||||
{ID: v30, Priority: 30, Suffix: "/v3/"},
|
{ID: v3, Priority: 30, Suffix: "/v3/"},
|
||||||
}
|
}
|
||||||
|
|
||||||
chosen, endpoint, err := utils.ChooseVersion(client, versions)
|
chosen, endpoint, err := utils.ChooseVersion(client, versions)
|
||||||
|
|
@ -102,9 +110,9 @@ func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOp
|
||||||
}
|
}
|
||||||
|
|
||||||
switch chosen.ID {
|
switch chosen.ID {
|
||||||
case v20:
|
case v2:
|
||||||
return v2auth(client, endpoint, options, gophercloud.EndpointOpts{})
|
return v2auth(client, endpoint, options, gophercloud.EndpointOpts{})
|
||||||
case v30:
|
case v3:
|
||||||
return v3auth(client, endpoint, &options, gophercloud.EndpointOpts{})
|
return v3auth(client, endpoint, &options, gophercloud.EndpointOpts{})
|
||||||
default:
|
default:
|
||||||
// The switch statement must be out of date from the versions list.
|
// The switch statement must be out of date from the versions list.
|
||||||
|
|
@ -241,6 +249,13 @@ func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure endpoint still has a suffix of v3.
|
||||||
|
// This is because EndpointLocator might have found a versionless
|
||||||
|
// endpoint and requests will fail unless targeted at /v3.
|
||||||
|
if !strings.HasSuffix(endpoint, "v3/") {
|
||||||
|
endpoint = endpoint + "v3/"
|
||||||
|
}
|
||||||
|
|
||||||
return &gophercloud.ServiceClient{
|
return &gophercloud.ServiceClient{
|
||||||
ProviderClient: client,
|
ProviderClient: client,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete will permanently delete a rule the project's default security group.
|
// Delete will permanently delete a rule the project's default security group.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(resourceURL(client, id), nil)
|
_, r.Err = client.Delete(resourceURL(client, id), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,3 +65,9 @@ func (r commonResult) Extract() (*DefaultRule, error) {
|
||||||
err := r.ExtractInto(&s)
|
err := r.ExtractInto(&s)
|
||||||
return &s.DefaultRule, err
|
return &s.DefaultRule, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the response from a delete operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
|
||||||
13
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/doc.go
generated
vendored
Normal file
13
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
Package evacuate provides functionality to evacuates servers that have been
|
||||||
|
provisioned by the OpenStack Compute service from a failed host to a new host.
|
||||||
|
|
||||||
|
Example to Evacuate a Server from a Host
|
||||||
|
|
||||||
|
serverID := "b16ba811-199d-4ffd-8839-ba96c1185a67"
|
||||||
|
err := evacuate.Evacuate(computeClient, serverID, evacuate.EvacuateOpts{}).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package evacuate
|
||||||
41
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/requests.go
generated
vendored
Normal file
41
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/requests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
package evacuate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EvacuateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// the Evacuate request.
|
||||||
|
type EvacuateOptsBuilder interface {
|
||||||
|
ToEvacuateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EvacuateOpts specifies Evacuate action parameters.
|
||||||
|
type EvacuateOpts struct {
|
||||||
|
// The name of the host to which the server is evacuated
|
||||||
|
Host string `json:"host,omitempty"`
|
||||||
|
|
||||||
|
// Indicates whether server is on shared storage
|
||||||
|
OnSharedStorage bool `json:"onSharedStorage"`
|
||||||
|
|
||||||
|
// An administrative password to access the evacuated server
|
||||||
|
AdminPass string `json:"adminPass,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToServerGroupCreateMap constructs a request body from CreateOpts.
|
||||||
|
func (opts EvacuateOpts) ToEvacuateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "evacuate")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evacuate will Evacuate a failed instance to another host.
|
||||||
|
func Evacuate(client *gophercloud.ServiceClient, id string, opts EvacuateOptsBuilder) (r EvacuateResult) {
|
||||||
|
b, err := opts.ToEvacuateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
23
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/results.go
generated
vendored
Normal file
23
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/results.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package evacuate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EvacuateResult is the response from an Evacuate operation.
|
||||||
|
//Call its ExtractAdminPass method to retrieve the admin password of the instance.
|
||||||
|
//The admin password will be an empty string if the cloud is not configured to inject admin passwords..
|
||||||
|
type EvacuateResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r EvacuateResult) ExtractAdminPass() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
AdminPass string `json:"adminPass"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil && err.Error() == "EOF" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return s.AdminPass, err
|
||||||
|
}
|
||||||
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/testing/doc.go
generated
vendored
Normal file
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/testing/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// compute_extensions_evacuate_v2
|
||||||
|
package testing
|
||||||
83
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/testing/fixtures.go
generated
vendored
Normal file
83
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/testing/fixtures.go
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mockEvacuateResponse(t *testing.T, id string) {
|
||||||
|
th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, `
|
||||||
|
{
|
||||||
|
"evacuate": {
|
||||||
|
"adminPass": "MySecretPass",
|
||||||
|
"host": "derp",
|
||||||
|
"onSharedStorage": false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockEvacuateResponseWithHost(t *testing.T, id string) {
|
||||||
|
th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, `
|
||||||
|
{
|
||||||
|
"evacuate": {
|
||||||
|
"host": "derp",
|
||||||
|
"onSharedStorage": false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockEvacuateResponseWithNoOpts(t *testing.T, id string) {
|
||||||
|
th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, `
|
||||||
|
{
|
||||||
|
"evacuate": {
|
||||||
|
"onSharedStorage": false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const EvacuateResponse = `
|
||||||
|
{
|
||||||
|
"adminPass": "MySecretPass"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func mockEvacuateAdminpassResponse(t *testing.T, id string) {
|
||||||
|
th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, `
|
||||||
|
{
|
||||||
|
"evacuate": {
|
||||||
|
"onSharedStorage": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
fmt.Fprintf(w, EvacuateResponse)
|
||||||
|
})
|
||||||
|
}
|
||||||
60
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/testing/requests_test.go
generated
vendored
Normal file
60
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/testing/requests_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEvacuate(t *testing.T) {
|
||||||
|
const serverID = "b16ba811-199d-4ffd-8839-ba96c1185a67"
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
|
||||||
|
mockEvacuateResponse(t, serverID)
|
||||||
|
|
||||||
|
_, err := evacuate.Evacuate(client.ServiceClient(), serverID, evacuate.EvacuateOpts{
|
||||||
|
Host: "derp",
|
||||||
|
AdminPass: "MySecretPass",
|
||||||
|
OnSharedStorage: false,
|
||||||
|
}).ExtractAdminPass()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEvacuateWithHost(t *testing.T) {
|
||||||
|
const serverID = "b16ba811-199d-4ffd-8839-ba96c1185a67"
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
|
||||||
|
mockEvacuateResponseWithHost(t, serverID)
|
||||||
|
|
||||||
|
_, err := evacuate.Evacuate(client.ServiceClient(), serverID, evacuate.EvacuateOpts{
|
||||||
|
Host: "derp",
|
||||||
|
}).ExtractAdminPass()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEvacuateWithNoOpts(t *testing.T) {
|
||||||
|
const serverID = "b16ba811-199d-4ffd-8839-ba96c1185a67"
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
|
||||||
|
mockEvacuateResponseWithNoOpts(t, serverID)
|
||||||
|
|
||||||
|
_, err := evacuate.Evacuate(client.ServiceClient(), serverID, evacuate.EvacuateOpts{}).ExtractAdminPass()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEvacuateAdminpassResponse(t *testing.T) {
|
||||||
|
const serverID = "b16ba811-199d-4ffd-8839-ba96c1185a67"
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
|
||||||
|
mockEvacuateAdminpassResponse(t, serverID)
|
||||||
|
|
||||||
|
actual, err := evacuate.Evacuate(client.ServiceClient(), serverID, evacuate.EvacuateOpts{}).ExtractAdminPass()
|
||||||
|
th.CheckEquals(t, "MySecretPass", actual)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
9
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/urls.go
generated
vendored
Normal file
9
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/evacuate/urls.go
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package evacuate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return client.ServiceURL("servers", id, "action")
|
||||||
|
}
|
||||||
19
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/doc.go
generated
vendored
Normal file
19
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
Package lockunlock provides functionality to lock and unlock servers that
|
||||||
|
have been provisioned by the OpenStack Compute service.
|
||||||
|
|
||||||
|
Example to Lock and Unlock a Server
|
||||||
|
|
||||||
|
serverID := "47b6b7b7-568d-40e4-868c-d5c41735532e"
|
||||||
|
|
||||||
|
err := lockunlock.Lock(computeClient, serverID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = lockunlock.Unlock(computeClient, serverID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package lockunlock
|
||||||
19
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/requests.go
generated
vendored
Normal file
19
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/requests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package lockunlock
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return client.ServiceURL("servers", id, "action")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock is the operation responsible for locking a Compute server.
|
||||||
|
func Lock(client *gophercloud.ServiceClient, id string) (r LockResult) {
|
||||||
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"lock": nil}, nil, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock is the operation responsible for unlocking a Compute server.
|
||||||
|
func Unlock(client *gophercloud.ServiceClient, id string) (r UnlockResult) {
|
||||||
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"unlock": nil}, nil, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
16
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/results.go
generated
vendored
Normal file
16
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/results.go
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package lockunlock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LockResult and UnlockResult are the responses from a Lock and Unlock
|
||||||
|
// operations respectively. Call their ExtractErr methods to determine if the
|
||||||
|
// requests suceeded or failed.
|
||||||
|
type LockResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnlockResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/testing/doc.go
generated
vendored
Normal file
2
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/testing/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// unlocklock unit tests
|
||||||
|
package testing
|
||||||
27
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/testing/fixtures.go
generated
vendored
Normal file
27
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/testing/fixtures.go
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mockStartServerResponse(t *testing.T, id string) {
|
||||||
|
th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, `{"lock": null}`)
|
||||||
|
w.WriteHeader(http.StatusAccepted)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockStopServerResponse(t *testing.T, id string) {
|
||||||
|
th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, `{"unlock": null}`)
|
||||||
|
w.WriteHeader(http.StatusAccepted)
|
||||||
|
})
|
||||||
|
}
|
||||||
31
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/testing/request_test.go
generated
vendored
Normal file
31
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock/testing/request_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
const serverID = "{serverId}"
|
||||||
|
|
||||||
|
func TestLock(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
|
||||||
|
mockStartServerResponse(t, serverID)
|
||||||
|
|
||||||
|
err := lockunlock.Lock(client.ServiceClient(), serverID).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnlock(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
|
||||||
|
mockStopServerResponse(t, serverID)
|
||||||
|
|
||||||
|
err := lockunlock.Unlock(client.ServiceClient(), serverID).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// MigrateResult is the response from a Migrate operation. Call its ExtractErr
|
// MigrateResult is the response from a Migrate operation. Call its ExtractErr
|
||||||
// method to determine if the suceeded or failed.
|
// method to determine if the request suceeded or failed.
|
||||||
type MigrateResult struct {
|
type MigrateResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause is the operation responsible for pausing a Compute server.
|
// Pause is the operation responsible for pausing a Compute server.
|
||||||
func Pause(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Pause(client *gophercloud.ServiceClient, id string) (r PauseResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"pause": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"pause": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpause is the operation responsible for unpausing a Compute server.
|
// Unpause is the operation responsible for unpausing a Compute server.
|
||||||
func Unpause(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Unpause(client *gophercloud.ServiceClient, id string) (r UnpauseResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"unpause": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"unpause": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/pauseunpause/results.go
generated
vendored
Normal file
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/pauseunpause/results.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package pauseunpause
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
// PauseResult is the response from a Pause operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type PauseResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnpauseResult is the response from an Unpause operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type UnpauseResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
13
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/doc.go
generated
vendored
Normal file
13
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
Package resetstate provides functionality to reset the state of a server that has
|
||||||
|
been provisioned by the OpenStack Compute service.
|
||||||
|
|
||||||
|
Example to Reset a Server
|
||||||
|
|
||||||
|
serverID := "47b6b7b7-568d-40e4-868c-d5c41735532e"
|
||||||
|
err := resetstate.ResetState(client, id, resetstate.StateActive).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package resetstate
|
||||||
23
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/requests.go
generated
vendored
Normal file
23
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/requests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package resetstate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ServerState refers to the states usable in ResetState Action
|
||||||
|
type ServerState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StateActive returns the state of the server as active
|
||||||
|
StateActive ServerState = "active"
|
||||||
|
|
||||||
|
// StateError returns the state of the server as error
|
||||||
|
StateError ServerState = "error"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResetState will reset the state of a server
|
||||||
|
func ResetState(client *gophercloud.ServiceClient, id string, state ServerState) (r ResetResult) {
|
||||||
|
stateMap := map[string]interface{}{"state": state}
|
||||||
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-resetState": stateMap}, nil, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/results.go
generated
vendored
Normal file
11
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/results.go
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package resetstate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResetResult is the response of a ResetState operation. Call its ExtractErr
|
||||||
|
// method to determine if the request suceeded or failed.
|
||||||
|
type ResetResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
1
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/testing/doc.go
generated
vendored
Normal file
1
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/testing/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
package testing
|
||||||
19
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/testing/fixtures.go
generated
vendored
Normal file
19
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/testing/fixtures.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mockResetStateResponse(t *testing.T, id string, state string) {
|
||||||
|
th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, fmt.Sprintf(`{"os-resetState": {"state": "%s"}}`, state))
|
||||||
|
w.WriteHeader(http.StatusAccepted)
|
||||||
|
})
|
||||||
|
}
|
||||||
21
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/testing/requests_test.go
generated
vendored
Normal file
21
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/testing/requests_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
const serverID = "b16ba811-199d-4ffd-8839-ba96c1185a67"
|
||||||
|
|
||||||
|
func TestResetState(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
|
||||||
|
mockResetStateResponse(t, serverID, "active")
|
||||||
|
|
||||||
|
err := resetstate.ResetState(client.ServiceClient(), serverID, "active").ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
9
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/urls.go
generated
vendored
Normal file
9
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/resetstate/urls.go
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package resetstate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
|
return client.ServiceURL("servers", id, "action")
|
||||||
|
}
|
||||||
111
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups/doc.go
generated
vendored
111
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups/doc.go
generated
vendored
|
|
@ -1 +1,112 @@
|
||||||
|
/*
|
||||||
|
Package secgroups provides the ability to manage security groups through the
|
||||||
|
Nova API.
|
||||||
|
|
||||||
|
This API has been deprecated and will be removed from a future release of the
|
||||||
|
Nova API service.
|
||||||
|
|
||||||
|
For environments that support this extension, this package can be used
|
||||||
|
regardless of if either Neutron or nova-network is used as the cloud's network
|
||||||
|
service.
|
||||||
|
|
||||||
|
Example to List Security Groups
|
||||||
|
|
||||||
|
allPages, err := secroups.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allSecurityGroups, err := secgroups.ExtractSecurityGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sg := range allSecurityGroups {
|
||||||
|
fmt.Printf("%+v\n", sg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to List Security Groups by Server
|
||||||
|
|
||||||
|
serverID := "aab3ad01-9956-4623-a29b-24afc89a7d36"
|
||||||
|
|
||||||
|
allPages, err := secroups.ListByServer(computeClient, serverID).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allSecurityGroups, err := secgroups.ExtractSecurityGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sg := range allSecurityGroups {
|
||||||
|
fmt.Printf("%+v\n", sg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Security Group
|
||||||
|
|
||||||
|
createOpts := secgroups.CreateOpts{
|
||||||
|
Name: "group_name",
|
||||||
|
Description: "A Security Group",
|
||||||
|
}
|
||||||
|
|
||||||
|
sg, err := secgroups.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Security Group Rule
|
||||||
|
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
|
||||||
|
createOpts := secgroups.CreateRuleOpts{
|
||||||
|
ParentGroupID: sgID,
|
||||||
|
FromPort: 22,
|
||||||
|
ToPort: 22,
|
||||||
|
IPProtocol: "tcp",
|
||||||
|
CIDR: "0.0.0.0/0",
|
||||||
|
}
|
||||||
|
|
||||||
|
rule, err := secgroups.CreateRule(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Add a Security Group to a Server
|
||||||
|
|
||||||
|
serverID := "aab3ad01-9956-4623-a29b-24afc89a7d36"
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
|
||||||
|
err := secgroups.AddServer(computeClient, serverID, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Remove a Security Group from a Server
|
||||||
|
|
||||||
|
serverID := "aab3ad01-9956-4623-a29b-24afc89a7d36"
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
|
||||||
|
err := secgroups.RemoveServer(computeClient, serverID, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Security Group
|
||||||
|
|
||||||
|
|
||||||
|
sgID := "37d94f8a-d136-465c-ae46-144f0d8ef141"
|
||||||
|
err := secgroups.Delete(computeClient, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Security Group Rule
|
||||||
|
|
||||||
|
ruleID := "6221fe3e-383d-46c9-a3a6-845e66c1e8b4"
|
||||||
|
err := secgroups.DeleteRule(computeClient, ruleID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package secgroups
|
package secgroups
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,13 @@ type GroupOpts struct {
|
||||||
// CreateOpts is the struct responsible for creating a security group.
|
// CreateOpts is the struct responsible for creating a security group.
|
||||||
type CreateOpts GroupOpts
|
type CreateOpts GroupOpts
|
||||||
|
|
||||||
// CreateOptsBuilder builds the create options into a serializable format.
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Create request.
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToSecGroupCreateMap() (map[string]interface{}, error)
|
ToSecGroupCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToSecGroupCreateMap builds the create options into a serializable format.
|
// ToSecGroupCreateMap builds a request body from CreateOpts.
|
||||||
func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) {
|
func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "security_group")
|
return gophercloud.BuildRequestBody(opts, "security_group")
|
||||||
}
|
}
|
||||||
|
|
@ -62,12 +63,13 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
|
||||||
// UpdateOpts is the struct responsible for updating an existing security group.
|
// UpdateOpts is the struct responsible for updating an existing security group.
|
||||||
type UpdateOpts GroupOpts
|
type UpdateOpts GroupOpts
|
||||||
|
|
||||||
// UpdateOptsBuilder builds the update options into a serializable format.
|
// UpdateOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// Update request.
|
||||||
type UpdateOptsBuilder interface {
|
type UpdateOptsBuilder interface {
|
||||||
ToSecGroupUpdateMap() (map[string]interface{}, error)
|
ToSecGroupUpdateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToSecGroupUpdateMap builds the update options into a serializable format.
|
// ToSecGroupUpdateMap builds a request body from UpdateOpts.
|
||||||
func (opts UpdateOpts) ToSecGroupUpdateMap() (map[string]interface{}, error) {
|
func (opts UpdateOpts) ToSecGroupUpdateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "security_group")
|
return gophercloud.BuildRequestBody(opts, "security_group")
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +95,7 @@ func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete will permanently delete a security group from the project.
|
// Delete will permanently delete a security group from the project.
|
||||||
func Delete(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||||
_, r.Err = client.Delete(resourceURL(client, id), nil)
|
_, r.Err = client.Delete(resourceURL(client, id), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -101,31 +103,41 @@ func Delete(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResu
|
||||||
// CreateRuleOpts represents the configuration for adding a new rule to an
|
// CreateRuleOpts represents the configuration for adding a new rule to an
|
||||||
// existing security group.
|
// existing security group.
|
||||||
type CreateRuleOpts struct {
|
type CreateRuleOpts struct {
|
||||||
// the ID of the group that this rule will be added to.
|
// ID is the ID of the group that this rule will be added to.
|
||||||
ParentGroupID string `json:"parent_group_id" required:"true"`
|
ParentGroupID string `json:"parent_group_id" required:"true"`
|
||||||
// the lower bound of the port range that will be opened.
|
|
||||||
|
// FromPort is the lower bound of the port range that will be opened.
|
||||||
|
// Use -1 to allow all ICMP traffic.
|
||||||
FromPort int `json:"from_port"`
|
FromPort int `json:"from_port"`
|
||||||
// the upper bound of the port range that will be opened.
|
|
||||||
|
// ToPort is the upper bound of the port range that will be opened.
|
||||||
|
// Use -1 to allow all ICMP traffic.
|
||||||
ToPort int `json:"to_port"`
|
ToPort int `json:"to_port"`
|
||||||
// the protocol type that will be allowed, e.g. TCP.
|
|
||||||
|
// IPProtocol the protocol type that will be allowed, e.g. TCP.
|
||||||
IPProtocol string `json:"ip_protocol" required:"true"`
|
IPProtocol string `json:"ip_protocol" required:"true"`
|
||||||
// ONLY required if FromGroupID is blank. This represents the IP range that
|
|
||||||
// will be the source of network traffic to your security group. Use
|
// CIDR is the network CIDR to allow traffic from.
|
||||||
// 0.0.0.0/0 to allow all IP addresses.
|
// This is ONLY required if FromGroupID is blank. This represents the IP
|
||||||
|
// range that will be the source of network traffic to your security group.
|
||||||
|
// Use 0.0.0.0/0 to allow all IP addresses.
|
||||||
CIDR string `json:"cidr,omitempty" or:"FromGroupID"`
|
CIDR string `json:"cidr,omitempty" or:"FromGroupID"`
|
||||||
// ONLY required if CIDR is blank. This value represents the ID of a group
|
|
||||||
// that forwards traffic to the parent group. So, instead of accepting
|
// FromGroupID represents another security group to allow access.
|
||||||
|
// This is ONLY required if CIDR is blank. This value represents the ID of a
|
||||||
|
// group that forwards traffic to the parent group. So, instead of accepting
|
||||||
// network traffic from an entire IP range, you can instead refine the
|
// network traffic from an entire IP range, you can instead refine the
|
||||||
// inbound source by an existing security group.
|
// inbound source by an existing security group.
|
||||||
FromGroupID string `json:"group_id,omitempty" or:"CIDR"`
|
FromGroupID string `json:"group_id,omitempty" or:"CIDR"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRuleOptsBuilder builds the create rule options into a serializable format.
|
// CreateRuleOptsBuilder allows extensions to add additional parameters to the
|
||||||
|
// CreateRule request.
|
||||||
type CreateRuleOptsBuilder interface {
|
type CreateRuleOptsBuilder interface {
|
||||||
ToRuleCreateMap() (map[string]interface{}, error)
|
ToRuleCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToRuleCreateMap builds the create rule options into a serializable format.
|
// ToRuleCreateMap builds a request body from CreateRuleOpts.
|
||||||
func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
|
func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
|
||||||
return gophercloud.BuildRequestBody(opts, "security_group_rule")
|
return gophercloud.BuildRequestBody(opts, "security_group_rule")
|
||||||
}
|
}
|
||||||
|
|
@ -146,7 +158,7 @@ func CreateRule(client *gophercloud.ServiceClient, opts CreateRuleOptsBuilder) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRule will permanently delete a rule from a security group.
|
// DeleteRule will permanently delete a rule from a security group.
|
||||||
func DeleteRule(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func DeleteRule(client *gophercloud.ServiceClient, id string) (r DeleteRuleResult) {
|
||||||
_, r.Err = client.Delete(resourceRuleURL(client, id), nil)
|
_, r.Err = client.Delete(resourceRuleURL(client, id), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -159,13 +171,13 @@ func actionMap(prefix, groupName string) map[string]map[string]string {
|
||||||
|
|
||||||
// AddServer will associate a server and a security group, enforcing the
|
// AddServer will associate a server and a security group, enforcing the
|
||||||
// rules of the group on the server.
|
// rules of the group on the server.
|
||||||
func AddServer(client *gophercloud.ServiceClient, serverID, groupName string) (r gophercloud.ErrResult) {
|
func AddServer(client *gophercloud.ServiceClient, serverID, groupName string) (r AddServerResult) {
|
||||||
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("add", groupName), &r.Body, nil)
|
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("add", groupName), &r.Body, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveServer will disassociate a server from a security group.
|
// RemoveServer will disassociate a server from a security group.
|
||||||
func RemoveServer(client *gophercloud.ServiceClient, serverID, groupName string) (r gophercloud.ErrResult) {
|
func RemoveServer(client *gophercloud.ServiceClient, serverID, groupName string) (r RemoveServerResult) {
|
||||||
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("remove", groupName), &r.Body, nil)
|
_, r.Err = client.Post(serverActionURL(client, serverID), actionMap("remove", groupName), &r.Body, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,19 +59,19 @@ type Rule struct {
|
||||||
// numeric ID. For the sake of consistency, we always cast it to a string.
|
// numeric ID. For the sake of consistency, we always cast it to a string.
|
||||||
ID string `json:"-"`
|
ID string `json:"-"`
|
||||||
|
|
||||||
// The lower bound of the port range which this security group should open up
|
// The lower bound of the port range which this security group should open up.
|
||||||
FromPort int `json:"from_port"`
|
FromPort int `json:"from_port"`
|
||||||
|
|
||||||
// The upper bound of the port range which this security group should open up
|
// The upper bound of the port range which this security group should open up.
|
||||||
ToPort int `json:"to_port"`
|
ToPort int `json:"to_port"`
|
||||||
|
|
||||||
// The IP protocol (e.g. TCP) which the security group accepts
|
// The IP protocol (e.g. TCP) which the security group accepts.
|
||||||
IPProtocol string `json:"ip_protocol"`
|
IPProtocol string `json:"ip_protocol"`
|
||||||
|
|
||||||
// The CIDR IP range whose traffic can be received
|
// The CIDR IP range whose traffic can be received.
|
||||||
IPRange IPRange `json:"ip_range"`
|
IPRange IPRange `json:"ip_range"`
|
||||||
|
|
||||||
// The security group ID to which this rule belongs
|
// The security group ID to which this rule belongs.
|
||||||
ParentGroupID string `json:"parent_group_id"`
|
ParentGroupID string `json:"parent_group_id"`
|
||||||
|
|
||||||
// Not documented.
|
// Not documented.
|
||||||
|
|
@ -126,13 +126,15 @@ type SecurityGroupPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty determines whether or not a page of Security Groups contains any results.
|
// IsEmpty determines whether or not a page of Security Groups contains any
|
||||||
|
// results.
|
||||||
func (page SecurityGroupPage) IsEmpty() (bool, error) {
|
func (page SecurityGroupPage) IsEmpty() (bool, error) {
|
||||||
users, err := ExtractSecurityGroups(page)
|
users, err := ExtractSecurityGroups(page)
|
||||||
return len(users) == 0, err
|
return len(users) == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractSecurityGroups returns a slice of SecurityGroups contained in a single page of results.
|
// ExtractSecurityGroups returns a slice of SecurityGroups contained in a
|
||||||
|
// single page of results.
|
||||||
func ExtractSecurityGroups(r pagination.Page) ([]SecurityGroup, error) {
|
func ExtractSecurityGroups(r pagination.Page) ([]SecurityGroup, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
SecurityGroups []SecurityGroup `json:"security_groups"`
|
SecurityGroups []SecurityGroup `json:"security_groups"`
|
||||||
|
|
@ -145,17 +147,20 @@ type commonResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult represents the result of a create operation.
|
// CreateResult represents the result of a create operation. Call its Extract
|
||||||
|
// method to interpret the result as a SecurityGroup.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult represents the result of a get operation.
|
// GetResult represents the result of a get operation. Call its Extract
|
||||||
|
// method to interpret the result as a SecurityGroup.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateResult represents the result of an update operation.
|
// UpdateResult represents the result of an update operation. Call its Extract
|
||||||
|
// method to interpret the result as a SecurityGroup.
|
||||||
type UpdateResult struct {
|
type UpdateResult struct {
|
||||||
commonResult
|
commonResult
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +175,7 @@ func (r commonResult) Extract() (*SecurityGroup, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRuleResult represents the result when adding rules to a security group.
|
// CreateRuleResult represents the result when adding rules to a security group.
|
||||||
|
// Call its Extract method to interpret the result as a Rule.
|
||||||
type CreateRuleResult struct {
|
type CreateRuleResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
@ -182,3 +188,27 @@ func (r CreateRuleResult) Extract() (*Rule, error) {
|
||||||
err := r.ExtractInto(&s)
|
err := r.ExtractInto(&s)
|
||||||
return s.Rule, err
|
return s.Rule, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the response from delete operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRuleResult is the response from a DeleteRule operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type DeleteRuleResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddServerResult is the response from an AddServer operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type AddServerResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveServerResult is the response from a RemoveServer operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type RemoveServerResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,40 @@
|
||||||
// Package servergroups provides the ability to manage server groups
|
/*
|
||||||
|
Package servergroups provides the ability to manage server groups.
|
||||||
|
|
||||||
|
Example to List Server Groups
|
||||||
|
|
||||||
|
allpages, err := servergroups.List(computeClient).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allServerGroups, err := servergroups.ExtractServerGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sg := range allServerGroups {
|
||||||
|
fmt.Printf("%#v\n", sg)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Server Group
|
||||||
|
|
||||||
|
createOpts := servergroups.CreateOpts{
|
||||||
|
Name: "my_sg",
|
||||||
|
Policies: []string{"anti-affinity"},
|
||||||
|
}
|
||||||
|
|
||||||
|
sg, err := servergroups.Create(computeClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Server Group
|
||||||
|
|
||||||
|
sgID := "7a6f29ad-e34d-4368-951a-58a08f11cfb7"
|
||||||
|
err := servergroups.Delete(computeClient, sgID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package servergroups
|
package servergroups
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,25 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// List returns a Pager that allows you to iterate over a collection of ServerGroups.
|
// List returns a Pager that allows you to iterate over a collection of
|
||||||
|
// ServerGroups.
|
||||||
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||||
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
||||||
return ServerGroupPage{pagination.SinglePageBase(r)}
|
return ServerGroupPage{pagination.SinglePageBase(r)}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notably, the
|
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||||
// CreateOpts struct in this package does.
|
// Create request.
|
||||||
type CreateOptsBuilder interface {
|
type CreateOptsBuilder interface {
|
||||||
ToServerGroupCreateMap() (map[string]interface{}, error)
|
ToServerGroupCreateMap() (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOpts specifies a Server Group allocation request
|
// CreateOpts specifies Server Group creation parameters.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
// Name is the name of the server group
|
// Name is the name of the server group
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
|
|
||||||
// Policies are the server group policies
|
// Policies are the server group policies
|
||||||
Policies []string `json:"policies" required:"true"`
|
Policies []string `json:"policies" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +33,7 @@ func (opts CreateOpts) ToServerGroupCreateMap() (map[string]interface{}, error)
|
||||||
return gophercloud.BuildRequestBody(opts, "server_group")
|
return gophercloud.BuildRequestBody(opts, "server_group")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create requests the creation of a new Server Group
|
// Create requests the creation of a new Server Group.
|
||||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
b, err := opts.ToServerGroupCreateMap()
|
b, err := opts.ToServerGroupCreateMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A ServerGroup creates a policy for instance placement in the cloud
|
// A ServerGroup creates a policy for instance placement in the cloud.
|
||||||
type ServerGroup struct {
|
type ServerGroup struct {
|
||||||
// ID is the unique ID of the Server Group.
|
// ID is the unique ID of the Server Group.
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
@ -14,17 +14,26 @@ type ServerGroup struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
// Polices are the group policies.
|
// Polices are the group policies.
|
||||||
|
//
|
||||||
|
// Normally a single policy is applied:
|
||||||
|
//
|
||||||
|
// "affinity" will place all servers within the server group on the
|
||||||
|
// same compute node.
|
||||||
|
//
|
||||||
|
// "anti-affinity" will place servers within the server group on different
|
||||||
|
// compute nodes.
|
||||||
Policies []string `json:"policies"`
|
Policies []string `json:"policies"`
|
||||||
|
|
||||||
// Members are the members of the server group.
|
// Members are the members of the server group.
|
||||||
Members []string `json:"members"`
|
Members []string `json:"members"`
|
||||||
|
|
||||||
// Metadata includes a list of all user-specified key-value pairs attached to the Server Group.
|
// Metadata includes a list of all user-specified key-value pairs attached
|
||||||
|
// to the Server Group.
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerGroupPage stores a single, only page of ServerGroups
|
// ServerGroupPage stores a single page of all ServerGroups results from a
|
||||||
// results from a List call.
|
// List call.
|
||||||
type ServerGroupPage struct {
|
type ServerGroupPage struct {
|
||||||
pagination.SinglePageBase
|
pagination.SinglePageBase
|
||||||
}
|
}
|
||||||
|
|
@ -59,20 +68,20 @@ func (r ServerGroupResult) Extract() (*ServerGroup, error) {
|
||||||
return s.ServerGroup, err
|
return s.ServerGroup, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
// as a ServerGroup.
|
// to interpret it as a ServerGroup.
|
||||||
type CreateResult struct {
|
type CreateResult struct {
|
||||||
ServerGroupResult
|
ServerGroupResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResult is the response from a Get operation. Call its Extract method to interpret it
|
// GetResult is the response from a Get operation. Call its Extract method to
|
||||||
// as a ServerGroup.
|
// interpret it as a ServerGroup.
|
||||||
type GetResult struct {
|
type GetResult struct {
|
||||||
ServerGroupResult
|
ServerGroupResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult is the response from a Delete operation. Call its Extract method to determine if
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
||||||
// the call succeeded or failed.
|
// method to determine if the call succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start is the operation responsible for starting a Compute server.
|
// Start is the operation responsible for starting a Compute server.
|
||||||
func Start(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Start(client *gophercloud.ServiceClient, id string) (r StartResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-start": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-start": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop is the operation responsible for stopping a Compute server.
|
// Stop is the operation responsible for stopping a Compute server.
|
||||||
func Stop(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Stop(client *gophercloud.ServiceClient, id string) (r StopResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-stop": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-stop": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop/results.go
generated
vendored
Normal file
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop/results.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package startstop
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
// StartResult is the response from a Start operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type StartResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopResult is the response from Stop operation. Call its ExtractErr
|
||||||
|
// method to determine if the request succeeded or failed.
|
||||||
|
type StopResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
@ -7,13 +7,13 @@ func actionURL(client *gophercloud.ServiceClient, id string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suspend is the operation responsible for suspending a Compute server.
|
// Suspend is the operation responsible for suspending a Compute server.
|
||||||
func Suspend(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Suspend(client *gophercloud.ServiceClient, id string) (r SuspendResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"suspend": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"suspend": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resume is the operation responsible for resuming a Compute server.
|
// Resume is the operation responsible for resuming a Compute server.
|
||||||
func Resume(client *gophercloud.ServiceClient, id string) (r gophercloud.ErrResult) {
|
func Resume(client *gophercloud.ServiceClient, id string) (r UnsuspendResult) {
|
||||||
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"resume": nil}, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"resume": nil}, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/suspendresume/results.go
generated
vendored
Normal file
15
vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/suspendresume/results.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package suspendresume
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
// SuspendResult is the response from a Suspend operation. Call its
|
||||||
|
// ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type SuspendResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsuspendResult is the response from an Unsuspend operation. Call
|
||||||
|
// its ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type UnsuspendResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
14
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/instances/requests.go
generated
vendored
14
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/instances/requests.go
generated
vendored
|
|
@ -203,3 +203,17 @@ func ResizeVolume(client *gophercloud.ServiceClient, id string, size int) (r Act
|
||||||
_, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
|
_, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AttachConfigurationGroup will attach configuration group to the instance
|
||||||
|
func AttachConfigurationGroup(client *gophercloud.ServiceClient, instanceID string, configID string) (r ConfigurationResult) {
|
||||||
|
b := map[string]interface{}{"instance": map[string]interface{}{"configuration": configID}}
|
||||||
|
_, r.Err = client.Put(resourceURL(client, instanceID), &b, nil, &gophercloud.RequestOpts{OkCodes: []int{202}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DetachConfigurationGroup will dettach configuration group from the instance
|
||||||
|
func DetachConfigurationGroup(client *gophercloud.ServiceClient, instanceID string) (r ConfigurationResult) {
|
||||||
|
b := map[string]interface{}{"instance": map[string]interface{}{}}
|
||||||
|
_, r.Err = client.Put(resourceURL(client, instanceID), &b, nil, &gophercloud.RequestOpts{OkCodes: []int{202}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,11 @@ type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigurationResult represents the result of a AttachConfigurationGroup/DetachConfigurationGroup operation.
|
||||||
|
type ConfigurationResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
// Extract will extract an Instance from various result structs.
|
// Extract will extract an Instance from various result structs.
|
||||||
func (r commonResult) Extract() (*Instance, error) {
|
func (r commonResult) Extract() (*Instance, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
|
|
|
||||||
27
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/instances/testing/fixtures.go
generated
vendored
27
vendor/github.com/gophercloud/gophercloud/openstack/db/v1/instances/testing/fixtures.go
generated
vendored
|
|
@ -87,17 +87,20 @@ var createReq = `
|
||||||
`
|
`
|
||||||
|
|
||||||
var (
|
var (
|
||||||
instanceID = "{instanceID}"
|
instanceID = "{instanceID}"
|
||||||
rootURL = "/instances"
|
configGroupID = "00000000-0000-0000-0000-000000000000"
|
||||||
resURL = rootURL + "/" + instanceID
|
rootURL = "/instances"
|
||||||
uRootURL = resURL + "/root"
|
resURL = rootURL + "/" + instanceID
|
||||||
aURL = resURL + "/action"
|
uRootURL = resURL + "/root"
|
||||||
|
aURL = resURL + "/action"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
restartReq = `{"restart": {}}`
|
restartReq = `{"restart": {}}`
|
||||||
resizeReq = `{"resize": {"flavorRef": "2"}}`
|
resizeReq = `{"resize": {"flavorRef": "2"}}`
|
||||||
resizeVolReq = `{"resize": {"volume": {"size": 4}}}`
|
resizeVolReq = `{"resize": {"volume": {"size": 4}}}`
|
||||||
|
attachConfigurationGroupReq = `{"instance": {"configuration": "00000000-0000-0000-0000-000000000000"}}`
|
||||||
|
detachConfigurationGroupReq = `{"instance": {}}`
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -167,3 +170,11 @@ func HandleResize(t *testing.T) {
|
||||||
func HandleResizeVol(t *testing.T) {
|
func HandleResizeVol(t *testing.T) {
|
||||||
fixture.SetupHandler(t, aURL, "POST", resizeVolReq, "", 202)
|
fixture.SetupHandler(t, aURL, "POST", resizeVolReq, "", 202)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleAttachConfigurationGroup(t *testing.T) {
|
||||||
|
fixture.SetupHandler(t, resURL, "PUT", attachConfigurationGroupReq, "", 202)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleDetachConfigurationGroup(t *testing.T) {
|
||||||
|
fixture.SetupHandler(t, resURL, "PUT", detachConfigurationGroupReq, "", 202)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,3 +132,21 @@ func TestResizeVolume(t *testing.T) {
|
||||||
res := instances.ResizeVolume(fake.ServiceClient(), instanceID, 4)
|
res := instances.ResizeVolume(fake.ServiceClient(), instanceID, 4)
|
||||||
th.AssertNoErr(t, res.Err)
|
th.AssertNoErr(t, res.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAttachConfigurationGroup(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleAttachConfigurationGroup(t)
|
||||||
|
|
||||||
|
res := instances.AttachConfigurationGroup(fake.ServiceClient(), instanceID, configGroupID)
|
||||||
|
th.AssertNoErr(t, res.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetachConfigurationGroup(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleDetachConfigurationGroup(t)
|
||||||
|
|
||||||
|
res := instances.DetachConfigurationGroup(fake.ServiceClient(), instanceID)
|
||||||
|
th.AssertNoErr(t, res.Err)
|
||||||
|
}
|
||||||
|
|
|
||||||
59
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/doc.go
generated
vendored
Normal file
59
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
Package domains manages and retrieves Domains in the OpenStack Identity Service.
|
||||||
|
|
||||||
|
Example to List Domains
|
||||||
|
|
||||||
|
var iTrue bool = true
|
||||||
|
listOpts := domains.ListOpts{
|
||||||
|
Enabled: &iTrue,
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := domains.List(identityClient, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allDomains, err := domains.ExtractDomains(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, domain := range allDomains {
|
||||||
|
fmt.Printf("%+v\n", domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Domain
|
||||||
|
|
||||||
|
createOpts := domains.CreateOpts{
|
||||||
|
Name: "domain name",
|
||||||
|
Description: "Test domain",
|
||||||
|
}
|
||||||
|
|
||||||
|
domain, err := domains.Create(identityClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Update a Domain
|
||||||
|
|
||||||
|
domainID := "0fe36e73809d46aeae6705c39077b1b3"
|
||||||
|
|
||||||
|
var iFalse bool = false
|
||||||
|
updateOpts := domains.UpdateOpts{
|
||||||
|
Enabled: &iFalse,
|
||||||
|
}
|
||||||
|
|
||||||
|
domain, err := domains.Update(identityClient, domainID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Domain
|
||||||
|
|
||||||
|
domainID := "0fe36e73809d46aeae6705c39077b1b3"
|
||||||
|
err := domains.Delete(identityClient, domainID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package domains
|
||||||
126
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/requests.go
generated
vendored
Normal file
126
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/requests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
package domains
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the List request
|
||||||
|
type ListOptsBuilder interface {
|
||||||
|
ToDomainListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts provides options to filter the List results.
|
||||||
|
type ListOpts struct {
|
||||||
|
// Enabled filters the response by enabled domains.
|
||||||
|
Enabled *bool `q:"enabled"`
|
||||||
|
|
||||||
|
// Name filters the response by domain name.
|
||||||
|
Name string `q:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDomainListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToDomainListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List enumerates the domains to which the current token has access.
|
||||||
|
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := listURL(client)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToDomainListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return DomainPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves details on a single domain, by ID.
|
||||||
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
|
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Create request.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToDomainCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts provides options used to create a domain.
|
||||||
|
type CreateOpts struct {
|
||||||
|
// Name is the name of the new domain.
|
||||||
|
Name string `json:"name" required:"true"`
|
||||||
|
|
||||||
|
// Description is a description of the domain.
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// Enabled sets the domain status to enabled or disabled.
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDomainCreateMap formats a CreateOpts into a create request.
|
||||||
|
func (opts CreateOpts) ToDomainCreateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "domain")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new Domain.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToDomainCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(createURL(client), &b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{201},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a domain.
|
||||||
|
func Delete(client *gophercloud.ServiceClient, domainID string) (r DeleteResult) {
|
||||||
|
_, r.Err = client.Delete(deleteURL(client, domainID), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Update request.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToDomainUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOpts represents parameters to update a domain.
|
||||||
|
type UpdateOpts struct {
|
||||||
|
// Name is the name of the domain.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// Description is the description of the domain.
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// Enabled sets the domain status to enabled or disabled.
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToUpdateCreateMap formats a UpdateOpts into an update request.
|
||||||
|
func (opts UpdateOpts) ToDomainUpdateMap() (map[string]interface{}, error) {
|
||||||
|
return gophercloud.BuildRequestBody(opts, "domain")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update modifies the attributes of a domain.
|
||||||
|
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
b, err := opts.ToDomainUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Patch(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
97
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/results.go
generated
vendored
Normal file
97
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/results.go
generated
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
package domains
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Domain is a collection of projects, users, and roles.
|
||||||
|
type Domain struct {
|
||||||
|
// Description is the description of the Domain.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// Enabled is whether or not the domain is enabled.
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// ID is the unique ID of the domain.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// Links contains referencing links to the domain.
|
||||||
|
Links map[string]interface{} `json:"links"`
|
||||||
|
|
||||||
|
// Name is the name of the domain.
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type domainResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResult is the response from a Get operation. Call its Extract method
|
||||||
|
// to interpret it as a Domain.
|
||||||
|
type GetResult struct {
|
||||||
|
domainResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
|
// to interpret it as a Domain.
|
||||||
|
type CreateResult struct {
|
||||||
|
domainResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr to
|
||||||
|
// determine if the request succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult is the result of an Update request. Call its Extract method to
|
||||||
|
// interpret it as a Domain.
|
||||||
|
type UpdateResult struct {
|
||||||
|
domainResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DomainPage is a single page of Domain results.
|
||||||
|
type DomainPage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty determines whether or not a page of Domains contains any results.
|
||||||
|
func (r DomainPage) IsEmpty() (bool, error) {
|
||||||
|
domains, err := ExtractDomains(r)
|
||||||
|
return len(domains) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextPageURL extracts the "next" link from the links section of the result.
|
||||||
|
func (r DomainPage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Links struct {
|
||||||
|
Next string `json:"next"`
|
||||||
|
Previous string `json:"previous"`
|
||||||
|
} `json:"links"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return s.Links.Next, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractDomains returns a slice of Domains contained in a single page of
|
||||||
|
// results.
|
||||||
|
func ExtractDomains(r pagination.Page) ([]Domain, error) {
|
||||||
|
var s struct {
|
||||||
|
Domains []Domain `json:"domains"`
|
||||||
|
}
|
||||||
|
err := (r.(DomainPage)).ExtractInto(&s)
|
||||||
|
return s.Domains, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract interprets any domainResults as a Domain.
|
||||||
|
func (r domainResult) Extract() (*Domain, error) {
|
||||||
|
var s struct {
|
||||||
|
Domain *Domain `json:"domain"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Domain, err
|
||||||
|
}
|
||||||
188
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/testing/fixtures.go
generated
vendored
Normal file
188
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/testing/fixtures.go
generated
vendored
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/domains"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOutput provides a single page of Domain results.
|
||||||
|
const ListOutput = `
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"next": null,
|
||||||
|
"previous": null,
|
||||||
|
"self": "http://example.com/identity/v3/domains"
|
||||||
|
},
|
||||||
|
"domains": [
|
||||||
|
{
|
||||||
|
"enabled": true,
|
||||||
|
"id": "2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
"links": {
|
||||||
|
"self": "http://example.com/identity/v3/domains/2844b2a08be147a08ef58317d6471f1f"
|
||||||
|
},
|
||||||
|
"name": "domain one",
|
||||||
|
"description": "some description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled": true,
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/domains/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "domain two"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// GetOutput provides a Get result.
|
||||||
|
const GetOutput = `
|
||||||
|
{
|
||||||
|
"domain": {
|
||||||
|
"enabled": true,
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/domains/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "domain two"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// CreateRequest provides the input to a Create request.
|
||||||
|
const CreateRequest = `
|
||||||
|
{
|
||||||
|
"domain": {
|
||||||
|
"name": "domain two"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// UpdateRequest provides the input to as Update request.
|
||||||
|
const UpdateRequest = `
|
||||||
|
{
|
||||||
|
"domain": {
|
||||||
|
"description": "Staging Domain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// UpdateOutput provides an update result.
|
||||||
|
const UpdateOutput = `
|
||||||
|
{
|
||||||
|
"domain": {
|
||||||
|
"enabled": true,
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/domains/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "domain two",
|
||||||
|
"description": "Staging Domain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// FirstDomain is the first domain in the List request.
|
||||||
|
var FirstDomain = domains.Domain{
|
||||||
|
Enabled: true,
|
||||||
|
ID: "2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "http://example.com/identity/v3/domains/2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
},
|
||||||
|
Name: "domain one",
|
||||||
|
Description: "some description",
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecondDomain is the second domain in the List request.
|
||||||
|
var SecondDomain = domains.Domain{
|
||||||
|
Enabled: true,
|
||||||
|
ID: "9fe1d3",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "https://example.com/identity/v3/domains/9fe1d3",
|
||||||
|
},
|
||||||
|
Name: "domain two",
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecondDomainUpdated is how SecondDomain should look after an Update.
|
||||||
|
var SecondDomainUpdated = domains.Domain{
|
||||||
|
Enabled: true,
|
||||||
|
ID: "9fe1d3",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "https://example.com/identity/v3/domains/9fe1d3",
|
||||||
|
},
|
||||||
|
Name: "domain two",
|
||||||
|
Description: "Staging Domain",
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpectedDomainsSlice is the slice of domains expected to be returned from ListOutput.
|
||||||
|
var ExpectedDomainsSlice = []domains.Domain{FirstDomain, SecondDomain}
|
||||||
|
|
||||||
|
// HandleListDomainsSuccessfully creates an HTTP handler at `/domains` on the
|
||||||
|
// test handler mux that responds with a list of two domains.
|
||||||
|
func HandleListDomainsSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/domains", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, ListOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleGetDomainSuccessfully creates an HTTP handler at `/domains` on the
|
||||||
|
// test handler mux that responds with a single domain.
|
||||||
|
func HandleGetDomainSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, GetOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCreateDomainSuccessfully creates an HTTP handler at `/domains` on the
|
||||||
|
// test handler mux that tests domain creation.
|
||||||
|
func HandleCreateDomainSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/domains", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, CreateRequest)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
fmt.Fprintf(w, GetOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleDeleteDomainSuccessfully creates an HTTP handler at `/domains` on the
|
||||||
|
// test handler mux that tests domain deletion.
|
||||||
|
func HandleDeleteDomainSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "DELETE")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleUpdateDomainSuccessfully creates an HTTP handler at `/domains` on the
|
||||||
|
// test handler mux that tests domain update.
|
||||||
|
func HandleUpdateDomainSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/domains/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "PATCH")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, UpdateRequest)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, UpdateOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
89
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/testing/requests_test.go
generated
vendored
Normal file
89
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/testing/requests_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/domains"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestListDomains(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListDomainsSuccessfully(t)
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
err := domains.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) {
|
||||||
|
count++
|
||||||
|
|
||||||
|
actual, err := domains.ExtractDomains(page)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
th.CheckDeepEquals(t, ExpectedDomainsSlice, actual)
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckEquals(t, count, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListDomainsAllPages(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListDomainsSuccessfully(t)
|
||||||
|
|
||||||
|
allPages, err := domains.List(client.ServiceClient(), nil).AllPages()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
actual, err := domains.ExtractDomains(allPages)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, ExpectedDomainsSlice, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetDomain(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleGetDomainSuccessfully(t)
|
||||||
|
|
||||||
|
actual, err := domains.Get(client.ServiceClient(), "9fe1d3").Extract()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondDomain, *actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateDomain(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleCreateDomainSuccessfully(t)
|
||||||
|
|
||||||
|
createOpts := domains.CreateOpts{
|
||||||
|
Name: "domain two",
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := domains.Create(client.ServiceClient(), createOpts).Extract()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondDomain, *actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteDomain(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleDeleteDomainSuccessfully(t)
|
||||||
|
|
||||||
|
res := domains.Delete(client.ServiceClient(), "9fe1d3")
|
||||||
|
th.AssertNoErr(t, res.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateDomain(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleUpdateDomainSuccessfully(t)
|
||||||
|
|
||||||
|
updateOpts := domains.UpdateOpts{
|
||||||
|
Description: "Staging Domain",
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := domains.Update(client.ServiceClient(), "9fe1d3", updateOpts).Extract()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondDomainUpdated, *actual)
|
||||||
|
}
|
||||||
23
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/urls.go
generated
vendored
Normal file
23
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/domains/urls.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package domains
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func listURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL("domains")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getURL(client *gophercloud.ServiceClient, domainID string) string {
|
||||||
|
return client.ServiceURL("domains", domainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL("domains")
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteURL(client *gophercloud.ServiceClient, domainID string) string {
|
||||||
|
return client.ServiceURL("domains", domainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateURL(client *gophercloud.ServiceClient, domainID string) string {
|
||||||
|
return client.ServiceURL("domains", domainID)
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,60 @@
|
||||||
// Package groups retrieves and manages groups in the OpenStack Identity
|
/*
|
||||||
// Service.
|
Package groups manages and retrieves Groups in the OpenStack Identity Service.
|
||||||
|
|
||||||
|
Example to List Groups
|
||||||
|
|
||||||
|
listOpts := groups.ListOpts{
|
||||||
|
DomainID: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := groups.List(identityClient, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allGroups, err := groups.ExtractGroups(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, group := range allGroups {
|
||||||
|
fmt.Printf("%+v\n", group)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Group
|
||||||
|
|
||||||
|
createOpts := groups.CreateOpts{
|
||||||
|
Name: "groupname",
|
||||||
|
DomainID: "default",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "groupname@example.com",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := groups.Create(identityClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Update a Group
|
||||||
|
|
||||||
|
groupID := "0fe36e73809d46aeae6705c39077b1b3"
|
||||||
|
|
||||||
|
updateOpts := groups.UpdateOpts{
|
||||||
|
Description: "Updated Description for group",
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := groups.Update(identityClient, groupID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Group
|
||||||
|
|
||||||
|
groupID := "0fe36e73809d46aeae6705c39077b1b3"
|
||||||
|
err := groups.Delete(identityClient, groupID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
package groups
|
package groups
|
||||||
|
|
|
||||||
158
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/requests.go
generated
vendored
Normal file
158
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/requests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
package groups
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the List request
|
||||||
|
type ListOptsBuilder interface {
|
||||||
|
ToGroupListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts provides options to filter the List results.
|
||||||
|
type ListOpts struct {
|
||||||
|
// DomainID filters the response by a domain ID.
|
||||||
|
DomainID string `q:"domain_id"`
|
||||||
|
|
||||||
|
// Name filters the response by group name.
|
||||||
|
Name string `q:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToGroupListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToGroupListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List enumerates the Groups to which the current token has access.
|
||||||
|
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := listURL(client)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToGroupListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return GroupPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves details on a single group, by ID.
|
||||||
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
|
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Create request.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToGroupCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts provides options used to create a group.
|
||||||
|
type CreateOpts struct {
|
||||||
|
// Name is the name of the new group.
|
||||||
|
Name string `json:"name" required:"true"`
|
||||||
|
|
||||||
|
// Description is a description of the group.
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// DomainID is the ID of the domain the group belongs to.
|
||||||
|
DomainID string `json:"domain_id,omitempty"`
|
||||||
|
|
||||||
|
// Extra is free-form extra key/value pairs to describe the group.
|
||||||
|
Extra map[string]interface{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToGroupCreateMap formats a CreateOpts into a create request.
|
||||||
|
func (opts CreateOpts) ToGroupCreateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "group")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Extra != nil {
|
||||||
|
if v, ok := b["group"].(map[string]interface{}); ok {
|
||||||
|
for key, value := range opts.Extra {
|
||||||
|
v[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new Group.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToGroupCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(createURL(client), &b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{201},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Update request.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToGroupUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOpts provides options for updating a group.
|
||||||
|
type UpdateOpts struct {
|
||||||
|
// Name is the name of the new group.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// Description is a description of the group.
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// DomainID is the ID of the domain the group belongs to.
|
||||||
|
DomainID string `json:"domain_id,omitempty"`
|
||||||
|
|
||||||
|
// Extra is free-form extra key/value pairs to describe the group.
|
||||||
|
Extra map[string]interface{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToGroupUpdateMap formats a UpdateOpts into an update request.
|
||||||
|
func (opts UpdateOpts) ToGroupUpdateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "group")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Extra != nil {
|
||||||
|
if v, ok := b["group"].(map[string]interface{}); ok {
|
||||||
|
for key, value := range opts.Extra {
|
||||||
|
v[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates an existing Group.
|
||||||
|
func Update(client *gophercloud.ServiceClient, groupID string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
b, err := opts.ToGroupUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Patch(updateURL(client, groupID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a group.
|
||||||
|
func Delete(client *gophercloud.ServiceClient, groupID string) (r DeleteResult) {
|
||||||
|
_, r.Err = client.Delete(deleteURL(client, groupID), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
24
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/results.go
generated
vendored
24
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/results.go
generated
vendored
|
|
@ -63,6 +63,30 @@ type groupResult struct {
|
||||||
gophercloud.Result
|
gophercloud.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetResult is the response from a Get operation. Call its Extract method
|
||||||
|
// to interpret it as a Group.
|
||||||
|
type GetResult struct {
|
||||||
|
groupResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
|
// to interpret it as a Group.
|
||||||
|
type CreateResult struct {
|
||||||
|
groupResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult is the response from an Update operation. Call its Extract
|
||||||
|
// method to interpret it as a Group.
|
||||||
|
type UpdateResult struct {
|
||||||
|
groupResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr to
|
||||||
|
// determine if the request succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
// GroupPage is a single page of Group results.
|
// GroupPage is a single page of Group results.
|
||||||
type GroupPage struct {
|
type GroupPage struct {
|
||||||
pagination.LinkedPageBase
|
pagination.LinkedPageBase
|
||||||
|
|
|
||||||
216
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/testing/fixtures.go
generated
vendored
Normal file
216
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/testing/fixtures.go
generated
vendored
Normal file
|
|
@ -0,0 +1,216 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOutput provides a single page of Group results.
|
||||||
|
const ListOutput = `
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"next": null,
|
||||||
|
"previous": null,
|
||||||
|
"self": "http://example.com/identity/v3/groups"
|
||||||
|
},
|
||||||
|
"groups": [
|
||||||
|
{
|
||||||
|
"domain_id": "default",
|
||||||
|
"id": "2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
"description": "group for internal support users",
|
||||||
|
"links": {
|
||||||
|
"self": "http://example.com/identity/v3/groups/2844b2a08be147a08ef58317d6471f1f"
|
||||||
|
},
|
||||||
|
"name": "internal support",
|
||||||
|
"extra": {
|
||||||
|
"email": "support@localhost"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"description": "group for support users",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/groups/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "support",
|
||||||
|
"extra": {
|
||||||
|
"email": "support@example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// GetOutput provides a Get result.
|
||||||
|
const GetOutput = `
|
||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"description": "group for support users",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/groups/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "support",
|
||||||
|
"extra": {
|
||||||
|
"email": "support@example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// CreateRequest provides the input to a Create request.
|
||||||
|
const CreateRequest = `
|
||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"name": "support",
|
||||||
|
"description": "group for support users",
|
||||||
|
"email": "support@example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// UpdateRequest provides the input to as Update request.
|
||||||
|
const UpdateRequest = `
|
||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"description": "L2 Support Team",
|
||||||
|
"email": "supportteam@example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// UpdateOutput provides an update result.
|
||||||
|
const UpdateOutput = `
|
||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/groups/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "support",
|
||||||
|
"description": "L2 Support Team",
|
||||||
|
"extra": {
|
||||||
|
"email": "supportteam@example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// FirstGroup is the first group in the List request.
|
||||||
|
var FirstGroup = groups.Group{
|
||||||
|
DomainID: "default",
|
||||||
|
ID: "2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "http://example.com/identity/v3/groups/2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
},
|
||||||
|
Name: "internal support",
|
||||||
|
Description: "group for internal support users",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "support@localhost",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecondGroup is the second group in the List request.
|
||||||
|
var SecondGroup = groups.Group{
|
||||||
|
DomainID: "1789d1",
|
||||||
|
ID: "9fe1d3",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "https://example.com/identity/v3/groups/9fe1d3",
|
||||||
|
},
|
||||||
|
Name: "support",
|
||||||
|
Description: "group for support users",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "support@example.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecondGroupUpdated is how SecondGroup should look after an Update.
|
||||||
|
var SecondGroupUpdated = groups.Group{
|
||||||
|
DomainID: "1789d1",
|
||||||
|
ID: "9fe1d3",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "https://example.com/identity/v3/groups/9fe1d3",
|
||||||
|
},
|
||||||
|
Name: "support",
|
||||||
|
Description: "L2 Support Team",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "supportteam@example.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpectedGroupsSlice is the slice of groups expected to be returned from ListOutput.
|
||||||
|
var ExpectedGroupsSlice = []groups.Group{FirstGroup, SecondGroup}
|
||||||
|
|
||||||
|
// HandleListGroupsSuccessfully creates an HTTP handler at `/groups` on the
|
||||||
|
// test handler mux that responds with a list of two groups.
|
||||||
|
func HandleListGroupsSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/groups", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, ListOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleGetGroupSuccessfully creates an HTTP handler at `/groups` on the
|
||||||
|
// test handler mux that responds with a single group.
|
||||||
|
func HandleGetGroupSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, GetOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCreateGroupSuccessfully creates an HTTP handler at `/groups` on the
|
||||||
|
// test handler mux that tests group creation.
|
||||||
|
func HandleCreateGroupSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/groups", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, CreateRequest)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
fmt.Fprintf(w, GetOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleUpdateGroupSuccessfully creates an HTTP handler at `/groups` on the
|
||||||
|
// test handler mux that tests group update.
|
||||||
|
func HandleUpdateGroupSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "PATCH")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, UpdateRequest)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, UpdateOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleDeleteGroupSuccessfully creates an HTTP handler at `/groups` on the
|
||||||
|
// test handler mux that tests group deletion.
|
||||||
|
func HandleDeleteGroupSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/groups/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "DELETE")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
}
|
||||||
101
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/testing/requests_test.go
generated
vendored
Normal file
101
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/testing/requests_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestListGroups(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListGroupsSuccessfully(t)
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
err := groups.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) {
|
||||||
|
count++
|
||||||
|
|
||||||
|
actual, err := groups.ExtractGroups(page)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
th.CheckDeepEquals(t, ExpectedGroupsSlice, actual)
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckEquals(t, count, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListGroupsAllPages(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListGroupsSuccessfully(t)
|
||||||
|
|
||||||
|
allPages, err := groups.List(client.ServiceClient(), nil).AllPages()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
actual, err := groups.ExtractGroups(allPages)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, ExpectedGroupsSlice, actual)
|
||||||
|
th.AssertEquals(t, ExpectedGroupsSlice[0].Extra["email"], "support@localhost")
|
||||||
|
th.AssertEquals(t, ExpectedGroupsSlice[1].Extra["email"], "support@example.com")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetGroup(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleGetGroupSuccessfully(t)
|
||||||
|
|
||||||
|
actual, err := groups.Get(client.ServiceClient(), "9fe1d3").Extract()
|
||||||
|
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondGroup, *actual)
|
||||||
|
th.AssertEquals(t, SecondGroup.Extra["email"], "support@example.com")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateGroup(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleCreateGroupSuccessfully(t)
|
||||||
|
|
||||||
|
createOpts := groups.CreateOpts{
|
||||||
|
Name: "support",
|
||||||
|
DomainID: "1789d1",
|
||||||
|
Description: "group for support users",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "support@example.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := groups.Create(client.ServiceClient(), createOpts).Extract()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondGroup, *actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateGroup(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleUpdateGroupSuccessfully(t)
|
||||||
|
|
||||||
|
updateOpts := groups.UpdateOpts{
|
||||||
|
Description: "L2 Support Team",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"email": "supportteam@example.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := groups.Update(client.ServiceClient(), "9fe1d3", updateOpts).Extract()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondGroupUpdated, *actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteGroup(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleDeleteGroupSuccessfully(t)
|
||||||
|
|
||||||
|
res := groups.Delete(client.ServiceClient(), "9fe1d3")
|
||||||
|
th.AssertNoErr(t, res.Err)
|
||||||
|
}
|
||||||
23
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/urls.go
generated
vendored
Normal file
23
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/groups/urls.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package groups
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func listURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL("groups")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getURL(client *gophercloud.ServiceClient, groupID string) string {
|
||||||
|
return client.ServiceURL("groups", groupID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL("groups")
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateURL(client *gophercloud.ServiceClient, groupID string) string {
|
||||||
|
return client.ServiceURL("groups", groupID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteURL(client *gophercloud.ServiceClient, groupID string) string {
|
||||||
|
return client.ServiceURL("groups", groupID)
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,62 @@
|
||||||
Package roles provides information and interaction with the roles API
|
Package roles provides information and interaction with the roles API
|
||||||
resource for the OpenStack Identity service.
|
resource for the OpenStack Identity service.
|
||||||
|
|
||||||
|
Example to List Roles
|
||||||
|
|
||||||
|
listOpts := roles.ListOpts{
|
||||||
|
DomainID: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := roles.List(identityClient, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoles, err := roles.ExtractRoles(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, role := range allRoles {
|
||||||
|
fmt.Printf("%+v\n", role)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Create a Role
|
||||||
|
|
||||||
|
createOpts := roles.CreateOpts{
|
||||||
|
Name: "read-only-admin",
|
||||||
|
DomainID: "default",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"description": "this role grants read-only privilege cross tenant",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
role, err := roles.Create(identityClient, createOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Update a Role
|
||||||
|
|
||||||
|
roleID := "0fe36e73809d46aeae6705c39077b1b3"
|
||||||
|
|
||||||
|
updateOpts := roles.UpdateOpts{
|
||||||
|
Name: "read only admin",
|
||||||
|
}
|
||||||
|
|
||||||
|
role, err := roles.Update(identityClient, roleID, updateOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Delete a Role
|
||||||
|
|
||||||
|
roleID := "0fe36e73809d46aeae6705c39077b1b3"
|
||||||
|
err := roles.Delete(identityClient, roleID).ExtractErr()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
Example to List Role Assignments
|
Example to List Role Assignments
|
||||||
|
|
||||||
listOpts := roles.ListAssignmentsOpts{
|
listOpts := roles.ListAssignmentsOpts{
|
||||||
|
|
@ -22,5 +78,35 @@ Example to List Role Assignments
|
||||||
for _, role := range allRoles {
|
for _, role := range allRoles {
|
||||||
fmt.Printf("%+v\n", role)
|
fmt.Printf("%+v\n", role)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Example to Assign a Role to a User in a Project
|
||||||
|
|
||||||
|
projectID := "a99e9b4e620e4db09a2dfb6e42a01e66"
|
||||||
|
userID := "9df1a02f5eb2416a9781e8b0c022d3ae"
|
||||||
|
roleID := "9fe2ff9ee4384b1894a90878d3e92bab"
|
||||||
|
|
||||||
|
err := roles.Assign(identityClient, roleID, roles.AssignOpts{
|
||||||
|
UserID: userID,
|
||||||
|
ProjectID: projectID,
|
||||||
|
}).ExtractErr()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to Unassign a Role From a User in a Project
|
||||||
|
|
||||||
|
projectID := "a99e9b4e620e4db09a2dfb6e42a01e66"
|
||||||
|
userID := "9df1a02f5eb2416a9781e8b0c022d3ae"
|
||||||
|
roleID := "9fe2ff9ee4384b1894a90878d3e92bab"
|
||||||
|
|
||||||
|
err := roles.Unassign(identityClient, roleID, roles.UnassignOpts{
|
||||||
|
UserID: userID,
|
||||||
|
ProjectID: projectID,
|
||||||
|
}).ExtractErr()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
package roles
|
package roles
|
||||||
|
|
|
||||||
256
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/roles/requests.go
generated
vendored
256
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/roles/requests.go
generated
vendored
|
|
@ -5,6 +5,150 @@ import (
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ListOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the List request
|
||||||
|
type ListOptsBuilder interface {
|
||||||
|
ToRoleListQuery() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOpts provides options to filter the List results.
|
||||||
|
type ListOpts struct {
|
||||||
|
// DomainID filters the response by a domain ID.
|
||||||
|
DomainID string `q:"domain_id"`
|
||||||
|
|
||||||
|
// Name filters the response by role name.
|
||||||
|
Name string `q:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRoleListQuery formats a ListOpts into a query string.
|
||||||
|
func (opts ListOpts) ToRoleListQuery() (string, error) {
|
||||||
|
q, err := gophercloud.BuildQueryString(opts)
|
||||||
|
return q.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// List enumerates the roles to which the current token has access.
|
||||||
|
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := listURL(client)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToRoleListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return RolePage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves details on a single role, by ID.
|
||||||
|
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
|
||||||
|
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Create request.
|
||||||
|
type CreateOptsBuilder interface {
|
||||||
|
ToRoleCreateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOpts provides options used to create a role.
|
||||||
|
type CreateOpts struct {
|
||||||
|
// Name is the name of the new role.
|
||||||
|
Name string `json:"name" required:"true"`
|
||||||
|
|
||||||
|
// DomainID is the ID of the domain the role belongs to.
|
||||||
|
DomainID string `json:"domain_id,omitempty"`
|
||||||
|
|
||||||
|
// Extra is free-form extra key/value pairs to describe the role.
|
||||||
|
Extra map[string]interface{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRoleCreateMap formats a CreateOpts into a create request.
|
||||||
|
func (opts CreateOpts) ToRoleCreateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "role")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Extra != nil {
|
||||||
|
if v, ok := b["role"].(map[string]interface{}); ok {
|
||||||
|
for key, value := range opts.Extra {
|
||||||
|
v[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new Role.
|
||||||
|
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||||
|
b, err := opts.ToRoleCreateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Post(createURL(client), &b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{201},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOptsBuilder allows extensions to add additional parameters to
|
||||||
|
// the Update request.
|
||||||
|
type UpdateOptsBuilder interface {
|
||||||
|
ToRoleUpdateMap() (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOpts provides options for updating a role.
|
||||||
|
type UpdateOpts struct {
|
||||||
|
// Name is the name of the new role.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
|
||||||
|
// Extra is free-form extra key/value pairs to describe the role.
|
||||||
|
Extra map[string]interface{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRoleUpdateMap formats a UpdateOpts into an update request.
|
||||||
|
func (opts UpdateOpts) ToRoleUpdateMap() (map[string]interface{}, error) {
|
||||||
|
b, err := gophercloud.BuildRequestBody(opts, "role")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Extra != nil {
|
||||||
|
if v, ok := b["role"].(map[string]interface{}); ok {
|
||||||
|
for key, value := range opts.Extra {
|
||||||
|
v[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates an existing Role.
|
||||||
|
func Update(client *gophercloud.ServiceClient, roleID string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||||
|
b, err := opts.ToRoleUpdateMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, r.Err = client.Patch(updateURL(client, roleID), &b, &r.Body, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a role.
|
||||||
|
func Delete(client *gophercloud.ServiceClient, roleID string) (r DeleteResult) {
|
||||||
|
_, r.Err = client.Delete(deleteURL(client, roleID), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ListAssignmentsOptsBuilder allows extensions to add additional parameters to
|
// ListAssignmentsOptsBuilder allows extensions to add additional parameters to
|
||||||
// the ListAssignments request.
|
// the ListAssignments request.
|
||||||
type ListAssignmentsOptsBuilder interface {
|
type ListAssignmentsOptsBuilder interface {
|
||||||
|
|
@ -56,3 +200,115 @@ func ListAssignments(client *gophercloud.ServiceClient, opts ListAssignmentsOpts
|
||||||
return RoleAssignmentPage{pagination.LinkedPageBase{PageResult: r}}
|
return RoleAssignmentPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AssignOpts provides options to assign a role
|
||||||
|
type AssignOpts struct {
|
||||||
|
// UserID is the ID of a user to assign a role
|
||||||
|
// Note: exactly one of UserID or GroupID must be provided
|
||||||
|
UserID string `xor:"GroupID"`
|
||||||
|
|
||||||
|
// GroupID is the ID of a group to assign a role
|
||||||
|
// Note: exactly one of UserID or GroupID must be provided
|
||||||
|
GroupID string `xor:"UserID"`
|
||||||
|
|
||||||
|
// ProjectID is the ID of a project to assign a role on
|
||||||
|
// Note: exactly one of ProjectID or DomainID must be provided
|
||||||
|
ProjectID string `xor:"DomainID"`
|
||||||
|
|
||||||
|
// DomainID is the ID of a domain to assign a role on
|
||||||
|
// Note: exactly one of ProjectID or DomainID must be provided
|
||||||
|
DomainID string `xor:"ProjectID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnassignOpts provides options to unassign a role
|
||||||
|
type UnassignOpts struct {
|
||||||
|
// UserID is the ID of a user to unassign a role
|
||||||
|
// Note: exactly one of UserID or GroupID must be provided
|
||||||
|
UserID string `xor:"GroupID"`
|
||||||
|
|
||||||
|
// GroupID is the ID of a group to unassign a role
|
||||||
|
// Note: exactly one of UserID or GroupID must be provided
|
||||||
|
GroupID string `xor:"UserID"`
|
||||||
|
|
||||||
|
// ProjectID is the ID of a project to unassign a role on
|
||||||
|
// Note: exactly one of ProjectID or DomainID must be provided
|
||||||
|
ProjectID string `xor:"DomainID"`
|
||||||
|
|
||||||
|
// DomainID is the ID of a domain to unassign a role on
|
||||||
|
// Note: exactly one of ProjectID or DomainID must be provided
|
||||||
|
DomainID string `xor:"ProjectID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign is the operation responsible for assigning a role
|
||||||
|
// to a user/group on a project/domain.
|
||||||
|
func Assign(client *gophercloud.ServiceClient, roleID string, opts AssignOpts) (r AssignmentResult) {
|
||||||
|
// Check xor conditions
|
||||||
|
_, err := gophercloud.BuildRequestBody(opts, "")
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get corresponding URL
|
||||||
|
var targetID string
|
||||||
|
var targetType string
|
||||||
|
if opts.ProjectID != "" {
|
||||||
|
targetID = opts.ProjectID
|
||||||
|
targetType = "projects"
|
||||||
|
} else {
|
||||||
|
targetID = opts.DomainID
|
||||||
|
targetType = "domains"
|
||||||
|
}
|
||||||
|
|
||||||
|
var actorID string
|
||||||
|
var actorType string
|
||||||
|
if opts.UserID != "" {
|
||||||
|
actorID = opts.UserID
|
||||||
|
actorType = "users"
|
||||||
|
} else {
|
||||||
|
actorID = opts.GroupID
|
||||||
|
actorType = "groups"
|
||||||
|
}
|
||||||
|
|
||||||
|
_, r.Err = client.Put(assignURL(client, targetType, targetID, actorType, actorID, roleID), nil, nil, &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{204},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unassign is the operation responsible for unassigning a role
|
||||||
|
// from a user/group on a project/domain.
|
||||||
|
func Unassign(client *gophercloud.ServiceClient, roleID string, opts UnassignOpts) (r UnassignmentResult) {
|
||||||
|
// Check xor conditions
|
||||||
|
_, err := gophercloud.BuildRequestBody(opts, "")
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get corresponding URL
|
||||||
|
var targetID string
|
||||||
|
var targetType string
|
||||||
|
if opts.ProjectID != "" {
|
||||||
|
targetID = opts.ProjectID
|
||||||
|
targetType = "projects"
|
||||||
|
} else {
|
||||||
|
targetID = opts.DomainID
|
||||||
|
targetType = "domains"
|
||||||
|
}
|
||||||
|
|
||||||
|
var actorID string
|
||||||
|
var actorType string
|
||||||
|
if opts.UserID != "" {
|
||||||
|
actorID = opts.UserID
|
||||||
|
actorType = "users"
|
||||||
|
} else {
|
||||||
|
actorID = opts.GroupID
|
||||||
|
actorType = "groups"
|
||||||
|
}
|
||||||
|
|
||||||
|
_, r.Err = client.Delete(assignURL(client, targetType, targetID, actorType, actorID, roleID), &gophercloud.RequestOpts{
|
||||||
|
OkCodes: []int{204},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
153
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/roles/results.go
generated
vendored
153
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/roles/results.go
generated
vendored
|
|
@ -1,17 +1,144 @@
|
||||||
package roles
|
package roles
|
||||||
|
|
||||||
import "github.com/gophercloud/gophercloud/pagination"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/internal"
|
||||||
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Role grants permissions to a user.
|
||||||
|
type Role struct {
|
||||||
|
// DomainID is the domain ID the role belongs to.
|
||||||
|
DomainID string `json:"domain_id"`
|
||||||
|
|
||||||
|
// ID is the unique ID of the role.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// Links contains referencing links to the role.
|
||||||
|
Links map[string]interface{} `json:"links"`
|
||||||
|
|
||||||
|
// Name is the role name
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Extra is a collection of miscellaneous key/values.
|
||||||
|
Extra map[string]interface{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Role) UnmarshalJSON(b []byte) error {
|
||||||
|
type tmp Role
|
||||||
|
var s struct {
|
||||||
|
tmp
|
||||||
|
Extra map[string]interface{} `json:"extra"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*r = Role(s.tmp)
|
||||||
|
|
||||||
|
// Collect other fields and bundle them into Extra
|
||||||
|
// but only if a field titled "extra" wasn't sent.
|
||||||
|
if s.Extra != nil {
|
||||||
|
r.Extra = s.Extra
|
||||||
|
} else {
|
||||||
|
var result interface{}
|
||||||
|
err := json.Unmarshal(b, &result)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resultMap, ok := result.(map[string]interface{}); ok {
|
||||||
|
r.Extra = internal.RemainingKeys(Role{}, resultMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type roleResult struct {
|
||||||
|
gophercloud.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResult is the response from a Get operation. Call its Extract method
|
||||||
|
// to interpret it as a Role.
|
||||||
|
type GetResult struct {
|
||||||
|
roleResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateResult is the response from a Create operation. Call its Extract method
|
||||||
|
// to interpret it as a Role
|
||||||
|
type CreateResult struct {
|
||||||
|
roleResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResult is the response from an Update operation. Call its Extract
|
||||||
|
// method to interpret it as a Role.
|
||||||
|
type UpdateResult struct {
|
||||||
|
roleResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr to
|
||||||
|
// determine if the request succeeded or failed.
|
||||||
|
type DeleteResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// RolePage is a single page of Role results.
|
||||||
|
type RolePage struct {
|
||||||
|
pagination.LinkedPageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty determines whether or not a page of Roles contains any results.
|
||||||
|
func (r RolePage) IsEmpty() (bool, error) {
|
||||||
|
roles, err := ExtractRoles(r)
|
||||||
|
return len(roles) == 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextPageURL extracts the "next" link from the links section of the result.
|
||||||
|
func (r RolePage) NextPageURL() (string, error) {
|
||||||
|
var s struct {
|
||||||
|
Links struct {
|
||||||
|
Next string `json:"next"`
|
||||||
|
Previous string `json:"previous"`
|
||||||
|
} `json:"links"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return s.Links.Next, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractProjects returns a slice of Roles contained in a single page of
|
||||||
|
// results.
|
||||||
|
func ExtractRoles(r pagination.Page) ([]Role, error) {
|
||||||
|
var s struct {
|
||||||
|
Roles []Role `json:"roles"`
|
||||||
|
}
|
||||||
|
err := (r.(RolePage)).ExtractInto(&s)
|
||||||
|
return s.Roles, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract interprets any roleResults as a Role.
|
||||||
|
func (r roleResult) Extract() (*Role, error) {
|
||||||
|
var s struct {
|
||||||
|
Role *Role `json:"role"`
|
||||||
|
}
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s.Role, err
|
||||||
|
}
|
||||||
|
|
||||||
// RoleAssignment is the result of a role assignments query.
|
// RoleAssignment is the result of a role assignments query.
|
||||||
type RoleAssignment struct {
|
type RoleAssignment struct {
|
||||||
Role Role `json:"role,omitempty"`
|
Role AssignedRole `json:"role,omitempty"`
|
||||||
Scope Scope `json:"scope,omitempty"`
|
Scope Scope `json:"scope,omitempty"`
|
||||||
User User `json:"user,omitempty"`
|
User User `json:"user,omitempty"`
|
||||||
Group Group `json:"group,omitempty"`
|
Group Group `json:"group,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Role represents a Role in an assignment.
|
// AssignedRole represents a Role in an assignment.
|
||||||
type Role struct {
|
type AssignedRole struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,3 +200,15 @@ func ExtractRoleAssignments(r pagination.Page) ([]RoleAssignment, error) {
|
||||||
err := (r.(RoleAssignmentPage)).ExtractInto(&s)
|
err := (r.(RoleAssignmentPage)).ExtractInto(&s)
|
||||||
return s.RoleAssignments, err
|
return s.RoleAssignments, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AssignmentResult represents the result of an assign operation.
|
||||||
|
// Call ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type AssignmentResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnassignmentResult represents the result of an unassign operation.
|
||||||
|
// Call ExtractErr method to determine if the request succeeded or failed.
|
||||||
|
type UnassignmentResult struct {
|
||||||
|
gophercloud.ErrResult
|
||||||
|
}
|
||||||
|
|
|
||||||
333
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/roles/testing/fixtures.go
generated
vendored
Normal file
333
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/roles/testing/fixtures.go
generated
vendored
Normal file
|
|
@ -0,0 +1,333 @@
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/roles"
|
||||||
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
fake "github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOutput provides a single page of Role results.
|
||||||
|
const ListOutput = `
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"next": null,
|
||||||
|
"previous": null,
|
||||||
|
"self": "http://example.com/identity/v3/roles"
|
||||||
|
},
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"domain_id": "default",
|
||||||
|
"id": "2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
"links": {
|
||||||
|
"self": "http://example.com/identity/v3/roles/2844b2a08be147a08ef58317d6471f1f"
|
||||||
|
},
|
||||||
|
"name": "admin-read-only"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/roles/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "support",
|
||||||
|
"extra": {
|
||||||
|
"description": "read-only support role"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// GetOutput provides a Get result.
|
||||||
|
const GetOutput = `
|
||||||
|
{
|
||||||
|
"role": {
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/roles/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "support",
|
||||||
|
"extra": {
|
||||||
|
"description": "read-only support role"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// CreateRequest provides the input to a Create request.
|
||||||
|
const CreateRequest = `
|
||||||
|
{
|
||||||
|
"role": {
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"name": "support",
|
||||||
|
"description": "read-only support role"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// UpdateRequest provides the input to as Update request.
|
||||||
|
const UpdateRequest = `
|
||||||
|
{
|
||||||
|
"role": {
|
||||||
|
"description": "admin read-only support role"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// UpdateOutput provides an update result.
|
||||||
|
const UpdateOutput = `
|
||||||
|
{
|
||||||
|
"role": {
|
||||||
|
"domain_id": "1789d1",
|
||||||
|
"id": "9fe1d3",
|
||||||
|
"links": {
|
||||||
|
"self": "https://example.com/identity/v3/roles/9fe1d3"
|
||||||
|
},
|
||||||
|
"name": "support",
|
||||||
|
"extra": {
|
||||||
|
"description": "admin read-only support role"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const ListAssignmentOutput = `
|
||||||
|
{
|
||||||
|
"role_assignments": [
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"assignment": "http://identity:35357/v3/domains/161718/users/313233/roles/123456"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"id": "123456"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"domain": {
|
||||||
|
"id": "161718"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"id": "313233"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"assignment": "http://identity:35357/v3/projects/456789/groups/101112/roles/123456",
|
||||||
|
"membership": "http://identity:35357/v3/groups/101112/users/313233"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"id": "123456"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"project": {
|
||||||
|
"id": "456789"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"id": "313233"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": {
|
||||||
|
"self": "http://identity:35357/v3/role_assignments?effective",
|
||||||
|
"previous": null,
|
||||||
|
"next": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// FirstRole is the first role in the List request.
|
||||||
|
var FirstRole = roles.Role{
|
||||||
|
DomainID: "default",
|
||||||
|
ID: "2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "http://example.com/identity/v3/roles/2844b2a08be147a08ef58317d6471f1f",
|
||||||
|
},
|
||||||
|
Name: "admin-read-only",
|
||||||
|
Extra: map[string]interface{}{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecondRole is the second role in the List request.
|
||||||
|
var SecondRole = roles.Role{
|
||||||
|
DomainID: "1789d1",
|
||||||
|
ID: "9fe1d3",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "https://example.com/identity/v3/roles/9fe1d3",
|
||||||
|
},
|
||||||
|
Name: "support",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"description": "read-only support role",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecondRoleUpdated is how SecondRole should look after an Update.
|
||||||
|
var SecondRoleUpdated = roles.Role{
|
||||||
|
DomainID: "1789d1",
|
||||||
|
ID: "9fe1d3",
|
||||||
|
Links: map[string]interface{}{
|
||||||
|
"self": "https://example.com/identity/v3/roles/9fe1d3",
|
||||||
|
},
|
||||||
|
Name: "support",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"description": "admin read-only support role",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpectedRolesSlice is the slice of roles expected to be returned from ListOutput.
|
||||||
|
var ExpectedRolesSlice = []roles.Role{FirstRole, SecondRole}
|
||||||
|
|
||||||
|
// HandleListRolesSuccessfully creates an HTTP handler at `/roles` on the
|
||||||
|
// test handler mux that responds with a list of two roles.
|
||||||
|
func HandleListRolesSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, ListOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleGetRoleSuccessfully creates an HTTP handler at `/roles` on the
|
||||||
|
// test handler mux that responds with a single role.
|
||||||
|
func HandleGetRoleSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, GetOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCreateRoleSuccessfully creates an HTTP handler at `/roles` on the
|
||||||
|
// test handler mux that tests role creation.
|
||||||
|
func HandleCreateRoleSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/roles", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "POST")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, CreateRequest)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
fmt.Fprintf(w, GetOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleUpdateRoleSuccessfully creates an HTTP handler at `/roles` on the
|
||||||
|
// test handler mux that tests role update.
|
||||||
|
func HandleUpdateRoleSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "PATCH")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
th.TestJSONRequest(t, r, UpdateRequest)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, UpdateOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleDeleteRoleSuccessfully creates an HTTP handler at `/roles` on the
|
||||||
|
// test handler mux that tests role deletion.
|
||||||
|
func HandleDeleteRoleSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/roles/9fe1d3", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "DELETE")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleAssignSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "PUT")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "PUT")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "PUT")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "PUT")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleUnassignSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/projects/{project_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "DELETE")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
th.Mux.HandleFunc("/projects/{project_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "DELETE")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
th.Mux.HandleFunc("/domains/{domain_id}/users/{user_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "DELETE")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
th.Mux.HandleFunc("/domains/{domain_id}/groups/{group_id}/roles/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "DELETE")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstRoleAssignment is the first role assignment in the List request.
|
||||||
|
var FirstRoleAssignment = roles.RoleAssignment{
|
||||||
|
Role: roles.AssignedRole{ID: "123456"},
|
||||||
|
Scope: roles.Scope{Domain: roles.Domain{ID: "161718"}},
|
||||||
|
User: roles.User{ID: "313233"},
|
||||||
|
Group: roles.Group{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecondRoleAssignemnt is the second role assignemnt in the List request.
|
||||||
|
var SecondRoleAssignment = roles.RoleAssignment{
|
||||||
|
Role: roles.AssignedRole{ID: "123456"},
|
||||||
|
Scope: roles.Scope{Project: roles.Project{ID: "456789"}},
|
||||||
|
User: roles.User{ID: "313233"},
|
||||||
|
Group: roles.Group{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpectedRoleAssignmentsSlice is the slice of role assignments expected to be
|
||||||
|
// returned from ListAssignmentOutput.
|
||||||
|
var ExpectedRoleAssignmentsSlice = []roles.RoleAssignment{FirstRoleAssignment, SecondRoleAssignment}
|
||||||
|
|
||||||
|
// HandleListRoleAssignmentsSuccessfully creates an HTTP handler at `/role_assignments` on the
|
||||||
|
// test handler mux that responds with a list of two role assignments.
|
||||||
|
func HandleListRoleAssignmentsSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, ListAssignmentOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -1,105 +1,176 @@
|
||||||
package testing
|
package testing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/roles"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/roles"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
"github.com/gophercloud/gophercloud/testhelper"
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
"github.com/gophercloud/gophercloud/testhelper/client"
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestListSinglePage(t *testing.T) {
|
func TestListRoles(t *testing.T) {
|
||||||
testhelper.SetupHTTP()
|
th.SetupHTTP()
|
||||||
defer testhelper.TeardownHTTP()
|
defer th.TeardownHTTP()
|
||||||
|
HandleListRolesSuccessfully(t)
|
||||||
|
|
||||||
testhelper.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) {
|
count := 0
|
||||||
testhelper.TestMethod(t, r, "GET")
|
err := roles.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) {
|
||||||
testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
count++
|
||||||
|
|
||||||
w.Header().Add("Content-Type", "application/json")
|
actual, err := roles.ExtractRoles(page)
|
||||||
fmt.Fprintf(w, `
|
th.AssertNoErr(t, err)
|
||||||
{
|
|
||||||
"role_assignments": [
|
th.CheckDeepEquals(t, ExpectedRolesSlice, actual)
|
||||||
{
|
|
||||||
"links": {
|
return true, nil
|
||||||
"assignment": "http://identity:35357/v3/domains/161718/users/313233/roles/123456"
|
|
||||||
},
|
|
||||||
"role": {
|
|
||||||
"id": "123456"
|
|
||||||
},
|
|
||||||
"scope": {
|
|
||||||
"domain": {
|
|
||||||
"id": "161718"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"id": "313233"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"links": {
|
|
||||||
"assignment": "http://identity:35357/v3/projects/456789/groups/101112/roles/123456",
|
|
||||||
"membership": "http://identity:35357/v3/groups/101112/users/313233"
|
|
||||||
},
|
|
||||||
"role": {
|
|
||||||
"id": "123456"
|
|
||||||
},
|
|
||||||
"scope": {
|
|
||||||
"project": {
|
|
||||||
"id": "456789"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"id": "313233"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"links": {
|
|
||||||
"self": "http://identity:35357/v3/role_assignments?effective",
|
|
||||||
"previous": null,
|
|
||||||
"next": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
})
|
})
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckEquals(t, count, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListRolesAllPages(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListRolesSuccessfully(t)
|
||||||
|
|
||||||
|
allPages, err := roles.List(client.ServiceClient(), nil).AllPages()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
actual, err := roles.ExtractRoles(allPages)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, ExpectedRolesSlice, actual)
|
||||||
|
th.AssertEquals(t, ExpectedRolesSlice[1].Extra["description"], "read-only support role")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRole(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleGetRoleSuccessfully(t)
|
||||||
|
|
||||||
|
actual, err := roles.Get(client.ServiceClient(), "9fe1d3").Extract()
|
||||||
|
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondRole, *actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateRole(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleCreateRoleSuccessfully(t)
|
||||||
|
|
||||||
|
createOpts := roles.CreateOpts{
|
||||||
|
Name: "support",
|
||||||
|
DomainID: "1789d1",
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"description": "read-only support role",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := roles.Create(client.ServiceClient(), createOpts).Extract()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondRole, *actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateRole(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleUpdateRoleSuccessfully(t)
|
||||||
|
|
||||||
|
updateOpts := roles.UpdateOpts{
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
"description": "admin read-only support role",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := roles.Update(client.ServiceClient(), "9fe1d3", updateOpts).Extract()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, SecondRoleUpdated, *actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteRole(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleDeleteRoleSuccessfully(t)
|
||||||
|
|
||||||
|
res := roles.Delete(client.ServiceClient(), "9fe1d3")
|
||||||
|
th.AssertNoErr(t, res.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListAssignmentsSinglePage(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListRoleAssignmentsSuccessfully(t)
|
||||||
|
|
||||||
count := 0
|
count := 0
|
||||||
err := roles.ListAssignments(client.ServiceClient(), roles.ListAssignmentsOpts{}).EachPage(func(page pagination.Page) (bool, error) {
|
err := roles.ListAssignments(client.ServiceClient(), roles.ListAssignmentsOpts{}).EachPage(func(page pagination.Page) (bool, error) {
|
||||||
count++
|
count++
|
||||||
actual, err := roles.ExtractRoleAssignments(page)
|
actual, err := roles.ExtractRoleAssignments(page)
|
||||||
if err != nil {
|
th.AssertNoErr(t, err)
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := []roles.RoleAssignment{
|
th.CheckDeepEquals(t, ExpectedRoleAssignmentsSlice, actual)
|
||||||
{
|
|
||||||
Role: roles.Role{ID: "123456"},
|
|
||||||
Scope: roles.Scope{Domain: roles.Domain{ID: "161718"}},
|
|
||||||
User: roles.User{ID: "313233"},
|
|
||||||
Group: roles.Group{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Role: roles.Role{ID: "123456"},
|
|
||||||
Scope: roles.Scope{Project: roles.Project{ID: "456789"}},
|
|
||||||
User: roles.User{ID: "313233"},
|
|
||||||
Group: roles.Group{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(expected, actual) {
|
|
||||||
t.Errorf("Expected %#v, got %#v", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
th.AssertNoErr(t, err)
|
||||||
t.Errorf("Unexpected error while paging: %v", err)
|
th.CheckEquals(t, count, 1)
|
||||||
}
|
}
|
||||||
if count != 1 {
|
|
||||||
t.Errorf("Expected 1 page, got %d", count)
|
func TestAssign(t *testing.T) {
|
||||||
}
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleAssignSuccessfully(t)
|
||||||
|
|
||||||
|
err := roles.Assign(client.ServiceClient(), "{role_id}", roles.AssignOpts{
|
||||||
|
UserID: "{user_id}",
|
||||||
|
ProjectID: "{project_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
err = roles.Assign(client.ServiceClient(), "{role_id}", roles.AssignOpts{
|
||||||
|
UserID: "{user_id}",
|
||||||
|
DomainID: "{domain_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
err = roles.Assign(client.ServiceClient(), "{role_id}", roles.AssignOpts{
|
||||||
|
GroupID: "{group_id}",
|
||||||
|
ProjectID: "{project_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
err = roles.Assign(client.ServiceClient(), "{role_id}", roles.AssignOpts{
|
||||||
|
GroupID: "{group_id}",
|
||||||
|
DomainID: "{domain_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnassign(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleUnassignSuccessfully(t)
|
||||||
|
|
||||||
|
err := roles.Unassign(client.ServiceClient(), "{role_id}", roles.UnassignOpts{
|
||||||
|
UserID: "{user_id}",
|
||||||
|
ProjectID: "{project_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
err = roles.Unassign(client.ServiceClient(), "{role_id}", roles.UnassignOpts{
|
||||||
|
UserID: "{user_id}",
|
||||||
|
DomainID: "{domain_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
err = roles.Unassign(client.ServiceClient(), "{role_id}", roles.UnassignOpts{
|
||||||
|
GroupID: "{group_id}",
|
||||||
|
ProjectID: "{project_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
|
||||||
|
err = roles.Unassign(client.ServiceClient(), "{role_id}", roles.UnassignOpts{
|
||||||
|
GroupID: "{group_id}",
|
||||||
|
DomainID: "{domain_id}",
|
||||||
|
}).ExtractErr()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,34 @@ package roles
|
||||||
|
|
||||||
import "github.com/gophercloud/gophercloud"
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
const (
|
||||||
|
rolePath = "roles"
|
||||||
|
)
|
||||||
|
|
||||||
|
func listURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL(rolePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getURL(client *gophercloud.ServiceClient, roleID string) string {
|
||||||
|
return client.ServiceURL(rolePath, roleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createURL(client *gophercloud.ServiceClient) string {
|
||||||
|
return client.ServiceURL(rolePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateURL(client *gophercloud.ServiceClient, roleID string) string {
|
||||||
|
return client.ServiceURL(rolePath, roleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteURL(client *gophercloud.ServiceClient, roleID string) string {
|
||||||
|
return client.ServiceURL(rolePath, roleID)
|
||||||
|
}
|
||||||
|
|
||||||
func listAssignmentsURL(client *gophercloud.ServiceClient) string {
|
func listAssignmentsURL(client *gophercloud.ServiceClient) string {
|
||||||
return client.ServiceURL("role_assignments")
|
return client.ServiceURL("role_assignments")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assignURL(client *gophercloud.ServiceClient, targetType, targetID, actorType, actorID, roleID string) string {
|
||||||
|
return client.ServiceURL(targetType, targetID, actorType, actorID, rolePath, roleID)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ Example to List Groups a User Belongs To
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
allGroups, err := users.ExtractGroups(allPages)
|
allGroups, err := groups.ExtractGroups(allPages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -79,5 +79,45 @@ Example to List Groups a User Belongs To
|
||||||
for _, group := range allGroups {
|
for _, group := range allGroups {
|
||||||
fmt.Printf("%+v\n", group)
|
fmt.Printf("%+v\n", group)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Example to List Projects a User Belongs To
|
||||||
|
|
||||||
|
userID := "0fe36e73809d46aeae6705c39077b1b3"
|
||||||
|
|
||||||
|
allPages, err := users.ListProjects(identityClient, userID).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allProjects, err := projects.ExtractProjects(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, project := range allProjects {
|
||||||
|
fmt.Printf("%+v\n", project)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example to List Users in a Group
|
||||||
|
|
||||||
|
groupID := "bede500ee1124ae9b0006ff859758b3a"
|
||||||
|
listOpts := users.ListOpts{
|
||||||
|
DomainID: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := users.ListInGroup(identityClient, groupID, listOpts).AllPages()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allUsers, err := users.ExtractUsers(allPages)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range allUsers {
|
||||||
|
fmt.Printf("%+v\n", user)
|
||||||
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package users
|
package users
|
||||||
|
|
|
||||||
26
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/users/requests.go
generated
vendored
26
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/users/requests.go
generated
vendored
|
|
@ -3,6 +3,7 @@ package users
|
||||||
import (
|
import (
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -213,6 +214,29 @@ func Delete(client *gophercloud.ServiceClient, userID string) (r DeleteResult) {
|
||||||
func ListGroups(client *gophercloud.ServiceClient, userID string) pagination.Pager {
|
func ListGroups(client *gophercloud.ServiceClient, userID string) pagination.Pager {
|
||||||
url := listGroupsURL(client, userID)
|
url := listGroupsURL(client, userID)
|
||||||
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
return groups.GroupPage{pagination.LinkedPageBase{PageResult: r}}
|
return groups.GroupPage{LinkedPageBase: pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListProjects enumerates groups user belongs to.
|
||||||
|
func ListProjects(client *gophercloud.ServiceClient, userID string) pagination.Pager {
|
||||||
|
url := listProjectsURL(client, userID)
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return projects.ProjectPage{LinkedPageBase: pagination.LinkedPageBase{PageResult: r}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListInGroup enumerates users that belong to a group.
|
||||||
|
func ListInGroup(client *gophercloud.ServiceClient, groupID string, opts ListOptsBuilder) pagination.Pager {
|
||||||
|
url := listInGroupURL(client, groupID)
|
||||||
|
if opts != nil {
|
||||||
|
query, err := opts.ToUserListQuery()
|
||||||
|
if err != nil {
|
||||||
|
return pagination.Pager{Err: err}
|
||||||
|
}
|
||||||
|
url += query
|
||||||
|
}
|
||||||
|
return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
|
||||||
|
return UserPage{pagination.LinkedPageBase{PageResult: r}}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/users/results.go
generated
vendored
4
vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/users/results.go
generated
vendored
|
|
@ -98,8 +98,8 @@ type UpdateResult struct {
|
||||||
userResult
|
userResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResult is the response from a Delete operation. Call its ExtractErr
|
// DeleteResult is the response from a Delete operation. Call its ExtractErr to
|
||||||
// method to interpret it as a User.
|
// determine if the request succeeded or failed.
|
||||||
type DeleteResult struct {
|
type DeleteResult struct {
|
||||||
gophercloud.ErrResult
|
gophercloud.ErrResult
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
||||||
th "github.com/gophercloud/gophercloud/testhelper"
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
"github.com/gophercloud/gophercloud/testhelper/client"
|
"github.com/gophercloud/gophercloud/testhelper/client"
|
||||||
|
|
@ -195,6 +196,41 @@ const ListGroupsOutput = `
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
// ListProjectsOutput provides a ListProjects result.
|
||||||
|
const ListProjectsOutput = `
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"next": null,
|
||||||
|
"previous": null,
|
||||||
|
"self": "http://localhost:5000/identity/v3/users/foobar/projects"
|
||||||
|
},
|
||||||
|
"projects": [
|
||||||
|
{
|
||||||
|
"description": "my first project",
|
||||||
|
"domain_id": "11111",
|
||||||
|
"enabled": true,
|
||||||
|
"id": "abcde",
|
||||||
|
"links": {
|
||||||
|
"self": "http://localhost:5000/identity/v3/projects/abcde"
|
||||||
|
},
|
||||||
|
"name": "project 1",
|
||||||
|
"parent_id": "11111"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "my second project",
|
||||||
|
"domain_id": "22222",
|
||||||
|
"enabled": true,
|
||||||
|
"id": "bcdef",
|
||||||
|
"links": {
|
||||||
|
"self": "http://localhost:5000/identity/v3/projects/bcdef"
|
||||||
|
},
|
||||||
|
"name": "project 2",
|
||||||
|
"parent_id": "22222"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
// FirstUser is the first user in the List request.
|
// FirstUser is the first user in the List request.
|
||||||
var nilTime time.Time
|
var nilTime time.Time
|
||||||
var FirstUser = users.User{
|
var FirstUser = users.User{
|
||||||
|
|
@ -300,6 +336,26 @@ var SecondGroup = groups.Group{
|
||||||
|
|
||||||
var ExpectedGroupsSlice = []groups.Group{FirstGroup, SecondGroup}
|
var ExpectedGroupsSlice = []groups.Group{FirstGroup, SecondGroup}
|
||||||
|
|
||||||
|
var FirstProject = projects.Project{
|
||||||
|
Description: "my first project",
|
||||||
|
DomainID: "11111",
|
||||||
|
Enabled: true,
|
||||||
|
ID: "abcde",
|
||||||
|
Name: "project 1",
|
||||||
|
ParentID: "11111",
|
||||||
|
}
|
||||||
|
|
||||||
|
var SecondProject = projects.Project{
|
||||||
|
Description: "my second project",
|
||||||
|
DomainID: "22222",
|
||||||
|
Enabled: true,
|
||||||
|
ID: "bcdef",
|
||||||
|
Name: "project 2",
|
||||||
|
ParentID: "22222",
|
||||||
|
}
|
||||||
|
|
||||||
|
var ExpectedProjectsSlice = []projects.Project{FirstProject, SecondProject}
|
||||||
|
|
||||||
// HandleListUsersSuccessfully creates an HTTP handler at `/users` on the
|
// HandleListUsersSuccessfully creates an HTTP handler at `/users` on the
|
||||||
// test handler mux that responds with a list of two users.
|
// test handler mux that responds with a list of two users.
|
||||||
func HandleListUsersSuccessfully(t *testing.T) {
|
func HandleListUsersSuccessfully(t *testing.T) {
|
||||||
|
|
@ -379,7 +435,7 @@ func HandleDeleteUserSuccessfully(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleListUserGroupsSuccessfully creates an HTTP handler at /users/{userID}/groups
|
// HandleListUserGroupsSuccessfully creates an HTTP handler at /users/{userID}/groups
|
||||||
// on the test handler mux that respons wit a list of two groups
|
// on the test handler mux that respons with a list of two groups
|
||||||
func HandleListUserGroupsSuccessfully(t *testing.T) {
|
func HandleListUserGroupsSuccessfully(t *testing.T) {
|
||||||
th.Mux.HandleFunc("/users/9fe1d3/groups", func(w http.ResponseWriter, r *http.Request) {
|
th.Mux.HandleFunc("/users/9fe1d3/groups", func(w http.ResponseWriter, r *http.Request) {
|
||||||
th.TestMethod(t, r, "GET")
|
th.TestMethod(t, r, "GET")
|
||||||
|
|
@ -391,3 +447,31 @@ func HandleListUserGroupsSuccessfully(t *testing.T) {
|
||||||
fmt.Fprintf(w, ListGroupsOutput)
|
fmt.Fprintf(w, ListGroupsOutput)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleListUserProjectsSuccessfully creates an HTTP handler at /users/{userID}/projects
|
||||||
|
// on the test handler mux that respons wit a list of two projects
|
||||||
|
func HandleListUserProjectsSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/users/9fe1d3/projects", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, ListProjectsOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleListInGroupSuccessfully creates an HTTP handler at /groups/{groupID}/users
|
||||||
|
// on the test handler mux that response with a list of two users
|
||||||
|
func HandleListInGroupSuccessfully(t *testing.T) {
|
||||||
|
th.Mux.HandleFunc("/groups/ea167b/users", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
th.TestMethod(t, r, "GET")
|
||||||
|
th.TestHeader(t, r, "Accept", "application/json")
|
||||||
|
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, ListOutput)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
|
||||||
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
|
||||||
"github.com/gophercloud/gophercloud/pagination"
|
"github.com/gophercloud/gophercloud/pagination"
|
||||||
th "github.com/gophercloud/gophercloud/testhelper"
|
th "github.com/gophercloud/gophercloud/testhelper"
|
||||||
|
|
@ -146,3 +147,31 @@ func TestListUserGroups(t *testing.T) {
|
||||||
th.AssertNoErr(t, err)
|
th.AssertNoErr(t, err)
|
||||||
th.CheckDeepEquals(t, ExpectedGroupsSlice, actual)
|
th.CheckDeepEquals(t, ExpectedGroupsSlice, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListUserProjects(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListUserProjectsSuccessfully(t)
|
||||||
|
allPages, err := users.ListProjects(client.ServiceClient(), "9fe1d3").AllPages()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
actual, err := projects.ExtractProjects(allPages)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, ExpectedProjectsSlice, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListInGroup(t *testing.T) {
|
||||||
|
th.SetupHTTP()
|
||||||
|
defer th.TeardownHTTP()
|
||||||
|
HandleListInGroupSuccessfully(t)
|
||||||
|
|
||||||
|
iTrue := true
|
||||||
|
listOpts := users.ListOpts{
|
||||||
|
Enabled: &iTrue,
|
||||||
|
}
|
||||||
|
|
||||||
|
allPages, err := users.ListInGroup(client.ServiceClient(), "ea167b", listOpts).AllPages()
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
actual, err := users.ExtractUsers(allPages)
|
||||||
|
th.AssertNoErr(t, err)
|
||||||
|
th.CheckDeepEquals(t, ExpectedUsersSlice, actual)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,3 +25,11 @@ func deleteURL(client *gophercloud.ServiceClient, userID string) string {
|
||||||
func listGroupsURL(client *gophercloud.ServiceClient, userID string) string {
|
func listGroupsURL(client *gophercloud.ServiceClient, userID string) string {
|
||||||
return client.ServiceURL("users", userID, "groups")
|
return client.ServiceURL("users", userID, "groups")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func listProjectsURL(client *gophercloud.ServiceClient, userID string) string {
|
||||||
|
return client.ServiceURL("users", userID, "projects")
|
||||||
|
}
|
||||||
|
|
||||||
|
func listInGroupURL(client *gophercloud.ServiceClient, groupID string) string {
|
||||||
|
return client.ServiceURL("groups", groupID, "users")
|
||||||
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue