Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 1 | package instances |
| 2 | |
| 3 | import ( |
Jon Perritt | 27249f4 | 2016-02-18 10:35:59 -0600 | [diff] [blame] | 4 | "github.com/gophercloud/gophercloud" |
| 5 | db "github.com/gophercloud/gophercloud/openstack/db/v1/databases" |
| 6 | "github.com/gophercloud/gophercloud/openstack/db/v1/users" |
| 7 | "github.com/gophercloud/gophercloud/pagination" |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 8 | ) |
| 9 | |
| 10 | // CreateOptsBuilder is the top-level interface for create options. |
| 11 | type CreateOptsBuilder interface { |
| 12 | ToInstanceCreateMap() (map[string]interface{}, error) |
| 13 | } |
| 14 | |
Jamie Hannaford | 99eced5 | 2015-03-02 15:24:22 +0100 | [diff] [blame] | 15 | // DatastoreOpts represents the configuration for how an instance stores data. |
| 16 | type DatastoreOpts struct { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 17 | Version string `json:"version"` |
| 18 | Type string `json:"type"` |
Jamie Hannaford | 99eced5 | 2015-03-02 15:24:22 +0100 | [diff] [blame] | 19 | } |
| 20 | |
Jon Perritt | 763e592 | 2016-03-07 03:21:18 -0600 | [diff] [blame] | 21 | // ToMap converts a DatastoreOpts to a map[string]string (for a request body) |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 22 | func (opts DatastoreOpts) ToMap() (map[string]interface{}, error) { |
| 23 | return gophercloud.BuildRequestBody(opts, "") |
Jamie Hannaford | 99eced5 | 2015-03-02 15:24:22 +0100 | [diff] [blame] | 24 | } |
| 25 | |
esalipe | 10a2744 | 2017-02-14 06:11:01 +0200 | [diff] [blame] | 26 | // NetworkOpts is used within CreateOpts to control a new server's network attachments. |
| 27 | type NetworkOpts struct { |
| 28 | // UUID of a nova-network to attach to the newly provisioned server. |
| 29 | // Required unless Port is provided. |
| 30 | UUID string `json:"net-id,omitempty"` |
| 31 | |
| 32 | // Port of a neutron network to attach to the newly provisioned server. |
| 33 | // Required unless UUID is provided. |
| 34 | Port string `json:"port-id,omitempty"` |
| 35 | |
| 36 | // V4FixedIP [optional] specifies a fixed IPv4 address to be used on this network. |
| 37 | V4FixedIP string `json:"v4-fixed-ip,omitempty"` |
| 38 | |
| 39 | // V6FixedIP [optional] specifies a fixed IPv6 address to be used on this network. |
| 40 | V6FixedIP string `json:"v6-fixed-ip,omitempty"` |
| 41 | } |
| 42 | |
| 43 | // ToMap converts a NetworkOpts to a map[string]string (for a request body) |
| 44 | func (opts NetworkOpts) ToMap() (map[string]interface{}, error) { |
| 45 | return gophercloud.BuildRequestBody(opts, "") |
| 46 | } |
| 47 | |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 48 | // CreateOpts is the struct responsible for configuring a new database instance. |
| 49 | type CreateOpts struct { |
| 50 | // Either the integer UUID (in string form) of the flavor, or its URI |
| 51 | // reference as specified in the response from the List() call. Required. |
| 52 | FlavorRef string |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 53 | // Specifies the volume size in gigabytes (GB). The value must be between 1 |
| 54 | // and 300. Required. |
| 55 | Size int |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 56 | // Name of the instance to create. The length of the name is limited to |
| 57 | // 255 characters and any characters are permitted. Optional. |
| 58 | Name string |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 59 | // A slice of database information options. |
Jamie Hannaford | 2e695a3 | 2015-11-16 16:36:10 +0100 | [diff] [blame] | 60 | Databases db.CreateOptsBuilder |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 61 | // A slice of user information options. |
Jamie Hannaford | 2e695a3 | 2015-11-16 16:36:10 +0100 | [diff] [blame] | 62 | Users users.CreateOptsBuilder |
Jamie Hannaford | 99eced5 | 2015-03-02 15:24:22 +0100 | [diff] [blame] | 63 | // Options to configure the type of datastore the instance will use. This is |
| 64 | // optional, and if excluded will default to MySQL. |
| 65 | Datastore *DatastoreOpts |
esalipe | 10a2744 | 2017-02-14 06:11:01 +0200 | [diff] [blame] | 66 | // Networks dictates how this server will be attached to available networks. |
| 67 | Networks []NetworkOpts |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 68 | } |
| 69 | |
Jamie Hannaford | 9793d94 | 2015-02-18 15:13:20 +0100 | [diff] [blame] | 70 | // ToInstanceCreateMap will render a JSON map. |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 71 | func (opts CreateOpts) ToInstanceCreateMap() (map[string]interface{}, error) { |
| 72 | if opts.Size > 300 || opts.Size < 1 { |
Jon Perritt | 763e592 | 2016-03-07 03:21:18 -0600 | [diff] [blame] | 73 | err := gophercloud.ErrInvalidInput{} |
Jon Perritt | 763e592 | 2016-03-07 03:21:18 -0600 | [diff] [blame] | 74 | err.Argument = "instances.CreateOpts.Size" |
| 75 | err.Value = opts.Size |
| 76 | err.Info = "Size (GB) must be between 1-300" |
| 77 | return nil, err |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 78 | } |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 79 | |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 80 | if opts.FlavorRef == "" { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 81 | return nil, gophercloud.ErrMissingInput{Argument: "instances.CreateOpts.FlavorRef"} |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | instance := map[string]interface{}{ |
| 85 | "volume": map[string]int{"size": opts.Size}, |
| 86 | "flavorRef": opts.FlavorRef, |
| 87 | } |
| 88 | |
| 89 | if opts.Name != "" { |
| 90 | instance["name"] = opts.Name |
| 91 | } |
Jamie Hannaford | 2e695a3 | 2015-11-16 16:36:10 +0100 | [diff] [blame] | 92 | if opts.Databases != nil { |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 93 | dbs, err := opts.Databases.ToDBCreateMap() |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 94 | if err != nil { |
| 95 | return nil, err |
| 96 | } |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 97 | instance["databases"] = dbs["databases"] |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 98 | } |
Jamie Hannaford | 2e695a3 | 2015-11-16 16:36:10 +0100 | [diff] [blame] | 99 | if opts.Users != nil { |
Jamie Hannaford | 2ca55d8 | 2015-02-12 14:21:55 +0100 | [diff] [blame] | 100 | users, err := opts.Users.ToUserCreateMap() |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 101 | if err != nil { |
| 102 | return nil, err |
| 103 | } |
Jamie Hannaford | 2ca55d8 | 2015-02-12 14:21:55 +0100 | [diff] [blame] | 104 | instance["users"] = users["users"] |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 105 | } |
Jon Perritt | 763e592 | 2016-03-07 03:21:18 -0600 | [diff] [blame] | 106 | if opts.Datastore != nil { |
| 107 | datastore, err := opts.Datastore.ToMap() |
| 108 | if err != nil { |
| 109 | return nil, err |
| 110 | } |
| 111 | instance["datastore"] = datastore |
| 112 | } |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 113 | |
esalipe | 10a2744 | 2017-02-14 06:11:01 +0200 | [diff] [blame] | 114 | if len(opts.Networks) > 0 { |
| 115 | networks := make([]map[string]interface{}, len(opts.Networks)) |
| 116 | for i, net := range opts.Networks { |
| 117 | var err error |
| 118 | networks[i], err = net.ToMap() |
| 119 | if err != nil { |
| 120 | return nil, err |
| 121 | } |
| 122 | } |
| 123 | instance["nics"] = networks |
| 124 | } |
| 125 | |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 126 | return map[string]interface{}{"instance": instance}, nil |
| 127 | } |
| 128 | |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 129 | // Create asynchronously provisions a new database instance. It requires the |
| 130 | // user to specify a flavor and a volume size. The API service then provisions |
| 131 | // the instance with the requested flavor and sets up a volume of the specified |
| 132 | // size, which is the storage for the database instance. |
| 133 | // |
| 134 | // Although this call only allows the creation of 1 instance per request, you |
| 135 | // can create an instance with multiple databases and users. The default |
| 136 | // binding for a MySQL instance is port 3306. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 137 | func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 138 | b, err := opts.ToInstanceCreateMap() |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 139 | if err != nil { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 140 | r.Err = err |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 141 | return |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 142 | } |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 143 | _, r.Err = client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}}) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 144 | return |
Jamie Hannaford | 9fdda58 | 2015-02-10 12:15:43 +0100 | [diff] [blame] | 145 | } |
Jamie Hannaford | 9068424 | 2015-02-10 12:46:07 +0100 | [diff] [blame] | 146 | |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 147 | // List retrieves the status and information for all database instances. |
Jamie Hannaford | 9068424 | 2015-02-10 12:46:07 +0100 | [diff] [blame] | 148 | func List(client *gophercloud.ServiceClient) pagination.Pager { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 149 | return pagination.NewPager(client, baseURL(client), func(r pagination.PageResult) pagination.Page { |
Jamie Hannaford | 9068424 | 2015-02-10 12:46:07 +0100 | [diff] [blame] | 150 | return InstancePage{pagination.LinkedPageBase{PageResult: r}} |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 151 | }) |
Jamie Hannaford | 9068424 | 2015-02-10 12:46:07 +0100 | [diff] [blame] | 152 | } |
Jamie Hannaford | 821015f | 2015-02-10 12:58:36 +0100 | [diff] [blame] | 153 | |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 154 | // Get retrieves the status and information for a specified database instance. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 155 | func Get(client *gophercloud.ServiceClient, id string) (r GetResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 156 | _, r.Err = client.Get(resourceURL(client, id), &r.Body, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 157 | return |
Jamie Hannaford | 821015f | 2015-02-10 12:58:36 +0100 | [diff] [blame] | 158 | } |
Jamie Hannaford | 5b16b63 | 2015-02-10 13:36:23 +0100 | [diff] [blame] | 159 | |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 160 | // Delete permanently destroys the database instance. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 161 | func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 162 | _, r.Err = client.Delete(resourceURL(client, id), nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 163 | return |
Jamie Hannaford | 5b16b63 | 2015-02-10 13:36:23 +0100 | [diff] [blame] | 164 | } |
Jamie Hannaford | 94164fa | 2015-02-10 13:58:45 +0100 | [diff] [blame] | 165 | |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 166 | // EnableRootUser enables the login from any host for the root user and |
| 167 | // provides the user with a generated root password. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 168 | func EnableRootUser(client *gophercloud.ServiceClient, id string) (r EnableRootUserResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 169 | _, r.Err = client.Post(userRootURL(client, id), nil, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}}) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 170 | return |
Jamie Hannaford | 94164fa | 2015-02-10 13:58:45 +0100 | [diff] [blame] | 171 | } |
Jamie Hannaford | a74d425 | 2015-02-10 15:35:01 +0100 | [diff] [blame] | 172 | |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 173 | // IsRootEnabled checks an instance to see if root access is enabled. It returns |
| 174 | // True if root user is enabled for the specified database instance or False |
| 175 | // otherwise. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 176 | func IsRootEnabled(client *gophercloud.ServiceClient, id string) (r IsRootEnabledResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 177 | _, r.Err = client.Get(userRootURL(client, id), &r.Body, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 178 | return |
Jamie Hannaford | a74d425 | 2015-02-10 15:35:01 +0100 | [diff] [blame] | 179 | } |
Jamie Hannaford | 219ca59 | 2015-02-10 15:59:05 +0100 | [diff] [blame] | 180 | |
Jamie Hannaford | 75e8cc4 | 2015-11-16 14:09:25 +0100 | [diff] [blame] | 181 | // Restart will restart only the MySQL Instance. Restarting MySQL will |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 182 | // erase any dynamic configuration settings that you have made within MySQL. |
| 183 | // The MySQL service will be unavailable until the instance restarts. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 184 | func Restart(client *gophercloud.ServiceClient, id string) (r ActionResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 185 | b := map[string]interface{}{"restart": struct{}{}} |
| 186 | _, r.Err = client.Post(actionURL(client, id), &b, nil, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 187 | return |
Jamie Hannaford | 219ca59 | 2015-02-10 15:59:05 +0100 | [diff] [blame] | 188 | } |
| 189 | |
Jamie Hannaford | 75e8cc4 | 2015-11-16 14:09:25 +0100 | [diff] [blame] | 190 | // Resize changes the memory size of the instance, assuming a valid |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 191 | // flavorRef is provided. It will also restart the MySQL service. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 192 | func Resize(client *gophercloud.ServiceClient, id, flavorRef string) (r ActionResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 193 | b := map[string]interface{}{"resize": map[string]string{"flavorRef": flavorRef}} |
| 194 | _, r.Err = client.Post(actionURL(client, id), &b, nil, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 195 | return |
Jamie Hannaford | 219ca59 | 2015-02-10 15:59:05 +0100 | [diff] [blame] | 196 | } |
| 197 | |
Jamie Hannaford | 56d0c2e | 2015-02-12 11:50:18 +0100 | [diff] [blame] | 198 | // ResizeVolume will resize the attached volume for an instance. It supports |
| 199 | // only increasing the volume size and does not support decreasing the size. |
| 200 | // The volume size is in gigabytes (GB) and must be an integer. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 201 | func ResizeVolume(client *gophercloud.ServiceClient, id string, size int) (r ActionResult) { |
Jon Perritt | db0ae14 | 2016-03-13 00:33:41 -0600 | [diff] [blame] | 202 | b := map[string]interface{}{"resize": map[string]interface{}{"volume": map[string]int{"size": size}}} |
| 203 | _, r.Err = client.Post(actionURL(client, id), &b, nil, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 204 | return |
Jamie Hannaford | 219ca59 | 2015-02-10 15:59:05 +0100 | [diff] [blame] | 205 | } |