blob: d87fdecc36686d739c1695f7af21c79408c0d6c9 [file] [log] [blame]
Jamie Hannaford9fdda582015-02-10 12:15:43 +01001package instances
2
3import (
4 "fmt"
5
Jamie Hannaford9fdda582015-02-10 12:15:43 +01006 "github.com/rackspace/gophercloud"
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +01007 db "github.com/rackspace/gophercloud/openstack/db/v1/databases"
Jamie Hannaford3aba0b12015-02-13 14:33:39 +01008 "github.com/rackspace/gophercloud/openstack/db/v1/users"
Jamie Hannaford90684242015-02-10 12:46:07 +01009 "github.com/rackspace/gophercloud/pagination"
Jamie Hannaford9fdda582015-02-10 12:15:43 +010010)
11
12// CreateOptsBuilder is the top-level interface for create options.
13type CreateOptsBuilder interface {
14 ToInstanceCreateMap() (map[string]interface{}, error)
15}
16
Jamie Hannaford9fdda582015-02-10 12:15:43 +010017// CreateOpts is the struct responsible for configuring a new database instance.
18type CreateOpts struct {
19 // Either the integer UUID (in string form) of the flavor, or its URI
20 // reference as specified in the response from the List() call. Required.
21 FlavorRef string
22
23 // Specifies the volume size in gigabytes (GB). The value must be between 1
24 // and 300. Required.
25 Size int
26
27 // Name of the instance to create. The length of the name is limited to
28 // 255 characters and any characters are permitted. Optional.
29 Name string
30
31 // A slice of database information options.
Jamie Hannaford85f10332015-02-12 11:51:37 +010032 Databases db.BatchCreateOpts
Jamie Hannaford9fdda582015-02-10 12:15:43 +010033
34 // A slice of user information options.
Jamie Hannaford2ca55d82015-02-12 14:21:55 +010035 Users users.BatchCreateOpts
Jamie Hannaford9fdda582015-02-10 12:15:43 +010036}
37
Jamie Hannaford9793d942015-02-18 15:13:20 +010038// ToInstanceCreateMap will render a JSON map.
Jamie Hannaford9fdda582015-02-10 12:15:43 +010039func (opts CreateOpts) ToInstanceCreateMap() (map[string]interface{}, error) {
40 if opts.Size > 300 || opts.Size < 1 {
41 return nil, fmt.Errorf("Size (GB) must be between 1-300")
42 }
43 if opts.FlavorRef == "" {
44 return nil, fmt.Errorf("FlavorRef is a required field")
45 }
46
47 instance := map[string]interface{}{
48 "volume": map[string]int{"size": opts.Size},
49 "flavorRef": opts.FlavorRef,
50 }
51
52 if opts.Name != "" {
53 instance["name"] = opts.Name
54 }
55 if len(opts.Databases) > 0 {
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +010056 dbs, err := opts.Databases.ToDBCreateMap()
Jamie Hannaford9fdda582015-02-10 12:15:43 +010057 if err != nil {
58 return nil, err
59 }
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +010060 instance["databases"] = dbs["databases"]
Jamie Hannaford9fdda582015-02-10 12:15:43 +010061 }
62 if len(opts.Users) > 0 {
Jamie Hannaford2ca55d82015-02-12 14:21:55 +010063 users, err := opts.Users.ToUserCreateMap()
Jamie Hannaford9fdda582015-02-10 12:15:43 +010064 if err != nil {
65 return nil, err
66 }
Jamie Hannaford2ca55d82015-02-12 14:21:55 +010067 instance["users"] = users["users"]
Jamie Hannaford9fdda582015-02-10 12:15:43 +010068 }
69
70 return map[string]interface{}{"instance": instance}, nil
71}
72
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +010073// Create asynchronously provisions a new database instance. It requires the
74// user to specify a flavor and a volume size. The API service then provisions
75// the instance with the requested flavor and sets up a volume of the specified
76// size, which is the storage for the database instance.
77//
78// Although this call only allows the creation of 1 instance per request, you
79// can create an instance with multiple databases and users. The default
80// binding for a MySQL instance is port 3306.
Jamie Hannaford9fdda582015-02-10 12:15:43 +010081func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
82 var res CreateResult
83
84 reqBody, err := opts.ToInstanceCreateMap()
85 if err != nil {
86 res.Err = err
87 return res
88 }
89
Jamie Hannaforda50d1352015-02-18 11:38:38 +010090 _, res.Err = client.Request("POST", baseURL(client), gophercloud.RequestOpts{
91 JSONBody: &reqBody,
92 JSONResponse: &res.Body,
93 OkCodes: []int{200},
Jamie Hannaford9fdda582015-02-10 12:15:43 +010094 })
95
Jamie Hannaford9fdda582015-02-10 12:15:43 +010096 return res
97}
Jamie Hannaford90684242015-02-10 12:46:07 +010098
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +010099// List retrieves the status and information for all database instances.
Jamie Hannaford90684242015-02-10 12:46:07 +0100100func List(client *gophercloud.ServiceClient) pagination.Pager {
101 createPageFn := func(r pagination.PageResult) pagination.Page {
102 return InstancePage{pagination.LinkedPageBase{PageResult: r}}
103 }
104
105 return pagination.NewPager(client, baseURL(client), createPageFn)
106}
Jamie Hannaford821015f2015-02-10 12:58:36 +0100107
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100108// Get retrieves the status and information for a specified database instance.
Jamie Hannaford821015f2015-02-10 12:58:36 +0100109func Get(client *gophercloud.ServiceClient, id string) GetResult {
110 var res GetResult
111
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100112 _, res.Err = client.Request("GET", resourceURL(client, id), gophercloud.RequestOpts{
113 JSONResponse: &res.Body,
114 OkCodes: []int{200},
Jamie Hannaford821015f2015-02-10 12:58:36 +0100115 })
116
Jamie Hannaford821015f2015-02-10 12:58:36 +0100117 return res
118}
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100119
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100120// Delete permanently destroys the database instance.
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100121func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
122 var res DeleteResult
123
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100124 _, res.Err = client.Request("DELETE", resourceURL(client, id), gophercloud.RequestOpts{
125 OkCodes: []int{202},
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100126 })
127
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100128 return res
129}
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100130
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100131// EnableRootUser enables the login from any host for the root user and
132// provides the user with a generated root password.
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100133func EnableRootUser(client *gophercloud.ServiceClient, id string) UserRootResult {
134 var res UserRootResult
135
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100136 _, res.Err = client.Request("POST", userRootURL(client, id), gophercloud.RequestOpts{
137 JSONResponse: &res.Body,
138 OkCodes: []int{200},
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100139 })
140
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100141 return res
142}
Jamie Hannaforda74d4252015-02-10 15:35:01 +0100143
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100144// IsRootEnabled checks an instance to see if root access is enabled. It returns
145// True if root user is enabled for the specified database instance or False
146// otherwise.
Jamie Hannaforda74d4252015-02-10 15:35:01 +0100147func IsRootEnabled(client *gophercloud.ServiceClient, id string) (bool, error) {
148 var res gophercloud.Result
149
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100150 _, err := client.Request("GET", userRootURL(client, id), gophercloud.RequestOpts{
151 JSONResponse: &res.Body,
152 OkCodes: []int{200},
Jamie Hannaforda74d4252015-02-10 15:35:01 +0100153 })
154
155 return res.Body.(map[string]interface{})["rootEnabled"] == true, err
156}
Jamie Hannaford219ca592015-02-10 15:59:05 +0100157
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100158// RestartService will restart only the MySQL Instance. Restarting MySQL will
159// erase any dynamic configuration settings that you have made within MySQL.
160// The MySQL service will be unavailable until the instance restarts.
Jamie Hannaford219ca592015-02-10 15:59:05 +0100161func RestartService(client *gophercloud.ServiceClient, id string) ActionResult {
162 var res ActionResult
163
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100164 _, res.Err = client.Request("POST", actionURL(client, id), gophercloud.RequestOpts{
165 JSONBody: map[string]bool{"restart": true},
166 OkCodes: []int{202},
Jamie Hannaford219ca592015-02-10 15:59:05 +0100167 })
168
Jamie Hannaford219ca592015-02-10 15:59:05 +0100169 return res
170}
171
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100172// ResizeInstance changes the memory size of the instance, assuming a valid
173// flavorRef is provided. It will also restart the MySQL service.
Jamie Hannaford219ca592015-02-10 15:59:05 +0100174func ResizeInstance(client *gophercloud.ServiceClient, id, flavorRef string) ActionResult {
175 var res ActionResult
176
177 reqBody := map[string]map[string]string{
178 "resize": map[string]string{
179 "flavorRef": flavorRef,
180 },
181 }
182
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100183 _, res.Err = client.Request("POST", actionURL(client, id), gophercloud.RequestOpts{
184 JSONBody: reqBody,
185 OkCodes: []int{202},
Jamie Hannaford219ca592015-02-10 15:59:05 +0100186 })
187
Jamie Hannaford219ca592015-02-10 15:59:05 +0100188 return res
189}
190
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100191// ResizeVolume will resize the attached volume for an instance. It supports
192// only increasing the volume size and does not support decreasing the size.
193// The volume size is in gigabytes (GB) and must be an integer.
Jamie Hannaford219ca592015-02-10 15:59:05 +0100194func ResizeVolume(client *gophercloud.ServiceClient, id string, size int) ActionResult {
195 var res ActionResult
196
197 reqBody := map[string]map[string]map[string]int{
198 "resize": map[string]map[string]int{
199 "volume": map[string]int{"size": size},
200 },
201 }
202
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100203 _, res.Err = client.Request("POST", actionURL(client, id), gophercloud.RequestOpts{
204 JSONBody: reqBody,
205 OkCodes: []int{202},
Jamie Hannaford219ca592015-02-10 15:59:05 +0100206 })
207
Jamie Hannaford219ca592015-02-10 15:59:05 +0100208 return res
209}