Add list options
diff --git a/rackspace/db/v1/instances/delegate.go b/rackspace/db/v1/instances/delegate.go
index 53d9289..40838f7 100644
--- a/rackspace/db/v1/instances/delegate.go
+++ b/rackspace/db/v1/instances/delegate.go
@@ -2,108 +2,9 @@
import (
"github.com/rackspace/gophercloud"
- osDBs "github.com/rackspace/gophercloud/openstack/db/v1/databases"
os "github.com/rackspace/gophercloud/openstack/db/v1/instances"
- osUsers "github.com/rackspace/gophercloud/openstack/db/v1/users"
- "github.com/rackspace/gophercloud/pagination"
)
-// CreateOpts is the struct responsible for configuring a new database instance.
-type CreateOpts struct {
- // Either the integer UUID (in string form) of the flavor, or its URI
- // reference as specified in the response from the List() call. Required.
- FlavorRef string
-
- // Specifies the volume size in gigabytes (GB). The value must be between 1
- // and 300. Required.
- Size int
-
- // Name of the instance to create. The length of the name is limited to
- // 255 characters and any characters are permitted. Optional.
- Name string
-
- // A slice of database information options.
- Databases osDBs.BatchCreateOpts
-
- // A slice of user information options.
- Users osUsers.BatchCreateOpts
-
- // ID of the configuration group to associate with the instance. Optional.
- ConfigID string
-
- // Options to configure the type of datastore the instance will use. This is
- // optional, and if excluded will default to MySQL.
- Datastore *os.DatastoreOpts
-
- // Specifies the backup ID from which to restore the database instance. There
- // are some things to be aware of before using this field. When you execute
- // the Restore Backup operation, a new database instance is created to store
- // the backup whose ID is specified by the restorePoint attribute. This will
- // mean that:
- // - All users, passwords and access that were on the instance at the time of
- // the backup will be restored along with the databases.
- // - You can create new users or databases if you want, but they cannot be
- // the same as the ones from the instance that was backed up.
- RestorePoint string
-
- ReplicaOf string
-}
-
-func (opts CreateOpts) ToInstanceCreateMap() (map[string]interface{}, error) {
- instance, err := os.CreateOpts{
- FlavorRef: opts.FlavorRef,
- Size: opts.Size,
- Name: opts.Name,
- Databases: opts.Databases,
- Users: opts.Users,
- }.ToInstanceCreateMap()
-
- if err != nil {
- return nil, err
- }
-
- instance = instance["instance"].(map[string]interface{})
-
- if opts.ConfigID != "" {
- instance["configuration"] = opts.ConfigID
- }
-
- if opts.Datastore != nil {
- ds, err := opts.Datastore.ToMap()
- if err != nil {
- return nil, err
- }
- instance["datastore"] = ds
- }
-
- if opts.RestorePoint != "" {
- instance["restorePoint"] = map[string]string{"backupRef": opts.RestorePoint}
- }
-
- if opts.ReplicaOf != "" {
- instance["replica_of"] = opts.ReplicaOf
- }
-
- return map[string]interface{}{"instance": instance}, nil
-}
-
-// Create asynchronously provisions a new database instance. It requires the
-// user to specify a flavor and a volume size. The API service then provisions
-// the instance with the requested flavor and sets up a volume of the specified
-// size, which is the storage for the database instance.
-//
-// Although this call only allows the creation of 1 instance per request, you
-// can create an instance with multiple databases and users. The default
-// binding for a MySQL instance is port 3306.
-func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) CreateResult {
- return CreateResult{os.Create(client, opts)}
-}
-
-// List retrieves the status and information for all database instances.
-func List(client *gophercloud.ServiceClient) pagination.Pager {
- return os.List(client)
-}
-
// Get retrieves the status and information for a specified database instance.
func Get(client *gophercloud.ServiceClient, id string) GetResult {
return GetResult{os.Get(client, id)}
diff --git a/rackspace/db/v1/instances/delegate_test.go b/rackspace/db/v1/instances/delegate_test.go
index 60a13c4..e94ce39 100644
--- a/rackspace/db/v1/instances/delegate_test.go
+++ b/rackspace/db/v1/instances/delegate_test.go
@@ -3,10 +3,7 @@
import (
"testing"
- "github.com/rackspace/gophercloud"
osDBs "github.com/rackspace/gophercloud/openstack/db/v1/databases"
- "github.com/rackspace/gophercloud/openstack/db/v1/datastores"
- "github.com/rackspace/gophercloud/openstack/db/v1/flavors"
os "github.com/rackspace/gophercloud/openstack/db/v1/instances"
osUsers "github.com/rackspace/gophercloud/openstack/db/v1/users"
th "github.com/rackspace/gophercloud/testhelper"
@@ -15,32 +12,10 @@
)
var (
- instanceID = "{instanceID}"
- _rootURL = "/instances"
- resURL = "/instances/" + instanceID
+ _rootURL = "/instances"
+ resURL = "/instances/" + instanceID
)
-var expectedInstance = &Instance{
- Created: "2014-02-13T21:47:13",
- Updated: "2014-02-13T21:47:13",
- Datastore: datastores.DatastorePartial{Type: "mysql", Version: "5.6"},
- Flavor: flavors.Flavor{
- ID: "1",
- Links: []gophercloud.Link{
- gophercloud.Link{Href: "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1", Rel: "self"},
- gophercloud.Link{Href: "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1", Rel: "bookmark"},
- },
- },
- Hostname: "e09ad9a3f73309469cf1f43d11e79549caf9acf2.rackspaceclouddb.com",
- ID: instanceID,
- Links: []gophercloud.Link{
- gophercloud.Link{Href: "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1", Rel: "self"},
- },
- Name: "json_rack_instance",
- Status: "BUILD",
- Volume: os.Volume{Size: 2},
-}
-
func TestCreate(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
diff --git a/rackspace/db/v1/instances/fixtures.go b/rackspace/db/v1/instances/fixtures.go
index 7275a32..9200dd9 100644
--- a/rackspace/db/v1/instances/fixtures.go
+++ b/rackspace/db/v1/instances/fixtures.go
@@ -1,6 +1,8 @@
package instances
import (
+ "fmt"
+
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/db/v1/datastores"
"github.com/rackspace/gophercloud/openstack/db/v1/flavors"
@@ -9,39 +11,37 @@
const instance = `
{
- "instance": {
- "created": "2014-02-13T21:47:13",
- "datastore": {
- "type": "mysql",
- "version": "5.6"
- },
- "flavor": {
- "id": "1",
- "links": [
- {
- "href": "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1",
- "rel": "self"
- },
- {
- "href": "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1",
- "rel": "bookmark"
- }
- ]
- },
+ "created": "2014-02-13T21:47:13",
+ "datastore": {
+ "type": "mysql",
+ "version": "5.6"
+ },
+ "flavor": {
+ "id": "1",
"links": [
{
"href": "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1",
"rel": "self"
+ },
+ {
+ "href": "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1",
+ "rel": "bookmark"
}
- ],
- "hostname": "e09ad9a3f73309469cf1f43d11e79549caf9acf2.rackspaceclouddb.com",
- "id": "{instanceID}",
- "name": "json_rack_instance",
- "status": "BUILD",
- "updated": "2014-02-13T21:47:13",
- "volume": {
- "size": 2
+ ]
+ },
+ "links": [
+ {
+ "href": "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1",
+ "rel": "self"
}
+ ],
+ "hostname": "e09ad9a3f73309469cf1f43d11e79549caf9acf2.rackspaceclouddb.com",
+ "id": "{instanceID}",
+ "name": "json_rack_instance",
+ "status": "BUILD",
+ "updated": "2014-02-13T21:47:13",
+ "volume": {
+ "size": 2
}
}
`
@@ -286,11 +286,35 @@
`
var (
- createResp = instance
- getResp = instance
- associateResp = instance
+ createResp = fmt.Sprintf(`{"instance":%s}`, instance)
+ getResp = fmt.Sprintf(`{"instance":%s}`, instance)
+ associateResp = fmt.Sprintf(`{"instance":%s}`, instance)
+ listInstancesResp = fmt.Sprintf(`{"instances":[%s]}`, instance)
)
+var instanceID = "{instanceID}"
+
+var expectedInstance = &Instance{
+ Created: "2014-02-13T21:47:13",
+ Updated: "2014-02-13T21:47:13",
+ Datastore: datastores.DatastorePartial{Type: "mysql", Version: "5.6"},
+ Flavor: flavors.Flavor{
+ ID: "1",
+ Links: []gophercloud.Link{
+ gophercloud.Link{Href: "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1", Rel: "self"},
+ gophercloud.Link{Href: "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1", Rel: "bookmark"},
+ },
+ },
+ Hostname: "e09ad9a3f73309469cf1f43d11e79549caf9acf2.rackspaceclouddb.com",
+ ID: instanceID,
+ Links: []gophercloud.Link{
+ gophercloud.Link{Href: "https://ord.databases.api.rackspacecloud.com/v1.0/1234/flavors/1", Rel: "self"},
+ },
+ Name: "json_rack_instance",
+ Status: "BUILD",
+ Volume: os.Volume{Size: 2},
+}
+
var expectedReplica = &Instance{
Status: "BUILD",
Updated: "2014-10-14T18:42:15",
diff --git a/rackspace/db/v1/instances/requests.go b/rackspace/db/v1/instances/requests.go
index bd8a899..c8876da 100644
--- a/rackspace/db/v1/instances/requests.go
+++ b/rackspace/db/v1/instances/requests.go
@@ -2,10 +2,142 @@
import (
"github.com/rackspace/gophercloud"
+ osDBs "github.com/rackspace/gophercloud/openstack/db/v1/databases"
+ os "github.com/rackspace/gophercloud/openstack/db/v1/instances"
+ osUsers "github.com/rackspace/gophercloud/openstack/db/v1/users"
"github.com/rackspace/gophercloud/pagination"
"github.com/rackspace/gophercloud/rackspace/db/v1/backups"
)
+// CreateOpts is the struct responsible for configuring a new database instance.
+type CreateOpts struct {
+ // Either the integer UUID (in string form) of the flavor, or its URI
+ // reference as specified in the response from the List() call. Required.
+ FlavorRef string
+
+ // Specifies the volume size in gigabytes (GB). The value must be between 1
+ // and 300. Required.
+ Size int
+
+ // Name of the instance to create. The length of the name is limited to
+ // 255 characters and any characters are permitted. Optional.
+ Name string
+
+ // A slice of database information options.
+ Databases osDBs.BatchCreateOpts
+
+ // A slice of user information options.
+ Users osUsers.BatchCreateOpts
+
+ // ID of the configuration group to associate with the instance. Optional.
+ ConfigID string
+
+ // Options to configure the type of datastore the instance will use. This is
+ // optional, and if excluded will default to MySQL.
+ Datastore *os.DatastoreOpts
+
+ // Specifies the backup ID from which to restore the database instance. There
+ // are some things to be aware of before using this field. When you execute
+ // the Restore Backup operation, a new database instance is created to store
+ // the backup whose ID is specified by the restorePoint attribute. This will
+ // mean that:
+ // - All users, passwords and access that were on the instance at the time of
+ // the backup will be restored along with the databases.
+ // - You can create new users or databases if you want, but they cannot be
+ // the same as the ones from the instance that was backed up.
+ RestorePoint string
+
+ ReplicaOf string
+}
+
+func (opts CreateOpts) ToInstanceCreateMap() (map[string]interface{}, error) {
+ instance, err := os.CreateOpts{
+ FlavorRef: opts.FlavorRef,
+ Size: opts.Size,
+ Name: opts.Name,
+ Databases: opts.Databases,
+ Users: opts.Users,
+ }.ToInstanceCreateMap()
+
+ if err != nil {
+ return nil, err
+ }
+
+ instance = instance["instance"].(map[string]interface{})
+
+ if opts.ConfigID != "" {
+ instance["configuration"] = opts.ConfigID
+ }
+
+ if opts.Datastore != nil {
+ ds, err := opts.Datastore.ToMap()
+ if err != nil {
+ return nil, err
+ }
+ instance["datastore"] = ds
+ }
+
+ if opts.RestorePoint != "" {
+ instance["restorePoint"] = map[string]string{"backupRef": opts.RestorePoint}
+ }
+
+ if opts.ReplicaOf != "" {
+ instance["replica_of"] = opts.ReplicaOf
+ }
+
+ return map[string]interface{}{"instance": instance}, nil
+}
+
+// Create asynchronously provisions a new database instance. It requires the
+// user to specify a flavor and a volume size. The API service then provisions
+// the instance with the requested flavor and sets up a volume of the specified
+// size, which is the storage for the database instance.
+//
+// Although this call only allows the creation of 1 instance per request, you
+// can create an instance with multiple databases and users. The default
+// binding for a MySQL instance is port 3306.
+func Create(client *gophercloud.ServiceClient, opts os.CreateOptsBuilder) CreateResult {
+ return CreateResult{os.Create(client, opts)}
+}
+
+// ListOpts specifies all of the query options to be used when returning a list
+// of database instances.
+type ListOpts struct {
+ // IncludeHA includes or excludes High Availability instances from the result set
+ IncludeHA bool `q:"include_ha"`
+
+ // IncludeReplicas includes or excludes Replica instances from the result set
+ IncludeReplicas bool `q:"include_replicas"`
+}
+
+// ToInstanceListQuery formats a ListOpts into a query string.
+func (opts ListOpts) ToInstanceListQuery() (string, error) {
+ q, err := gophercloud.BuildQueryString(opts)
+ if err != nil {
+ return "", err
+ }
+ return q.String(), nil
+}
+
+// List retrieves the status and information for all database instances.
+func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager {
+ url := baseURL(client)
+
+ if opts != nil {
+ query, err := opts.ToInstanceListQuery()
+ if err != nil {
+ return pagination.Pager{Err: err}
+ }
+ url += query
+ }
+
+ createPageFn := func(r pagination.PageResult) pagination.Page {
+ return os.InstancePage{pagination.LinkedPageBase{PageResult: r}}
+ }
+
+ return pagination.NewPager(client, url, createPageFn)
+}
+
// GetDefaultConfig lists the default configuration settings from the template
// that was applied to the specified instance. In a sense, this is the vanilla
// configuration setting applied to an instance. Further configuration can be
diff --git a/rackspace/db/v1/instances/requests_test.go b/rackspace/db/v1/instances/requests_test.go
index b242c0f..2b40a04 100644
--- a/rackspace/db/v1/instances/requests_test.go
+++ b/rackspace/db/v1/instances/requests_test.go
@@ -14,6 +14,34 @@
"github.com/rackspace/gophercloud/testhelper/fixture"
)
+func TestInstanceList(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ fixture.SetupHandler(t, "/instances", "GET", "", listInstancesResp, 200)
+
+ opts := &ListOpts{
+ IncludeHA: false,
+ IncludeReplicas: false,
+ }
+
+ pages := 0
+ err := List(fake.ServiceClient(), opts).EachPage(func(page pagination.Page) (bool, error) {
+ pages++
+
+ actual, err := ExtractInstances(page)
+ if err != nil {
+ return false, err
+ }
+
+ th.CheckDeepEquals(t, []Instance{*expectedInstance}, actual)
+ return true, nil
+ })
+
+ th.AssertNoErr(t, err)
+ th.AssertEquals(t, 1, pages)
+}
+
func TestGetConfig(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
@@ -138,7 +166,7 @@
fixture.SetupHandler(t, _rootURL, "GET", "", listReplicasResp, 200)
pages := 0
- err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
+ err := List(fake.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) {
pages++
actual, err := ExtractInstances(page)