blob: 4f0664958e14df3cdfb300848e966ae38eaa7d5d [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.
Jon Perritt3860b512016-03-29 12:01:48 -0500101func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600102 b, err := opts.ToInstanceCreateMap()
Jamie Hannaford9fdda582015-02-10 12:15:43 +0100103 if err != nil {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600104 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500105 return
Jamie Hannaford9fdda582015-02-10 12:15:43 +0100106 }
Jon Perrittdb0ae142016-03-13 00:33:41 -0600107 _, r.Err = client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
jrperritt29ae6b32016-04-13 12:59:37 -0500108 return
Jamie Hannaford9fdda582015-02-10 12:15:43 +0100109}
Jamie Hannaford90684242015-02-10 12:46:07 +0100110
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100111// List retrieves the status and information for all database instances.
Jamie Hannaford90684242015-02-10 12:46:07 +0100112func List(client *gophercloud.ServiceClient) pagination.Pager {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600113 return pagination.NewPager(client, baseURL(client), func(r pagination.PageResult) pagination.Page {
Jamie Hannaford90684242015-02-10 12:46:07 +0100114 return InstancePage{pagination.LinkedPageBase{PageResult: r}}
Jon Perrittdb0ae142016-03-13 00:33:41 -0600115 })
Jamie Hannaford90684242015-02-10 12:46:07 +0100116}
Jamie Hannaford821015f2015-02-10 12:58:36 +0100117
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100118// Get retrieves the status and information for a specified database instance.
Jon Perritt3860b512016-03-29 12:01:48 -0500119func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600120 _, r.Err = client.Get(resourceURL(client, id), &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500121 return
Jamie Hannaford821015f2015-02-10 12:58:36 +0100122}
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100123
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100124// Delete permanently destroys the database instance.
Jon Perritt3860b512016-03-29 12:01:48 -0500125func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600126 _, r.Err = client.Delete(resourceURL(client, id), nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500127 return
Jamie Hannaford5b16b632015-02-10 13:36:23 +0100128}
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100129
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100130// EnableRootUser enables the login from any host for the root user and
131// provides the user with a generated root password.
Jon Perritt3860b512016-03-29 12:01:48 -0500132func EnableRootUser(client *gophercloud.ServiceClient, id string) (r EnableRootUserResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600133 _, r.Err = client.Post(userRootURL(client, id), nil, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
jrperritt29ae6b32016-04-13 12:59:37 -0500134 return
Jamie Hannaford94164fa2015-02-10 13:58:45 +0100135}
Jamie Hannaforda74d4252015-02-10 15:35:01 +0100136
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100137// IsRootEnabled checks an instance to see if root access is enabled. It returns
138// True if root user is enabled for the specified database instance or False
139// otherwise.
Jon Perritt3860b512016-03-29 12:01:48 -0500140func IsRootEnabled(client *gophercloud.ServiceClient, id string) (r IsRootEnabledResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600141 _, r.Err = client.Get(userRootURL(client, id), &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500142 return
Jamie Hannaforda74d4252015-02-10 15:35:01 +0100143}
Jamie Hannaford219ca592015-02-10 15:59:05 +0100144
Jamie Hannaford75e8cc42015-11-16 14:09:25 +0100145// Restart will restart only the MySQL Instance. Restarting MySQL will
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100146// erase any dynamic configuration settings that you have made within MySQL.
147// The MySQL service will be unavailable until the instance restarts.
Jon Perritt3860b512016-03-29 12:01:48 -0500148func Restart(client *gophercloud.ServiceClient, id string) (r ActionResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600149 b := map[string]interface{}{"restart": struct{}{}}
150 _, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500151 return
Jamie Hannaford219ca592015-02-10 15:59:05 +0100152}
153
Jamie Hannaford75e8cc42015-11-16 14:09:25 +0100154// Resize changes the memory size of the instance, assuming a valid
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100155// flavorRef is provided. It will also restart the MySQL service.
Jon Perritt3860b512016-03-29 12:01:48 -0500156func Resize(client *gophercloud.ServiceClient, id, flavorRef string) (r ActionResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600157 b := map[string]interface{}{"resize": map[string]string{"flavorRef": flavorRef}}
158 _, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500159 return
Jamie Hannaford219ca592015-02-10 15:59:05 +0100160}
161
Jamie Hannaford56d0c2e2015-02-12 11:50:18 +0100162// ResizeVolume will resize the attached volume for an instance. It supports
163// only increasing the volume size and does not support decreasing the size.
164// The volume size is in gigabytes (GB) and must be an integer.
Jon Perritt3860b512016-03-29 12:01:48 -0500165func ResizeVolume(client *gophercloud.ServiceClient, id string, size int) (r ActionResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600166 b := map[string]interface{}{"resize": map[string]interface{}{"volume": map[string]int{"size": size}}}
167 _, r.Err = client.Post(actionURL(client, id), &b, nil, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500168 return
Jamie Hannaford219ca592015-02-10 15:59:05 +0100169}