blob: b8cae03e3dd709471879585d25ac2171674bb9e4 [file] [log] [blame]
Jamie Hannaford9fdda582015-02-10 12:15:43 +01001package instances
2
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "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 Hannaford9fdda582015-02-10 12:15:43 +01008)
9
10// CreateOptsBuilder is the top-level interface for create options.
11type CreateOptsBuilder interface {
12 ToInstanceCreateMap() (map[string]interface{}, error)
13}
14
Jamie Hannaford99eced52015-03-02 15:24:22 +010015// DatastoreOpts represents the configuration for how an instance stores data.
16type DatastoreOpts struct {
Jon Perrittdb0ae142016-03-13 00:33:41 -060017 Version string `json:"version"`
18 Type string `json:"type"`
Jamie Hannaford99eced52015-03-02 15:24:22 +010019}
20
Jon Perritt763e5922016-03-07 03:21:18 -060021// ToMap converts a DatastoreOpts to a map[string]string (for a request body)
Jon Perrittdb0ae142016-03-13 00:33:41 -060022func (opts DatastoreOpts) ToMap() (map[string]interface{}, error) {
23 return gophercloud.BuildRequestBody(opts, "")
Jamie Hannaford99eced52015-03-02 15:24:22 +010024}
25
Jamie Hannaford9fdda582015-02-10 12:15:43 +010026// CreateOpts is the struct responsible for configuring a new database instance.
27type CreateOpts struct {
28 // Either the integer UUID (in string form) of the flavor, or its URI
29 // reference as specified in the response from the List() call. Required.
30 FlavorRef string
Jamie Hannaford9fdda582015-02-10 12:15:43 +010031 // Specifies the volume size in gigabytes (GB). The value must be between 1
32 // and 300. Required.
33 Size int
Jamie Hannaford9fdda582015-02-10 12:15:43 +010034 // Name of the instance to create. The length of the name is limited to
35 // 255 characters and any characters are permitted. Optional.
36 Name string
Jamie Hannaford9fdda582015-02-10 12:15:43 +010037 // A slice of database information options.
Jamie Hannaford2e695a32015-11-16 16:36:10 +010038 Databases db.CreateOptsBuilder
Jamie Hannaford9fdda582015-02-10 12:15:43 +010039 // A slice of user information options.
Jamie Hannaford2e695a32015-11-16 16:36:10 +010040 Users users.CreateOptsBuilder
Jamie Hannaford99eced52015-03-02 15:24:22 +010041 // Options to configure the type of datastore the instance will use. This is
42 // optional, and if excluded will default to MySQL.
43 Datastore *DatastoreOpts
Jamie Hannaford9fdda582015-02-10 12:15:43 +010044}
45
Jamie Hannaford9793d942015-02-18 15:13:20 +010046// ToInstanceCreateMap will render a JSON map.
Jamie Hannaford9fdda582015-02-10 12:15:43 +010047func (opts CreateOpts) ToInstanceCreateMap() (map[string]interface{}, error) {
48 if opts.Size > 300 || opts.Size < 1 {
Jon Perritt763e5922016-03-07 03:21:18 -060049 err := gophercloud.ErrInvalidInput{}
Jon Perritt763e5922016-03-07 03:21:18 -060050 err.Argument = "instances.CreateOpts.Size"
51 err.Value = opts.Size
52 err.Info = "Size (GB) must be between 1-300"
53 return nil, err
Jamie Hannaford9fdda582015-02-10 12:15:43 +010054 }
Jon Perrittdb0ae142016-03-13 00:33:41 -060055
Jamie Hannaford9fdda582015-02-10 12:15:43 +010056 if opts.FlavorRef == "" {
Jon Perrittdb0ae142016-03-13 00:33:41 -060057 return nil, gophercloud.ErrMissingInput{Argument: "instances.CreateOpts.FlavorRef"}
Jamie Hannaford9fdda582015-02-10 12:15:43 +010058 }
59
60 instance := map[string]interface{}{
61 "volume": map[string]int{"size": opts.Size},
62 "flavorRef": opts.FlavorRef,
63 }
64
65 if opts.Name != "" {
66 instance["name"] = opts.Name
67 }
Jamie Hannaford2e695a32015-11-16 16:36:10 +010068 if opts.Databases != nil {
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +010069 dbs, err := opts.Databases.ToDBCreateMap()
Jamie Hannaford9fdda582015-02-10 12:15:43 +010070 if err != nil {
71 return nil, err
72 }
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +010073 instance["databases"] = dbs["databases"]
Jamie Hannaford9fdda582015-02-10 12:15:43 +010074 }
Jamie Hannaford2e695a32015-11-16 16:36:10 +010075 if opts.Users != nil {
Jamie Hannaford2ca55d82015-02-12 14:21:55 +010076 users, err := opts.Users.ToUserCreateMap()
Jamie Hannaford9fdda582015-02-10 12:15:43 +010077 if err != nil {
78 return nil, err
79 }
Jamie Hannaford2ca55d82015-02-12 14:21:55 +010080 instance["users"] = users["users"]
Jamie Hannaford9fdda582015-02-10 12:15:43 +010081 }
Jon Perritt763e5922016-03-07 03:21:18 -060082 if opts.Datastore != nil {
83 datastore, err := opts.Datastore.ToMap()
84 if err != nil {
85 return nil, err
86 }
87 instance["datastore"] = datastore
88 }
Jamie Hannaford9fdda582015-02-10 12:15:43 +010089
90 return map[string]interface{}{"instance": instance}, nil
91}
92
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +010093// Create asynchronously provisions a new database instance. It requires the
94// user to specify a flavor and a volume size. The API service then provisions
95// the instance with the requested flavor and sets up a volume of the specified
96// size, which is the storage for the database instance.
97//
98// Although this call only allows the creation of 1 instance per request, you
99// can create an instance with multiple databases and users. The default
100// binding for a MySQL instance is port 3306.
Jamie Hannaford9fdda582015-02-10 12:15:43 +0100101func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600102 var r CreateResult
103 b, err := opts.ToInstanceCreateMap()
Jamie Hannaford9fdda582015-02-10 12:15:43 +0100104 if err != nil {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600105 r.Err = err
106 return r
Jamie Hannaford9fdda582015-02-10 12:15:43 +0100107 }
Jon Perrittdb0ae142016-03-13 00:33:41 -0600108 _, r.Err = client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
109 return r
Jamie Hannaford9fdda582015-02-10 12:15:43 +0100110}
Jamie Hannaford90684242015-02-10 12:46:07 +0100111
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100112// List retrieves the status and information for all database instances.
Jamie Hannaford90684242015-02-10 12:46:07 +0100113func List(client *gophercloud.ServiceClient) pagination.Pager {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600114 return pagination.NewPager(client, baseURL(client), func(r pagination.PageResult) pagination.Page {
Jamie Hannaford90684242015-02-10 12:46:07 +0100115 return InstancePage{pagination.LinkedPageBase{PageResult: r}}
Jon Perrittdb0ae142016-03-13 00:33:41 -0600116 })
Jamie Hannaford90684242015-02-10 12:46:07 +0100117}
Jamie Hannaford821015f2015-02-10 12:58:36 +0100118
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100119// Get retrieves the status and information for a specified database instance.
Jamie Hannaford821015f2015-02-10 12:58:36 +0100120func Get(client *gophercloud.ServiceClient, id string) GetResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600121 var r GetResult
122 _, r.Err = client.Get(resourceURL(client, id), &r.Body, nil)
123 return r
Jamie Hannaford821015f2015-02-10 12:58:36 +0100124}
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100125
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100126// Delete permanently destroys the database instance.
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100127func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600128 var r DeleteResult
129 _, r.Err = client.Delete(resourceURL(client, id), nil)
130 return r
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100131}
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100132
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100133// EnableRootUser enables the login from any host for the root user and
134// provides the user with a generated root password.
Jon Perrittdb0ae142016-03-13 00:33:41 -0600135func EnableRootUser(client *gophercloud.ServiceClient, id string) EnableRootUserResult {
136 var r EnableRootUserResult
137 _, r.Err = client.Post(userRootURL(client, id), nil, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
138 return r
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100139}
Jamie Hannaforda74d4252015-02-10 15:35:01 +0100140
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100141// IsRootEnabled checks an instance to see if root access is enabled. It returns
142// True if root user is enabled for the specified database instance or False
143// otherwise.
Jon Perrittdb0ae142016-03-13 00:33:41 -0600144func IsRootEnabled(client *gophercloud.ServiceClient, id string) IsRootEnabledResult {
145 var r IsRootEnabledResult
146 _, r.Err = client.Get(userRootURL(client, id), &r.Body, nil)
147 return r
Jamie Hannaforda74d4252015-02-10 15:35:01 +0100148}
Jamie Hannaford219ca592015-02-10 15:59:05 +0100149
Jamie Hannaford75e8cc42015-11-16 14:09:25 +0100150// Restart will restart only the MySQL Instance. Restarting MySQL will
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100151// erase any dynamic configuration settings that you have made within MySQL.
152// The MySQL service will be unavailable until the instance restarts.
Jamie Hannaford75e8cc42015-11-16 14:09:25 +0100153func Restart(client *gophercloud.ServiceClient, id string) ActionResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600154 var r ActionResult
155 b := map[string]interface{}{"restart": struct{}{}}
156 _, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
157 return r
Jamie Hannaford219ca592015-02-10 15:59:05 +0100158}
159
Jamie Hannaford75e8cc42015-11-16 14:09:25 +0100160// Resize changes the memory size of the instance, assuming a valid
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100161// flavorRef is provided. It will also restart the MySQL service.
Jamie Hannaford75e8cc42015-11-16 14:09:25 +0100162func Resize(client *gophercloud.ServiceClient, id, flavorRef string) ActionResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600163 var r ActionResult
164 b := map[string]interface{}{"resize": map[string]string{"flavorRef": flavorRef}}
165 _, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
166 return r
Jamie Hannaford219ca592015-02-10 15:59:05 +0100167}
168
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100169// ResizeVolume will resize the attached volume for an instance. It supports
170// only increasing the volume size and does not support decreasing the size.
171// The volume size is in gigabytes (GB) and must be an integer.
Jamie Hannaford219ca592015-02-10 15:59:05 +0100172func ResizeVolume(client *gophercloud.ServiceClient, id string, size int) ActionResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600173 var r ActionResult
174 b := map[string]interface{}{"resize": map[string]interface{}{"volume": map[string]int{"size": size}}}
175 _, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
176 return r
Jamie Hannaford219ca592015-02-10 15:59:05 +0100177}