db: fix flavor id parsing (#197)

* Flavor IDs returned with instances are always strings
* Flavor IDs returned with flavors are integers or null, there is a
  str_id parameter that contains the ID in string format
diff --git a/openstack/db/v1/flavors/results.go b/openstack/db/v1/flavors/results.go
index f74f20c..0ba515c 100644
--- a/openstack/db/v1/flavors/results.go
+++ b/openstack/db/v1/flavors/results.go
@@ -22,6 +22,7 @@
 // Flavor records represent (virtual) hardware configurations for server resources in a region.
 type Flavor struct {
 	// The flavor's unique identifier.
+	// Contains 0 if the ID is not an integer.
 	ID int `json:"id"`
 
 	// The RAM capacity for the flavor.
@@ -32,6 +33,9 @@
 
 	// Links to access the flavor.
 	Links []gophercloud.Link
+
+	// The flavor's unique identifier as a string
+	StrID string `json:"str_id"`
 }
 
 // FlavorPage contains a single page of the response from a List call.
diff --git a/openstack/db/v1/flavors/testing/fixtures.go b/openstack/db/v1/flavors/testing/fixtures.go
index b2b2d5f..9c323b8 100644
--- a/openstack/db/v1/flavors/testing/fixtures.go
+++ b/openstack/db/v1/flavors/testing/fixtures.go
@@ -9,19 +9,20 @@
 
 const flavor = `
 {
-	"id": %d,
+	"id": %s,
 	"links": [
 		{
-			"href": "https://openstack.example.com/v1.0/1234/flavors/%d",
+			"href": "https://openstack.example.com/v1.0/1234/flavors/%s",
 			"rel": "self"
 		},
 		{
-			"href": "https://openstack.example.com/flavors/%d",
+			"href": "https://openstack.example.com/flavors/%s",
 			"rel": "bookmark"
 		}
 	],
 	"name": "%s",
-	"ram": %d
+	"ram": %d,
+	"str_id": "%s"
 }
 `
 
@@ -32,12 +33,13 @@
 )
 
 var (
-	flavor1 = fmt.Sprintf(flavor, 1, 1, 1, "m1.tiny", 512)
-	flavor2 = fmt.Sprintf(flavor, 2, 2, 2, "m1.small", 1024)
-	flavor3 = fmt.Sprintf(flavor, 3, 3, 3, "m1.medium", 2048)
-	flavor4 = fmt.Sprintf(flavor, 4, 4, 4, "m1.large", 4096)
+	flavor1 = fmt.Sprintf(flavor, "1", "1", "1", "m1.tiny", 512, "1")
+	flavor2 = fmt.Sprintf(flavor, "2", "2", "2", "m1.small", 1024, "2")
+	flavor3 = fmt.Sprintf(flavor, "3", "3", "3", "m1.medium", 2048, "3")
+	flavor4 = fmt.Sprintf(flavor, "4", "4", "4", "m1.large", 4096, "4")
+	flavor5 = fmt.Sprintf(flavor, "null", "d1", "d1", "ds512M", 512, "d1")
 
-	listFlavorsResp = fmt.Sprintf(`{"flavors":[%s, %s, %s, %s]}`, flavor1, flavor2, flavor3, flavor4)
+	listFlavorsResp = fmt.Sprintf(`{"flavors":[%s, %s, %s, %s, %s]}`, flavor1, flavor2, flavor3, flavor4, flavor5)
 	getFlavorResp   = fmt.Sprintf(`{"flavor": %s}`, flavor1)
 )
 
diff --git a/openstack/db/v1/flavors/testing/requests_test.go b/openstack/db/v1/flavors/testing/requests_test.go
index cbc0edd..e8b580a 100644
--- a/openstack/db/v1/flavors/testing/requests_test.go
+++ b/openstack/db/v1/flavors/testing/requests_test.go
@@ -33,6 +33,7 @@
 					{Href: "https://openstack.example.com/v1.0/1234/flavors/1", Rel: "self"},
 					{Href: "https://openstack.example.com/flavors/1", Rel: "bookmark"},
 				},
+				StrID: "1",
 			},
 			{
 				ID:   2,
@@ -42,6 +43,7 @@
 					{Href: "https://openstack.example.com/v1.0/1234/flavors/2", Rel: "self"},
 					{Href: "https://openstack.example.com/flavors/2", Rel: "bookmark"},
 				},
+				StrID: "2",
 			},
 			{
 				ID:   3,
@@ -51,6 +53,7 @@
 					{Href: "https://openstack.example.com/v1.0/1234/flavors/3", Rel: "self"},
 					{Href: "https://openstack.example.com/flavors/3", Rel: "bookmark"},
 				},
+				StrID: "3",
 			},
 			{
 				ID:   4,
@@ -60,6 +63,17 @@
 					{Href: "https://openstack.example.com/v1.0/1234/flavors/4", Rel: "self"},
 					{Href: "https://openstack.example.com/flavors/4", Rel: "bookmark"},
 				},
+				StrID: "4",
+			},
+			{
+				ID:   0,
+				Name: "ds512M",
+				RAM:  512,
+				Links: []gophercloud.Link{
+					{Href: "https://openstack.example.com/v1.0/1234/flavors/d1", Rel: "self"},
+					{Href: "https://openstack.example.com/flavors/d1", Rel: "bookmark"},
+				},
+				StrID: "d1",
 			},
 		}
 
@@ -86,6 +100,7 @@
 		Links: []gophercloud.Link{
 			{Href: "https://openstack.example.com/v1.0/1234/flavors/1", Rel: "self"},
 		},
+		StrID: "1",
 	}
 
 	th.AssertDeepEquals(t, expected, actual)