1package instances 2 3import ( 4 "encoding/json" 5 "time" 6 7 "github.com/gophercloud/gophercloud" 8 "github.com/gophercloud/gophercloud/openstack/db/v1/datastores" 9 "github.com/gophercloud/gophercloud/openstack/db/v1/users" 10 "github.com/gophercloud/gophercloud/pagination" 11) 12 13// Volume represents information about an attached volume for a database instance. 14type Volume struct { 15 // The size in GB of the volume 16 Size int 17 18 Used float64 19} 20 21// Flavor represents (virtual) hardware configurations for server resources in a region. 22type Flavor struct { 23 // The flavor's unique identifier. 24 ID string 25 // Links to access the flavor. 26 Links []gophercloud.Link 27} 28 29// Fault describes the fault reason in more detail when a database instance has errored 30type Fault struct { 31 // Indicates the time when the fault occured 32 Created time.Time `json:"-"` 33 34 // A message describing the fault reason 35 Message string 36 37 // More details about the fault, for example a stack trace. Only filled 38 // in for admin users. 39 Details string 40} 41 42func (r *Fault) UnmarshalJSON(b []byte) error { 43 type tmp Fault 44 var s struct { 45 tmp 46 Created gophercloud.JSONRFC3339NoZ `json:"created"` 47 } 48 err := json.Unmarshal(b, &s) 49 if err != nil { 50 return err 51 } 52 *r = Fault(s.tmp) 53 54 r.Created = time.Time(s.Created) 55 56 return nil 57} 58 59// Instance represents a remote MySQL instance. 60type Instance struct { 61 // Indicates the datetime that the instance was created 62 Created time.Time `json:"-"` 63 64 // Indicates the most recent datetime that the instance was updated. 65 Updated time.Time `json:"-"` 66 67 // Indicates the hardware flavor the instance uses. 68 Flavor Flavor 69 70 // A DNS-resolvable hostname associated with the database instance (rather 71 // than an IPv4 address). Since the hostname always resolves to the correct 72 // IP address of the database instance, this relieves the user from the task 73 // of maintaining the mapping. Note that although the IP address may likely 74 // change on resizing, migrating, and so forth, the hostname always resolves 75 // to the correct database instance. 76 Hostname string 77 78 // The IP addresses associated with the database instance 79 // Is empty if the instance has a hostname 80 IP []string 81 82 // Indicates the unique identifier for the instance resource. 83 ID string 84 85 // Exposes various links that reference the instance resource. 86 Links []gophercloud.Link 87 88 // The human-readable name of the instance. 89 Name string 90 91 // The build status of the instance. 92 Status string 93 94 // Fault information (only available when the instance has errored) 95 Fault *Fault 96 97 // Information about the attached volume of the instance. 98 Volume Volume 99 100 // Indicates how the instance stores data. 101 Datastore datastores.DatastorePartial 102} 103 104func (r *Instance) UnmarshalJSON(b []byte) error { 105 type tmp Instance 106 var s struct { 107 tmp 108 Created gophercloud.JSONRFC3339NoZ `json:"created"` 109 Updated gophercloud.JSONRFC3339NoZ `json:"updated"` 110 } 111 err := json.Unmarshal(b, &s) 112 if err != nil { 113 return err 114 } 115 *r = Instance(s.tmp) 116 117 r.Created = time.Time(s.Created) 118 r.Updated = time.Time(s.Updated) 119 120 return nil 121} 122 123type commonResult struct { 124 gophercloud.Result 125} 126 127// CreateResult represents the result of a Create operation. 128type CreateResult struct { 129 commonResult 130} 131 132// GetResult represents the result of a Get operation. 133type GetResult struct { 134 commonResult 135} 136 137// DeleteResult represents the result of a Delete operation. 138type DeleteResult struct { 139 gophercloud.ErrResult 140} 141 142// ConfigurationResult represents the result of a AttachConfigurationGroup/DetachConfigurationGroup operation. 143type ConfigurationResult struct { 144 gophercloud.ErrResult 145} 146 147// Extract will extract an Instance from various result structs. 148func (r commonResult) Extract() (*Instance, error) { 149 var s struct { 150 Instance *Instance `json:"instance"` 151 } 152 err := r.ExtractInto(&s) 153 return s.Instance, err 154} 155 156// InstancePage represents a single page of a paginated instance collection. 157type InstancePage struct { 158 pagination.LinkedPageBase 159} 160 161// IsEmpty checks to see whether the collection is empty. 162func (page InstancePage) IsEmpty() (bool, error) { 163 instances, err := ExtractInstances(page) 164 return len(instances) == 0, err 165} 166 167// NextPageURL will retrieve the next page URL. 168func (page InstancePage) NextPageURL() (string, error) { 169 var s struct { 170 Links []gophercloud.Link `json:"instances_links"` 171 } 172 err := page.ExtractInto(&s) 173 if err != nil { 174 return "", err 175 } 176 return gophercloud.ExtractNextURL(s.Links) 177} 178 179// ExtractInstances will convert a generic pagination struct into a more 180// relevant slice of Instance structs. 181func ExtractInstances(r pagination.Page) ([]Instance, error) { 182 var s struct { 183 Instances []Instance `json:"instances"` 184 } 185 err := (r.(InstancePage)).ExtractInto(&s) 186 return s.Instances, err 187} 188 189// EnableRootUserResult represents the result of an operation to enable the root user. 190type EnableRootUserResult struct { 191 gophercloud.Result 192} 193 194// Extract will extract root user information from a UserRootResult. 195func (r EnableRootUserResult) Extract() (*users.User, error) { 196 var s struct { 197 User *users.User `json:"user"` 198 } 199 err := r.ExtractInto(&s) 200 return s.User, err 201} 202 203// ActionResult represents the result of action requests, such as: restarting 204// an instance service, resizing its memory allocation, and resizing its 205// attached volume size. 206type ActionResult struct { 207 gophercloud.ErrResult 208} 209 210// IsRootEnabledResult is the result of a call to IsRootEnabled. To see if 211// root is enabled, call the type's Extract method. 212type IsRootEnabledResult struct { 213 gophercloud.Result 214} 215 216// Extract is used to extract the data from a IsRootEnabledResult. 217func (r IsRootEnabledResult) Extract() (bool, error) { 218 return r.Body.(map[string]interface{})["rootEnabled"] == true, r.Err 219} 220