fix general issues
diff --git a/openstack/db/v1/configurations/doc.go b/openstack/db/v1/configurations/doc.go
new file mode 100644
index 0000000..45b9cfb
--- /dev/null
+++ b/openstack/db/v1/configurations/doc.go
@@ -0,0 +1,11 @@
+// Package configurations provides information and interaction with the
+// configuration API resource in the Rackspace Database service.
+//
+// A configuration group is a collection of key/value pairs which define how a
+// particular database operates. These key/value pairs are specific to each
+// datastore type and serve like settings. Some directives are capable of being
+// applied dynamically, while other directives require a server restart to take
+// effect. The configuration group can be applied to an instance at creation or
+// applied to an existing instance to modify the behavior of the running
+// datastore on the instance.
+package configurations
diff --git a/openstack/db/v1/configurations/fixtures.go b/openstack/db/v1/configurations/fixtures.go
new file mode 100644
index 0000000..c3723ab
--- /dev/null
+++ b/openstack/db/v1/configurations/fixtures.go
@@ -0,0 +1,149 @@
+package configurations
+
+import "fmt"
+
+const singleConfigJSON = `
+{
+  "created": "2014-07-31T18:56:09",
+  "datastore_name": "mysql",
+  "datastore_version_id": "b00000b0-00b0-0b00-00b0-000b000000bb",
+  "datastore_version_name": "5.6",
+  "description": "example_description",
+  "id": "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
+  "name": "example-configuration-name",
+  "updated": "2014-07-31T18:56:09"
+}
+`
+
+const singleConfigWithValuesJSON = `
+{
+  "created": "2014-07-31T15:02:52",
+  "datastore_name": "mysql",
+  "datastore_version_id": "b00000b0-00b0-0b00-00b0-000b000000bb",
+  "datastore_version_name": "5.6",
+  "description": "example description",
+  "id": "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
+  "instance_count": 0,
+  "name": "example-configuration-name",
+  "updated": "2014-07-31T15:02:52",
+  "values": {
+    "collation_server": "latin1_swedish_ci",
+    "connect_timeout": 120
+  }
+}
+`
+
+var (
+	listConfigsJSON  = fmt.Sprintf(`{"configurations": [%s]}`, singleConfigJSON)
+	getConfigJSON    = fmt.Sprintf(`{"configuration": %s}`, singleConfigJSON)
+	createConfigJSON = fmt.Sprintf(`{"configuration": %s}`, singleConfigWithValuesJSON)
+)
+
+var createReq = `
+{
+  "configuration": {
+    "datastore": {
+      "type": "a00000a0-00a0-0a00-00a0-000a000000aa",
+      "version": "b00000b0-00b0-0b00-00b0-000b000000bb"
+    },
+    "description": "example description",
+    "name": "example-configuration-name",
+    "values": {
+      "collation_server": "latin1_swedish_ci",
+      "connect_timeout": 120
+    }
+  }
+}
+`
+
+var updateReq = `
+{
+  "configuration": {
+    "values": {
+      "connect_timeout": 300
+    }
+  }
+}
+`
+
+var listInstancesJSON = `
+{
+  "instances": [
+    {
+      "id": "d4603f69-ec7e-4e9b-803f-600b9205576f",
+      "name": "json_rack_instance"
+    }
+  ]
+}
+`
+
+var listParamsJSON = `
+{
+  "configuration-parameters": [
+    {
+      "max": 1,
+      "min": 0,
+      "name": "innodb_file_per_table",
+      "restart_required": true,
+      "type": "integer"
+    },
+    {
+      "max": 4294967296,
+      "min": 0,
+      "name": "key_buffer_size",
+      "restart_required": false,
+      "type": "integer"
+    },
+    {
+      "max": 65535,
+      "min": 2,
+      "name": "connect_timeout",
+      "restart_required": false,
+      "type": "integer"
+    },
+    {
+      "max": 4294967296,
+      "min": 0,
+      "name": "join_buffer_size",
+      "restart_required": false,
+      "type": "integer"
+    }
+  ]
+}
+`
+
+var getParamJSON = `
+{
+  "max": 1,
+  "min": 0,
+  "name": "innodb_file_per_table",
+  "restart_required": true,
+  "type": "integer"
+}
+`
+
+var exampleConfig = Config{
+	Created:              "2014-07-31T18:56:09",
+	DatastoreName:        "mysql",
+	DatastoreVersionID:   "b00000b0-00b0-0b00-00b0-000b000000bb",
+	DatastoreVersionName: "5.6",
+	Description:          "example_description",
+	ID:                   "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
+	Name:                 "example-configuration-name",
+	Updated:              "2014-07-31T18:56:09",
+}
+
+var exampleConfigWithValues = Config{
+	Created:              "2014-07-31T15:02:52",
+	DatastoreName:        "mysql",
+	DatastoreVersionID:   "b00000b0-00b0-0b00-00b0-000b000000bb",
+	DatastoreVersionName: "5.6",
+	Description:          "example description",
+	ID:                   "005a8bb7-a8df-40ee-b0b7-fc144641abc2",
+	Name:                 "example-configuration-name",
+	Updated:              "2014-07-31T15:02:52",
+	Values: map[string]interface{}{
+		"collation_server": "latin1_swedish_ci",
+		"connect_timeout":  120,
+	},
+}
diff --git a/openstack/db/v1/configurations/requests.go b/openstack/db/v1/configurations/requests.go
new file mode 100644
index 0000000..83c7102
--- /dev/null
+++ b/openstack/db/v1/configurations/requests.go
@@ -0,0 +1,287 @@
+package configurations
+
+import (
+	"errors"
+
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/openstack/db/v1/instances"
+	"github.com/rackspace/gophercloud/pagination"
+)
+
+// List will list all of the available configurations.
+func List(client *gophercloud.ServiceClient) pagination.Pager {
+	pageFn := func(r pagination.PageResult) pagination.Page {
+		return ConfigPage{pagination.SinglePageBase(r)}
+	}
+
+	return pagination.NewPager(client, baseURL(client), pageFn)
+}
+
+// CreateOptsBuilder is a top-level interface which renders a JSON map.
+type CreateOptsBuilder interface {
+	ToConfigCreateMap() (map[string]interface{}, error)
+}
+
+// DatastoreOpts is the primary options struct for creating and modifying
+// how configuration resources are associated with datastores.
+type DatastoreOpts struct {
+	// [OPTIONAL] The type of datastore. Defaults to "MySQL".
+	Type string
+
+	// [OPTIONAL] The specific version of a datastore. Defaults to "5.6".
+	Version string
+}
+
+// ToMap renders a JSON map for a datastore setting.
+func (opts DatastoreOpts) ToMap() (map[string]string, error) {
+	datastore := map[string]string{}
+
+	if opts.Type != "" {
+		datastore["type"] = opts.Type
+	}
+
+	if opts.Version != "" {
+		datastore["version"] = opts.Version
+	}
+
+	return datastore, nil
+}
+
+// CreateOpts is the struct responsible for configuring new configurations.
+type CreateOpts struct {
+	// [REQUIRED] The configuration group name
+	Name string
+
+	// [REQUIRED] A map of user-defined configuration settings that will define
+	// how each associated datastore works. Each key/value pair is specific to a
+	// datastore type.
+	Values map[string]interface{}
+
+	// [OPTIONAL] Associates the configuration group with a particular datastore.
+	Datastore *DatastoreOpts
+
+	// [OPTIONAL] A human-readable explanation for the group.
+	Description string
+}
+
+// ToConfigCreateMap casts a CreateOpts struct into a JSON map.
+func (opts CreateOpts) ToConfigCreateMap() (map[string]interface{}, error) {
+	if opts.Name == "" {
+		return nil, errors.New("Name is a required field")
+	}
+	if len(opts.Values) == 0 {
+		return nil, errors.New("Values must be a populated map")
+	}
+
+	config := map[string]interface{}{
+		"name":   opts.Name,
+		"values": opts.Values,
+	}
+
+	if opts.Datastore != nil {
+		ds, err := opts.Datastore.ToMap()
+		if err != nil {
+			return config, err
+		}
+		config["datastore"] = ds
+	}
+
+	if opts.Description != "" {
+		config["description"] = opts.Description
+	}
+
+	return map[string]interface{}{"configuration": config}, nil
+}
+
+// Create will create a new configuration group.
+func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
+	var res CreateResult
+
+	reqBody, err := opts.ToConfigCreateMap()
+	if err != nil {
+		res.Err = err
+		return res
+	}
+
+	_, res.Err = client.Request("POST", baseURL(client), gophercloud.RequestOpts{
+		OkCodes:      []int{200},
+		JSONBody:     &reqBody,
+		JSONResponse: &res.Body,
+	})
+
+	return res
+}
+
+// Get will retrieve the details for a specified configuration group.
+func Get(client *gophercloud.ServiceClient, configID string) GetResult {
+	var res GetResult
+
+	_, res.Err = client.Request("GET", resourceURL(client, configID), gophercloud.RequestOpts{
+		OkCodes:      []int{200},
+		JSONResponse: &res.Body,
+	})
+
+	return res
+}
+
+// UpdateOptsBuilder is the top-level interface for casting update options into
+// JSON maps.
+type UpdateOptsBuilder interface {
+	ToConfigUpdateMap() (map[string]interface{}, error)
+}
+
+// UpdateOpts is the struct responsible for modifying existing configurations.
+type UpdateOpts struct {
+	// [OPTIONAL] The configuration group name
+	Name string
+
+	// [OPTIONAL] A map of user-defined configuration settings that will define
+	// how each associated datastore works. Each key/value pair is specific to a
+	// datastore type.
+	Values map[string]interface{}
+
+	// [OPTIONAL] Associates the configuration group with a particular datastore.
+	Datastore *DatastoreOpts
+
+	// [OPTIONAL] A human-readable explanation for the group.
+	Description string
+}
+
+// ToConfigUpdateMap will cast an UpdateOpts struct into a JSON map.
+func (opts UpdateOpts) ToConfigUpdateMap() (map[string]interface{}, error) {
+	config := map[string]interface{}{}
+
+	if opts.Name != "" {
+		config["name"] = opts.Name
+	}
+
+	if opts.Description != "" {
+		config["description"] = opts.Description
+	}
+
+	if opts.Datastore != nil {
+		ds, err := opts.Datastore.ToMap()
+		if err != nil {
+			return config, err
+		}
+		config["datastore"] = ds
+	}
+
+	if len(opts.Values) > 0 {
+		config["values"] = opts.Values
+	}
+
+	return map[string]interface{}{"configuration": config}, nil
+}
+
+// Update will modify an existing configuration group by performing a merge
+// between new and existing values. If the key already exists, the new value
+// will overwrite. All other keys will remain unaffected.
+func Update(client *gophercloud.ServiceClient, configID string, opts UpdateOptsBuilder) UpdateResult {
+	var res UpdateResult
+
+	reqBody, err := opts.ToConfigUpdateMap()
+	if err != nil {
+		res.Err = err
+		return res
+	}
+
+	_, res.Err = client.Request("PATCH", resourceURL(client, configID), gophercloud.RequestOpts{
+		OkCodes:  []int{200},
+		JSONBody: &reqBody,
+	})
+
+	return res
+}
+
+// Replace will modify an existing configuration group by overwriting the
+// entire parameter group with the new values provided. Any existing keys not
+// included in UpdateOptsBuilder will be deleted.
+func Replace(client *gophercloud.ServiceClient, configID string, opts UpdateOptsBuilder) ReplaceResult {
+	var res ReplaceResult
+
+	reqBody, err := opts.ToConfigUpdateMap()
+	if err != nil {
+		res.Err = err
+		return res
+	}
+
+	_, res.Err = client.Request("PUT", resourceURL(client, configID), gophercloud.RequestOpts{
+		OkCodes:  []int{202},
+		JSONBody: &reqBody,
+	})
+
+	return res
+}
+
+// Delete will permanently delete a configuration group. Please note that
+// config groups cannot be deleted whilst still attached to running instances -
+// you must detach and then delete them.
+func Delete(client *gophercloud.ServiceClient, configID string) DeleteResult {
+	var res DeleteResult
+
+	_, res.Err = client.Request("DELETE", resourceURL(client, configID), gophercloud.RequestOpts{
+		OkCodes: []int{202},
+	})
+
+	return res
+}
+
+// ListInstances will list all the instances associated with a particular
+// configuration group.
+func ListInstances(client *gophercloud.ServiceClient, configID string) pagination.Pager {
+	pageFn := func(r pagination.PageResult) pagination.Page {
+		return instances.InstancePage{pagination.LinkedPageBase{PageResult: r}}
+	}
+	return pagination.NewPager(client, instancesURL(client, configID), pageFn)
+}
+
+// ListDatastoreParams will list all the available and supported parameters
+// that can be used for a particular datastore ID and a particular version.
+// For example, if you are wondering how you can configure a MySQL 5.6 instance,
+// you can use this operation (you will need to retrieve the MySQL datastore ID
+// by using the datastores API).
+func ListDatastoreParams(client *gophercloud.ServiceClient, datastoreID, versionID string) pagination.Pager {
+	pageFn := func(r pagination.PageResult) pagination.Page {
+		return ParamPage{pagination.SinglePageBase(r)}
+	}
+	return pagination.NewPager(client, listDSParamsURL(client, datastoreID, versionID), pageFn)
+}
+
+// GetDatastoreParam will retrieve information about a specific configuration
+// parameter. For example, you can use this operation to understand more about
+// "innodb_file_per_table" configuration param for MySQL datastores. You will
+// need the param's ID first, which can be attained by using the ListDatastoreParams
+// operation.
+func GetDatastoreParam(client *gophercloud.ServiceClient, datastoreID, versionID, paramID string) ParamResult {
+	var res ParamResult
+
+	_, res.Err = client.Request("GET", getDSParamURL(client, datastoreID, versionID, paramID), gophercloud.RequestOpts{
+		OkCodes:      []int{200},
+		JSONResponse: &res.Body,
+	})
+
+	return res
+}
+
+// ListGlobalParams is similar to ListDatastoreParams but does not require a
+// DatastoreID.
+func ListGlobalParams(client *gophercloud.ServiceClient, versionID string) pagination.Pager {
+	pageFn := func(r pagination.PageResult) pagination.Page {
+		return ParamPage{pagination.SinglePageBase(r)}
+	}
+	return pagination.NewPager(client, listGlobalParamsURL(client, versionID), pageFn)
+}
+
+// GetGlobalParam is similar to GetDatastoreParam but does not require a
+// DatastoreID.
+func GetGlobalParam(client *gophercloud.ServiceClient, versionID, paramID string) ParamResult {
+	var res ParamResult
+
+	_, res.Err = client.Request("GET", getGlobalParamURL(client, versionID, paramID), gophercloud.RequestOpts{
+		OkCodes:      []int{200},
+		JSONResponse: &res.Body,
+	})
+
+	return res
+}
diff --git a/openstack/db/v1/configurations/requests_test.go b/openstack/db/v1/configurations/requests_test.go
new file mode 100644
index 0000000..ca085d8
--- /dev/null
+++ b/openstack/db/v1/configurations/requests_test.go
@@ -0,0 +1,236 @@
+package configurations
+
+import (
+	"testing"
+
+	"github.com/rackspace/gophercloud/pagination"
+	"github.com/rackspace/gophercloud/rackspace/db/v1/instances"
+	th "github.com/rackspace/gophercloud/testhelper"
+	fake "github.com/rackspace/gophercloud/testhelper/client"
+	"github.com/rackspace/gophercloud/testhelper/fixture"
+)
+
+var (
+	configID = "{configID}"
+	_baseURL = "/configurations"
+	resURL   = _baseURL + "/" + configID
+
+	dsID               = "{datastoreID}"
+	versionID          = "{versionID}"
+	paramID            = "{paramID}"
+	dsParamListURL     = "/datastores/" + dsID + "/versions/" + versionID + "/parameters"
+	dsParamGetURL      = "/datastores/" + dsID + "/versions/" + versionID + "/parameters/" + paramID
+	globalParamListURL = "/datastores/versions/" + versionID + "/parameters"
+	globalParamGetURL  = "/datastores/versions/" + versionID + "/parameters/" + paramID
+)
+
+func TestList(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, _baseURL, "GET", "", listConfigsJSON, 200)
+
+	count := 0
+	err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
+		count++
+		actual, err := ExtractConfigs(page)
+		th.AssertNoErr(t, err)
+
+		expected := []Config{exampleConfig}
+		th.AssertDeepEquals(t, expected, actual)
+
+		return true, nil
+	})
+
+	th.AssertEquals(t, 1, count)
+	th.AssertNoErr(t, err)
+}
+
+func TestGet(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, resURL, "GET", "", getConfigJSON, 200)
+
+	config, err := Get(fake.ServiceClient(), configID).Extract()
+	th.AssertNoErr(t, err)
+	th.AssertDeepEquals(t, &exampleConfig, config)
+}
+
+func TestCreate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, _baseURL, "POST", createReq, createConfigJSON, 200)
+
+	opts := CreateOpts{
+		Datastore: &DatastoreOpts{
+			Type:    "a00000a0-00a0-0a00-00a0-000a000000aa",
+			Version: "b00000b0-00b0-0b00-00b0-000b000000bb",
+		},
+		Description: "example description",
+		Name:        "example-configuration-name",
+		Values: map[string]interface{}{
+			"collation_server": "latin1_swedish_ci",
+			"connect_timeout":  120,
+		},
+	}
+
+	config, err := Create(fake.ServiceClient(), opts).Extract()
+	th.AssertNoErr(t, err)
+	th.AssertDeepEquals(t, &exampleConfigWithValues, config)
+}
+
+func TestUpdate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, resURL, "PATCH", updateReq, "", 200)
+
+	opts := UpdateOpts{
+		Values: map[string]interface{}{
+			"connect_timeout": 300,
+		},
+	}
+
+	err := Update(fake.ServiceClient(), configID, opts).ExtractErr()
+	th.AssertNoErr(t, err)
+}
+
+func TestReplace(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, resURL, "PUT", updateReq, "", 202)
+
+	opts := UpdateOpts{
+		Values: map[string]interface{}{
+			"connect_timeout": 300,
+		},
+	}
+
+	err := Replace(fake.ServiceClient(), configID, opts).ExtractErr()
+	th.AssertNoErr(t, err)
+}
+
+func TestDelete(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, resURL, "DELETE", "", "", 202)
+
+	err := Delete(fake.ServiceClient(), configID).ExtractErr()
+	th.AssertNoErr(t, err)
+}
+
+func TestListInstances(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, resURL+"/instances", "GET", "", listInstancesJSON, 200)
+
+	expectedInstance := instances.Instance{
+		ID:   "d4603f69-ec7e-4e9b-803f-600b9205576f",
+		Name: "json_rack_instance",
+	}
+
+	pages := 0
+	err := ListInstances(fake.ServiceClient(), configID).EachPage(func(page pagination.Page) (bool, error) {
+		pages++
+
+		actual, err := instances.ExtractInstances(page)
+		if err != nil {
+			return false, err
+		}
+
+		th.AssertDeepEquals(t, actual, []instances.Instance{expectedInstance})
+
+		return true, nil
+	})
+
+	th.AssertNoErr(t, err)
+	th.AssertEquals(t, 1, pages)
+}
+
+func TestListDSParams(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, dsParamListURL, "GET", "", listParamsJSON, 200)
+
+	pages := 0
+	err := ListDatastoreParams(fake.ServiceClient(), dsID, versionID).EachPage(func(page pagination.Page) (bool, error) {
+		pages++
+
+		actual, err := ExtractParams(page)
+		if err != nil {
+			return false, err
+		}
+
+		expected := []Param{
+			Param{Max: 1, Min: 0, Name: "innodb_file_per_table", RestartRequired: true, Type: "integer"},
+			Param{Max: 4294967296, Min: 0, Name: "key_buffer_size", RestartRequired: false, Type: "integer"},
+			Param{Max: 65535, Min: 2, Name: "connect_timeout", RestartRequired: false, Type: "integer"},
+			Param{Max: 4294967296, Min: 0, Name: "join_buffer_size", RestartRequired: false, Type: "integer"},
+		}
+
+		th.AssertDeepEquals(t, actual, expected)
+
+		return true, nil
+	})
+
+	th.AssertNoErr(t, err)
+	th.AssertEquals(t, 1, pages)
+}
+
+func TestGetDSParam(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, dsParamGetURL, "GET", "", getParamJSON, 200)
+
+	param, err := GetDatastoreParam(fake.ServiceClient(), dsID, versionID, paramID).Extract()
+	th.AssertNoErr(t, err)
+
+	expected := &Param{
+		Max: 1, Min: 0, Name: "innodb_file_per_table", RestartRequired: true, Type: "integer",
+	}
+
+	th.AssertDeepEquals(t, expected, param)
+}
+
+func TestListGlobalParams(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, globalParamListURL, "GET", "", listParamsJSON, 200)
+
+	pages := 0
+	err := ListGlobalParams(fake.ServiceClient(), versionID).EachPage(func(page pagination.Page) (bool, error) {
+		pages++
+
+		actual, err := ExtractParams(page)
+		if err != nil {
+			return false, err
+		}
+
+		expected := []Param{
+			Param{Max: 1, Min: 0, Name: "innodb_file_per_table", RestartRequired: true, Type: "integer"},
+			Param{Max: 4294967296, Min: 0, Name: "key_buffer_size", RestartRequired: false, Type: "integer"},
+			Param{Max: 65535, Min: 2, Name: "connect_timeout", RestartRequired: false, Type: "integer"},
+			Param{Max: 4294967296, Min: 0, Name: "join_buffer_size", RestartRequired: false, Type: "integer"},
+		}
+
+		th.AssertDeepEquals(t, actual, expected)
+
+		return true, nil
+	})
+
+	th.AssertNoErr(t, err)
+	th.AssertEquals(t, 1, pages)
+}
+
+func TestGetGlobalParam(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, globalParamGetURL, "GET", "", getParamJSON, 200)
+
+	param, err := GetGlobalParam(fake.ServiceClient(), versionID, paramID).Extract()
+	th.AssertNoErr(t, err)
+
+	expected := &Param{
+		Max: 1, Min: 0, Name: "innodb_file_per_table", RestartRequired: true, Type: "integer",
+	}
+
+	th.AssertDeepEquals(t, expected, param)
+}
diff --git a/openstack/db/v1/configurations/results.go b/openstack/db/v1/configurations/results.go
new file mode 100644
index 0000000..98ce25f
--- /dev/null
+++ b/openstack/db/v1/configurations/results.go
@@ -0,0 +1,142 @@
+package configurations
+
+import (
+	"github.com/mitchellh/mapstructure"
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/pagination"
+)
+
+// Config represents a configuration group API resource.
+type Config struct {
+	Created              string
+	Updated              string
+	DatastoreName        string `mapstructure:"datastore_name"`
+	DatastoreVersionID   string `mapstructure:"datastore_version_id"`
+	DatastoreVersionName string `mapstructure:"datastore_version_name"`
+	Description          string
+	ID                   string
+	Name                 string
+	Values               map[string]interface{}
+}
+
+// ConfigPage contains a page of Config resources in a paginated collection.
+type ConfigPage struct {
+	pagination.SinglePageBase
+}
+
+// IsEmpty indicates whether a ConfigPage is empty.
+func (r ConfigPage) IsEmpty() (bool, error) {
+	is, err := ExtractConfigs(r)
+	if err != nil {
+		return true, err
+	}
+	return len(is) == 0, nil
+}
+
+// ExtractConfigs will retrieve a slice of Config structs from a page.
+func ExtractConfigs(page pagination.Page) ([]Config, error) {
+	casted := page.(ConfigPage).Body
+
+	var resp struct {
+		Configs []Config `mapstructure:"configurations" json:"configurations"`
+	}
+
+	err := mapstructure.Decode(casted, &resp)
+	return resp.Configs, err
+}
+
+type commonResult struct {
+	gophercloud.Result
+}
+
+// Extract will retrieve a Config resource from an operation result.
+func (r commonResult) Extract() (*Config, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	var response struct {
+		Config Config `mapstructure:"configuration"`
+	}
+
+	err := mapstructure.Decode(r.Body, &response)
+	return &response.Config, err
+}
+
+// GetResult represents the result of a Get operation.
+type GetResult struct {
+	commonResult
+}
+
+// CreateResult represents the result of a Create operation.
+type CreateResult struct {
+	commonResult
+}
+
+// UpdateResult represents the result of an Update operation.
+type UpdateResult struct {
+	gophercloud.ErrResult
+}
+
+// ReplaceResult represents the result of a Replace operation.
+type ReplaceResult struct {
+	gophercloud.ErrResult
+}
+
+// DeleteResult represents the result of a Delete operation.
+type DeleteResult struct {
+	gophercloud.ErrResult
+}
+
+// Param represents a configuration parameter API resource.
+type Param struct {
+	Max             int
+	Min             int
+	Name            string
+	RestartRequired bool `mapstructure:"restart_required" json:"restart_required"`
+	Type            string
+}
+
+// ParamPage contains a page of Param resources in a paginated collection.
+type ParamPage struct {
+	pagination.SinglePageBase
+}
+
+// IsEmpty indicates whether a ParamPage is empty.
+func (r ParamPage) IsEmpty() (bool, error) {
+	is, err := ExtractParams(r)
+	if err != nil {
+		return true, err
+	}
+	return len(is) == 0, nil
+}
+
+// ExtractParams will retrieve a slice of Param structs from a page.
+func ExtractParams(page pagination.Page) ([]Param, error) {
+	casted := page.(ParamPage).Body
+
+	var resp struct {
+		Params []Param `mapstructure:"configuration-parameters" json:"configuration-parameters"`
+	}
+
+	err := mapstructure.Decode(casted, &resp)
+	return resp.Params, err
+}
+
+// ParamResult represents the result of an operation which retrieves details
+// about a particular configuration param.
+type ParamResult struct {
+	gophercloud.Result
+}
+
+// Extract will retrieve a param from an operation result.
+func (r ParamResult) Extract() (*Param, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	var param Param
+
+	err := mapstructure.Decode(r.Body, &param)
+	return &param, err
+}
diff --git a/openstack/db/v1/configurations/urls.go b/openstack/db/v1/configurations/urls.go
new file mode 100644
index 0000000..abea961
--- /dev/null
+++ b/openstack/db/v1/configurations/urls.go
@@ -0,0 +1,31 @@
+package configurations
+
+import "github.com/rackspace/gophercloud"
+
+func baseURL(c *gophercloud.ServiceClient) string {
+	return c.ServiceURL("configurations")
+}
+
+func resourceURL(c *gophercloud.ServiceClient, configID string) string {
+	return c.ServiceURL("configurations", configID)
+}
+
+func instancesURL(c *gophercloud.ServiceClient, configID string) string {
+	return c.ServiceURL("configurations", configID, "instances")
+}
+
+func listDSParamsURL(c *gophercloud.ServiceClient, datastoreID, versionID string) string {
+	return c.ServiceURL("datastores", datastoreID, "versions", versionID, "parameters")
+}
+
+func getDSParamURL(c *gophercloud.ServiceClient, datastoreID, versionID, paramID string) string {
+	return c.ServiceURL("datastores", datastoreID, "versions", versionID, "parameters", paramID)
+}
+
+func listGlobalParamsURL(c *gophercloud.ServiceClient, versionID string) string {
+	return c.ServiceURL("datastores", "versions", versionID, "parameters")
+}
+
+func getGlobalParamURL(c *gophercloud.ServiceClient, versionID, paramID string) string {
+	return c.ServiceURL("datastores", "versions", versionID, "parameters", paramID)
+}
diff --git a/openstack/db/v1/databases/requests.go b/openstack/db/v1/databases/requests.go
index 18a0798..4a1b40c 100644
--- a/openstack/db/v1/databases/requests.go
+++ b/openstack/db/v1/databases/requests.go
@@ -84,9 +84,8 @@
 	}
 
 	_, res.Err = client.Request("POST", baseURL(client, instanceID), gophercloud.RequestOpts{
-		JSONBody:     &reqBody,
-		JSONResponse: &res.Body,
-		OkCodes:      []int{202},
+		JSONBody: &reqBody,
+		OkCodes:  []int{202},
 	})
 
 	return res
