Add ability to list flavors
diff --git a/acceptance/openstack/compute_test.go b/acceptance/openstack/compute_test.go
index 27386ed..7a478e0 100644
--- a/acceptance/openstack/compute_test.go
+++ b/acceptance/openstack/compute_test.go
@@ -5,6 +5,7 @@
 	"fmt"
 	"github.com/rackspace/gophercloud/openstack/compute/servers"
 	"github.com/rackspace/gophercloud/openstack/compute/images"
+	"github.com/rackspace/gophercloud/openstack/compute/flavors"
 	"github.com/rackspace/gophercloud/openstack/identity"
 	"github.com/rackspace/gophercloud/openstack/utils"
 	"os"
@@ -137,7 +138,7 @@
 		return
 	}
 
-	fmt.Fprintln(ts.w, "ID\tRegion\tName\tStatus\tCreated\t")
+	fmt.Fprintln(ts.w, "ID\tRegion\tName\tRAM\tDisk\tVCPUs\t")
 
 	region := os.Getenv("OS_REGION_NAME")
 	n := 0
@@ -163,7 +164,7 @@
 		n = n + len(flavs)
 
 		for _, f := range flavs {
-			fmt.Fprintf(ts.w, "%s\t%s\t%s\t%s\t%s\t\n", f.Id, ep.Region, f.Name, f.Status, f.Created)
+			fmt.Fprintf(ts.w, "%s\t%s\t%s\t%d\t%d\t%d\t\n", f.Id, ep.Region, f.Name, f.Ram, f.Disk, f.VCpus)
 		}
 	}
 	ts.w.Flush()
diff --git a/openstack/compute/flavors/client.go b/openstack/compute/flavors/client.go
new file mode 100644
index 0000000..5ad97af
--- /dev/null
+++ b/openstack/compute/flavors/client.go
@@ -0,0 +1,35 @@
+package flavors
+
+import (
+	"github.com/rackspace/gophercloud/openstack/identity"
+)
+
+type Client struct {
+	endpoint string
+	authority identity.AuthResults
+	options identity.AuthOptions
+}
+
+func NewClient(e string, a identity.AuthResults, ao identity.AuthOptions) *Client {
+	return &Client{
+		endpoint: e,
+		authority: a,
+		options: ao,
+	}
+}
+
+func (c *Client) getListUrl() string {
+	return c.endpoint + "/flavors/detail"
+}
+
+func (c *Client) getListHeaders() (map[string]string, error) {
+	t, err := identity.GetToken(c.authority)
+	if err != nil {
+		return map[string]string{}, err
+	}
+
+	return map[string]string{
+		"X-Auth-Token": t.Id,
+	}, nil
+}
+
diff --git a/openstack/compute/flavors/flavors.go b/openstack/compute/flavors/flavors.go
new file mode 100644
index 0000000..b66115f
--- /dev/null
+++ b/openstack/compute/flavors/flavors.go
@@ -0,0 +1,64 @@
+package flavors
+
+import (
+	"github.com/mitchellh/mapstructure"
+	"reflect"
+)
+
+
+// Flavor records represent (virtual) hardware configurations for server resources in a region.
+//
+// The Id field contains the flavor's unique identifier.
+// For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance.
+//
+// The Disk and Ram fields provide a measure of storage space offered by the flavor, in GB and MB, respectively.
+//
+// The Name field provides a human-readable moniker for the flavor.
+//
+// Swap indicates how much space is reserved for swap.
+// If not provided, this field will be set to 0.
+//
+// VCpus indicates how many (virtual) CPUs are available for this flavor.
+type Flavor struct {
+	Disk          int
+	Id            string
+	Name          string
+	Ram           int
+	RxTxFactor    float64	`mapstructure:"rxtx_factor"`
+	Swap          int
+	VCpus         int
+}
+
+func defaulter(from, to reflect.Kind, v interface{}) (interface{}, error) {
+	if (from == reflect.String) && (to == reflect.Int) {
+		return 0, nil
+	}
+	return v, nil
+}
+
+func GetFlavors(lr ListResults) ([]Flavor, error) {
+	fa, ok := lr["flavors"]
+	if !ok {
+		return nil, ErrNotImplemented
+	}
+	fms := fa.([]interface{})
+
+	flavors := make([]Flavor, len(fms))
+	for i, fm := range fms {
+		flavorObj := fm.(map[string]interface{})
+		cfg := &mapstructure.DecoderConfig{
+			DecodeHook: defaulter,
+			Result: &flavors[i],
+		}
+		decoder, err := mapstructure.NewDecoder(cfg)
+		if err != nil {
+			return flavors, err
+		}
+		err = decoder.Decode(flavorObj)
+		if err != nil {
+			return flavors, err
+		}
+	}
+	return flavors, nil
+}
+
diff --git a/openstack/compute/flavors/requests.go b/openstack/compute/flavors/requests.go
new file mode 100644
index 0000000..c76e5af
--- /dev/null
+++ b/openstack/compute/flavors/requests.go
@@ -0,0 +1,27 @@
+package flavors
+
+import (
+	"fmt"
+	"github.com/racker/perigee"
+)
+
+
+var ErrNotImplemented = fmt.Errorf("Flavors functionality not implemented.")
+
+type ListResults map[string]interface{}
+
+func List(c *Client) (ListResults, error) {
+	var lr ListResults
+
+	h, err := c.getListHeaders()
+	if err != nil {
+		return nil, err
+	}
+
+	err = perigee.Get(c.getListUrl(), perigee.Options{
+		Results: &lr,
+		MoreHeaders: h,
+	})
+	return lr, err
+}
+