diff --git a/openstack/db/v1/datastores/doc.go b/openstack/db/v1/datastores/doc.go
new file mode 100644
index 0000000..ae14026
--- /dev/null
+++ b/openstack/db/v1/datastores/doc.go
@@ -0,0 +1,3 @@
+// Package datastores provides information and interaction with the datastore
+// API resource in the Rackspace Database service.
+package datastores
diff --git a/openstack/db/v1/datastores/fixtures.go b/openstack/db/v1/datastores/fixtures.go
new file mode 100644
index 0000000..fd767cd
--- /dev/null
+++ b/openstack/db/v1/datastores/fixtures.go
@@ -0,0 +1,100 @@
+package datastores
+
+import (
+	"fmt"
+
+	"github.com/rackspace/gophercloud"
+)
+
+const version1JSON = `
+{
+	"id": "b00000b0-00b0-0b00-00b0-000b000000bb",
+	"links": [
+		{
+			"href": "https://10.240.28.38:8779/v1.0/1234/datastores/versions/b00000b0-00b0-0b00-00b0-000b000000bb",
+			"rel": "self"
+		},
+		{
+			"href": "https://10.240.28.38:8779/datastores/versions/b00000b0-00b0-0b00-00b0-000b000000bb",
+			"rel": "bookmark"
+		}
+	],
+	"name": "5.1"
+}
+`
+
+const version2JSON = `
+{
+	"id": "c00000b0-00c0-0c00-00c0-000b000000cc",
+	"links": [
+		{
+			"href": "https://10.240.28.38:8779/v1.0/1234/datastores/versions/c00000b0-00c0-0c00-00c0-000b000000cc",
+			"rel": "self"
+		},
+		{
+			"href": "https://10.240.28.38:8779/datastores/versions/c00000b0-00c0-0c00-00c0-000b000000cc",
+			"rel": "bookmark"
+		}
+	],
+	"name": "5.2"
+}
+`
+
+var versionsJSON = fmt.Sprintf(`"versions": [%s, %s]`, version1JSON, version2JSON)
+
+var singleDSJSON = fmt.Sprintf(`
+{
+  "default_version": "c00000b0-00c0-0c00-00c0-000b000000cc",
+  "id": "10000000-0000-0000-0000-000000000001",
+  "links": [
+    {
+      "href": "https://10.240.28.38:8779/v1.0/1234/datastores/10000000-0000-0000-0000-000000000001",
+      "rel": "self"
+    },
+    {
+      "href": "https://10.240.28.38:8779/datastores/10000000-0000-0000-0000-000000000001",
+      "rel": "bookmark"
+    }
+  ],
+  "name": "mysql",
+  %s
+}
+`, versionsJSON)
+
+var (
+	ListDSResp       = fmt.Sprintf(`{"datastores":[%s]}`, singleDSJSON)
+	GetDSResp        = fmt.Sprintf(`{"datastore":%s}`, singleDSJSON)
+	ListVersionsResp = fmt.Sprintf(`{%s}`, versionsJSON)
+	GetVersionResp   = fmt.Sprintf(`{"version":%s}`, version1JSON)
+)
+
+var ExampleVersion1 = Version{
+	ID: "b00000b0-00b0-0b00-00b0-000b000000bb",
+	Links: []gophercloud.Link{
+		gophercloud.Link{Rel: "self", Href: "https://10.240.28.38:8779/v1.0/1234/datastores/versions/b00000b0-00b0-0b00-00b0-000b000000bb"},
+		gophercloud.Link{Rel: "bookmark", Href: "https://10.240.28.38:8779/datastores/versions/b00000b0-00b0-0b00-00b0-000b000000bb"},
+	},
+	Name: "5.1",
+}
+
+var exampleVersion2 = Version{
+	ID: "c00000b0-00c0-0c00-00c0-000b000000cc",
+	Links: []gophercloud.Link{
+		gophercloud.Link{Rel: "self", Href: "https://10.240.28.38:8779/v1.0/1234/datastores/versions/c00000b0-00c0-0c00-00c0-000b000000cc"},
+		gophercloud.Link{Rel: "bookmark", Href: "https://10.240.28.38:8779/datastores/versions/c00000b0-00c0-0c00-00c0-000b000000cc"},
+	},
+	Name: "5.2",
+}
+
+var ExampleVersions = []Version{ExampleVersion1, exampleVersion2}
+
+var ExampleDatastore = Datastore{
+	DefaultVersion: "c00000b0-00c0-0c00-00c0-000b000000cc",
+	ID:             "10000000-0000-0000-0000-000000000001",
+	Links: []gophercloud.Link{
+		gophercloud.Link{Rel: "self", Href: "https://10.240.28.38:8779/v1.0/1234/datastores/10000000-0000-0000-0000-000000000001"},
+		gophercloud.Link{Rel: "bookmark", Href: "https://10.240.28.38:8779/datastores/10000000-0000-0000-0000-000000000001"},
+	},
+	Name:     "mysql",
+	Versions: ExampleVersions,
+}
diff --git a/openstack/db/v1/datastores/requests.go b/openstack/db/v1/datastores/requests.go
new file mode 100644
index 0000000..9e147ab
--- /dev/null
+++ b/openstack/db/v1/datastores/requests.go
@@ -0,0 +1,47 @@
+package datastores
+
+import (
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/pagination"
+)
+
+// List will list all available datastore types that instances can use.
+func List(client *gophercloud.ServiceClient) pagination.Pager {
+	pageFn := func(r pagination.PageResult) pagination.Page {
+		return DatastorePage{pagination.SinglePageBase(r)}
+	}
+	return pagination.NewPager(client, baseURL(client), pageFn)
+}
+
+// Get will retrieve the details of a specified datastore type.
+func Get(client *gophercloud.ServiceClient, datastoreID string) GetResult {
+	var res GetResult
+
+	_, res.Err = client.Request("GET", resourceURL(client, datastoreID), gophercloud.RequestOpts{
+		OkCodes:      []int{200},
+		JSONResponse: &res.Body,
+	})
+
+	return res
+}
+
+// ListVersions will list all of the available versions for a specified
+// datastore type.
+func ListVersions(client *gophercloud.ServiceClient, datastoreID string) pagination.Pager {
+	pageFn := func(r pagination.PageResult) pagination.Page {
+		return VersionPage{pagination.SinglePageBase(r)}
+	}
+	return pagination.NewPager(client, versionsURL(client, datastoreID), pageFn)
+}
+
+// GetVersion will retrieve the details of a specified datastore version.
+func GetVersion(client *gophercloud.ServiceClient, datastoreID, versionID string) GetVersionResult {
+	var res GetVersionResult
+
+	_, res.Err = client.Request("GET", versionURL(client, datastoreID, versionID), gophercloud.RequestOpts{
+		OkCodes:      []int{200},
+		JSONResponse: &res.Body,
+	})
+
+	return res
+}
diff --git a/openstack/db/v1/datastores/requests_test.go b/openstack/db/v1/datastores/requests_test.go
new file mode 100644
index 0000000..b4ce871
--- /dev/null
+++ b/openstack/db/v1/datastores/requests_test.go
@@ -0,0 +1,78 @@
+package datastores
+
+import (
+	"testing"
+
+	"github.com/rackspace/gophercloud/pagination"
+	th "github.com/rackspace/gophercloud/testhelper"
+	fake "github.com/rackspace/gophercloud/testhelper/client"
+	"github.com/rackspace/gophercloud/testhelper/fixture"
+)
+
+func TestList(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, "/datastores", "GET", "", ListDSResp, 200)
+
+	pages := 0
+
+	err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
+		pages++
+
+		actual, err := ExtractDatastores(page)
+		if err != nil {
+			return false, err
+		}
+
+		th.CheckDeepEquals(t, []Datastore{ExampleDatastore}, actual)
+
+		return true, nil
+	})
+
+	th.AssertNoErr(t, err)
+	th.AssertEquals(t, 1, pages)
+}
+
+func TestGet(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, "/datastores/{dsID}", "GET", "", GetDSResp, 200)
+
+	ds, err := Get(fake.ServiceClient(), "{dsID}").Extract()
+	th.AssertNoErr(t, err)
+	th.AssertDeepEquals(t, &ExampleDatastore, ds)
+}
+
+func TestListVersions(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, "/datastores/{dsID}/versions", "GET", "", ListVersionsResp, 200)
+
+	pages := 0
+
+	err := ListVersions(fake.ServiceClient(), "{dsID}").EachPage(func(page pagination.Page) (bool, error) {
+		pages++
+
+		actual, err := ExtractVersions(page)
+		if err != nil {
+			return false, err
+		}
+
+		th.CheckDeepEquals(t, ExampleVersions, actual)
+
+		return true, nil
+	})
+
+	th.AssertNoErr(t, err)
+	th.AssertEquals(t, 1, pages)
+}
+
+func TestGetVersion(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	fixture.SetupHandler(t, "/datastores/{dsID}/versions/{versionID}", "GET", "", GetVersionResp, 200)
+
+	ds, err := GetVersion(fake.ServiceClient(), "{dsID}", "{versionID}").Extract()
+	th.AssertNoErr(t, err)
+	th.AssertDeepEquals(t, &ExampleVersion1, ds)
+}
diff --git a/openstack/db/v1/datastores/results.go b/openstack/db/v1/datastores/results.go
new file mode 100644
index 0000000..a86a3cc
--- /dev/null
+++ b/openstack/db/v1/datastores/results.go
@@ -0,0 +1,123 @@
+package datastores
+
+import (
+	"github.com/mitchellh/mapstructure"
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/pagination"
+)
+
+// Version represents a version API resource. Multiple versions belong to a Datastore.
+type Version struct {
+	ID    string
+	Links []gophercloud.Link
+	Name  string
+}
+
+// Datastore represents a Datastore API resource.
+type Datastore struct {
+	DefaultVersion string `json:"default_version" mapstructure:"default_version"`
+	ID             string
+	Links          []gophercloud.Link
+	Name           string
+	Versions       []Version
+}
+
+// DatastorePartial is a meta structure which is used in various API responses.
+// It is a lightweight and truncated version of a full Datastore resource,
+// offering details of the Version, Type and VersionID only.
+type DatastorePartial struct {
+	Version   string
+	Type      string
+	VersionID string `json:"version_id" mapstructure:"version_id"`
+}
+
+// GetResult represents the result of a Get operation.
+type GetResult struct {
+	gophercloud.Result
+}
+
+// GetVersionResult represents the result of getting a version.
+type GetVersionResult struct {
+	gophercloud.Result
+}
+
+// DatastorePage represents a page of datastore resources.
+type DatastorePage struct {
+	pagination.SinglePageBase
+}
+
+// IsEmpty indicates whether a Datastore collection is empty.
+func (r DatastorePage) IsEmpty() (bool, error) {
+	is, err := ExtractDatastores(r)
+	if err != nil {
+		return true, err
+	}
+	return len(is) == 0, nil
+}
+
+// ExtractDatastores retrieves a slice of datastore structs from a paginated
+// collection.
+func ExtractDatastores(page pagination.Page) ([]Datastore, error) {
+	casted := page.(DatastorePage).Body
+
+	var resp struct {
+		Datastores []Datastore `mapstructure:"datastores" json:"datastores"`
+	}
+
+	err := mapstructure.Decode(casted, &resp)
+	return resp.Datastores, err
+}
+
+// Extract retrieves a single Datastore struct from an operation result.
+func (r GetResult) Extract() (*Datastore, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	var response struct {
+		Datastore Datastore `mapstructure:"datastore"`
+	}
+
+	err := mapstructure.Decode(r.Body, &response)
+	return &response.Datastore, err
+}
+
+// DatastorePage represents a page of version resources.
+type VersionPage struct {
+	pagination.SinglePageBase
+}
+
+// IsEmpty indicates whether a collection of version resources is empty.
+func (r VersionPage) IsEmpty() (bool, error) {
+	is, err := ExtractVersions(r)
+	if err != nil {
+		return true, err
+	}
+	return len(is) == 0, nil
+}
+
+// ExtractVersions retrieves a slice of versions from a paginated collection.
+func ExtractVersions(page pagination.Page) ([]Version, error) {
+	casted := page.(VersionPage).Body
+
+	var resp struct {
+		Versions []Version `mapstructure:"versions" json:"versions"`
+	}
+
+	err := mapstructure.Decode(casted, &resp)
+	return resp.Versions, err
+}
+
+// Extract retrieves a single Version struct from an operation result.
+func (r GetVersionResult) Extract() (*Version, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	var response struct {
+		Version Version `mapstructure:"version"`
+	}
+
+	err := mapstructure.Decode(r.Body, &response)
+	return &response.Version, err
+}
diff --git a/openstack/db/v1/datastores/urls.go b/openstack/db/v1/datastores/urls.go
new file mode 100644
index 0000000..c4d5248
--- /dev/null
+++ b/openstack/db/v1/datastores/urls.go
@@ -0,0 +1,19 @@
+package datastores
+
+import "github.com/rackspace/gophercloud"
+
+func baseURL(c *gophercloud.ServiceClient) string {
+	return c.ServiceURL("datastores")
+}
+
+func resourceURL(c *gophercloud.ServiceClient, dsID string) string {
+	return c.ServiceURL("datastores", dsID)
+}
+
+func versionsURL(c *gophercloud.ServiceClient, dsID string) string {
+	return c.ServiceURL("datastores", dsID, "versions")
+}
+
+func versionURL(c *gophercloud.ServiceClient, dsID, versionID string) string {
+	return c.ServiceURL("datastores", dsID, "versions", versionID)
+}
diff --git a/openstack/db/v1/instances/fixtures.go b/openstack/db/v1/instances/fixtures.go
index 502d87f..9b4b209 100644
--- a/openstack/db/v1/instances/fixtures.go
+++ b/openstack/db/v1/instances/fixtures.go
@@ -5,6 +5,7 @@
 	"testing"
 
 	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/openstack/db/v1/datastores"
 	"github.com/rackspace/gophercloud/openstack/db/v1/flavors"
 	"github.com/rackspace/gophercloud/testhelper/fixture"
 )
@@ -119,6 +120,10 @@
 	Name:   "json_rack_instance",
 	Status: "BUILD",
 	Volume: Volume{Size: 2},
+	Datastore: datastores.DatastorePartial{
+		Type:    "mysql",
+		Version: "5.6",
+	},
 }
 
 func HandleCreate(t *testing.T) {
diff --git a/openstack/db/v1/instances/requests.go b/openstack/db/v1/instances/requests.go
index 1872d75..bd70295 100644
--- a/openstack/db/v1/instances/requests.go
+++ b/openstack/db/v1/instances/requests.go
@@ -179,7 +179,7 @@
 	var res ActionResult
 
 	_, res.Err = client.Request("POST", actionURL(client, id), gophercloud.RequestOpts{
-		JSONBody: map[string]interface{}{"restart": map[string]string{}},
+		JSONBody: map[string]interface{}{"restart": true},
 		OkCodes:  []int{202},
 	})
 
diff --git a/openstack/db/v1/instances/results.go b/openstack/db/v1/instances/results.go
index b7eeb86..61dc021 100644
--- a/openstack/db/v1/instances/results.go
+++ b/openstack/db/v1/instances/results.go
@@ -3,10 +3,10 @@
 import (
 	"github.com/mitchellh/mapstructure"
 	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/openstack/db/v1/datastores"
 	"github.com/rackspace/gophercloud/openstack/db/v1/flavors"
 	"github.com/rackspace/gophercloud/openstack/db/v1/users"
 	"github.com/rackspace/gophercloud/pagination"
-	"github.com/rackspace/gophercloud/rackspace/db/v1/datastores"
 )
 
 // Volume represents information about an attached volume for a database instance.